From fb9258d3ac58757cd69e0a0b40f92c7e99feaa3d Mon Sep 17 00:00:00 2001 From: zelbitar Date: Wed, 9 Jun 2021 14:41:52 +0200 Subject: [PATCH 01/26] Enabling the access of the triggers list in method DecodeNextEvent in BoardReaderMimosis --- code/include/BoardReaderMIMOSIS.h | 10 +- code/src/BoardReaderMIMOSIS.cxx | 252 +- code/src/DAcq.cxx | 5 +- code/src/DCut.cxx | 2 +- code/src/DHit.cxx | 33 +- code/src/DPlane.cxx | 12 +- code/src/MMain.cxx | 1 + code/src/MRaw.cxx | 8 +- include/AliMIMOSA22RawStreamVASingle.h | 99 + include/BoardReader.h | 90 + include/BoardReaderEUDAQ.h | 142 + include/BoardReaderIHEP.h | 187 + include/BoardReaderMIMOSIS.h | 111 + include/DAcq.h | 173 + include/DAlign.h | 149 + include/DBeaster.h | 328 + include/DCut.h | 74 + include/DEvent.h | 367 + include/DEventMC.h | 171 + include/DGlobalTools.h | 226 + include/DHelix.h | 66 + include/DHelixFitter.h | 103 + include/DHit.h | 224 + include/DLadder.h | 166 + include/DLine.h | 72 + include/DMiniVector.h | 109 + include/DModule.h | 74 + include/DMonteCarlo.h | 58 + include/DParticle.h | 45 + include/DPixel.h | 120 + include/DPlane.h | 397 + include/DPrecAlign.h | 176 + include/DPrecAlign_linkdef.h | 1 + include/DR3.h | 74 + include/DSession.h | 164 + include/DSetup.h | 460 + include/DStrip.h | 161 + include/DTLinkDef.h | 79 + include/DTrack.h | 129 + include/DTrackFitter.h | 110 + include/DTracker.h | 258 + include/DXRay2DPdf.h | 75 + include/DecoderGeant.h | 82 + include/DecoderM18.h | 103 + include/DecoderM18_fb.h | 185 + include/GIGBoardReader.h | 166 + include/IMGBoardReader.h | 222 + include/MAlign.h | 207 + include/MAlignment.h | 106 + include/MAnalysis.h | 890 + include/MCBoardReader.h | 287 + include/MGlobalAlign.h | 212 + include/MHist.h | 950 + include/MKalmanFilter.h | 224 + include/MLeastChiSquare.h | 81 + include/MLinkDef.h | 16 + include/MMillepede.h | 122 + include/MRaw.h | 312 + include/MRax.h | 1051 + include/PXIBoardReader.h | 167 + include/PXIeBoardReader.h | 277 + include/TMimosa24_25Map.h | 201 + include/TNTBoardReader.h | 165 + include/VMEBoardReader.h | 137 + include/img_daq_lib/das.h | 31 + include/img_daq_lib/event_header.typ | 108 + include/mi26types.h | 47 + include/mimo_daq_lib/.DS_Store | Bin 0 -> 10244 bytes include/mimo_daq_lib/c4pi_test_team.h | 166 + include/mimo_daq_lib/errors_light.c | 1089 + include/mimo_daq_lib/errors_light.h | 361 + include/mimo_daq_lib/globals_root.def | 43 + include/mimo_daq_lib/mimo_daq_lib.c | 65 + include/mimo_daq_lib/mimo_daq_lib.h | 106 + include/mimo_daq_lib/msg_light.c | 559 + include/mimo_daq_lib/msg_light.h | 194 + include/mimo_daq_lib/msis1_data.c | 22394 ++++++++++++++++ include/mimo_daq_lib/msis1_data.def | 799 + include/mimo_daq_lib/msis1_data.typ | 2800 ++ include/mimo_daq_lib/msis1_data_exp.h | 69 + include/mimo_daq_lib/sync_index_rec.c | 163 + include/mimo_daq_lib/sync_index_rec.typ | 57 + include/mimo_daq_lib/types.def | 35 + include/mimo_daq_lib/types.typ | 167 + include/mimo_daq_lib/var_decl_def.h | 57 + include/pxi_daq_lib_config.h | 163 + include/pxi_daq_lib_v.0.0/asic.def | 56 + include/pxi_daq_lib_v.0.0/asic.typ | 46 + include/pxi_daq_lib_v.0.0/daq_pxi.def | 89 + include/pxi_daq_lib_v.0.0/globals.def | 37 + include/pxi_daq_lib_v.0.0/maps.def | 49 + include/pxi_daq_lib_v.0.0/mi26.def | 175 + include/pxi_daq_lib_v.0.0/mi26.typ | 1195 + include/pxi_daq_lib_v.0.0/types.typ | 151 + include/pxi_daq_lib_v.1.0/asic.def | 92 + include/pxi_daq_lib_v.1.0/asic.typ | 51 + include/pxi_daq_lib_v.1.0/asic.var | 35 + include/pxi_daq_lib_v.1.0/errors.c | 336 + include/pxi_daq_lib_v.1.0/errors.def | 153 + include/pxi_daq_lib_v.1.0/errors.typ | 27 + include/pxi_daq_lib_v.1.0/errors.var | 79 + include/pxi_daq_lib_v.1.0/eudet_frio.def | 226 + include/pxi_daq_lib_v.1.0/eudet_frio.typ | 792 + include/pxi_daq_lib_v.1.0/eudet_frio.var | 39 + include/pxi_daq_lib_v.1.0/eudet_frio_print.c | 1009 + include/pxi_daq_lib_v.1.0/files.c | 3744 +++ include/pxi_daq_lib_v.1.0/files.def | 33 + include/pxi_daq_lib_v.1.0/files.typ | 279 + include/pxi_daq_lib_v.1.0/files.var | 18 + include/pxi_daq_lib_v.1.0/globals.def | 39 + include/pxi_daq_lib_v.1.0/globals_root.def | 44 + include/pxi_daq_lib_v.1.0/maps.def | 49 + include/pxi_daq_lib_v.1.0/maps.typ | 383 + include/pxi_daq_lib_v.1.0/maps.var | 33 + include/pxi_daq_lib_v.1.0/mi26_usr.def | 75 + include/pxi_daq_lib_v.1.0/mi26_usr.typ | 193 + include/pxi_daq_lib_v.1.0/msg.c | 230 + include/pxi_daq_lib_v.1.0/msg.def | 63 + include/pxi_daq_lib_v.1.0/msg.typ | 27 + include/pxi_daq_lib_v.1.0/msg.var | 59 + include/pxi_daq_lib_v.1.0/pxi_daq_lib_v.1.0.c | 754 + include/pxi_daq_lib_v.1.0/time.c | 623 + include/pxi_daq_lib_v.1.0/time.def | 40 + include/pxi_daq_lib_v.1.0/time.typ | 140 + include/pxi_daq_lib_v.1.0/time.var | 35 + include/pxi_daq_lib_v.1.0/types.typ | 164 + include/pxi_daq_lib_v.1.1/asic.def | 92 + include/pxi_daq_lib_v.1.1/asic.typ | 51 + include/pxi_daq_lib_v.1.1/asic.var | 35 + include/pxi_daq_lib_v.1.1/daq_lib.c | 645 + include/pxi_daq_lib_v.1.1/daq_lib.h | 115 + include/pxi_daq_lib_v.1.1/errors.c | 336 + include/pxi_daq_lib_v.1.1/errors.def | 153 + include/pxi_daq_lib_v.1.1/errors.typ | 27 + include/pxi_daq_lib_v.1.1/errors.var | 79 + include/pxi_daq_lib_v.1.1/eudet_frio.def | 233 + include/pxi_daq_lib_v.1.1/eudet_frio.typ | 792 + include/pxi_daq_lib_v.1.1/eudet_frio.var | 39 + include/pxi_daq_lib_v.1.1/eudet_frio_print.c | 1009 + include/pxi_daq_lib_v.1.1/files.c | 3772 +++ include/pxi_daq_lib_v.1.1/files.def | 42 + include/pxi_daq_lib_v.1.1/files.typ | 281 + include/pxi_daq_lib_v.1.1/files.var | 18 + include/pxi_daq_lib_v.1.1/globals.def | 39 + include/pxi_daq_lib_v.1.1/globals_root.def | 44 + include/pxi_daq_lib_v.1.1/maps.def | 49 + include/pxi_daq_lib_v.1.1/maps.typ | 383 + include/pxi_daq_lib_v.1.1/maps.var | 33 + include/pxi_daq_lib_v.1.1/mi26_usr.def | 75 + include/pxi_daq_lib_v.1.1/mi26_usr.typ | 193 + include/pxi_daq_lib_v.1.1/msg.c | 230 + include/pxi_daq_lib_v.1.1/msg.def | 63 + include/pxi_daq_lib_v.1.1/msg.typ | 27 + include/pxi_daq_lib_v.1.1/msg.var | 59 + include/pxi_daq_lib_v.1.1/pxi_daq_lib_v.1.1.c | 758 + include/pxi_daq_lib_v.1.1/sync_index_rec.c | 163 + include/pxi_daq_lib_v.1.1/sync_index_rec.typ | 57 + include/pxi_daq_lib_v.1.1/time.c | 623 + include/pxi_daq_lib_v.1.1/time.def | 40 + include/pxi_daq_lib_v.1.1/time.typ | 140 + include/pxi_daq_lib_v.1.1/time.var | 35 + include/pxi_daq_lib_v.1.1/types.typ | 167 + include/pxi_daq_lib_v.1.2/asic.def | 92 + include/pxi_daq_lib_v.1.2/asic.typ | 51 + include/pxi_daq_lib_v.1.2/asic.var | 35 + include/pxi_daq_lib_v.1.2/daq_lib.c | 647 + include/pxi_daq_lib_v.1.2/daq_lib.h | 141 + include/pxi_daq_lib_v.1.2/errors.c | 336 + include/pxi_daq_lib_v.1.2/errors.def | 153 + include/pxi_daq_lib_v.1.2/errors.typ | 27 + include/pxi_daq_lib_v.1.2/errors.var | 79 + include/pxi_daq_lib_v.1.2/eudet_frio.c | 8455 ++++++ include/pxi_daq_lib_v.1.2/eudet_frio.def | 268 + include/pxi_daq_lib_v.1.2/eudet_frio.typ | 972 + include/pxi_daq_lib_v.1.2/eudet_frio.var | 39 + include/pxi_daq_lib_v.1.2/eudet_frio_print.c | 1148 + include/pxi_daq_lib_v.1.2/files.c | 3773 +++ include/pxi_daq_lib_v.1.2/files.def | 89 + include/pxi_daq_lib_v.1.2/files.typ | 281 + include/pxi_daq_lib_v.1.2/files.var | 18 + include/pxi_daq_lib_v.1.2/globals.def | 39 + include/pxi_daq_lib_v.1.2/globals_root.def | 44 + include/pxi_daq_lib_v.1.2/maps.def | 49 + include/pxi_daq_lib_v.1.2/maps.typ | 383 + include/pxi_daq_lib_v.1.2/maps.var | 33 + include/pxi_daq_lib_v.1.2/mi26_usr.def | 75 + include/pxi_daq_lib_v.1.2/mi26_usr.typ | 193 + include/pxi_daq_lib_v.1.2/msg.c | 230 + include/pxi_daq_lib_v.1.2/msg.def | 63 + include/pxi_daq_lib_v.1.2/msg.typ | 27 + include/pxi_daq_lib_v.1.2/msg.var | 59 + include/pxi_daq_lib_v.1.2/sync_index_rec.c | 163 + include/pxi_daq_lib_v.1.2/sync_index_rec.typ | 57 + include/pxi_daq_lib_v.1.2/time.c | 623 + include/pxi_daq_lib_v.1.2/time.def | 40 + include/pxi_daq_lib_v.1.2/time.typ | 140 + include/pxi_daq_lib_v.1.2/time.var | 35 + include/pxi_daq_lib_v.1.2/types.typ | 167 + .../pxi_daq_lib_v.2.1/Copie de eudet_frio.c | 13185 +++++++++ .../Copie de eudet_frio_emul.c | 2100 ++ include/pxi_daq_lib_v.2.1/__eudet_frio.h | 37 + include/pxi_daq_lib_v.2.1/_errors.c | 320 + include/pxi_daq_lib_v.2.1/_eudet_frio.typ | 792 + include/pxi_daq_lib_v.2.1/a.out | Bin 0 -> 249084 bytes include/pxi_daq_lib_v.2.1/asic.c | 93 + include/pxi_daq_lib_v.2.1/asic.def | 238 + include/pxi_daq_lib_v.2.1/asic.h | 39 + include/pxi_daq_lib_v.2.1/asic.typ | 51 + include/pxi_daq_lib_v.2.1/asic.var | 35 + include/pxi_daq_lib_v.2.1/backup.c | 412 + include/pxi_daq_lib_v.2.1/cc.def | 33 + include/pxi_daq_lib_v.2.1/com.def | 36 + include/pxi_daq_lib_v.2.1/com.typ | 32 + include/pxi_daq_lib_v.2.1/com_pc.c | 542 + include/pxi_daq_lib_v.2.1/com_pc.def | 31 + include/pxi_daq_lib_v.2.1/com_pc.h | 18 + include/pxi_daq_lib_v.2.1/com_pc.typ | 26 + include/pxi_daq_lib_v.2.1/com_pc.var | 20 + include/pxi_daq_lib_v.2.1/com_uc.c | 290 + include/pxi_daq_lib_v.2.1/com_uc.def | 27 + include/pxi_daq_lib_v.2.1/com_uc.h | 18 + include/pxi_daq_lib_v.2.1/com_uc.typ | 27 + include/pxi_daq_lib_v.2.1/com_uc.var | 21 + include/pxi_daq_lib_v.2.1/daq_lib.c | 1142 + include/pxi_daq_lib_v.2.1/dbg_log.def | 69 + include/pxi_daq_lib_v.2.1/dbg_log.typ | 25 + include/pxi_daq_lib_v.2.1/dbg_log.var | 31 + include/pxi_daq_lib_v.2.1/errors.c | 360 + include/pxi_daq_lib_v.2.1/errors.def | 153 + include/pxi_daq_lib_v.2.1/errors.h | 71 + include/pxi_daq_lib_v.2.1/errors.txt | 73 + include/pxi_daq_lib_v.2.1/errors.typ | 27 + include/pxi_daq_lib_v.2.1/errors.var | 79 + include/pxi_daq_lib_v.2.1/eudet_frio.c | 13478 ++++++++++ include/pxi_daq_lib_v.2.1/eudet_frio.def | 279 + include/pxi_daq_lib_v.2.1/eudet_frio.h | 96 + include/pxi_daq_lib_v.2.1/eudet_frio.typ | 996 + include/pxi_daq_lib_v.2.1/eudet_frio.var | 43 + .../pxi_daq_lib_v.2.1/eudet_frio__100112.c | 9791 +++++++ .../pxi_daq_lib_v.2.1/eudet_frio__270411.c | 6068 +++++ ...udet_frio__all_func_in_file_061110_13H43.c | 9274 +++++++ ...udet_frio__all_func_in_file_061110_13H43.h | 133 + .../eudet_frio_array_one.typ | 792 + .../eudet_frio_array_zero.typ | 792 + include/pxi_daq_lib_v.2.1/eudet_frio_dbg.c | 449 + include/pxi_daq_lib_v.2.1/eudet_frio_dbg.h | 42 + include/pxi_daq_lib_v.2.1/eudet_frio_emul.c | 4543 ++++ include/pxi_daq_lib_v.2.1/eudet_frio_emul.h | 48 + include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.c | 2883 ++ include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.h | 45 + include/pxi_daq_lib_v.2.1/eudet_frio_get.c | 2182 ++ include/pxi_daq_lib_v.2.1/eudet_frio_get.h | 104 + include/pxi_daq_lib_v.2.1/eudet_frio_print.c | 1460 + include/pxi_daq_lib_v.2.1/eudet_frio_print.h | 59 + include/pxi_daq_lib_v.2.1/eudet_frio_set.c | 449 + include/pxi_daq_lib_v.2.1/eudet_frio_set.h | 69 + include/pxi_daq_lib_v.2.1/eudet_frio_ult1.c | 9046 +++++++ include/pxi_daq_lib_v.2.1/eudet_frio_ult1.h | 60 + .../eudet_frio_ult1_300513.c | 6453 +++++ .../eudet_frio_ult1__code_listing.c | 7921 ++++++ include/pxi_daq_lib_v.2.1/eudet_frio_usr.c | 2240 ++ include/pxi_daq_lib_v.2.1/eudet_frio_usr.def | 66 + include/pxi_daq_lib_v.2.1/eudet_frio_usr.h | 74 + include/pxi_daq_lib_v.2.1/eudet_frio_usr.typ | 105 + include/pxi_daq_lib_v.2.1/eudet_frio_usr.var | 34 + include/pxi_daq_lib_v.2.1/files.c | 5127 ++++ include/pxi_daq_lib_v.2.1/files.def | 51 + include/pxi_daq_lib_v.2.1/files.h | 62 + include/pxi_daq_lib_v.2.1/files.typ | 341 + include/pxi_daq_lib_v.2.1/files.var | 21 + include/pxi_daq_lib_v.2.1/files__090112.c | 3744 +++ include/pxi_daq_lib_v.2.1/fsbb0.c | 7972 ++++++ include/pxi_daq_lib_v.2.1/fsbb0.def | 204 + include/pxi_daq_lib_v.2.1/fsbb0.h | 58 + include/pxi_daq_lib_v.2.1/fsbb0.typ | 1233 + include/pxi_daq_lib_v.2.1/fsbb0.var | 36 + include/pxi_daq_lib_v.2.1/fsbb0_110614.c | 7346 +++++ include/pxi_daq_lib_v.2.1/fsbb0_110614.def | 204 + include/pxi_daq_lib_v.2.1/fsbb0_convert_frm.c | 774 + include/pxi_daq_lib_v.2.1/fsbb0_test_ult1.def | 214 + include/pxi_daq_lib_v.2.1/fsbb0_usr.c | 114 + include/pxi_daq_lib_v.2.1/fsbb0_usr.def | 210 + include/pxi_daq_lib_v.2.1/fsbb0_usr.h | 41 + include/pxi_daq_lib_v.2.1/fsbb0_usr.typ | 414 + include/pxi_daq_lib_v.2.1/fsbb0_usr.var | 44 + .../pxi_daq_lib_v.2.1/fsbb0_usr_020614.typ | 316 + .../pxi_daq_lib_v.2.1/fsbb0_usr_110614.def | 144 + .../pxi_daq_lib_v.2.1/fsbb0_usr_110614.typ | 316 + .../pxi_daq_lib_v.2.1/fsbb0_usr_220514.def | 82 + .../pxi_daq_lib_v.2.1/fsbb0_usr_220514.typ | 194 + .../pxi_daq_lib_v.2.1/fsbb0_usr_test_ult1.def | 80 + include/pxi_daq_lib_v.2.1/globals.def | 39 + include/pxi_daq_lib_v.2.1/globals_root.def | 44 + include/pxi_daq_lib_v.2.1/inter_app_com.c | 3991 +++ include/pxi_daq_lib_v.2.1/inter_app_com.def | 95 + include/pxi_daq_lib_v.2.1/inter_app_com.h | 108 + .../pxi_daq_lib_v.2.1/inter_app_com.old1.c | 4256 +++ .../pxi_daq_lib_v.2.1/inter_app_com.old2.c | 3648 +++ include/pxi_daq_lib_v.2.1/inter_app_com.typ | 336 + include/pxi_daq_lib_v.2.1/inter_app_com.var | 36 + include/pxi_daq_lib_v.2.1/maps.c | 1241 + include/pxi_daq_lib_v.2.1/maps.def | 59 + include/pxi_daq_lib_v.2.1/maps.h | 38 + include/pxi_daq_lib_v.2.1/maps.typ | 383 + include/pxi_daq_lib_v.2.1/maps.var | 33 + include/pxi_daq_lib_v.2.1/math.c | 4350 +++ include/pxi_daq_lib_v.2.1/math.def | 27 + include/pxi_daq_lib_v.2.1/math.h | 69 + include/pxi_daq_lib_v.2.1/math.typ | 8 + include/pxi_daq_lib_v.2.1/math.var | 7 + include/pxi_daq_lib_v.2.1/mi26_usr.c | 115 + include/pxi_daq_lib_v.2.1/mi26_usr.def | 75 + include/pxi_daq_lib_v.2.1/mi26_usr.h | 41 + include/pxi_daq_lib_v.2.1/mi26_usr.typ | 193 + include/pxi_daq_lib_v.2.1/mi26_usr.var | 33 + include/pxi_daq_lib_v.2.1/msg.c | 230 + include/pxi_daq_lib_v.2.1/msg.def | 63 + include/pxi_daq_lib_v.2.1/msg.h | 69 + include/pxi_daq_lib_v.2.1/msg.txt | 4456 +++ include/pxi_daq_lib_v.2.1/msg.typ | 27 + include/pxi_daq_lib_v.2.1/msg.var | 59 + include/pxi_daq_lib_v.2.1/pipe.c | 1142 + include/pxi_daq_lib_v.2.1/pipe.def | 75 + include/pxi_daq_lib_v.2.1/pipe.h | 34 + include/pxi_daq_lib_v.2.1/pipe.typ | 52 + include/pxi_daq_lib_v.2.1/pipe.var | 22 + include/pxi_daq_lib_v.2.1/pport.c | 1364 + include/pxi_daq_lib_v.2.1/pport.def | 33 + include/pxi_daq_lib_v.2.1/pport.h | 68 + include/pxi_daq_lib_v.2.1/pport.typ | 84 + include/pxi_daq_lib_v.2.1/pport.var | 46 + include/pxi_daq_lib_v.2.1/sync_index_rec.c | 163 + include/pxi_daq_lib_v.2.1/sync_index_rec.typ | 57 + include/pxi_daq_lib_v.2.1/system.def | 110 + include/pxi_daq_lib_v.2.1/time.c | 623 + include/pxi_daq_lib_v.2.1/time.def | 40 + include/pxi_daq_lib_v.2.1/time.h | 39 + include/pxi_daq_lib_v.2.1/time.typ | 140 + include/pxi_daq_lib_v.2.1/time.var | 35 + include/pxi_daq_lib_v.2.1/tools.h | 47 + include/pxi_daq_lib_v.2.1/types.def | 34 + include/pxi_daq_lib_v.2.1/types.typ | 187 + include/pxi_daq_lib_v.2.1/ult1.c | 7294 +++++ include/pxi_daq_lib_v.2.1/ult1.def | 221 + include/pxi_daq_lib_v.2.1/ult1.h | 53 + include/pxi_daq_lib_v.2.1/ult1.typ | 1223 + include/pxi_daq_lib_v.2.1/ult1.var | 33 + include/pxi_daq_lib_v.2.1/ult1_test_mi26.def | 191 + include/pxi_daq_lib_v.2.1/ult1_usr.c | 115 + include/pxi_daq_lib_v.2.1/ult1_usr.def | 86 + include/pxi_daq_lib_v.2.1/ult1_usr.h | 41 + include/pxi_daq_lib_v.2.1/ult1_usr.typ | 193 + include/pxi_daq_lib_v.2.1/ult1_usr.var | 33 + .../pxi_daq_lib_v.2.1/ult1_usr_test_mi26.def | 76 + include/pxi_daq_lib_v.2.1/vme_stat.h | 19 + include/pxi_daq_lib_v.2.1/win_files.c | 3387 +++ include/pxi_daq_lib_v.2.1/win_files.def | 29 + include/pxi_daq_lib_v.2.1/win_files.h | 51 + include/pxi_daq_lib_v.2.1/win_files.typ | 261 + include/pxi_daq_lib_v.2.1/win_files.var | 16 + include/pxi_daq_lib_v.2.1/win_globals.def | 37 + include/pxi_daq_lib_v.2.1/win_time.c | 622 + include/pxi_daq_lib_v.2.1/win_types.typ | 148 + include/pxi_daq_lib_v.3.1/asic.def | 238 + include/pxi_daq_lib_v.3.1/asic.typ | 51 + include/pxi_daq_lib_v.3.1/asic.var | 35 + include/pxi_daq_lib_v.3.1/daq_lib.c | 1306 + include/pxi_daq_lib_v.3.1/errors.c | 360 + include/pxi_daq_lib_v.3.1/errors.def | 153 + include/pxi_daq_lib_v.3.1/errors.typ | 27 + include/pxi_daq_lib_v.3.1/errors.var | 79 + include/pxi_daq_lib_v.3.1/eudet_frio.def | 271 + include/pxi_daq_lib_v.3.1/eudet_frio.typ | 996 + include/pxi_daq_lib_v.3.1/eudet_frio.var | 43 + include/pxi_daq_lib_v.3.1/eudet_frio_fsbb0.c | 2883 ++ include/pxi_daq_lib_v.3.1/eudet_frio_print.c | 1460 + include/pxi_daq_lib_v.3.1/eudet_frio_usr.def | 66 + include/pxi_daq_lib_v.3.1/eudet_frio_usr.typ | 105 + include/pxi_daq_lib_v.3.1/eudet_frio_usr.var | 34 + include/pxi_daq_lib_v.3.1/files.c | 5135 ++++ include/pxi_daq_lib_v.3.1/files.def | 105 + include/pxi_daq_lib_v.3.1/files.typ | 341 + include/pxi_daq_lib_v.3.1/files.var | 21 + include/pxi_daq_lib_v.3.1/fsbb0.def | 204 + include/pxi_daq_lib_v.3.1/fsbb0.typ | 1233 + include/pxi_daq_lib_v.3.1/fsbb0_test_ult1.def | 214 + include/pxi_daq_lib_v.3.1/fsbb0_usr.def | 210 + include/pxi_daq_lib_v.3.1/fsbb0_usr.typ | 414 + .../pxi_daq_lib_v.3.1/fsbb0_usr_test_ult1.def | 80 + include/pxi_daq_lib_v.3.1/globals.def | 39 + include/pxi_daq_lib_v.3.1/globals_root.def | 44 + include/pxi_daq_lib_v.3.1/maps.def | 59 + include/pxi_daq_lib_v.3.1/maps.typ | 383 + include/pxi_daq_lib_v.3.1/maps.var | 33 + include/pxi_daq_lib_v.3.1/math.c | 4350 +++ include/pxi_daq_lib_v.3.1/math.def | 27 + include/pxi_daq_lib_v.3.1/math.typ | 8 + include/pxi_daq_lib_v.3.1/math.var | 7 + include/pxi_daq_lib_v.3.1/mi26_usr.def | 75 + include/pxi_daq_lib_v.3.1/mi26_usr.typ | 193 + include/pxi_daq_lib_v.3.1/msg.c | 230 + include/pxi_daq_lib_v.3.1/msg.def | 63 + include/pxi_daq_lib_v.3.1/msg.typ | 27 + include/pxi_daq_lib_v.3.1/msg.var | 59 + include/pxi_daq_lib_v.3.1/sync_index_rec.c | 163 + include/pxi_daq_lib_v.3.1/sync_index_rec.typ | 57 + include/pxi_daq_lib_v.3.1/time.c | 623 + include/pxi_daq_lib_v.3.1/time.def | 40 + include/pxi_daq_lib_v.3.1/time.typ | 140 + include/pxi_daq_lib_v.3.1/time.var | 35 + include/pxi_daq_lib_v.3.1/types.def | 34 + include/pxi_daq_lib_v.3.1/types.typ | 187 + include/pxi_daq_lib_v.3.1/ult1.def | 221 + include/pxi_daq_lib_v.3.1/ult1.typ | 1223 + include/pxi_daq_lib_v.3.1/ult1_test_mi26.def | 191 + include/pxi_daq_lib_v.3.1/ult1_usr.def | 86 + include/pxi_daq_lib_v.3.1/ult1_usr.typ | 193 + .../pxi_daq_lib_v.3.1/ult1_usr_test_mi26.def | 76 + include/spiralNumerotation.h | 43 + include/sup_exp.typ | 212 + include/tiff.h | 437 + include/tiffio.h | 314 + include/vetoPixels.c | 3429 +++ src/AliMIMOSA22RawStreamVASingle.cxx | 242 + src/BoardReader.cxx | 48 + src/BoardReaderEUDAQ.cxx | 740 + src/BoardReaderIHEP.cxx | 1095 + src/BoardReaderMIMOSIS.cxx | 1490 + src/DAcq.cxx | 2456 ++ src/DAlign.cxx | 1276 + src/DBeaster.cxx | 1573 ++ src/DCut.cxx | 145 + src/DEvent.cxx | 727 + src/DEventMC.cxx | 280 + src/DGlobalTools.cxx | 2050 ++ src/DHelix.cxx | 72 + src/DHelixFitter.cxx | 440 + src/DHit.cxx | 4109 +++ src/DLadder.cxx | 852 + src/DLine.cxx | 157 + src/DMiniVector.cxx | 586 + src/DModule.cxx | 124 + src/DMonteCarlo.cxx | 48 + src/DParticle.cxx | 50 + src/DPixel.cxx | 210 + src/DPlane.cxx | 4350 +++ src/DPrecAlign.cxx | 1600 ++ src/DPrecAlign.cxx_NEW | 1429 + src/DR3.cxx | 293 + src/DSession.cxx | 703 + src/DSetup.cxx | 4256 +++ src/DStrip.cxx | 681 + src/DTrack.cxx | 1002 + src/DTrackFitter.cxx | 480 + src/DTracker.cxx | 3545 +++ src/DXRay2DPdf.cxx | 204 + src/DecoderGeant.cxx | 177 + src/DecoderM18.cxx | 318 + src/DecoderM18_fb.cxx | 379 + src/GIGBoardReader.cxx | 359 + src/IMGBoardReader.cxx | 1454 + src/MAlign.cxx | 6801 +++++ src/MAlignment.cxx | 343 + src/MAnalysis.cxx | 5453 ++++ src/MCBoardReader.cxx | 866 + src/MCommands.cxx | 5975 +++++ src/MGlobalAlign.cxx | 1698 ++ src/MHist.cxx | 2825 ++ src/MKalmanFilter.cxx | 438 + src/MLeastChiSquare.cxx | 146 + src/MMCGeneration.cxx | 2438 ++ src/MMain.cxx | 825 + src/MMillepede.cxx | 1456 + src/MPost.cxx | 9265 +++++++ src/MPrep.cxx | 1037 + src/MRaw.cxx | 17062 ++++++++++++ src/MRax.cxx | 10451 ++++++++ src/PXIBoardReader.cxx | 757 + src/PXIeBoardReader.cxx | 3172 +++ src/TNTBoardReader.cxx | 769 + src/VMEBoardReader.cxx | 635 + 481 files changed, 396883 insertions(+), 196 deletions(-) create mode 100755 include/AliMIMOSA22RawStreamVASingle.h create mode 100644 include/BoardReader.h create mode 100644 include/BoardReaderEUDAQ.h create mode 100644 include/BoardReaderIHEP.h create mode 100644 include/BoardReaderMIMOSIS.h create mode 100644 include/DAcq.h create mode 100644 include/DAlign.h create mode 100644 include/DBeaster.h create mode 100755 include/DCut.h create mode 100644 include/DEvent.h create mode 100644 include/DEventMC.h create mode 100644 include/DGlobalTools.h create mode 100644 include/DHelix.h create mode 100644 include/DHelixFitter.h create mode 100644 include/DHit.h create mode 100755 include/DLadder.h create mode 100755 include/DLine.h create mode 100755 include/DMiniVector.h create mode 100644 include/DModule.h create mode 100755 include/DMonteCarlo.h create mode 100755 include/DParticle.h create mode 100644 include/DPixel.h create mode 100644 include/DPlane.h create mode 100644 include/DPrecAlign.h create mode 100755 include/DPrecAlign_linkdef.h create mode 100755 include/DR3.h create mode 100644 include/DSession.h create mode 100644 include/DSetup.h create mode 100755 include/DStrip.h create mode 100644 include/DTLinkDef.h create mode 100644 include/DTrack.h create mode 100755 include/DTrackFitter.h create mode 100644 include/DTracker.h create mode 100755 include/DXRay2DPdf.h create mode 100644 include/DecoderGeant.h create mode 100644 include/DecoderM18.h create mode 100755 include/DecoderM18_fb.h create mode 100644 include/GIGBoardReader.h create mode 100644 include/IMGBoardReader.h create mode 100644 include/MAlign.h create mode 100755 include/MAlignment.h create mode 100644 include/MAnalysis.h create mode 100644 include/MCBoardReader.h create mode 100755 include/MGlobalAlign.h create mode 100755 include/MHist.h create mode 100644 include/MKalmanFilter.h create mode 100644 include/MLeastChiSquare.h create mode 100644 include/MLinkDef.h create mode 100755 include/MMillepede.h create mode 100644 include/MRaw.h create mode 100644 include/MRax.h create mode 100644 include/PXIBoardReader.h create mode 100644 include/PXIeBoardReader.h create mode 100755 include/TMimosa24_25Map.h create mode 100644 include/TNTBoardReader.h create mode 100644 include/VMEBoardReader.h create mode 100755 include/img_daq_lib/das.h create mode 100755 include/img_daq_lib/event_header.typ create mode 100755 include/mi26types.h create mode 100644 include/mimo_daq_lib/.DS_Store create mode 100644 include/mimo_daq_lib/c4pi_test_team.h create mode 100644 include/mimo_daq_lib/errors_light.c create mode 100644 include/mimo_daq_lib/errors_light.h create mode 100644 include/mimo_daq_lib/globals_root.def create mode 100644 include/mimo_daq_lib/mimo_daq_lib.c create mode 100755 include/mimo_daq_lib/mimo_daq_lib.h create mode 100644 include/mimo_daq_lib/msg_light.c create mode 100644 include/mimo_daq_lib/msg_light.h create mode 100644 include/mimo_daq_lib/msis1_data.c create mode 100644 include/mimo_daq_lib/msis1_data.def create mode 100644 include/mimo_daq_lib/msis1_data.typ create mode 100644 include/mimo_daq_lib/msis1_data_exp.h create mode 100755 include/mimo_daq_lib/sync_index_rec.c create mode 100755 include/mimo_daq_lib/sync_index_rec.typ create mode 100644 include/mimo_daq_lib/types.def create mode 100755 include/mimo_daq_lib/types.typ create mode 100644 include/mimo_daq_lib/var_decl_def.h create mode 100644 include/pxi_daq_lib_config.h create mode 100755 include/pxi_daq_lib_v.0.0/asic.def create mode 100755 include/pxi_daq_lib_v.0.0/asic.typ create mode 100755 include/pxi_daq_lib_v.0.0/daq_pxi.def create mode 100755 include/pxi_daq_lib_v.0.0/globals.def create mode 100755 include/pxi_daq_lib_v.0.0/maps.def create mode 100755 include/pxi_daq_lib_v.0.0/mi26.def create mode 100755 include/pxi_daq_lib_v.0.0/mi26.typ create mode 100755 include/pxi_daq_lib_v.0.0/types.typ create mode 100755 include/pxi_daq_lib_v.1.0/asic.def create mode 100755 include/pxi_daq_lib_v.1.0/asic.typ create mode 100755 include/pxi_daq_lib_v.1.0/asic.var create mode 100755 include/pxi_daq_lib_v.1.0/errors.c create mode 100755 include/pxi_daq_lib_v.1.0/errors.def create mode 100755 include/pxi_daq_lib_v.1.0/errors.typ create mode 100755 include/pxi_daq_lib_v.1.0/errors.var create mode 100755 include/pxi_daq_lib_v.1.0/eudet_frio.def create mode 100755 include/pxi_daq_lib_v.1.0/eudet_frio.typ create mode 100755 include/pxi_daq_lib_v.1.0/eudet_frio.var create mode 100755 include/pxi_daq_lib_v.1.0/eudet_frio_print.c create mode 100755 include/pxi_daq_lib_v.1.0/files.c create mode 100755 include/pxi_daq_lib_v.1.0/files.def create mode 100755 include/pxi_daq_lib_v.1.0/files.typ create mode 100755 include/pxi_daq_lib_v.1.0/files.var create mode 100755 include/pxi_daq_lib_v.1.0/globals.def create mode 100755 include/pxi_daq_lib_v.1.0/globals_root.def create mode 100755 include/pxi_daq_lib_v.1.0/maps.def create mode 100755 include/pxi_daq_lib_v.1.0/maps.typ create mode 100755 include/pxi_daq_lib_v.1.0/maps.var create mode 100755 include/pxi_daq_lib_v.1.0/mi26_usr.def create mode 100755 include/pxi_daq_lib_v.1.0/mi26_usr.typ create mode 100755 include/pxi_daq_lib_v.1.0/msg.c create mode 100755 include/pxi_daq_lib_v.1.0/msg.def create mode 100755 include/pxi_daq_lib_v.1.0/msg.typ create mode 100755 include/pxi_daq_lib_v.1.0/msg.var create mode 100755 include/pxi_daq_lib_v.1.0/pxi_daq_lib_v.1.0.c create mode 100755 include/pxi_daq_lib_v.1.0/time.c create mode 100755 include/pxi_daq_lib_v.1.0/time.def create mode 100755 include/pxi_daq_lib_v.1.0/time.typ create mode 100755 include/pxi_daq_lib_v.1.0/time.var create mode 100755 include/pxi_daq_lib_v.1.0/types.typ create mode 100755 include/pxi_daq_lib_v.1.1/asic.def create mode 100755 include/pxi_daq_lib_v.1.1/asic.typ create mode 100755 include/pxi_daq_lib_v.1.1/asic.var create mode 100755 include/pxi_daq_lib_v.1.1/daq_lib.c create mode 100755 include/pxi_daq_lib_v.1.1/daq_lib.h create mode 100755 include/pxi_daq_lib_v.1.1/errors.c create mode 100755 include/pxi_daq_lib_v.1.1/errors.def create mode 100755 include/pxi_daq_lib_v.1.1/errors.typ create mode 100755 include/pxi_daq_lib_v.1.1/errors.var create mode 100755 include/pxi_daq_lib_v.1.1/eudet_frio.def create mode 100755 include/pxi_daq_lib_v.1.1/eudet_frio.typ create mode 100755 include/pxi_daq_lib_v.1.1/eudet_frio.var create mode 100755 include/pxi_daq_lib_v.1.1/eudet_frio_print.c create mode 100755 include/pxi_daq_lib_v.1.1/files.c create mode 100755 include/pxi_daq_lib_v.1.1/files.def create mode 100755 include/pxi_daq_lib_v.1.1/files.typ create mode 100755 include/pxi_daq_lib_v.1.1/files.var create mode 100755 include/pxi_daq_lib_v.1.1/globals.def create mode 100755 include/pxi_daq_lib_v.1.1/globals_root.def create mode 100755 include/pxi_daq_lib_v.1.1/maps.def create mode 100755 include/pxi_daq_lib_v.1.1/maps.typ create mode 100755 include/pxi_daq_lib_v.1.1/maps.var create mode 100755 include/pxi_daq_lib_v.1.1/mi26_usr.def create mode 100755 include/pxi_daq_lib_v.1.1/mi26_usr.typ create mode 100755 include/pxi_daq_lib_v.1.1/msg.c create mode 100755 include/pxi_daq_lib_v.1.1/msg.def create mode 100755 include/pxi_daq_lib_v.1.1/msg.typ create mode 100755 include/pxi_daq_lib_v.1.1/msg.var create mode 100755 include/pxi_daq_lib_v.1.1/pxi_daq_lib_v.1.1.c create mode 100755 include/pxi_daq_lib_v.1.1/sync_index_rec.c create mode 100755 include/pxi_daq_lib_v.1.1/sync_index_rec.typ create mode 100755 include/pxi_daq_lib_v.1.1/time.c create mode 100755 include/pxi_daq_lib_v.1.1/time.def create mode 100755 include/pxi_daq_lib_v.1.1/time.typ create mode 100755 include/pxi_daq_lib_v.1.1/time.var create mode 100755 include/pxi_daq_lib_v.1.1/types.typ create mode 100755 include/pxi_daq_lib_v.1.2/asic.def create mode 100755 include/pxi_daq_lib_v.1.2/asic.typ create mode 100755 include/pxi_daq_lib_v.1.2/asic.var create mode 100644 include/pxi_daq_lib_v.1.2/daq_lib.c create mode 100755 include/pxi_daq_lib_v.1.2/daq_lib.h create mode 100755 include/pxi_daq_lib_v.1.2/errors.c create mode 100755 include/pxi_daq_lib_v.1.2/errors.def create mode 100755 include/pxi_daq_lib_v.1.2/errors.typ create mode 100755 include/pxi_daq_lib_v.1.2/errors.var create mode 100755 include/pxi_daq_lib_v.1.2/eudet_frio.c create mode 100755 include/pxi_daq_lib_v.1.2/eudet_frio.def create mode 100755 include/pxi_daq_lib_v.1.2/eudet_frio.typ create mode 100755 include/pxi_daq_lib_v.1.2/eudet_frio.var create mode 100755 include/pxi_daq_lib_v.1.2/eudet_frio_print.c create mode 100755 include/pxi_daq_lib_v.1.2/files.c create mode 100755 include/pxi_daq_lib_v.1.2/files.def create mode 100755 include/pxi_daq_lib_v.1.2/files.typ create mode 100755 include/pxi_daq_lib_v.1.2/files.var create mode 100755 include/pxi_daq_lib_v.1.2/globals.def create mode 100755 include/pxi_daq_lib_v.1.2/globals_root.def create mode 100755 include/pxi_daq_lib_v.1.2/maps.def create mode 100755 include/pxi_daq_lib_v.1.2/maps.typ create mode 100755 include/pxi_daq_lib_v.1.2/maps.var create mode 100755 include/pxi_daq_lib_v.1.2/mi26_usr.def create mode 100755 include/pxi_daq_lib_v.1.2/mi26_usr.typ create mode 100755 include/pxi_daq_lib_v.1.2/msg.c create mode 100755 include/pxi_daq_lib_v.1.2/msg.def create mode 100755 include/pxi_daq_lib_v.1.2/msg.typ create mode 100755 include/pxi_daq_lib_v.1.2/msg.var create mode 100755 include/pxi_daq_lib_v.1.2/sync_index_rec.c create mode 100755 include/pxi_daq_lib_v.1.2/sync_index_rec.typ create mode 100755 include/pxi_daq_lib_v.1.2/time.c create mode 100755 include/pxi_daq_lib_v.1.2/time.def create mode 100755 include/pxi_daq_lib_v.1.2/time.typ create mode 100755 include/pxi_daq_lib_v.1.2/time.var create mode 100755 include/pxi_daq_lib_v.1.2/types.typ create mode 100755 include/pxi_daq_lib_v.2.1/Copie de eudet_frio.c create mode 100755 include/pxi_daq_lib_v.2.1/Copie de eudet_frio_emul.c create mode 100755 include/pxi_daq_lib_v.2.1/__eudet_frio.h create mode 100755 include/pxi_daq_lib_v.2.1/_errors.c create mode 100755 include/pxi_daq_lib_v.2.1/_eudet_frio.typ create mode 100755 include/pxi_daq_lib_v.2.1/a.out create mode 100755 include/pxi_daq_lib_v.2.1/asic.c create mode 100755 include/pxi_daq_lib_v.2.1/asic.def create mode 100755 include/pxi_daq_lib_v.2.1/asic.h create mode 100755 include/pxi_daq_lib_v.2.1/asic.typ create mode 100755 include/pxi_daq_lib_v.2.1/asic.var create mode 100755 include/pxi_daq_lib_v.2.1/backup.c create mode 100755 include/pxi_daq_lib_v.2.1/cc.def create mode 100755 include/pxi_daq_lib_v.2.1/com.def create mode 100755 include/pxi_daq_lib_v.2.1/com.typ create mode 100755 include/pxi_daq_lib_v.2.1/com_pc.c create mode 100755 include/pxi_daq_lib_v.2.1/com_pc.def create mode 100755 include/pxi_daq_lib_v.2.1/com_pc.h create mode 100755 include/pxi_daq_lib_v.2.1/com_pc.typ create mode 100755 include/pxi_daq_lib_v.2.1/com_pc.var create mode 100755 include/pxi_daq_lib_v.2.1/com_uc.c create mode 100755 include/pxi_daq_lib_v.2.1/com_uc.def create mode 100755 include/pxi_daq_lib_v.2.1/com_uc.h create mode 100755 include/pxi_daq_lib_v.2.1/com_uc.typ create mode 100755 include/pxi_daq_lib_v.2.1/com_uc.var create mode 100755 include/pxi_daq_lib_v.2.1/daq_lib.c create mode 100755 include/pxi_daq_lib_v.2.1/dbg_log.def create mode 100755 include/pxi_daq_lib_v.2.1/dbg_log.typ create mode 100755 include/pxi_daq_lib_v.2.1/dbg_log.var create mode 100755 include/pxi_daq_lib_v.2.1/errors.c create mode 100755 include/pxi_daq_lib_v.2.1/errors.def create mode 100755 include/pxi_daq_lib_v.2.1/errors.h create mode 100755 include/pxi_daq_lib_v.2.1/errors.txt create mode 100755 include/pxi_daq_lib_v.2.1/errors.typ create mode 100755 include/pxi_daq_lib_v.2.1/errors.var create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio.def create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio.typ create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio.var create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio__100112.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio__270411.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio__all_func_in_file_061110_13H43.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio__all_func_in_file_061110_13H43.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_array_one.typ create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_array_zero.typ create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_dbg.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_dbg.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_emul.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_emul.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_get.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_get.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_print.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_print.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_set.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_set.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_ult1.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_ult1.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_ult1_300513.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_ult1__code_listing.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_usr.c create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_usr.def create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_usr.h create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_usr.typ create mode 100755 include/pxi_daq_lib_v.2.1/eudet_frio_usr.var create mode 100755 include/pxi_daq_lib_v.2.1/files.c create mode 100755 include/pxi_daq_lib_v.2.1/files.def create mode 100755 include/pxi_daq_lib_v.2.1/files.h create mode 100755 include/pxi_daq_lib_v.2.1/files.typ create mode 100755 include/pxi_daq_lib_v.2.1/files.var create mode 100755 include/pxi_daq_lib_v.2.1/files__090112.c create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0.c create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0.def create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0.h create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0.typ create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0.var create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_110614.c create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_110614.def create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_convert_frm.c create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_test_ult1.def create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr.c create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr.def create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr.h create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr.typ create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr.var create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr_020614.typ create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr_110614.def create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr_110614.typ create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr_220514.def create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr_220514.typ create mode 100755 include/pxi_daq_lib_v.2.1/fsbb0_usr_test_ult1.def create mode 100755 include/pxi_daq_lib_v.2.1/globals.def create mode 100755 include/pxi_daq_lib_v.2.1/globals_root.def create mode 100755 include/pxi_daq_lib_v.2.1/inter_app_com.c create mode 100755 include/pxi_daq_lib_v.2.1/inter_app_com.def create mode 100755 include/pxi_daq_lib_v.2.1/inter_app_com.h create mode 100755 include/pxi_daq_lib_v.2.1/inter_app_com.old1.c create mode 100755 include/pxi_daq_lib_v.2.1/inter_app_com.old2.c create mode 100755 include/pxi_daq_lib_v.2.1/inter_app_com.typ create mode 100755 include/pxi_daq_lib_v.2.1/inter_app_com.var create mode 100755 include/pxi_daq_lib_v.2.1/maps.c create mode 100755 include/pxi_daq_lib_v.2.1/maps.def create mode 100755 include/pxi_daq_lib_v.2.1/maps.h create mode 100755 include/pxi_daq_lib_v.2.1/maps.typ create mode 100755 include/pxi_daq_lib_v.2.1/maps.var create mode 100755 include/pxi_daq_lib_v.2.1/math.c create mode 100755 include/pxi_daq_lib_v.2.1/math.def create mode 100755 include/pxi_daq_lib_v.2.1/math.h create mode 100755 include/pxi_daq_lib_v.2.1/math.typ create mode 100755 include/pxi_daq_lib_v.2.1/math.var create mode 100755 include/pxi_daq_lib_v.2.1/mi26_usr.c create mode 100755 include/pxi_daq_lib_v.2.1/mi26_usr.def create mode 100755 include/pxi_daq_lib_v.2.1/mi26_usr.h create mode 100755 include/pxi_daq_lib_v.2.1/mi26_usr.typ create mode 100755 include/pxi_daq_lib_v.2.1/mi26_usr.var create mode 100755 include/pxi_daq_lib_v.2.1/msg.c create mode 100755 include/pxi_daq_lib_v.2.1/msg.def create mode 100755 include/pxi_daq_lib_v.2.1/msg.h create mode 100755 include/pxi_daq_lib_v.2.1/msg.txt create mode 100755 include/pxi_daq_lib_v.2.1/msg.typ create mode 100755 include/pxi_daq_lib_v.2.1/msg.var create mode 100755 include/pxi_daq_lib_v.2.1/pipe.c create mode 100755 include/pxi_daq_lib_v.2.1/pipe.def create mode 100755 include/pxi_daq_lib_v.2.1/pipe.h create mode 100755 include/pxi_daq_lib_v.2.1/pipe.typ create mode 100755 include/pxi_daq_lib_v.2.1/pipe.var create mode 100755 include/pxi_daq_lib_v.2.1/pport.c create mode 100755 include/pxi_daq_lib_v.2.1/pport.def create mode 100755 include/pxi_daq_lib_v.2.1/pport.h create mode 100755 include/pxi_daq_lib_v.2.1/pport.typ create mode 100755 include/pxi_daq_lib_v.2.1/pport.var create mode 100755 include/pxi_daq_lib_v.2.1/sync_index_rec.c create mode 100755 include/pxi_daq_lib_v.2.1/sync_index_rec.typ create mode 100755 include/pxi_daq_lib_v.2.1/system.def create mode 100755 include/pxi_daq_lib_v.2.1/time.c create mode 100755 include/pxi_daq_lib_v.2.1/time.def create mode 100755 include/pxi_daq_lib_v.2.1/time.h create mode 100755 include/pxi_daq_lib_v.2.1/time.typ create mode 100755 include/pxi_daq_lib_v.2.1/time.var create mode 100755 include/pxi_daq_lib_v.2.1/tools.h create mode 100755 include/pxi_daq_lib_v.2.1/types.def create mode 100755 include/pxi_daq_lib_v.2.1/types.typ create mode 100755 include/pxi_daq_lib_v.2.1/ult1.c create mode 100755 include/pxi_daq_lib_v.2.1/ult1.def create mode 100755 include/pxi_daq_lib_v.2.1/ult1.h create mode 100755 include/pxi_daq_lib_v.2.1/ult1.typ create mode 100755 include/pxi_daq_lib_v.2.1/ult1.var create mode 100755 include/pxi_daq_lib_v.2.1/ult1_test_mi26.def create mode 100755 include/pxi_daq_lib_v.2.1/ult1_usr.c create mode 100755 include/pxi_daq_lib_v.2.1/ult1_usr.def create mode 100755 include/pxi_daq_lib_v.2.1/ult1_usr.h create mode 100755 include/pxi_daq_lib_v.2.1/ult1_usr.typ create mode 100755 include/pxi_daq_lib_v.2.1/ult1_usr.var create mode 100755 include/pxi_daq_lib_v.2.1/ult1_usr_test_mi26.def create mode 100755 include/pxi_daq_lib_v.2.1/vme_stat.h create mode 100755 include/pxi_daq_lib_v.2.1/win_files.c create mode 100755 include/pxi_daq_lib_v.2.1/win_files.def create mode 100755 include/pxi_daq_lib_v.2.1/win_files.h create mode 100755 include/pxi_daq_lib_v.2.1/win_files.typ create mode 100755 include/pxi_daq_lib_v.2.1/win_files.var create mode 100755 include/pxi_daq_lib_v.2.1/win_globals.def create mode 100755 include/pxi_daq_lib_v.2.1/win_time.c create mode 100755 include/pxi_daq_lib_v.2.1/win_types.typ create mode 100755 include/pxi_daq_lib_v.3.1/asic.def create mode 100755 include/pxi_daq_lib_v.3.1/asic.typ create mode 100755 include/pxi_daq_lib_v.3.1/asic.var create mode 100755 include/pxi_daq_lib_v.3.1/daq_lib.c create mode 100755 include/pxi_daq_lib_v.3.1/errors.c create mode 100755 include/pxi_daq_lib_v.3.1/errors.def create mode 100755 include/pxi_daq_lib_v.3.1/errors.typ create mode 100755 include/pxi_daq_lib_v.3.1/errors.var create mode 100755 include/pxi_daq_lib_v.3.1/eudet_frio.def create mode 100755 include/pxi_daq_lib_v.3.1/eudet_frio.typ create mode 100755 include/pxi_daq_lib_v.3.1/eudet_frio.var create mode 100755 include/pxi_daq_lib_v.3.1/eudet_frio_fsbb0.c create mode 100755 include/pxi_daq_lib_v.3.1/eudet_frio_print.c create mode 100755 include/pxi_daq_lib_v.3.1/eudet_frio_usr.def create mode 100755 include/pxi_daq_lib_v.3.1/eudet_frio_usr.typ create mode 100755 include/pxi_daq_lib_v.3.1/eudet_frio_usr.var create mode 100755 include/pxi_daq_lib_v.3.1/files.c create mode 100755 include/pxi_daq_lib_v.3.1/files.def create mode 100755 include/pxi_daq_lib_v.3.1/files.typ create mode 100755 include/pxi_daq_lib_v.3.1/files.var create mode 100755 include/pxi_daq_lib_v.3.1/fsbb0.def create mode 100755 include/pxi_daq_lib_v.3.1/fsbb0.typ create mode 100755 include/pxi_daq_lib_v.3.1/fsbb0_test_ult1.def create mode 100755 include/pxi_daq_lib_v.3.1/fsbb0_usr.def create mode 100755 include/pxi_daq_lib_v.3.1/fsbb0_usr.typ create mode 100755 include/pxi_daq_lib_v.3.1/fsbb0_usr_test_ult1.def create mode 100755 include/pxi_daq_lib_v.3.1/globals.def create mode 100755 include/pxi_daq_lib_v.3.1/globals_root.def create mode 100755 include/pxi_daq_lib_v.3.1/maps.def create mode 100755 include/pxi_daq_lib_v.3.1/maps.typ create mode 100755 include/pxi_daq_lib_v.3.1/maps.var create mode 100755 include/pxi_daq_lib_v.3.1/math.c create mode 100755 include/pxi_daq_lib_v.3.1/math.def create mode 100755 include/pxi_daq_lib_v.3.1/math.typ create mode 100755 include/pxi_daq_lib_v.3.1/math.var create mode 100755 include/pxi_daq_lib_v.3.1/mi26_usr.def create mode 100755 include/pxi_daq_lib_v.3.1/mi26_usr.typ create mode 100755 include/pxi_daq_lib_v.3.1/msg.c create mode 100755 include/pxi_daq_lib_v.3.1/msg.def create mode 100755 include/pxi_daq_lib_v.3.1/msg.typ create mode 100755 include/pxi_daq_lib_v.3.1/msg.var create mode 100755 include/pxi_daq_lib_v.3.1/sync_index_rec.c create mode 100755 include/pxi_daq_lib_v.3.1/sync_index_rec.typ create mode 100755 include/pxi_daq_lib_v.3.1/time.c create mode 100755 include/pxi_daq_lib_v.3.1/time.def create mode 100755 include/pxi_daq_lib_v.3.1/time.typ create mode 100755 include/pxi_daq_lib_v.3.1/time.var create mode 100755 include/pxi_daq_lib_v.3.1/types.def create mode 100755 include/pxi_daq_lib_v.3.1/types.typ create mode 100755 include/pxi_daq_lib_v.3.1/ult1.def create mode 100755 include/pxi_daq_lib_v.3.1/ult1.typ create mode 100755 include/pxi_daq_lib_v.3.1/ult1_test_mi26.def create mode 100755 include/pxi_daq_lib_v.3.1/ult1_usr.def create mode 100755 include/pxi_daq_lib_v.3.1/ult1_usr.typ create mode 100755 include/pxi_daq_lib_v.3.1/ult1_usr_test_mi26.def create mode 100755 include/spiralNumerotation.h create mode 100755 include/sup_exp.typ create mode 100755 include/tiff.h create mode 100755 include/tiffio.h create mode 100644 include/vetoPixels.c create mode 100755 src/AliMIMOSA22RawStreamVASingle.cxx create mode 100755 src/BoardReader.cxx create mode 100644 src/BoardReaderEUDAQ.cxx create mode 100644 src/BoardReaderIHEP.cxx create mode 100644 src/BoardReaderMIMOSIS.cxx create mode 100644 src/DAcq.cxx create mode 100644 src/DAlign.cxx create mode 100644 src/DBeaster.cxx create mode 100644 src/DCut.cxx create mode 100644 src/DEvent.cxx create mode 100644 src/DEventMC.cxx create mode 100644 src/DGlobalTools.cxx create mode 100644 src/DHelix.cxx create mode 100644 src/DHelixFitter.cxx create mode 100644 src/DHit.cxx create mode 100755 src/DLadder.cxx create mode 100755 src/DLine.cxx create mode 100755 src/DMiniVector.cxx create mode 100644 src/DModule.cxx create mode 100755 src/DMonteCarlo.cxx create mode 100755 src/DParticle.cxx create mode 100644 src/DPixel.cxx create mode 100644 src/DPlane.cxx create mode 100644 src/DPrecAlign.cxx create mode 100755 src/DPrecAlign.cxx_NEW create mode 100755 src/DR3.cxx create mode 100644 src/DSession.cxx create mode 100644 src/DSetup.cxx create mode 100644 src/DStrip.cxx create mode 100644 src/DTrack.cxx create mode 100644 src/DTrackFitter.cxx create mode 100644 src/DTracker.cxx create mode 100755 src/DXRay2DPdf.cxx create mode 100644 src/DecoderGeant.cxx create mode 100644 src/DecoderM18.cxx create mode 100755 src/DecoderM18_fb.cxx create mode 100755 src/GIGBoardReader.cxx create mode 100644 src/IMGBoardReader.cxx create mode 100644 src/MAlign.cxx create mode 100644 src/MAlignment.cxx create mode 100644 src/MAnalysis.cxx create mode 100644 src/MCBoardReader.cxx create mode 100644 src/MCommands.cxx create mode 100644 src/MGlobalAlign.cxx create mode 100644 src/MHist.cxx create mode 100644 src/MKalmanFilter.cxx create mode 100644 src/MLeastChiSquare.cxx create mode 100644 src/MMCGeneration.cxx create mode 100644 src/MMain.cxx create mode 100755 src/MMillepede.cxx create mode 100644 src/MPost.cxx create mode 100644 src/MPrep.cxx create mode 100644 src/MRaw.cxx create mode 100644 src/MRax.cxx create mode 100644 src/PXIBoardReader.cxx create mode 100644 src/PXIeBoardReader.cxx create mode 100644 src/TNTBoardReader.cxx create mode 100644 src/VMEBoardReader.cxx diff --git a/code/include/BoardReaderMIMOSIS.h b/code/include/BoardReaderMIMOSIS.h index 45a057a..c46bb09 100644 --- a/code/include/BoardReaderMIMOSIS.h +++ b/code/include/BoardReaderMIMOSIS.h @@ -48,8 +48,6 @@ class BoardReaderMIMOSIS : public TObject { bool fVetoOverflow; int fEndianness; // 0= do not swap bytes, 1= swap bytes - int fSizeOfHeader; - int fSizeOfTrailer; std::ifstream fRawFileStream; std::vector fListInputFileNames; size_t fCurrentFileNumber; @@ -81,26 +79,20 @@ class BoardReaderMIMOSIS : public TObject { std::vector fListOfNextTimestamps; // JB 2012/05/04 - bool LookUpRawFile(); - bool CloseRawFile(); - bool OpenRawFile(); bool DecodeNextEvent(); bool DecodeFrame(); // bool DecodeFrame(MIS1__BT_FBtAcqW16AAlloc*, MIS1__TBtAcqRawRec*, int moduleID, int frameID, // UInt8 MeasExecTime, UInt8 PrintLvl); // ZE 2021/06/02 void AddPixel( int iSensor, int value, int aLine, int aColumn, int aTime=0); - // ==> PROBABLY MORE PRIVATE METHODS are needed <== public: int test(); - BoardReaderMIMOSIS(int boardNumber, char *dataPath, int runNumber, int nSensors=1, int triggerMode=0, int eventBuildingMode=0, int headerSize=0, int trailerSize=0, int endianness=0); - // BoardReaderMIMOSIS(int boardNumber, int runNumber, int nSensors=1, int triggerMode=0, int eventBuildingMode=0, int headerSize=0, int trailerSize=0, int endianness=0); + BoardReaderMIMOSIS(int boardNumber, char *dataPath, int runNumber, int nSensors=1, int triggerMode=0, int eventBuildingMode=0, int endianness=0); ~BoardReaderMIMOSIS(); void SetDebugLevel( int aLevel) { fDebugLevel = aLevel; cout << "BoardReaderMIMOSIS " << fBoardNumber << " debug updated to " << fDebugLevel << endl; } - bool AddFileList(std::string prefixFileName, int startIndex, int endIndex, std::string suffixFileName); void SetVetoPixel( int noiseRun=0); bool HasData(); void SkipNextEvent(); diff --git a/code/src/BoardReaderMIMOSIS.cxx b/code/src/BoardReaderMIMOSIS.cxx index da53168..cbc1b8b 100644 --- a/code/src/BoardReaderMIMOSIS.cxx +++ b/code/src/BoardReaderMIMOSIS.cxx @@ -4,11 +4,13 @@ // Dedicated to decode output files from the PXI acquisition system // dedicated to MIMOSIS sensors // +// Use Gilles Claus library to decode rawdata file, see code/inculde/mimo_daq_lib // ///////////////////////////////////////////////////////////// // // created JB, 2021/04/21 -// Last Modified: +// Last Modified: Ziad, 2021/06/04 + #define AP 0 #include "TCanvas.h" #include "TApplication.h" @@ -59,7 +61,6 @@ MIS1__TBtRunRead* APP_VGPtRunRead; MIS1__TBtAcqRawRec* APP_VGPtAcqSrc; // 26/05/2021 V1.1 // Pointer on current acq of run = source Acq to be decoded - MIS1__TBtAcqW16A* APP_VGPtAcqW16A; // 26/05/2021 V1.1 // AcqW16A record = Flex RIO data reoorganized // Contains Acq data reordered in order to have one array of W16 for each MSis1 @@ -73,6 +74,7 @@ MIS1__TBtAcqDec* APP_VGPtAcqDec; // 26/05/2021 V1.1 // Contains decoded pixels + info on Acq, Frames : reggions nb, fired pixels nb, etc ... + // --------------------------------------------------------------------------------- // Main : Mimosis 1 beam test run file access example, via class MIS1__TBtRunRead // --------------------------------------------------------------------------------- @@ -907,10 +909,11 @@ int BoardReaderMIMOSIS::test() { } //------------------------------------------+----------------------------------- -//BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, int runNumber, int nSensors, int triggerMode, int eventBuildingMode, int headerSize, int trailerSize, int endianness) { -BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runNumber, int nSensors, int triggerMode, int eventBuildingMode, int headerSize, int trailerSize, int endianness) { -// Board creator - // ==> OF COURSE the list of arguments might be changed if needed! <== +BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runNumber, int nSensors, int triggerMode, int eventBuildingMode, int endianness) { + // Board creator + // Load the rawdata file + // + // Ziad, 2021 int VParHdPrintTriggers = 5; // Nb of triggers to print -1 => All, 0 => None, N > 0 => N first triggers @@ -923,8 +926,6 @@ BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runN fNSensors = nSensors; fTriggerMode = triggerMode; fEventBuildingMode = eventBuildingMode; - fSizeOfHeader = headerSize; - fSizeOfTrailer = trailerSize; fEndianness = endianness; fVetoOverflow = false; // set later by SetVetoPixel fisfirstAcq = true; @@ -951,12 +952,13 @@ BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runN cout << "*****************************************" << endl; cout << "Creating a BoardReaderMIMOSIS" << endl; cout << " * board nb: " << fBoardNumber << endl; + cout << " * runNumber : " << runNumber << endl; cout << " * nb of sensors: " << fNSensors << endl; cout << " * trigger mode: " << fTriggerMode << endl; cout << " * event building mode: " << fEventBuildingMode << endl; - cout << " * event header & trailer sizes: " << fSizeOfHeader << " & " << fSizeOfTrailer << endl; cout << " * Endiannes: " << fEndianness << " => " << (fEndianness==0?"NO SWAP":"SWAP") << endl; cout << " * usage of veto for event with overflow: " << fVetoOverflow << " => " << (fVetoOverflow?"YES":"NO") << endl; + cout << " * dataPath : " << dataPath << endl; // Initialization fCurrentFileNumber = 0; // See also AddFileList @@ -972,14 +974,14 @@ BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runN // Initialization of Current Acquisition Number and Current Frame Number - // ---------------------------------------------------------------- - // Class creation - // ---------------------------------------------------------------- + // ---------------------------------------------------------------- + // Reading Class creation + // ---------------------------------------------------------------- MIS1__TBtRunCnfRec* VPtRunConf = NULL; // Pointer to run conf record MIS1__TBtAcqRawRec* VPtAcq = NULL; // Pointer to current Acq - - APP_VGPtRunRead = new MIS1__TBtRunRead(); + APP_VGPtRunRead = new MIS1__TBtRunRead(); + if ( APP_VGPtRunRead == NULL ) { printf ( "\n" ); printf ( "ERROR : Creation of MIS1__TBtRunRead failed ! \n" ); @@ -990,7 +992,7 @@ BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runN printf ( "\n" ); // Initialisation required by DAQ library - APP__TContext* VPtCont = &APP__VGContext; + //APP__TContext* VPtCont = &APP__VGContext; //ZE 2021/06/09 not used in BoardReaderMIMOSIS char msgFile[100], errFile[100]; // JB 2011/06/28 // int runNumber ; @@ -999,10 +1001,17 @@ BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runN sprintf( errFile, "Results/%d/err_run%d.txt", runNumber, runNumber); sprintf(errFile,"%s", fTool.LocalizeDirName( errFile)); // JB 2011/07/07 + cout << " * msgFile : " << msgFile << " errFile = " << errFile << endl; + // ZE 2021/06/01 access configuration file VRet = APP_VGPtRunRead->FRunConf ( dataPath, runNumber, 0 /* PrintRunHeader */, MIS1__BT_RUN_RD_FILE_FORMAT ); - + if( VRet<0 ) { + cout << endl << "ERROR: cannot configure run -> return of RunConf = " << VRet << endl; + cout << " Consult " << errFile << " to investigate." << endl << endl; + return; + } + ERR_FBegin ( ( APP_VGErrFileLogLvl != 0 ) /* Enable */, errFile ); ERR_FSetFileLogLevel ( APP_VGErrFileLogLvl ); ERR_FSetUserLogLevel ( APP_VGErrUserLogLvl ); @@ -1013,7 +1022,9 @@ BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runN // ZE 2021/06/03 two following steps to get the number of frames per acquisition VPtRunConf = APP_VGPtRunRead->FRunHeaderGet ( 1 /* Print */ ); + fnbFrPerAcq = VPtRunConf->FrNbPerAcq ; + cout << " * Number of Frames per Acq : " << fnbFrPerAcq << endl; // In case of more info required in log_msg and log_err use the syntax below /* @@ -1031,8 +1042,9 @@ BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runN if ( VRet < 0 ) { printf ( "\n" ); - printf ( "Configure Acq header printing option has failed \n" ); + printf ( "ERROR: Configure Acq header printing option has failed \n" ); printf ( "\n" ); + return; } // AcqW16A record @@ -1071,19 +1083,19 @@ BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runN // OK - if(fDebugLevel>1) { + //if(fDebugLevel>1) { printf ( "\n" ); printf ( "Allocation of AcqDec of %.1f MB ... \n", VAcqDecSz / 1024. / 1024. ); printf ( "Max frames nb / Acq = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); printf ( "Max pixels nb / Frame = %d \n", MIS1__BT_FR_DEC_MAX_PIX_NB ); - printf ( "Done :-) \n" ); - printf ( "\n" ); - } + //printf ( "Done :-) \n" ); + //printf ( "\n" ); + //} - - + + cout << "*****************************************" << endl; cout << " < BoardReaderMIMOSIS constructor DONE > " << endl; - + cout << "*****************************************" << endl; } //------------------------------------------+----------------------------------- @@ -1141,122 +1153,6 @@ BoardReaderMIMOSIS::~BoardReaderMIMOSIS() } -// -------------------------------------------------------------------------------------- -bool BoardReaderMIMOSIS::AddFileList(string prefixFileName, int startIndex, int endIndex, string suffixFileName) { - // Try opening each input files built from name=prefix+index+suffix - // Keep only the good one - // Work also for a single file with startIndex=endIndex - // - // Return true if at least one file can be opened - - bool rc = true; - std::string fileName; - - if(fDebugLevel) { - cout << "BoardReaderMIMOSIS::AddFileList => Adding files with indexes from " << startIndex << " to " << endIndex; - cout << " prefix=" << prefixFileName << ", suffix=" << suffixFileName << endl; - } - - // Try each filename looping on indexes, and keep in the list only the good ones - for (size_t iFile = startIndex; iFile <= endIndex; iFile++) { - fileName = prefixFileName + "_" + std::to_string(iFile) + suffixFileName; - if(fDebugLevel>1) cout << " trying file " << fileName << endl; - fRawFileStream.open( fileName); - if( fRawFileStream.fail() ) { - cout << endl << "ERROR BoardReaderMIMOSIS " << fBoardNumber << " file " << fileName << " does not exist!!" << endl; - fRawFileStream.close(); - rc = false; - } - else{ - fListInputFileNames.push_back( fileName); - cout << " BoardReaderMIMOSIS " << fBoardNumber << " New file " << fileName << ", total of " << fListInputFileNames.size() << " files." << endl; - fRawFileStream.close(); - } - } - - // If there is only one file, try a filename without an index - if ( !rc && endIndex==startIndex ) { - fileName = prefixFileName + suffixFileName; - if(fDebugLevel>1) cout << " trying file " << fileName << endl; - fRawFileStream.open( fileName); - if( fRawFileStream.fail() ) { - cout << endl << " ERROR BoardReaderMIMOSIS " << fBoardNumber << " file " << fileName << " does not exist!!" << endl; - fRawFileStream.close(); - rc = false; - } - else{ - fListInputFileNames.push_back( fileName); - cout << " BoardReaderMIMOSIS " << fBoardNumber << " New file " << fileName << ", total of " << fListInputFileNames.size() << " files." << endl; - fRawFileStream.close(); - } - } - - cout << "#files OK = " << fListInputFileNames.size() << " out of " << endIndex-startIndex+1 << endl; - - // if at least one file is OK, reopens the very first file - if ( fListInputFileNames.size() == 0 ) { - fNoMoreFile = true; - return false; - } - - fCurrentFileNumber = 0; - return LookUpRawFile(); - -} - -// -------------------------------------------------------------------------------------- -bool BoardReaderMIMOSIS::LookUpRawFile() { - // Try to open the next rawdata file - - // If the stream is open, close it - if( fRawFileStream.is_open() ) { - CloseRawFile(); - fCurrentFileNumber++; - } - - // Try to go to the next file, if any are left - if( fCurrentFileNumber < fListInputFileNames.size() ) { - if(fDebugLevel) cout << " --> BoardReaderMIMOSIS " << fBoardNumber << " New file to read " << fCurrentFileNumber << " < " << fListInputFileNames.size() << "." << endl; - return OpenRawFile(); - } - else { // Otherwise no more file, end the reading - cout << " -+-+- INFO BoardReaderMIMOSIS " << fBoardNumber << ": No more files to read " << fCurrentFileNumber << " >= " << fListInputFileNames.size() << " closing!" << endl; - fNoMoreFile = true; - return false; - } - -} - -// -------------------------------------------------------------------------------------- -bool BoardReaderMIMOSIS::OpenRawFile() { - // Open the next rawdata file - - fRawFileStream.open( fListInputFileNames[fCurrentFileNumber]); - bool b = fRawFileStream.fail(); - if (b == 0) { - cout << " -+-+- INFO BoardReaderMIMOSIS " << fBoardNumber << ": File " << fListInputFileNames[fCurrentFileNumber] << " opened." << endl; - } - else { - cout << " -/-/- INFO BoardReaderMIMOSIS " << fBoardNumber << ": File " << fListInputFileNames[fCurrentFileNumber] << " not opened, rc = " << b << "." << endl; - } - return !b; - -} - -// -------------------------------------------------------------------------------------- -bool BoardReaderMIMOSIS::CloseRawFile() { - // Closes a File of a Run - - fRawFileStream.close(); - bool b = fRawFileStream.fail(); - if (b == 0) - cout << " -+-+- INFO BoardReaderMIMOSIS " << fBoardNumber << ": File " << fCurrentFileNumber << " closed " << endl; - else - cout << " -/-/- INFO BoardReaderMIMOSIS " << fBoardNumber << ": File " << fCurrentFileNumber << " not closed, rc = " << b << "(eof="<< fRawFileStream.eof() << ", bad="<< fRawFileStream.bad() <<"." << endl; - return b; - -} - // -------------------------------------------------------------------------------------- bool BoardReaderMIMOSIS::HasData( ) { @@ -1320,10 +1216,13 @@ bool BoardReaderMIMOSIS::DecodeNextEvent() { // or if there is nothing to read anymore ==> ready = false SInt32 VRet; // Error code returned by functions ( 0 => ok, < 0 => error ) - - + + MIS1__TBtAcqRawRec* VPtAcq ; // Pointer to current Acq - + MIS1__TBtAcqRawHead* VPtAcqHead; // Pointer to current Acq Header + MIS1__TBtTrigRec* VPtTrig; // Pointer to triggers of current Acquisition + + // UInt32 VAcqW16ASz; // 26/05/2021 V1.1 // Size of AcqW16A record = Flex RIO data reoorganized // Contains Acq data reordered in order to have one array of W16 for each MSis1 @@ -1336,31 +1235,60 @@ bool BoardReaderMIMOSIS::DecodeNextEvent() { // Contains decoded pixels + info on Acq, Frames : reggions nb, fired pixels nb, etc ... UInt8 VResReachEndOfRun = (UInt8) fReachEndOfRun; - + SInt32 nbTrg; // Decoding status bool ready = false; - if(fDebugLevel>2) printf( " BoardReaderMIMOSIS board %d::DecodeNextEvent() trying with event %d\n", fBoardNumber, fCurrentEventNumber); + if(fDebugLevel>1) printf( " BoardReaderMIMOSIS board %d::DecodeNextEvent() trying with event %d (current Acq=%d, frame=%d)\n", fBoardNumber, fCurrentEventNumber, fCurrentAcqNumber, fCurrentFrameNumber); // Check if first Acquisition or if CurrentFrameNumber less than fnbFrPerAcq; fnbFrPerAcq is not mandatory equal to MIS1__BT_VRS_MAX_FR_NB_PER_ACQ if ((fCurrentFrameNumber % fnbFrPerAcq == 0) || (fCurrentFrameNumber % MIS1__BT_VRS_MAX_FR_NB_PER_ACQ == 0)) { if (fisfirstAcq == true) { - cout << "Getting the pointer for the first acquisition " << endl; - VPtAcq = APP_VGPtRunRead->FAcqFirst ( 0 /* ChkAcqHead */, 1 /* PrintAcqHead */ ); + if(fDebugLevel>1) cout << "BoardReaderMIMOSIS Getting the pointer for the first acquisition " << endl; + VPtAcq = APP_VGPtRunRead->FAcqFirst ( 0 /* ChkAcqHead */, 0 /* PrintAcqHead */ ); fCurrentAcqNumber ++; fisfirstAcq = false; fCurrentFrameNumber = 0; // ZE 2021/06/04 } else { - printf (" Changing to NextAcq % d since fCurrentFrameNumber = % d \n", fCurrentAcqNumber + 1, fCurrentFrameNumber); - VPtAcq = APP_VGPtRunRead->FAcqNext ( 0 /* ChkAcqHead */, 1 /* PrintAcqHead */, &VResReachEndOfRun ); + if(fDebugLevel>1) printf (" BoardReaderMIMOSIS Changing to NextAcq % d since fCurrentFrameNumber = % d \n", fCurrentAcqNumber + 1, fCurrentFrameNumber); + VPtAcq = APP_VGPtRunRead->FAcqNext ( 0 /* ChkAcqHead */, 0 /* PrintAcqHead */, &VResReachEndOfRun ); fCurrentAcqNumber ++; fCurrentFrameNumber = 0; // ZE 2021/06/04 } + + + // ZE 2021/06/09. Access Triggers + + // Get A point for the hear of acquisition + VPtAcqHead = &(APP_VGPtAcqW16A->AcqRawHead); + + if (VPtAcqHead == NULL){ + printf ( "\n" ); + printf ( " ERROR in getting pointer to the acquisition header ! \n" ); + printf ( "\n" ); + } + + // Getting the information on the triggers in the current acquisition + VPtTrig = &(VPtAcqHead->Trigs); + nbTrg = VPtAcqHead->Trigs.TrigNb; + + // Printing the Triggers information + printf("Printing triggers information in Acquistion % d \n", fCurrentAcqNumber); + VRet = MIS1__BT_FTrigRecPrint ( nbTrg, VPtTrig); // Function described in line file msis1_data.c, line 15312 + + if ( VRet < 0 ) { + + printf ( "WARNING: Failed in printing Trigger information for Acquisition : %d ! \n", VPtAcqHead->Ids.AcqIdInRun); + printf ( "\n" ); + return (-1); + + } + } fReachEndOfRun = (int) VResReachEndOfRun; @@ -1369,13 +1297,14 @@ bool BoardReaderMIMOSIS::DecodeNextEvent() { printf("fReachEndOfRun = %d ", fReachEndOfRun); printf("\n"); } - + // Get a pointer for the first Acquisition APP_VGPtAcqSrc = (MIS1__TBtAcqRawRec*) APP_VGPtRunRead->FAcqGetPt (); + if ( APP_VGPtAcqSrc == NULL ) { printf ( "\n" ); - printf ( "Get a pointer on first Acq of run has failed ! \n" ); + printf ( "WARNING: BoardReaderMIMOSIS Get a pointer on first Acq of run has failed ! \n" ); printf ( "\n" ); return (-1); } @@ -1384,7 +1313,7 @@ bool BoardReaderMIMOSIS::DecodeNextEvent() { if(fDebugLevel>1) { printf ( "\n" ); - printf ( "Get a pointer on first Acq of run done ! \n" ); + printf ( " BoardReaderMIMOSIS Get a pointer on first Acq of run done ! \n" ); printf ( "\n" ); } @@ -1402,7 +1331,7 @@ bool BoardReaderMIMOSIS::DecodeNextEvent() { if ( VRet < 0 ) { - printf ( "Filling AcqW16A failed ! \n" ); + printf ( "WARNING: BoardReaderMIMOSIS Filling AcqW16A failed ! \n" ); printf ( "\n" ); return (-1); @@ -1410,11 +1339,12 @@ bool BoardReaderMIMOSIS::DecodeNextEvent() { else if(fDebugLevel>1) { printf ( "\n" ); - printf ( "Filling AcqW16A done ! \n" ); + printf ( " BoardReaderMIMOSIS Filling AcqW16A done ! \n" ); printf ( "\n" ); } + // ZE 2021/06/02, just for test. Has to write a method specific to TAF //VRet = MIS1__BT_FAcqDecPrintGen ( APP_VGPtAcqDec, 0 /* MSIsId 0 to 5 */, 0 /* PrintMode */ ); @@ -1457,18 +1387,17 @@ bool BoardReaderMIMOSIS::DecodeFrame() { VRet = MIS1__BT_FBtDecodeFr ( APP_VGPtAcqW16A, APP_VGPtAcqDec, MSisId, fCurrentFrameNumber, 0 /* MeasExecTime */, 0 /* PrintLvl */ ); if ( VRet < 0 ) { - printf ( "Decoding MSis data failed for Sensor : %d and FrameNb : %d \n", MSisId, fCurrentFrameNumber ); + printf ( "WARNING: Decoding MSis data failed for Sensor : %d and FrameNb : %d \n", MSisId, fCurrentFrameNumber ); printf ( "\n" ); fBadDecFrameCounter ++; return (-1); } - VRet = MIS1__BT_FAcqDecPrintGen ( APP_VGPtAcqDec, MSisId, 0 /* PrintMode */ ); + + //VRet = MIS1__BT_FAcqDecPrintGen ( APP_VGPtAcqDec, MSisId, 0 /* PrintMode */ ); - if ( VRet < 0 ) { - printf ( "Printing info of decoded Acq failed for sensor : % d :-( \n", MSisId ); - printf ( "\n" ); - return (-1); - } + // if ( VRet < 0 ) + // printf ( "Printing info of decoded Acq failed for sensor : % d :-( \n\n", MSisId ); + // Decode pixels only for frames with FiredPixNb > 0 if ( APP_VGPtAcqDec->ResAAFrHead[MSisId][fCurrentFrameNumber].FiredPixNb > 0 ) { @@ -1486,7 +1415,6 @@ bool BoardReaderMIMOSIS::DecodeFrame() { if (fDebugLevel > 3) { printf(" Pixel [%.4d] : Y = %.4d - X = %.4d - frameID = %d \n ", ViPix, VPix.C.y, VPix.C.x, fCurrentFrameNumber ); - printf(" \n "); } AddPixel( MSisId, 1, VPix.C.y ,VPix.C.x ); diff --git a/code/src/DAcq.cxx b/code/src/DAcq.cxx index 28fcdcf..f024490 100644 --- a/code/src/DAcq.cxx +++ b/code/src/DAcq.cxx @@ -478,7 +478,6 @@ DAcq::DAcq(DSetup& c) // -+-+- MIMOSIS modules case 13: - //cout << "ZIAD --> Module Type : " << 13 << endl; fUseTimestamp[mdt-1][mdl-1] = kFALSE; fMSIS[iModule] = new BoardReaderMIMOSIS( iModule, fc->GetRunPar().DataPath, // ZE 2021/06/01 @@ -486,8 +485,6 @@ DAcq::DAcq(DSetup& c) fc->GetModulePar(mdt).Inputs, fc->GetAcqPar().TriggerMode, fc->GetModulePar(mdt).EventBuildingBoardMode, - fc->GetAcqPar().EventHeaderSize, - fc->GetAcqPar().EventTrailerSize, fc->GetAcqPar().BinaryCoding); fMSIS[iModule]->SetDebugLevel( fDebugAcq); @@ -548,7 +545,7 @@ DAcq::DAcq(DSetup& c) Int_t aModuleType, aModuleNumber, aInput, aChannel, aOffset, aSegment; //Int_t aChannelNumber; - cout << " Ziad Number of Planes: " << fc->GetTrackerPar().Planes << endl; + cout << "Number of Planes: " << fc->GetTrackerPar().Planes << endl; for ( Int_t iPlane = 1; iPlane <= fc->GetTrackerPar().Planes; iPlane++){ // loop on planes for ( Int_t iInp = 0; iInp < fc->GetPlanePar(iPlane).Inputs; iInp++) { // loop on inputs for this plane if (fc->GetPlanePar(iPlane).ModuleType[iInp] == 0) { diff --git a/code/src/DCut.cxx b/code/src/DCut.cxx index 6ddaad5..a884e27 100644 --- a/code/src/DCut.cxx +++ b/code/src/DCut.cxx @@ -70,7 +70,7 @@ DCut::DCut(DPlane& aPlane) if (fDebugCut) cout << " fClusterLimit=" << (*fClusterLimit)(0) << ", " << (*fClusterLimit)(1) << endl; // slightly modified JB 2009/09/23 - fStripsInClusterArea = ceil( ((*fClusterLimit)(0)*2./tPitch(0)+1) * ((*fClusterLimit)(1)*2./tPitch(1)+1) ); + fStripsInClusterArea = ceil( ((*fClusterLimit)(0)*2./tPitch(0)+1) * ((*fClusterLimit)(1)*2./tPitch(1)+1) ); // fStripsInClusterArea = (Int_t)( ((*fClusterLimit)(0)*2./tPitch(0)) * ((*fClusterLimit)(1)*2./tPitch(1)) );//VR 2014/07/12 if (fDebugCut) cout << " fStripsInClusterArea= " << fStripsInClusterArea << endl; diff --git a/code/src/DHit.cxx b/code/src/DHit.cxx index 6fc859c..6a4de4d 100644 --- a/code/src/DHit.cxx +++ b/code/src/DHit.cxx @@ -128,7 +128,7 @@ DHit::DHit(DR3 &aPosition, DPlane& aPlane, Int_t aHitNumber) fStoNover2 = 0; // MB/12/11/2010 fIsFromPreviousEvent = 0;// VR 2014.08.28 fTimestamp = 0; // JB 2015/05/25 - } + } // Hit Monte Carlo fIfMonteCarlo = 0; @@ -1975,10 +1975,10 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe // Last Modified, JB 2013/11/08 store initial seed information // Last Modified, VR 2014/07/12 Condition to look for a new seed change : cogRow type Int_t -> Double_t // Modified: JB 2015/05/26 to introduce timestamps and TimeLimit - + + if(fDebugHit>2) cout << "DHit:: Starting Analyze of potential hit nb " << fHitNumber << endl; fFound = kFALSE; // JB 2009/05/22 fPSeed = aListOfPixels->at( aPixelIndexInList); - DPixel *aNeighbour; DPixel *aPixel=NULL; Bool_t pixelTwice = kFALSE; // test if a pixel is present twice in the neighbour list @@ -1987,9 +1987,8 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe Int_t tStripIndex; Int_t tStripsInClusterPossible = 0; // remove a warning //Int_t tPixelIndexList[500]; - Int_t tTimeLimit = fPlane->GetTimeLimit(); // 2015/05/26 - + fPositionHitCG->Zero(); // clear the position fPositionHitEta->Zero(); fPositionHitEta22->Zero(); // JB 2010/12/8 @@ -1999,7 +1998,7 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe fSeedU = fPSeed->GetPosition()(0); fSeedV = fPSeed->GetPosition()(1); fIndexSeed = fPSeed->GetPixelIndex(); - + Int_t seedRow = fPSeed->GetPixelLine(); Int_t seedCol = fPSeed->GetPixelColumn(); Double_t cogRow = fPSeed->GetPixelLine(); //VR 2014/07/12 @@ -2019,6 +2018,7 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe fClusterNoiseAverage = (fPSeed->GetNoise())*(fPSeed->GetNoise()); // => so it's only a seed strip in the beginning fStripsInClusterFound = 1; fPSeed->SetFound(kTRUE); + if (fStripsInClusterDemanded >0) { // exact number demanded tStripsInClusterPossible = fStripsInClusterDemanded; @@ -2042,16 +2042,26 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe fStripDistanceU[0] = 0.; // distance seed to seed = 0. fStripDistanceV[0] = 0.; // distance seed to seed = 0. fStoNover2 = 0; // MB/12/11/2010 + //=============== // associate neighbouring pixels to seed one //=============== - if(fDebugHit>1) printf(" DHit:Analyse seed pixel index %d (%d in list, r%d, c%d) (q=%f, time=%d) with possibly %d neighbours\n", fIndexSeed, aPixelIndexInList, fPSeed->GetPixelLine(), fPSeed->GetPixelColumn(), fPSeed->GetPulseHeight(), fPSeed->GetTimestamp(), tStripsInClusterPossible); + if(fDebugHit>1) printf(" DHit:Analyse hit nb %d with seed pixel index %d (%d in list, r%d, c%d) (q=%f, time=%d) with possibly %d neighbours\n", fHitNumber, fIndexSeed, aPixelIndexInList, fPSeed->GetPixelLine(), fPSeed->GetPixelColumn(), fPSeed->GetPulseHeight(), fPSeed->GetTimestamp(), tStripsInClusterPossible); tStripIndex = 1; // start with the first neighbour, in the geometric ordered neighbourhood, avoid 0 because it is the seed itself! for (Int_t iPix = 0; iPix < (Int_t)aListOfPixels->size(); iPix++){ // loop over hit pixels aNeighbour = aListOfPixels->at(iPix); + + // Test that the pixel is actually different from the seed + // (could happen in case of bad DAQ behaviour) + // If it happens, set as true but ignore as neighbour + if( aNeighbour->GetPixelIndex() == fPSeed->GetPixelIndex() ) { + aNeighbour->SetFound(kTRUE); + if( fDebugHit>1) printf(" neighbour %d at index %d (r%d, c%d) is identical as seed at index %d => set as found and ignore!\n", tStripIndex, aNeighbour->GetPixelIndex(), aNeighbour->GetPixelLine(), aNeighbour->GetPixelColumn(), fPSeed->GetPixelIndex()); + } + // Test if the pixel can be associated to the seed // inside the geometrical cluster limits // and also in the time limit using the timestamp (which are all 0 if unavailable). @@ -2077,7 +2087,7 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe // pixelTwice = kTRUE; // break; //} - pixelTwice &= aNeighbour->GetPixelIndex() == aPixel->GetPixelIndex(); + pixelTwice |= aNeighbour->GetPixelIndex() == aPixel->GetPixelIndex(); } // end loop on currently found pixels if( !pixelTwice ) { // if pixel is not counted twice @@ -2162,7 +2172,7 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe //============= // order pixels //============= - Int_t *nOfneighbours = new Int_t[fStripsInClusterFound]; + Int_t *nOfneighbours; // For analog readout // re-order pixels from the highest charge to the lowest @@ -2187,6 +2197,7 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe // Redefine the seed as the one with the highest number of direct neighbours // This is only needed when the dynamic seed reallocation is not used // JB 2011/07/21 + nOfneighbours = new Int_t[fStripsInClusterFound]; DPixel *aPixel=NULL, *bPixel=NULL; for( Int_t iPix=0; iPix *aListOfPixe } if( fDebugHit>2 ) { - printf(" DHit:Analyse seed is now pixel %d in list, index %d, with %d direct neighbours\n", tPixelIndexList[ 0], fIndexSeed, nOfneighbours[ iSeed]); + printf(" DHit:Analyse seed is now pixel %d in list, index %d, with %d direct neighbours\n", tPixelIndexList[ 0], fIndexSeed, fStripsInClusterFound); } } // end if binary readout @@ -2520,7 +2531,7 @@ Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixe } // end if !valid else if(fDebugHit>1) { - printf(" hit selected with %d pixels\n", fStripsInClusterFound); + printf(" hit nb %d selected with %d pixels\n", fHitNumber, fStripsInClusterFound); } return valid; diff --git a/code/src/DPlane.cxx b/code/src/DPlane.cxx index 44418e0..019ba49 100644 --- a/code/src/DPlane.cxx +++ b/code/src/DPlane.cxx @@ -3720,7 +3720,7 @@ void DPlane::find_hits(){ // All pusleheight is 1 so all pixels are seed candidates // JB 2009/08/21 else if ( fAnalysisMode==3 ){ - if( fDebugPlane>3) printf("DPlane: finding hits try pixel %d with Pulseheight %f\n", tci, fListOfPixels->at(tci)->GetPulseHeight()); + if( fDebugPlane>3) printf("DPlane(%d): finding hits (current index %d) try pixel %d with Pulseheight %f\n", fPlaneNumber, fHitsN, tci, fListOfPixels->at(tci)->GetPulseHeight()); seed = tci; break; @@ -3742,7 +3742,7 @@ void DPlane::find_hits(){ if( seed > -1 ) { // if a seed is defined - if( fDebugPlane>1 ) printf("DPlane: finding hits found potential seed pixel %d with pulse %.3f and SN %.3f ( %f)\n", seed, fListOfPixels->at(seed)->GetPulseHeight(), fListOfPixels->at(seed)->GetPulseHeightToNoise(), fCut->GetSeedPulseHeightToNoise()); + if( fDebugPlane>1 ) printf("DPlane(%d): finding hits (current index %d) found potential seed pixel %d with pulse %.3f and SN %.3f ( %f), already found=%d\n", fPlaneNumber, fHitsN, seed, fListOfPixels->at(seed)->GetPulseHeight(), fListOfPixels->at(seed)->GetPulseHeightToNoise(), fCut->GetSeedPulseHeightToNoise(), tested[seed]); fListOfPixels->at(seed)->SetFound(kTRUE); // mark the strip as found tested[seed] = kTRUE; // mark the strip as already tested for seed @@ -3763,7 +3763,7 @@ void DPlane::find_hits(){ bool IsBigCluster = false; int MaxClusterSize = fc->GetPlanePar(fPlaneNumber).MaxNStrips; hitOK = fHit[fHitsN]->Analyse_Iterative( GetStrip( stPhys),IsBigCluster,MaxClusterSize); - if(IsBigCluster) cout << " DHit: Found the big cluster at Evt " << fSession->GetCurrentEventNumber()-1 << endl << endl; + if(IsBigCluster) cout << " DPlane::find_hits: Found the big cluster at Evt " << fSession->GetCurrentEventNumber()-1 << endl << endl; } else { //Reseach region clustering algorith as default: @@ -3775,14 +3775,14 @@ void DPlane::find_hits(){ else { if(fHitFinder == 0) { //Reseach region clustering algorith - hitOK = fHit[fHitsN]->Analyse( seed, fListOfPixels); + hitOK = fHit[fHitsN]->Analyse( seed, fListOfPixels); } else if(fHitFinder == 1) { //Iterative clustering algorithm bool IsBigCluster = false; int MaxClusterSize = fc->GetPlanePar(fPlaneNumber).MaxNStrips; hitOK = fHit[fHitsN]->Analyse_Iterative( seed, fListOfPixels,IsBigCluster,MaxClusterSize); - if(IsBigCluster) cout << " DHit: Found the big cluster at Evt " << fSession->GetCurrentEventNumber()-1 << endl << endl; + if(IsBigCluster) cout << " DPlane::find_hits:: Found the big cluster at Evt " << fSession->GetCurrentEventNumber()-1 << endl << endl; } else if(fHitFinder == 2){ // Compare the distance from real center of gravity to the pixel position with a search radius to associate this pixel @@ -3846,7 +3846,7 @@ void DPlane::find_hits(){ delete[] tested; // reduce memory leakage, BH 2013/08/21 - if( fDebugPlane>1 ) printf(" %d hits found\n", fHitsN); + if( fDebugPlane>1 ) printf(" ==> DPlane(%d)::find_hits %d hits found\n", fPlaneNumber, fHitsN); return; diff --git a/code/src/MMain.cxx b/code/src/MMain.cxx index 605dd75..7d7745e 100644 --- a/code/src/MMain.cxx +++ b/code/src/MMain.cxx @@ -713,6 +713,7 @@ void TRint::PrintLogo(Bool_t lite) authors.push_back("L.Cousin(1)"); authors.push_back("R.De Masi(1)"); authors.push_back("C.Dritsa(1)"); + authors.push_back("Z.El Bitar(1)"); authors.push_back("M.Gelin(1)"); authors.push_back("Y.Gornoushkin(1)"); authors.push_back("D.Grandjean(1)"); diff --git a/code/src/MRaw.cxx b/code/src/MRaw.cxx index 7bde5fb..d9ea4f1 100644 --- a/code/src/MRaw.cxx +++ b/code/src/MRaw.cxx @@ -229,10 +229,12 @@ void MRaw::PrepareRaw() // bar3->AddButton("JUMP EVENTS","gTAF->GetRaw()->MimosaJump()", "RUN IT AFTER MIMOSA event display"); // bar3->AddButton("RAW CHANNELS", "gTAF->GetRaw()->DisplayRawData(1.)", "Display raw channels per plane and event"); bar3->AddButton("RAW CHANNELS 2D", "gTAF->GetRaw()->DisplayRawData2D()", "Display raw channels per plane and event in 2D"); - bar3->AddButton("CUMULATE RAW CHANNELS 2D", "gTAF->GetRaw()->DisplayCumulatedRawData2D(500)", "Display raw data per plane cumulated over 500 events in 2D"); + bar3->AddButton("CUMULATE RAW CHANNELS 2D", "gTAF->GetRaw()->DisplayCumulatedRawData2D(5000)", "Display raw data per plane cumulated over 500 events in 2D"); bar3->AddButton("HITS 2D", "gTAF->GetRaw()->DisplayHits2D(2,1,0)", "Display hits per plane and event in 2D"); - bar3->AddButton("CUMULATE HITS 2D", "gTAF->GetRaw()->DisplayCumulatedHits2D(500)", "Display hits per plane cumulated over 500 events in 2D"); - bar3->AddButton("CUMUL HITS 2D LADDER (exp)", "gTAF->GetRaw()->DisplayLadderCumulatedHits2D(500)", "Display hits per ladder cumulated over 500 events in 2D"); + bar3->AddButton("CUMULATE HITS 2D", "gTAF->GetRaw()->DisplayCumulatedHits2D(5000)", "Display hits per plane cumulated over 500 events in 2D"); + if( fSession->GetTracker()->GetNumberOfLadders()>0 ) { + bar3->AddButton("CUMUL HITS 2D LADDER (exp)", "gTAF->GetRaw()->DisplayLadderCumulatedHits2D(5000)", "Display hits per ladder cumulated over 500 events in 2D"); + } bar3->AddButton("NOISE MAP", "gTAF->GetRaw()->DisplayNoise()", "Display noise per pixel for each plane"); bar3->AddButton("BINARY FAKE", "gTAF->GetRaw()->FakeRateBinaryFromRawData(100000, 100, 0.01)", "Compute the fake rate for binary output sensors"); diff --git a/include/AliMIMOSA22RawStreamVASingle.h b/include/AliMIMOSA22RawStreamVASingle.h new file mode 100755 index 0000000..9b12cfe --- /dev/null +++ b/include/AliMIMOSA22RawStreamVASingle.h @@ -0,0 +1,99 @@ +#ifndef ALIMIMOSA22RAWSTREAMVASINGLE_H +#define ALIMIMOSA22RAWSTREAMVASINGLE_H + +/////////////////////////////////////////////////////////////////////////////// +/// +/// This class provides access to MIMOSA22THRB digits in raw data. +/// +/////////////////////////////////////////////////////////////////////////////// + + +#include "Riostream.h" +#include "TObject.h" +//#include +#include +#include +#include +#include "BoardReader.h" + +class AliMIMOSA22RawStreamVASingle: public TObject { + + public : + AliMIMOSA22RawStreamVASingle(); + AliMIMOSA22RawStreamVASingle(const AliMIMOSA22RawStreamVASingle& rstream); + AliMIMOSA22RawStreamVASingle& operator=(const AliMIMOSA22RawStreamVASingle& rstream); + ~AliMIMOSA22RawStreamVASingle() {}; + + void SetInputFile(const char *filename="FIFOdata_M22.dat"){ + if ((fFileInput = fopen(filename, "rb")) == NULL) + cout << "Could not open specified file: " << filename << endl; + else + cout << "File " << filename << " opened successfully" << endl; }; + + void SetFrame(int nframe){ + fNFrame=nframe; }; + + void SetDebugLevel( int aLevel) { fDebugLevel = aLevel; } + BoardReaderEvent* GetEvent() { return fCurrentEvent; } + void PrintStatistics(ostream &stream); + Int_t GetCDHEventCounter() { return fEventCounterCDH; } + + Bool_t HasData(); + + Bool_t ReadFrame(); + + Bool_t ReadCDH(); + + Bool_t ReadData(); + + Short_t GetADCCounts(Int_t row, Int_t col){ + if(row<0 || row>=kRowPerChip || col<0 || col>=kColPerChip){ + printf("GetADCCounts: you asked for no existing pixel\n"); + return -1;} + else { + if(col < 8) return 0; // First 8 columns set to 0 + else return fDataFrame[row][col]; } }; + + + enum {kDDLsNumber = 1}; // number of DDLs + enum {kChipsPerDDL = 1}; // number of chips in each DDL + enum {kRowPerChip = 64}; // number of rows per chip + enum {kColPerChip = 64}; //number of columns per chip +// enum {kNFrames = 21}; //number of frames, a parameter since 2014/08/26 + enum {kWordsPerFrame = (kRowPerChip*kColPerChip)/16}; //Number of words in one frame + void SetNFrames( Int_t aNbOfFrames ) { kNFrames = aNbOfFrames; } // JB 2014/08/26 + + + private : + + Int_t fDebugLevel; // debug level + + FILE *fFileInput; + + void NewEvent(); + Bool_t ReadNextInt(); + Int_t GetStart(); + + Int_t fBoardNumber; + Int_t fRunNumber; + Int_t kNFrames; // Nb of frames per channel, JB 2014/08/26 + Int_t fNFrame; // frame (from 0 to kNFrames-1) + UInt_t fDataChar; + UInt_t fEventCounterCDH; // event number read by CDH + UInt_t fcountEv; + Int_t fStart; // word before we start to read + + Short_t fDataFrame[kRowPerChip][kColPerChip]; + Bool_t fActiveChip[kChipsPerDDL]; + Bool_t fChipKey[kChipsPerDDL]; + + std::vector fData; + std::vector *fFrame; + + BoardReaderEvent *fCurrentEvent; + std::vector ListOfPixels; + + ClassDef(AliMIMOSA22RawStreamVASingle, 1) // class for reading MIMOSA22THRB raw digits +}; + +#endif diff --git a/include/BoardReader.h b/include/BoardReader.h new file mode 100644 index 0000000..03ae9fe --- /dev/null +++ b/include/BoardReader.h @@ -0,0 +1,90 @@ +#ifndef _BoardReader_included_ +#define _BoardReader_included_ + + +#include "Riostream.h" +#include "TObject.h" +#include +using namespace std; + +// -------------------------------------------------------------------------------------- + +class BoardReaderPixel : public TObject { + + // Container for a simple pixel + // JB, 2014/05/12 + + private: + + int Input; + int Value; + int Index; + int LineNumber; + int ColumnNumber; + int TimeStamp; + + public: + + BoardReaderPixel() { Input = 0; Value = 0; Index = 0; LineNumber = 0; ColumnNumber = 0; TimeStamp = 0;} + BoardReaderPixel( int input, int value, int index, int time) { Input = input; Value = value; Index = index; LineNumber = 0; ColumnNumber = 0; TimeStamp = time;} + BoardReaderPixel( int input, int value, int line, int col, int time) { Input = input; Value = value; Index = 0; LineNumber = line; ColumnNumber = col; TimeStamp = time;} + virtual ~BoardReaderPixel() {;} + int GetInput() { return Input; } + int GetValue() { return Value; } + int GetIndex() { return Index; } + int GetLineNumber() { return LineNumber; } + int GetColumnNumber() { return ColumnNumber; } + int GetTimeStamp() { return TimeStamp; } + void SetTimeStamp( int timeStamp) { TimeStamp = timeStamp; } + + ClassDef(BoardReaderPixel,1) +}; + +// -------------------------------------------------------------------------------------- + +class BoardReaderEvent : public TObject { + + // A simple event + // JB, 2014/05/12 + + private: + + int EventNumber; + int BoardNumber; + int RunNumber; + std::vector *ListOfPixels; + std::vector *ListOfTriggers; + std::vector *ListOfFrames; + std::vector *ListOfTimeStamps; + + public: + + BoardReaderEvent() {;} + BoardReaderEvent( int eventNumber, int boardNumber, int runNumber) ; + BoardReaderEvent( int eventNumber, int boardNumber, int runNumber, std::vector *aListOfPixels); + ~BoardReaderEvent(); + + int GetEventNumber() { return EventNumber; } + int GetBoardNumber() { return BoardNumber; } + int GetRunNumber() { return RunNumber; } + int GetNumberOfPixels() { return ListOfPixels->size(); } + std::vector *GetPixels() { return ListOfPixels;} + BoardReaderPixel *GetPixelAt( int index) { return &(ListOfPixels->at(index)); } + int GetNumberOfFrames() { return ListOfFrames->size(); } + std::vector *GetFrames() { return ListOfFrames;} + int GetNumberOfTriggers() { return ListOfTriggers->size(); } + std::vector *GetTriggers() { return ListOfTriggers;} + int GetNumberOfTimestamps() { return ListOfTimeStamps->size(); } + int GetTimestampAt( int index) { return ListOfTimeStamps->at(index);} + std::vector *GetTimestamps() { return ListOfTimeStamps;} + + void SetRunNumber( int aRunNumber ) { RunNumber = aRunNumber; } + void SetListOfTriggers( std::vector *aListOfTriggers ) { ListOfTriggers = aListOfTriggers; } + void SetListOfFrames( std::vector *aListOfFrames ) { ListOfFrames = aListOfFrames; } + void SetListOfTimeStamps( std::vector *aListOfTimeStamps ) { ListOfTimeStamps = aListOfTimeStamps; } + + + ClassDef(BoardReaderEvent,1) +}; + +# endif diff --git a/include/BoardReaderEUDAQ.h b/include/BoardReaderEUDAQ.h new file mode 100644 index 0000000..d5d4163 --- /dev/null +++ b/include/BoardReaderEUDAQ.h @@ -0,0 +1,142 @@ +#ifndef _BoardReaderEUDAQ_included_ +#define _BoardReaderEUDAQ_included_ + +#include "BoardReader.h" +#include "Riostream.h" +#include "TObject.h" +#include +#include +#include "DGlobalTools.h" // to have fTool has a data member +//using namespace std; + +//############################################################################## +class BoardReaderEUDAQ : public TObject { + +private: + + int fDebugLevel; // debug level + + int fBoardNumber; + int fRunNumber; + int fTriggerMode; + int fEventBuildingMode; + + int fSensorType; + int fNumberOfSensors; + int fNumberOfRows; + int fNumberOfColumns; + + + // management of input files + ifstream fRawFileStream; + char *fInputFileName; + std::vector fListOfInputFileNames; + std::vector::iterator fCurrentInputFileName; + int fCurrentFileNumber; + int fNumberOfFiles; + + + // management of data buffer + unsigned int *fData; // data array to fill + int fIndex; // index of data array + int fEventSize; // size of the event = header + data + trailer + int fEventHeaderSize; + int fEventDataSize; + int fEventTrailerSize; + int fFiletHeaderSize; + int fBufferRead; + + + // stored information for each event + unsigned int fCurrentTriggerCnt; + int fEventNumber; + + BoardReaderEvent *fCurrentEvent; + vector ListOfPixels; + vector ListOfTriggers; + vector ListOfFrames; + vector ListOfLineOverflow; + + + // management of event reading status + bool fVetoOverflow; // control veto for event with overflow + bool fOverflow; // flag to indicate overflow + int fEventsOverflow; // count total events with overflow + int fNStatesInLine; // count total # states + int fFramesReadFromFile; // count total # frames read + + +// typedef struct { +// +// unsigned int Header; +// unsigned int TriggerCnt; +// unsigned int StopIdx; +// unsigned int TimeStamp; +// +// } FAdcHeader; +// +// FAdcHeader* fFAdcHeader; + +// typedef struct { +// unsigned int Header; +// unsigned int TriggerCnt; +// unsigned int TriggerLine; // ? not sure +// unsigned int FrameCnt; +// unsigned int DataLength; +// unsigned int ADataW16[140]; //data MI26 +// unsigned int Trailer; +// +// } MI26_FrameRaw; +// + unsigned int *fDataBackup; // needed to get previous reading + int fBackupIndex; // index of backup data + int *fBackupSize; // nb of words back-up per sensor + + + bool CloseRawFile(); + bool OpenRawFile(const char *fileName); + bool LookUpRawFile(); + bool FetchEvent(); + + //! Get the starting point of each frame + bool GetStart(int iSensor); + + //! Get frame and returns frameRaw + void GetFrame(int iSensor, MI26_FrameRaw* data); + void GetBackupData(int iSensor, MI26_FrameRaw* data); + + void GetNextFrames(int iSensor, unsigned int trigger, unsigned int *dataBackup, int &backupIndex) + void AddPixel( int input, int value, int aLine, int aColumn); + + //! Get Sensor number + int GetSensor(unsigned int key); + + //! Check trigger counts + bool CheckTriggerCnt(unsigned int trig); + + //! decode frame + bool DecodeFrame(); + + +public: + + BoardReaderEUDAQ(int boardNumber, int runNumber, int fSensorType, int numberOfSensors, int triggerMode, int eventBuildingMode=0); + ~BoardReaderEUDAQ(); + + void SetDebugLevel( int aLevel) { fDebugLevel = aLevel; } + bool AddFile(const char *inputFileName); + void AddFileList(const char *prefixFileName, int firstIndex, int endIndex, const char *suffixFileName); + void OpenFile(); + void CloseFile(); + bool HasData(); + int GetBoardNumber() { return fBoardNumber; } + int GetEventNumber() { return fEventNumber; } + BoardReaderEvent* GetEvent() { return fCurrentEvent; } + void PrintEventHeader(); + void PrintStatistics(ostream &stream); + + + ClassDef(BoardReaderEUDAQ,0) +}; + +#endif diff --git a/include/BoardReaderIHEP.h b/include/BoardReaderIHEP.h new file mode 100644 index 0000000..914ada2 --- /dev/null +++ b/include/BoardReaderIHEP.h @@ -0,0 +1,187 @@ +#ifndef _BoardReaderIHEP_included_ +#define _BoardReaderIHEP_included_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "BoardReader.h" +#include "Riostream.h" +#include "TObject.h" +#include "DGlobalTools.h" // to have fTool has a data member +//using namespace std; + +//############################################################################## +class BoardReaderIHEP : public TObject { + +private: + + int fBoardNumber; + int fTriggerMode; + int fEventBuildingMode; + int fEventNumber; + int fCurrentTriggerNumber; + BoardReaderEvent *fCurrentEvent; + std::vector ListOfPixels; + std::vector ListOfTriggers; + std::vector ListOfTimestamps; + std::vector ListOfFrames; + + // management of event reading status + bool fVetoOverflow; // control veto for event with overflow + bool fOverflow; // flag to indicate overflow + int fEventsOverflow; // count total events with overflow + int fFramesReadFromFile; // count total # frames read + + int i_Trigger; + int Trigger_Framcount[200000][10]; + int Trigger[6]; + + int iFile; + + /* Verbosity : >3-Little information */ + /* 0/1 - Error, Status, Warning */ + /* 0/1/2 - Error, Status, Warning */ + /* 0/1/2/3 - Error, Warning */ + /* >3 - Error */ + int vi_Verbose; /* Recommend-4; Little-6; Less-10 */ + + /* Stream to input Raw Data file */ + fstream ifs_DataRaw; + unsigned long int vi_Pointer_FileBegin; + unsigned long int vi_Pointer_FileEnd; + unsigned long int vi_N_FileSize; + + /* Chip Parameters */ + unsigned long int N_COLUMN; + unsigned long int N_ROW; + unsigned long int N_BANK; + unsigned long int N_BANKCOLUMN; + + /* Read binary data */ + unsigned long int BYTE; // 1Byte = 8bits + unsigned long int WORD; // 1Word = 2Byte = 16bits (Mi28 default) + unsigned long int DWORD; // 1DWord = 2Word = 32bits + + /* Marker for a Ladder */ + unsigned long int M_LADDER_HEADER; + unsigned long int M_LADDER_CHIP; // Ladder Trailer Marker 32 bits : 0x3333333X, Check the Big 28 bits + unsigned long int M_LADDER_TRAILER; // Ladder Trailer Marker 32 bits : 0xCCCCCCCC, Check all the 32 bits + unsigned long int M_LADDER_TriggerHeader; // Ladder Trigger Header Marker 32 bits : 0x55555555, Check all the 32 bits + unsigned long int M_LADDER_TriggerTRAILER; // Ladder Trigger Trailer Marker 32 bits : 0x66666666, Check all the 32 bits + + /* Values for a Pack */ + unsigned long int vi_Trigger_Header; + unsigned long int vi_Trigger_ID; + unsigned long int vi_Pack_Length; + unsigned long int vi_Pack_State; + unsigned long int vi_Trigger_Trailer; + + /* Values for a Ladder */ + unsigned long int vi_Ladder_Header; + unsigned long int vi_Ladder_Header_1; + unsigned long int vi_Ladder_DataLength; + unsigned long int vi_Ladder_Trigger; + unsigned long int vi_Ladder_FrameCounter; + unsigned long int vi_Ladder_Chip; + unsigned long int vi_Ladder_Chip_1; + unsigned long int vi_Ladder_Trailer; + unsigned long int vi_ID_Ladder; + unsigned long int vi_ID_Ladder_Chip; + unsigned long int vi_N_Ladder_Chip; + + /* ------------------------------------------------------ */ + /* Marker for a Chip */ + /* const value for data length */ + //const int CHIP_LENGTH00 = 918 ; /* Mode00, 80MHz , DO1 , 459 + 459 = 918 */ + //const int CHIP_LENGTH01 = 1836 ; /* Mode01, 80MHz , DO0 DO1 , 918 + 918 = 1836 */ + //const int CHIP_LENGTH10 = 1844 ; /* Mode10, 160MHz , DO1 , 922 + 922 = 1844 */ + //const int CHIP_LENGTH11 = 3700 ; /* Mode11, 160MHz , DO0 DO1 , 1850 + 1850 = 3700 */ + + /* Header and Trailer */ + unsigned long int M_CHIP_HEADER; // hex=1234 5678 + unsigned long int M_CHIP_TRAILER; // hex=aaaa aaaa + + /* Signification of the bits in the Status/Line word */ + unsigned long int M_CHIP_N_STATE; // Status/Line, 0-3, number of States + unsigned long int M_CHIP_ADDRESS_LINE; // Status/Line, 4-13, address of the line + unsigned long int M_CHIP_FLAG_RESIDUAL_1; // Status/Line, 14, 1 bit zero + unsigned long int M_CHIP_FLAG_OVERFLOW; // Status/Line, 15, overflow + + /* Signification of the bits in the State word */ + unsigned long int M_CHIP_N_PIXEL; // State, 0-1, number of Pixels + unsigned long int M_CHIP_ADDRESS_COLUMN; // State, 2-11, address of the column + unsigned long int M_CHIP_FLAG_RESIDUAL_2; // State, 12-15, 4 bits zero + + /* Values for a frame */ + unsigned long int vi_DataRaw; + unsigned long int vi_Chip_Header; + unsigned long int vi_Chip_FrameCounter; + unsigned long int vi_Chip_DataLength; + unsigned long int vi_Chip_DataLength_1; + unsigned long int vi_Chip_DataLength_2; + unsigned long int vi_Chip_Status; + unsigned long int vi_Chip_N_State; + unsigned long int vi_Chip_Address_Line; + unsigned long int vi_Chip_Flag_Residual_1; + unsigned long int vi_Chip_Flag_OverFlow; + unsigned long int vi_Chip_State; + unsigned long int vi_Chip_N_Pixel; + unsigned long int vi_Chip_Address_Column; + unsigned long int vi_Chip_Flag_Residual_2; + unsigned long int vi_Chip_Trailer; + unsigned long int vi_Column_Temp; + + /* Pointers */ + unsigned long int vi_Pointer_Data; + unsigned long int vi_Pointer_Pack_DataLength; + unsigned long int vi_Pointer_Ladder_DataLength; + unsigned long int vi_Pointer_Chip_DataLength; + + unsigned long int vi_N_Frame_Good; + unsigned long int vi_N_Frame_Bad; + + double vd_N_PixelTotal; + double vd_N_PixelBankA; + double vd_N_PixelBankB; + double vd_N_PixelBankC; + double vd_N_PixelBankD; + + bool DecodeNextEvent(); + void AddPixel( int iSensor, int value, int aLine, int aColumn, int aTime=0); + unsigned long int SwitchWordBytes(unsigned long int fi_Word); + unsigned long int SwitchDWordBytes(unsigned long int fi_DWord); + unsigned long int SwitchDWordBytes2(unsigned long int fi_DWord); + unsigned long int SwitchDWordWords(unsigned long int fi_DWord); + + +public: + + BoardReaderIHEP(int boardNumber, int triggerMode=0, int eventBuildingMode=0); + ~BoardReaderIHEP(); + + void SetDebugLevel( int aLevel) { vi_Verbose = abs(12-aLevel*2); cout << "IHEP board debug set to " << vi_Verbose << endl; } + bool AddFile(const char *inputFileName); + bool HasData(); + int GetBoardNumber() { return fBoardNumber; } + int GetEventNumber() { return fEventNumber; } + BoardReaderEvent* GetEvent() { return fCurrentEvent; } + void PrintEventHeader(); + void PrintStatistics(ostream &stream); + + + ClassDef(BoardReaderIHEP,0) +}; + +#endif diff --git a/include/BoardReaderMIMOSIS.h b/include/BoardReaderMIMOSIS.h new file mode 100644 index 0000000..c46bb09 --- /dev/null +++ b/include/BoardReaderMIMOSIS.h @@ -0,0 +1,111 @@ +#ifndef _BoardReaderMIMOSIS_included_ +#define _BoardReaderMIMOSIS_included_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "TH1.h" +#include "TH1F.h" + +#include "TTree.h" +#include "TFile.h" + +#include "BoardReader.h" +#include "Riostream.h" +#include "TObject.h" +#include "DGlobalTools.h" // to have fTool has a data member + +//#include "mimo_daq_lib/mimo_daq_lib.h" +//#include "mimo_daq_lib/mimo_daq_lib.c" + +//using namespace std; + +//############################################################################## +class BoardReaderMIMOSIS : public TObject { + +private: + + int fDebugLevel; + DGlobalTools fTool; + + int fBoardNumber; + int fRunNumber; + int fNSensors; + int fTriggerMode; + int fEventBuildingMode; + bool fVetoOverflow; + int fEndianness; // 0= do not swap bytes, 1= swap bytes + + std::ifstream fRawFileStream; + std::vector fListInputFileNames; + size_t fCurrentFileNumber; + bool fNoMoreFile; + bool fisfirstAcq; + int fnbFrPerAcq; + + int fCurrentTriggerNumber; + int fCurrentEventNumber; + + int fReachEndOfRun; + + int fCurrentAcqNumber; + int fCurrentFrameNumber; + int fTriggerCount; + int fFrameCount; + int fBadDecFrameCounter ; // ZE 2021/06/04 - Counter for bad decoded frames + int fNEventsWithOverflow; + BoardReaderEvent *fCurrentEvent; + + std::vector fListOfPixels; + std::vector fListOfTriggers; + std::vector fListOfTimestamps; + std::vector fListOfFrames; + + std::vector fListOfTriggerPos; //JB 2010/06/16 + std::vector fListOfNextTriggerPos; //JB 2011/07/18 + std::vector *fListOfLineOverflow; // MG 2012/02/15 + std::vector fListOfNextTimestamps; // JB 2012/05/04 + + + bool DecodeNextEvent(); + bool DecodeFrame(); +// bool DecodeFrame(MIS1__BT_FBtAcqW16AAlloc*, MIS1__TBtAcqRawRec*, int moduleID, int frameID, +// UInt8 MeasExecTime, UInt8 PrintLvl); // ZE 2021/06/02 + void AddPixel( int iSensor, int value, int aLine, int aColumn, int aTime=0); + + +public: + + int test(); + BoardReaderMIMOSIS(int boardNumber, char *dataPath, int runNumber, int nSensors=1, int triggerMode=0, int eventBuildingMode=0, int endianness=0); + ~BoardReaderMIMOSIS(); + + void SetDebugLevel( int aLevel) { fDebugLevel = aLevel; cout << "BoardReaderMIMOSIS " << fBoardNumber << " debug updated to " << fDebugLevel << endl; } + void SetVetoPixel( int noiseRun=0); + bool HasData(); + void SkipNextEvent(); + int GetBoardNumber() { return fBoardNumber; } + int GetNumberOfSensors() { return fNSensors; } + int GetTriggerMode() { return fTriggerMode; } + int GetEventBuildingMode() { return fEventBuildingMode; } + int GetEventNumber() { return fCurrentEventNumber; } + int GetNofEventsWithOverflow() { return fNEventsWithOverflow; } + BoardReaderEvent* GetEvent() { return fCurrentEvent; } + void PrintEventHeader(); + void PrintStatistics(ostream &stream); + +}; + +#endif diff --git a/include/DAcq.h b/include/DAcq.h new file mode 100644 index 0000000..585bc4e --- /dev/null +++ b/include/DAcq.h @@ -0,0 +1,173 @@ +// @(#)maf/dtools:$Name: $:$Id: DAcq.h,v.2 2005/10/02 18:03:46 sha Exp $ +// Author: Dirk Meier 97/12/06 + +#ifndef _DAcq_included_ +#define _DAcq_included_ + + +////////////////////////////////////////////////////////////////////////// +// // +// DAcq // +// // +// Data Acquisition class // +// . // +////////////////////////////////////////////////////////////////////////// + +#include +#include +#include + +// ROOT classes +#include "TObject.h" +#include "TArrayD.h" // necessary for ? reason +#include "TArrayS.h" // also necessary +#include "Riostream.h" +#include "TBits.h" +#include "TVector2.h" +#include "TVector3.h" + +#include "DGlobalTools.h" +#include "DSetup.h" +#include "DPixel.h" +//#include "DMonteCarlo.h" +#include "TNTBoardReader.h" +#include "PXIBoardReader.h" +//#include "PXIeBoardReader.h" +#include "GIGBoardReader.h" +#include "IMGBoardReader.h" +#include "BoardReader.h" +#include "VMEBoardReader.h" +#include "MCBoardReader.h" +#include "AliMIMOSA22RawStreamVASingle.h" +#include "DecoderM18.h" +#include "DecoderGeant.h" +#include "DEventMC.h" +#include "BoardReaderIHEP.h" +#include "BoardReaderMIMOSIS.h" +#include "sup_exp.typ" // for time reference information + +class DAcq : public TObject { + + private: + + DSetup *fc; // pointer to the configuration + DGlobalTools fTool; // JB 2013/08/20 + + Int_t fDebugAcq; // Acq debug flag + Int_t fModuleTypes; // number of Acquisition Module Types + + TNTBoardReader **fTNT; // pointer to TNT boards + PXIBoardReader **fPXI; // pointer to PXI boards +// PXIeBoardReader **fPXIe; // pointer to PXIexpress boards + GIGBoardReader **fGIG; // pointer to GIG boards, JB 2012/04/25 + IMGBoardReader **fIMG; // pointer to IMG boards, JB 2012/07/22 + VMEBoardReader **fVME; // pointer to VME boards, JB 2014/05/13 + MCBoardReader **fMC; // pointer to MC boards, AP 2016/04/15 + AliMIMOSA22RawStreamVASingle **fALI22; // pointer to ALI22 boards, JB 2014/05/14 + DecoderM18 **fM18; // pointer to DecoderM18 boards, JB 2014/05/25, then 2014/08/26 + DecoderGeant **fGeant; // pointer to DecoderGeant + BoardReaderIHEP **fIHEP; // pointer to IHEP boards, JB 2018/06/03 + BoardReaderMIMOSIS **fMSIS; // pointer to MIMOSIS boards, JB 2021/05/01 + Int_t ***fRawData; // pointer to Raw Values + std::vector *fListOfPixels; // pointer to list of hit pixel + //std::vector *fListOfMonteCarlo; // pointer to list of hit montecarlo + //std::vector *fListOfPixels; // list of hit pixel index + Int_t fTriggersN; // number of triggers in the event, JB 2009/05/22 + Int_t fFramesN; // number of frames in the event, JB 2009/05/22 + Int_t fTimestampsN; // number of timestamps in the event, JB 2009/05/26 + Int_t *fLineOverflowN; // overflow line counter, MG 2012/02/15 + std::vector *ListOfTriggers; // list of triggers JB 2010/06/16 + std::vector *ListOfFrames; // list of frames JB 2010/06/16 + std::vector *ListOfTimestamps; // list of timestamps JB 2010/06/16 + std::vector *ListOfLineOverflow; // line overflow vector per sensor, MG 2012/02/15 + Int_t ****fMatchingPlane; // plane matching the input + Int_t ****fIndexShift; // index shift to add + std::vector ***fInputSegments; // limits of segments for this input, JB 2013/08/14 + Int_t fMaxSegments; // max nb of segements allowed for an input + Bool_t **fUseTimestamp; // flag for timestamp usage, JB 2015/05/26 + + Int_t fEventNumber; // Number of the event according to DSession, JB 2009/05/26 + Int_t fRealEventNumber; // Number of the event writen in the board + Int_t fEventsMissed; // Number of events missed for synchronization + Int_t fEventsDataNotOK; // Number of events with wrong data + Int_t fEventsModuleNotOK;// Number of events with pb in module + Int_t fRunNumber; // Run Number the event is in + + // Data to synchronize two PXIe boards, JB 2012/07/19 + Char_t *fSynchroFileName; + unsigned char *fSynchroInfo; + Int_t fNbSynchroInfo; + + // Data to synchronize two M18Decoders, JB 2015/03/27 + Int_t fSynchroFirstM18Decoder; + Int_t fSynchroOMKDTransition; + Int_t fSynchroStopPointerTransition; + + // Data to obtain external time references, JB 2018/02/11 + Char_t *fTimeRefFileName; + SEXP_TTsRec *fTimeRefInfo; + Int_t fNbTimeRefInfo; + Int_t fCurrentTimeRefInfo; + Int_t fEventReferenceTime; + Int_t fEventTime; + + Bool_t fIfMonteCarlo; // LC 2014/12/15 : If MonteCarlo Info in DPixel fIfMonteCarlo=1 else fIfMonteCarlo=0 + + Bool_t fIsMCBoardReader; // AP 2016/07/27 bool to specify if reading data with MCBoardReader + DEventMC* MCInfoHolder; // AP 2016/04/21 Object with all the MC information. i.e. the full list of particles, hits and pixels (both from physics and noise) + + public: + DAcq(); + DAcq(DSetup& c); + ~DAcq(); + TBits* NextEvent( Int_t eventNumber, Int_t aTrigger=-1); // actually read the data from raw file!, JB 2009/05/26, 2012/07/10 + void Reset(); // Restart event reading at 0, JB 2015/03/02 + Int_t* GetRawData( Int_t mdt, Int_t mdl, Int_t input); // get the raw data buffer + void GetMatchingPlaneAndShift( Int_t mdt, Int_t mdl, Int_t input, Int_t channel, Int_t &aPlane, Int_t &aShift); // get the plane and shift matching the input and channel + std::vector *GetListOfPixels( Int_t aPlaneNumber) { return &fListOfPixels[aPlaneNumber-1]; }// get the hit pixel list for a given plane + //std::vector *GetListOfPixels( Int_t aPlaneNumber) { return &fListOfPixels[aPlaneNumber]; }// get the hit pixel index list for a given plane + //std::vector *GetListOfMonteCarlo( Int_t aPlaneNumber) { return &fListOfMonteCarlo[aPlaneNumber-1]; }// get the hit monte carlo list for a given plane + Bool_t GetUsageTimestamp( Int_t mdt, Int_t mdl) { return fUseTimestamp[mdt-1][mdl-1];} // JB 2015/05/26 + + Bool_t DumpHexToTerm(); // performs a hexadecimal dump of data + // without any interpretation of data + Int_t GetEventNumber() const { return fEventNumber; } // Number of the event according to Dsession, JB 2009/05/26 + Int_t GetRealEventNumber() const { return fRealEventNumber; } // Number of the event in the raw data file + Int_t GetRunNumber() const { return fRunNumber; } // Run Number the event is in + + std::vector *GetTriggers() { return ListOfTriggers;} + std::vector *GetFrames() { return ListOfFrames;} + std::vector *GetTimestamps() { return ListOfTimestamps;} + std::vector *GetLineOverflow() { return ListOfLineOverflow;} + Int_t GetNumberOfTriggers() { return fTriggersN;} + Int_t GetNumberOfFrames() { return fFramesN;} + Int_t GetNumberOfTimestamps() { return fTimestampsN;} + Int_t GetTriggerAt( int index) { return ListOfTriggers->at(index); } + Int_t GetFrameAt( int index) { return ListOfFrames->at(index); } + Int_t GetTimestampAt( int index) { return ListOfTimestamps->at(index); } + + // Methods to synchronized two boards, JB 2012/07/19 + Bool_t InitSynchroInfo( ); + Bool_t GetSynchroInfo( int anEventId, int &anAcqId, int &aFrameId); + + // Methods to obtain an outside time reference , JB 2018/02/11 + Bool_t InitTimeRefInfo( ); + Bool_t GetTimeRef( int index, int &recordID, int &cycleID, int &rtcTime, int &ntpTime); + Int_t GetEventTime() { return fEventTime; } // JB 2018/02/12 + + DSetup& GetSetup() { return *fc; } + void SetDebug(Int_t aDebug); + Int_t GetDebug() { return fDebugAcq;} + + void PrintStatistics(ostream &stream=cout); // JB 2009/09/09 //SS 2011/12/14 + void DumpSynchroInfo( Int_t nEvents=-1); // JB 2013/08/20 + + Bool_t IfMonteCarlo() { return fIfMonteCarlo; } // LC 2014/12/15 : Test to include MonteCarlo Infos + + Bool_t GetIfMCBoardReader() { return fIsMCBoardReader; } // AP 2016/07/27 : Function to get the if reading data with MCBoardReader + DEventMC* GetMCInfoHolder() { return MCInfoHolder; } // AP 2016/04/21 : Function to get the MCInfoHolder + + ClassDef(DAcq,3) // Data Acquisition +}; + +#endif diff --git a/include/DAlign.h b/include/DAlign.h new file mode 100644 index 0000000..cbd8bb5 --- /dev/null +++ b/include/DAlign.h @@ -0,0 +1,149 @@ +// @(#)maf/dtools:$Name: $:$Id: DAlign.h,v.1 2005/10/02 18:03:46 sha Exp $ +// Author: Dirk Meier 97/01/20 + +#ifndef _DAlign_included_ +#define _DAlign_included_ + +//////////////////////////////////////////////////////////// +// // +// Class DAlign // +// book keeping for alignment // +// // +//////////////////////////////////////////////////////////// + +// ROOT classes +#include "TObject.h" +#include "Riostream.h" +// DT classes +#include "DR3.h" +#include "TH2.h" +#include "TH3.h" +#include "TF1.h" +#include "TProfile.h" +#include "TCanvas.h" +#include "TFile.h" + +class DCut; +class DTrack; + +class DAlign : public TObject { + private: + Int_t fDebugAlign; // Align debug flag + Int_t fPlaneNumber; // plane nb being aligned + TCanvas* fAlignCanvas; + TCanvas* fpfxAlignCanvas; // Added 060314 BB + TCanvas* fAlign3DCanvas; // Added 070414 BB + TF1* f1legendre7U; // Define a Legendre polynomial of the order 7th, BB 21/05/2014 + TF1* f1legendre7V; // Define a Legendre polynomial of the order 7th, BB 21/05/2014 + TH1F* fhAlignDU; + TH1F* fhAlignDV; + TH2F* fhAlignDVDU; + TH2F* fhAlignPosUV; + TH2F* fhAlignPosVU; + TH2F* fhAlignPosUU; + TH2F* fhAlignPosVV; + TH2F* fhAlignUU; // JB 2014/08/26 + TH2F* fhAlignVV; // JB 2014/08/26 + TH2F* fhAlignPosUUV; // BB 070414 + TH2F* fhAlignPosVUV; // BB 070414 + TProfile* fpfxAlignPosUV; // Profile of fhAlignPosUV, BB 050314 + TProfile* fpfxAlignPosVU; // Profile of fhAlignPosVU, BB 050314 + TProfile* fpfxAlignPosUU; // Profile of fhAlignPosUU, BB 050314 + TProfile* fpfxAlignPosVV; // Profile of fhAlignPosVV, BB 050314 + Bool_t fEnoughU; + Bool_t fEnoughV; + Bool_t fEnough2D; + Int_t fNumberOfEvents; // min # events to accumulate + Double_t fBound; // max distance track-hit + Double_t fBoundU; // max distance track-hit in U, JB 2013/06/10 + Double_t fBoundV; // max distance track-hit in V, JB 2013/06/10 + Double_t fLimitsU[2]; // min-max in U for tracks, JB 2013/06/10 + Double_t fLimitsV[2]; // min-max in V for tracks, JB 2013/06/10 + Double_t fAlignResolutionU; + Double_t fAlignMeanU; + Double_t fAlignResolutionV; + Double_t fAlignMeanV; + Double_t fAlignSum_du; + Double_t fAlignSum_dudu; + Double_t fAlignSum_duvt; + Double_t fAlignSum_vt; + Double_t fAlignSum_vtvt; + Int_t fAlignCountu; + Double_t fAlignSum_dv; + Double_t fAlignSum_dvdv; + Double_t fAlignSum_dvut; + Double_t fAlignSum_ut; + Double_t fAlignSum_utut; + Int_t fAlignCountv; + Double_t fAlignSum_uvt2; + Double_t fAlignSum_dvuduv; + Int_t fAlignCount2D; + Double_t fAlignTiltW; // name reaplced from tiltZ to tiltW, JB 2010/11/25 + Double_t fAlignOffsetU; + Double_t fAlignOffsetV; + Double_t fAlignTiltWError; + Double_t fAlignOffsetUError; + Double_t fAlignOffsetVError; + Double_t fAlignCorrelation; + DR3 fAlignOffset; + + public: + DAlign(); + DAlign(Int_t aPlaneNumber, Int_t aDebugLevel=0); + ~DAlign(); + void SetDebug(Int_t aDebug){fDebugAlign = aDebug;} + Int_t GetDebug() { return fDebugAlign;} + + void AccumulateU(DR3 &aTrackPos, Double_t aDistance_U); + void AccumulateV(DR3 &aTrackPos, Double_t aDistance_V); + void Accumulate2D(DR3& aTrackPos, Double_t aDistanceU, Double_t aDistanceV); + Double_t GetOffsetU() { return fAlignOffsetU; } + Double_t GetOffsetV() { return fAlignOffsetV; } + Double_t GetTiltW() { return fAlignTiltW; } + Double_t GetResolutionU() { return fAlignResolutionU; } + Double_t GetMeanU() { return fAlignMeanU; } + Double_t GetResolutionV() { return fAlignResolutionV; } + Double_t GetMeanV() { return fAlignMeanV; } + DR3& GetOffset() { return fAlignOffset; } + void Modified(); + Int_t GetCounts() { return TMath::Max(fAlignCountu, fAlignCount2D); } + Double_t GetBounding() { return fBound; } + Double_t GetBoundingU() { return fBoundU; } // JB 2013/06/10 + Double_t GetBoundingV() { return fBoundV; } // JB 2013/06/10 + void ShowCorrection(); + void ShowStoredResolution(); + void CreateDisplay( Double_t Umin, Double_t Umax, Double_t Vmin, Double_t Vmax); + void CreateDisplayDeformation( Double_t Umin, Double_t Umax, Double_t Vmin, Double_t Vmax); // BB 2014/05/20 + TCanvas* GetDisplay() { return fAlignCanvas; } + TCanvas* GetDisplayDeformation() { return fpfxAlignCanvas; } // BB 2014/05/20 + TCanvas* GetDisplayDeformationFitted() { return fpfxAlignCanvas; } // BB 2014/05/20 + void SaveDisplay( const Char_t *fileName); // JB 2014/05/06 + void SaveDisplayDeformation( const Char_t *fileName); // BB 2014/05/06 + void StoreU(DR3& aTrackPos, Double_t aDistanceU); + void StoreV(DR3& aTrackPos, Double_t aDistanceV); + void Store2D(DR3& aTrackPos, Double_t aDistanceU, Double_t aDistanceV); + void Display(); + void DisplayDeformation(); // BB 2014/05/20 + void DisplayDeformationFitted(); // BB 2014/05/21 + void Display(Int_t fRunNumber); // LC 2012/09/20. + void DisplayDeformation(Int_t fRunNumber); // BB 2014/05/20 + void DisplayDeformationFitted(Int_t fRunNumber); // BB 2014/05/21 + void SetBounding(Double_t aBound); + void SetBoundings(Double_t aBoundU, Double_t aBoundV); // JB 2013/06/10 + void SetGeoLimits(Double_t umin, Double_t umax, Double_t vmin, Double_t vmax); // JB 2013/06/10 + void SetEvents( Int_t nEvents) { fNumberOfEvents = nEvents; } // JB, 2009/05/25 + void FitDeformation(Double_t (*CoeffLegendreU), Double_t (*CoeffLegendreV), Float_t minU=0., Float_t maxU=0., Float_t minV=0., Float_t maxV=0.); // BB, 21/05/2014 + Bool_t EnoughU() { return fEnoughU; } + Bool_t EnoughV() { return fEnoughV; } + Bool_t Enough2D() { return fEnough2D; } + + TH2F* GetHistUV() { return fhAlignPosUV; } + TH2F* GetHistVU() { return fhAlignPosVU; } + TF1* GetFitDeformationU() { return f1legendre7U; } + TF1* GetFitDeformationV() { return f1legendre7V; } + + + ClassDef(DAlign,2) // book keeping for alignment + }; + +#endif diff --git a/include/DBeaster.h b/include/DBeaster.h new file mode 100644 index 0000000..08cdb1a --- /dev/null +++ b/include/DBeaster.h @@ -0,0 +1,328 @@ +#ifndef _DBeaster_included_ +#define _DBeaster_included_ + +// #include +// #include +#include "TLegend.h" +#include "TObject.h" + +//TAF Include +#include "DTracker.h" +#include "DLadder.h" +#include "DPlane.h" +#include "DAlign.h" +#include "DHit.h" +#include "DR3.h" +#include "DHelixFitter.h" + + +using namespace std; +class DHelixFitter; + +class DBeaster: public TObject { +private: +public: + DBeaster (DTracker *Tracker); + virtual ~DBeaster (); + + DLadder *aLadder; + DPlane *aPlane; + DHit *aHit; + DTracker *tTracker; + DEventMC *MCInfoHolder; + DSession *fSession; + DPrecAlign *Dprec; + DHelixFitter *fHelixFitter; + + struct ABeastHit { + //Hit Identification + int LadderId; + int ModuleId; + int SensorId; + int HitId; + int McHitId ; + //Position in Ladder Ref Frame + DR3 hitPositionLadderUVW; + //Position in Lab Ref Frame + DR3 hitPositionLabXYZ; + // Analysis Flag + + //Spatial Clustering + int RecoId_SC; + bool IsRec_SC; + //Superposition + int RecoId_SP; + bool IsRec_SP; + double RpairedSP; + bool IsFill_SC; + //Alignment + int RecoId_AL; + bool IsRec_AL; + double VpairedAL; + + }; + //List Of Hits on Module 1 & 2 + std::vector ListOfBeastHitsOnM1; + std::vector ListOfBeastHitsOnM2; + struct ABeastRecoPart { + int ClassType; + std::vector HitList; + std::vector HitScIdList; + std::vector HitSpIdList; + + bool IsRec_SPreco; + bool IsRec_ALreco; + }; + std::vector ListOfRecoPartsM1_SC; + std::vector ListOfRecoPartsM2_SC; + std::vector ListOfRecoPartsM1_AL; + std::vector ListOfRecoPartsM2_AL; + std::vector ListOfRecoParts_SP; + std::vector ListOfBeastRecoParts_L1; + std::vector ListOfBeastRecoParts_L2; + std::vector ListOfTsIpCandidat; + std::vector ListOfTsCandidat; + std::vector ListOfTslCandidat; + std::vector ListOfSimuPartClass; + std::vector ListOfSimuPartIdL1; + std::vector ListOfSimuPartIdL2; + std::vector ListOfRecoTS; + std::vector ListOfFakeRecoTs; + + //********* Particle patterns********* // + // OS --> One Side // + // TS --> Two Sides // + // OSL --> One Side Looper // + // TSL --> Two Sides Looper // + // ******************************** // + int NbPart; + int NbHit; + int NbPolyLine; + int NbHitsMod1; + int NbHitsMod2; + int NbHitsL1; + int NbHitsL2; + int LadderNumber; + int PlaneIdx; + int SensorMin; + int SensorMax; + // Boolean for Particle classification + bool Ladder1; + bool Ladder2; + bool Ladder; + bool Module1; + bool Module2; + bool MoreThanTwoHits; + int NbHitsTest; + + //********* Hit Parameters *********// + double PhiLoc; + double ThetaLoc; + double Rsphere; + double Utest; + double Vtest; + double Xsphere; + double Ysphere; + double Zsphere; + double DeltaV; + double DeltaU; + double DeltaVtest; + + //Lab reference frame + double X1; + double X2; + double X; + double Y1; + double Y2; + double Y; + double dR; + //Ladder reference frame + double U1; + double U2; + double dU; + double V1; + double V2; + double dV; + //Angular projection + double AP1; + double AP2; + double dAP; + //Momentum + double Pin; + double dP; + double Pt; + double Ptout; + double dPt; + double Pt0; + + double Rvertex; + + // int TwoSidesLoopersIdx; + // int OneSidesLoopersIdx; + // int TwoSidesHitsIdx; + + Int_t TwoSidesLoopersFrames; + Int_t TwoSidesLoopersParts; + + Int_t OneSidesLoopersFrames; + Int_t OneSidesLoopersParts; + + Int_t TwoSidesHitsFrames; + Int_t TwoSidesHitsParts; + + std::vector L1M1_1part; + std::vector L1M2_1part; + std::vector L2M1_1part; + std::vector L2M2_1part; + + std::vector L1M1_2part; + std::vector L1M2_2part; + std::vector L2M1_2part; + std::vector L2M2_2part; + + std::vector L1M1_3part; + std::vector L1M2_3part; + std::vector L2M1_3part; + std::vector L2M2_3part; + + + + DR3 *hitPositionPlane; + DR3 hitPositionLadder; + DR3 hitPositionLab; + //********* Histogram Definition *********// + + // TH1F *h_hitL1; + // + // TH1F *h_SimuPart; + // TH1F *h_RecoPart; + // + // TH1F *h_RecoPart_aL1; + // TH1F *h_RecoPart_bL1; + // TH1F *h_RecoPart_cL1; + // TH1F *h_RecoPart_dL1; + // + // TH1F *h_RecoPart_aL2; + // TH1F *h_RecoPart_bL2; + // TH1F *h_RecoPart_cL2; + // TH1F *h_RecoPart_dL2; + // + // TH1F *h_SimuPart_aL1; + // TH1F *h_SimuPart_bL1; + // TH1F *h_SimuPart_cL1; + // TH1F *h_SimuPart_dL1; + // + // TH1F *h_SimuPart_aL2; + // TH1F *h_SimuPart_bL2; + // TH1F *h_SimuPart_cL2; + // TH1F *h_SimuPart_dL2; + // + // TH1F *h_SimuOS; + // TH1F *h_SimuTS; + // TH1F *h_SimuOSL; + // TH1F *h_SimuTSL; + // + // TH1F *h_SimuOS_Good; + // TH1F *h_SimuTS_Good; + // TH1F *h_SimuOSL_Good; + // TH1F *h_SimuTSL_Good; + // + // TH1F *h_SimuOS_Bad; + // TH1F *h_SimuTS_Bad; + // TH1F *h_SimuOSL_Bad; + // TH1F *h_SimuTSL_Bad; + // + // THStack *hs_PartnerOS; + // THStack *hs_PartnerTS; + // THStack *hs_PartnerOSL; + // THStack *hs_PartnerTSL; + // + // TH1F *h_MomentumOS; + // TH1F *h_MomentumTS; + // TH1F *h_MomentumOSL; + // TH1F *h_MomentumTSL; + // + // TH1F *h_AngularDistributionTsL1; + // TH1F *h_AngularDistributionTsL2; + // TH1F *h_AngularDistributionTslL1; + // TH1F *h_AngularDistributionTslL2; + // + // TH1F *h_NbTslL1; + // TH1F *h_NbTslL2; + // + // TH2F *h_FractionLossL1; + // TH2F *h_FractionLossL2; + // + // THStack *hs_DCH_CatHitStack; + // + // + // TH1F *h_D3hit1Part; + // TH1F *h_D3hit2Part; + // TH1F *h_D3hit3Part; + // + // TH3F *h_VrtxPosXYZ; + // TH2F *h_VrtxPosXZ; + // TH2F *h_VrtxPosXY; + // TH2F *h_VrtxPosRZ; + // + // TH2F *h_VrtxPosXY_OS; + // TH2F *h_VrtxPosXY_TS; + // TH2F *h_VrtxPosXY_OSL; + // TH2F *h_VrtxPosXY_TSL; + // + // TH2F *h_VrtxPosXY2; + // + // TH1F *h_ER_P_OSL; + // TH1F *h_ER_Pt_OSL; + // + // TH1F *h_ER_P_TSL; + // TH1F *h_ER_Pt_TSL; + // + // TH1F *h_ER_P_TS; + // TH1F *h_ER_Pt_TS; + //TLine *l_projection; + + // TPolyMarker *m_Test; + // TPolyMarker *m_Test2; + // + // TPolyLine *l_Test; + // TPolyLine *l_Test2; + //TView3D *view; + + TVector3 Vhit; + TVector2 VDhit; + double MagVDhit; + DHelixFitter *GetHelixFitter() { return fHelixFitter; } + + // vector GetBeastHitsOnM1() const {return ListOfBeastHitsOnM1;} + // vector GetBeastHitsOnM2() const {return ListOfBeastHitsOnM2;} + // vector GetListOfBeastRecoPart() {return ListOfBeastRecoParts;} + virtual DR3 GetHitPositionOnLadderRefFrame(int PlaneId,int HitId); + virtual DR3 GetHitPositionOnLabRefFrame(int PlaneId,int HitId); + virtual void SpatialClustering(double Seuil); + virtual void Superposition(double Seuil); + virtual void Allignement(double Seuil); + virtual void FillListOfRecoPartsSC(); + virtual void FillListOfRecoPartsSP(); + virtual void FillListOfBeastRecoPart(int ladderID); + virtual void SimuCategorieClassification(); + virtual void SimuCategorieClassificationNew(); + virtual void RecoCategorieClassification(int ladderId,int iHitSeuil); + virtual void Fill_Modules_HitList(int LadderId); + virtual void Particle_Reconstruction(int LadderId); + virtual void Clear_List(); + // virtual void PurityTest(); + // virtual void PurityTest_Partner(); + // virtual void Categorie_Momentum(); + // virtual void Angular_DistributionSimuTS(); + // virtual void Angular_DistributionSimuTSL(); + virtual void FillTslCandidat(); + virtual void FillListOfRecoPartsSPnew(); + virtual void HelixFitBuildUpStudy(int iLadder); + virtual void BuildMcTrueTsFromIpList(int iLadder); + virtual void BuildMcTrueTsList(int iLadder); + virtual void BuildFakeRecoTsList(int iLadder); + +ClassDef(DBeaster,1) +}; +#endif diff --git a/include/DCut.h b/include/DCut.h new file mode 100755 index 0000000..d162587 --- /dev/null +++ b/include/DCut.h @@ -0,0 +1,74 @@ +// @(#)maf/dtools:$Name: $:$Id: DCut.h,v.2 2005/10/02 18:03:46 sha Exp $ +// Author: ? + + +#ifndef _DCut_included_ +#define _DCut_included_ + + + ///////////////////////////////////////////////////////////// + // // + // Class Description of DCut // + // // + //////////////////////////////////////////////////////////// + +#include + +// ROOT classes +#include "TObject.h" + + +class DSetup; +class DR3; +class DPlane; + +class DCut : public TObject { +private: + DSetup *fc; // pointer to configuration + Int_t fPlaneNumber; + Float_t fSeedPulseHeightToNoise; + Float_t fNeighbourPulseHeightToNoise; + Float_t fMaximalNoise; + Float_t fMinimalNoise; + Int_t fStripsInClusterArea; // # strips allowed in the cluster area + Int_t fStripsInClusterMin; // min # strips allowed in the cluster + Int_t fStripsInClusterMax; // max # strips allowed in the cluster + DR3 *fClusterLimit; + Float_t fClusterLimitRadius; // maximum search radius (in mm) from real center of gravity (in mm) to associate new pixels + Int_t fDebugCut; // debug flag + + public: + void SetDebug(Int_t aDebug){fDebugCut = aDebug;} + Int_t GetDebug() { return fDebugCut;} + + DCut(); + DCut(DPlane& aPlane); + ~DCut(); + Float_t GetSeedPulseHeightToNoise() const { return fSeedPulseHeightToNoise; } + Float_t GetNeighbourPulseHeightToNoise() const { return fNeighbourPulseHeightToNoise; } + Float_t GetMaximalNoise() const { return fMaximalNoise; } // JB 2013/08/29 + Float_t GetMinimalNoise() const { return fMinimalNoise; } + Int_t GetStripsInClusterArea() const { return fStripsInClusterArea; } + Int_t GetStripsInClusterMin() const { return fStripsInClusterMin; } + Int_t GetStripsInClusterMax() const { return fStripsInClusterMax; } + DR3& GetClusterLimit() const { return *fClusterLimit; } + Float_t GetClusterLimitRadius() const { return fClusterLimitRadius;} + + void SetSeedPulseHeightToNoise(Float_t val); + void SetNeighbourPulseHeightToNoise(Float_t val); + + ClassDef(DCut,1) // Describes DCut + +}; + +#endif + + + + + + + + + + diff --git a/include/DEvent.h b/include/DEvent.h new file mode 100644 index 0000000..1833e71 --- /dev/null +++ b/include/DEvent.h @@ -0,0 +1,367 @@ +// @(#)maf/dtools:$Name: $:$Id: DEvent.h,v.2 2005/10/02 18:03:46 sha Exp $ +// Author: Dirk Meier 98/02/18 +// Last Modified, AP 2015/05/22, DEvent class: Changed Short_t by Int_t +// fAHitsN,fT1PlanesN,fAPlanesN + +#ifndef _DEvent_included_ +#define _DEvent_included_ + + + //////////////////////////////////////////////////////////////// + // Class Description of DEvent // + // // + // Trigger event contains values from detector planes // + // This event is later written to a data summary ".root" file // + // // + // Datamembers are public for historical resons // + //////////////////////////////////////////////////////////////// + +#include +#include +#include "Riostream.h" + +// ROOT classes +#include "TObject.h" +#include "TClonesArray.h" +#include "TArrayF.h" +#include "TH1.h" + +class DSetup; +class DTracker; +class DPlane; // used to fill data into event plane +class DTrack; +class DHit; +class DAcq; + +#define MaxNumberOf 50 + +class DEventHeader { + + // data which is characteristic to the event + // convention: variables start with `E' + + public: + DEventHeader(){;} + virtual ~DEventHeader(){;} + void Clear(const Option_t * /*option*/ = ""); + void Set(const Int_t aNEvent, + const Int_t aNRun, + const Int_t aDate, + const Int_t aTime, + const Int_t aType, + std::vector *aListOfTriggers=NULL, + std::vector *aListOfFrames=NULL, + std::vector *aListOfTimestamps=NULL); + void SetTimeSinceLastEvent(const Int_t aDeltaTime); + Int_t GetEventNumber() const { return Ek; } + Int_t GetRunNumber() const { return Erunk; } + Int_t GetDate() const { return Edate; } + Int_t GetTime() const { return Etime; } + Int_t GetNumberOfTriggers() { return ENumberOfTriggers;} + Int_t GetNumberOfFrames() { return ENumberOfFrames;} + Int_t GetNumberOfTimestamps() { return ENumberOfTimestamps;} + Int_t GetTriggerAt( int index) { return EListOfTriggers[index]; } + Int_t GetFrameAt( int index) { return EListOfFrames[index]; } + Int_t GetTimestampAt( int index) { return EListOfTimestamps[index]; } + void Print(); + + Int_t Ek; // Number of the Event + Int_t Erunk; // Number of the Run + Int_t Edate; // Date YYMMDD + Int_t Etime; // Time HHMMSS + Int_t EtimeSinceLastEvent ; + Int_t Erelative; // time in seconds since start of month, + // causes problems when month wraps. + Int_t Etype; // type of the event + // (may be significant when random trigger comes) + Int_t ENumberOfTriggers; + Int_t EListOfTriggers[MaxNumberOf]; // list of triggers JB 2010/07/07 + Int_t ENumberOfFrames; + Int_t EListOfFrames[MaxNumberOf]; // list of frames JB 2010/07/07 + Int_t ENumberOfTimestamps; + Int_t EListOfTimestamps[MaxNumberOf]; // list of timestamps JB 2010/07/07 + + ClassDef(DEventHeader,2) // Describes Event Header + }; + +//__________________________________________________________________________________ +// + +class DEvent : public TObject { + public: + DEvent(); + DEvent(DSetup& fc); + virtual ~DEvent(); + void Clear(const Option_t * /*option*/ = ""); + void SetHeader(const Int_t aNEvent, + const Int_t aNRun, + const Int_t aDate, + const Int_t aTime, + const Int_t aType, + std::vector *aListOfTriggers=NULL, + std::vector *aListOfFrames=NULL, + std::vector *aListOfTimestamps=NULL); + void SetTimeInterval(const Int_t aDeltaTime); + void AddAuthenticPlane(DPlane& aPlane, Int_t aNEvent); + void AddTransparentPlane(DPlane& aPlane, DTrack& aTrack, DHit& aHit, Bool_t hitAssociated, DTracker &aTracker); // modified JB 2014/12/18, 2014/08/29 + void AddAuthenticHit(DHit& aHit, Int_t aNEvent, DTrack& aTrack); + DEventHeader& GetHeader() { return fHeader; } + TClonesArray *GetAuthenticHits() { return fAHits; } + TClonesArray *GetAuthenticPlanes() { return fAPlanes; } + TClonesArray *GetTransparentPlanes() { return fT1Planes; } + void SetTDC(Float_t aTDCValue) { fTDC = aTDCValue; } + void SetFrame(const Int_t aFrameNb, + const Int_t aLineNb); + Int_t GetFrameNb() { return fFrameNb; } + Int_t GetLineNb() { return fLineNb; } + + DEventHeader fHeader; // Header of the Event + Int_t fEvt; + Int_t fAHitsN; // number of cluster hits in data array + TClonesArray *fAHits; // pointer to hits + Int_t fT1PlanesN; // number of planes in transparent data array + TClonesArray *fT1Planes; // transparent data of detector planes + + Int_t fAPlanesN; // number of authentic planes in array + TClonesArray *fAPlanes; // pointer to authentic planes + + Float_t fTDC; // TDC value for SCT analysis + + Int_t fFrameNb; // frame number from CMOS sensor + Int_t fLineNb; // line number from CMOS sensor + + ClassDef(DEvent,3) // Describes Event + }; + +//____________________________________________________________________ +// + +class DAuthenticHit : public TObject { + + // data which is characteristic to a hit + // convention: variables start with `H' + + public: + DAuthenticHit(){;} + DAuthenticHit(DHit& aHit, Int_t aNEvent, DTrack& aTrack); + virtual ~DAuthenticHit(){;} + + Int_t Hevt; // event number + Short_t Hhk; // authentic hit number in the plane + Short_t HhN; // number of authentic hits in the plane + Short_t Hpk; // number of the plane (Hit Plane Number) + Float_t Hsu; // u position of hit Seed Strip + Float_t Hsv; // v position of hit Seed Strip + Float_t Hu; // position of hit measured with charge fraction method (2-strip + Float_t Hv; + Float_t Hresu; // spatial resolution of hit + Float_t Hresv; + + Int_t HTS; // time-stamp of hit + + Float_t HuCG; // position of hit measured with center of gravity (3x3) method + Float_t HvCG; // position of hit measured with center of gravity (3x3) method + Float_t HuEta; // position of hit measured with eta method + Float_t HvEta; // position of hit measured with eta method + + + Float_t Htv; // v position of track next to this hit + Float_t Htu; // u position of track next to this hit + Short_t HtN; // number of tracks found passing the plane + Short_t Htk; // nearest track number, JB 2009/06/26 + Short_t HtHn; // number of hits in the track, JB 2009/09/08 + Float_t HtChi2; // chiSquare/ndf of track fit (2D), track next to this hit + Float_t HtChi2u; // chiSquare/ndf of track fit in u dim, track next to this hit + Float_t HtChi2v; // chiSquare/ndf of track fit in v dim, track next to this hit + + Float_t Hqc; // cluster pulse sum + Short_t HsN; // strips in cluster -> changed to seed SNR, JB 2013/11/08 + Float_t Hsn; // seed strip noise + //----ab + Float_t HsnPulse; // seed strip pulse + Float_t HsnIndex; // seed strip index + + Float_t HSNc; // cluster S/N (for S/N of neighbours see HSNneighbour) + Float_t Hnc; // cluster noise average + Float_t HSNc1; // Hqc/Hsn + Int_t Hsk; // seed strip index + + Int_t HNNS; //Number of neighbours of the seed ; + + Float_t Hq0; // pulseheight on seed strip, (neighbour 0) + Float_t Hq1; // second highest pulseheight + Float_t Hq2; // third highest pulseheight + Float_t Hq3; + Float_t Hq4; + Float_t Hq5; + Float_t Hq6; + Float_t Hq7; + Float_t Hq8; + Float_t HqM[400]; // all pixels in MIMOSA cluster + + Int_t Hk0; // strip index of strip with charge Hq0 + Int_t Hk1; // strip index of strip with charge Hq1 + Int_t Hk2; // with Hq2 + Int_t Hk3; // with Hq3 + Int_t Hk4; // with Hq4 + Int_t Hk5; // with Hq5 + Int_t Hk6; // with Hq6 + Int_t Hk7; + Int_t Hk8; + Int_t HkM[400]; // needs to be large enough + + Float_t Hn0; // noise on seed strip, (neighbour 0) + Float_t Hn1; // second pixel noise + Float_t Hn2; // third pixel noise + Float_t Hn3; + Float_t Hn4; + Float_t Hn5; + Float_t Hn6; + Float_t Hn7; + Float_t Hn8; + Float_t HnM[400]; // all pixels in MIMOSA cluster + + + Float_t HqL; // charge on left most strip of two + Float_t HqR; // charge on right most strip of two + Float_t HqRoS; // charge right of seed + Float_t HqLoS; // charge left of seed + + Int_t HkL; // index of strip left of seed, `HkR' = HkL+1 would be redundant + Float_t HuL; // postion u [micron] left of two highest + + Float_t HSNneighbour; // S / N of neighbours. + + ClassDef(DAuthenticHit,4) + }; + +//__________________________________________________________________________ +// + +class DAuthenticPlane : public TObject { + + // data which is characteristic to a plane + // convention: variables start with `P' + + public: + DAuthenticPlane(){;} + DAuthenticPlane(DPlane& aPlane, Int_t aNEvent); + virtual ~DAuthenticPlane(){;} + + public: + Int_t Pevt; // event number + Short_t Ppk; // Authentic Plane Number + Short_t PhN; // number of hits in this plane + Short_t PtN; // number of tracks crossing this plane + Float_t Pt; // authentic plane threshold on single strip [ADC] + Short_t PotN; // authentic number of strips with pulseheight over threshold + Float_t PotQ; // charge sum on strips over threshold + + // the following is usefull for noise estimation on channels/strips + Int_t Psk; // index of MCstrip + Float_t Psq; // pulseheight on MCstrip + Float_t Ppq; // pedestal value on MCstrip + Float_t Pnq; // noise value on MCstrip + + Float_t PFq; //Charge on a fixed pixel + Float_t PFn; //Noise on a fixed pixel + Float_t PFp; //Pedestal - -- - + Float_t PFr; //Raw value - -- - + Float_t PFrfr1; //Raw value frame 1 - -- - + Float_t PFrfr2; //Raw value frame 2 - -- - + + Float_t Pcom1; // common mode correction on up to 2 regions + Float_t Pcom2; // (e.g. for three readout chips) + Float_t Pcom3; + Float_t Pcom4; + Float_t Pcom5; + Float_t Pcom6; + Float_t PqL1; // charge on MCstrip -1 + Float_t PCDSvar; + + ClassDef(DAuthenticPlane,1) + }; + +//_________________________________________________________ +// + +class DTransparentPlane : public TObject { + + // data from plane in region of track intersection + // convention: variables start with `T' except + // those of DoubleSided `DS' + + public: + DTransparentPlane(){;} + DTransparentPlane(DPlane& aPlane, DTrack& aTrack, DTracker &aTracker); + DTransparentPlane(DPlane& aPlane, DTrack& aTrack, DHit& aHit, Bool_t hitAssociated, DTracker &aTracker); + virtual ~DTransparentPlane() { + Tpk = 0; + Ttk = 0; + Tu = 0.; + Tv = 1.; + Tud = 0.; + Tvd = 0.; + ThN = 0 ; + Tpt = 0.; + TotN= 0; + TotQ= 0.; + } + + + Short_t Tpk; // number of the plane ( Track Plane Number) + Short_t TtN; // number of tracks in this plane + Short_t Ttk; // number of the track normally 1 + Short_t TtHn; // number of hits in the track, JB 2009/09/08 + + Float_t Tu; // track position perpendicular to strip, u-direction + Float_t Tv; // track position along strip, v-direction + + Float_t TvertexU; // LC 2012/12/17. vertex position. + Float_t TvertexV; + Float_t TvertexW; + + + Float_t TDOX ; //Incertitude sur la position de l origine de la trace + Float_t TDOY ; //Incertitude sur la position de l origine de la trace + + Float_t Tud; // (principal)Hu - Tu + Float_t Tvd; // (principal)Hv - Tv + Short_t ThN; // number of hits found in the plane + Short_t Thk; // // authentic hit number in the plane, <0 if hit associated to the track + Int_t TsN; // number of strips + Float_t Tpt; // transparent plane threshold on single strip [ADC] + Short_t TotN; // number of strips in neighbourhood to the track over thresh. + Float_t TotQ; // transparent charge sum on strips + // in neighbourhood of the track over threshold + Float_t Tqc; // Principal hit cluster pulse sum + Float_t Tq0; // Principal hit seed pulseheight + Float_t Tn0; // Principal hit seed noise + + Float_t Tq1; // transparent charge on nearest track, + Float_t Tq2; // transparent charge on 2nd next nearest + Float_t Tq3; // and so on + Float_t Tq4; + Float_t Tq5; + Float_t Tq6; + Float_t Tq7; + Float_t Tq8; + Float_t Tq9; + + Float_t Tu1; // absolute u postion [micron ] of strip next to track + Short_t Tk1; // index of strip next to track + + Float_t Tchi2; // ChiSquare/ndf of the track fit, 2 dim + Float_t Tchi2u; // ChiSquare/ndf of the track fit, U dim + Float_t Tchi2v; // ChiSquare/ndf of the track fit, V dim + + // here one would prefer Tdu, Tdv + Float_t Tx, Ty, Tz; // track coordinates + Float_t Tdx, Tdy; // track directions + Float_t Tdu, Tdv; // the slope in plane coordinates + + + ClassDef(DTransparentPlane,1) + }; + +#endif diff --git a/include/DEventMC.h b/include/DEventMC.h new file mode 100644 index 0000000..41795b7 --- /dev/null +++ b/include/DEventMC.h @@ -0,0 +1,171 @@ +// @(#)maf/dtools:$Name: $:$Id: DEventMC.h,v.2 2016/04/20 17:03:46 sha Exp $ +// Author: Alejandro Perez 2016/04/20 +// Last Modified, AP 2016/04/20 +// + +#ifndef _DEventMC_included_ +#define _DEventMC_included_ + + +////////////////////////////////////////////////////////////////////// +// Class Description of DEventMC // +// // +// Container of the MC truth information when reading a MC n-tuple // +// This info can be used for hit and track truth matching // +// // +////////////////////////////////////////////////////////////////////// + +#include +#include +#include "Riostream.h" + +// ROOT classes +#include "TObject.h" +#include "TClonesArray.h" +#include "TArrayF.h" +#include "TH1.h" +#include "TVector3.h" +#include "DPixel.h" +#include "DHit.h" +#include "DTrack.h" + +class DSetup; +class DTracker; +class DPlane; // used to fill data into event plane +class DTrack; +class DHit; +class DPixel; +class DAcq; + +#define MaxNumberOf 50 + +struct SimParticle_t { + int pdgID; + int BKGType; + TVector3 ProdVtx; + int NHits; + int FirstHitIdx; + int FrameNumber; +}; + +struct SimHit_t { + int ParticleIdx; + int sensorID; + TVector3 PosInXYZmm; + TVector2 PosAveUVmm; + TVector2 PosAveUVLaddermm; + TVector2 PosRecoAveUVmm; + TVector2 PosRecoAveUVLaddermm; + TVector3 MomentumInXYZMeV; + float ThetaLoc; + float PhiLoc; + float Geant4EdepMeV; + float GlobalTime; + float ClusterPhiPrincipalAxis; + float ClusterRMSPrincipalAxis; + float ClusterSizeCol; + float ClusterSizeRow; + int Npixels; + int FistPixelIdx; + int FrameNumber; +}; + +struct SimPixel_t { + int HitIdx; + int GlobalIdx; + int col; + int row; + float ChargeAnalog; + int sensorID; + TVector2 PosUVmm; + int status; + int FrameNumber; +}; + +struct NonSensitiveSimParticle_t { + int SensitiveIdx; + int pdgID; + TVector3 ProdVtx; + int NHits; + int FirstHitIdx; + int FrameNumber; +}; + +struct NonSensitiveSimHit_t { + int ParticleIdx; + float GlobalTime; + TVector3 PosInXYZmm; + TVector3 MomentumInXYZMeV; + float EnergyInMeV; + TVector3 PosOutXYZmm; + TVector3 MomentumOutXYZMeV; + float EnergyOutMeV; + float Geant4EdepMeV; + int FrameNumber; +}; + +//__________________________________________________________________________________ +// +class DEventMC : public TObject { + +private: + + //AP 2016/05/15 : Set of structures with the variables of Sim particles, Hits and pixels, as well as the set of corresponding lists. + + //List of particles, hits and pixels from sim-hits in sensitive volumes + std::vector ListOfSimParticles; + std::vector ListOfSimHits; + std::vector ListOfSimPixels; + + //List of particles and hits from sim-hits in non-sensitive volumes + std::vector ListOfNonSensitiveSimParticles; + std::vector ListOfNonSensitiveSimHits; + +public: + + DEventMC(); + virtual ~DEventMC(); + void Clear(const Option_t * /*option*/ = ""); + + //Set of functions to retrieve the lists of sim particles, hits and pixels. Only to be used when reading MC data + + void ResetLists(void); //Resets all the list + + //Set of functions to fill the particles, hits and pixels lists from sim-hits on sensitive volumes + void PushBackASimParticle(SimParticle_t ASimParticle) {ListOfSimParticles.push_back(ASimParticle);} + void PushBackASimHit(SimHit_t ASimHit) {ListOfSimHits.push_back(ASimHit);} + void PushBackASimPixel(SimPixel_t ASimPixel) {ListOfSimPixels.push_back(ASimPixel);} + + //Set of functions to fill the particles and hits lists from sim-hits on non-sensitive volumes + void PushBackANonSensitiveSimParticle(NonSensitiveSimParticle_t ASimParticle) {ListOfNonSensitiveSimParticles.push_back(ASimParticle);} + void PushBackANonSensitiveSimHit(NonSensitiveSimHit_t ANonSensitiveSimHit) {ListOfNonSensitiveSimHits.push_back(ANonSensitiveSimHit);} + + //Set of functions to get the size of list of particles, hits and pixels from sim-hits on sensitive volumes + int GetNSimParticles() { return int(ListOfSimParticles.size());} + int GetNSimHits() { return int(ListOfSimHits.size());} + int GetNSimPixels() { return int(ListOfSimPixels.size());} + + //Set of functions to get the size of list of particles and hits from sim-hits on non-sensitive volumes + int GetNNonSensitiveSimParticles() { return int(ListOfNonSensitiveSimParticles.size());} + int GetNNonSensitiveSimHits() { return int(ListOfNonSensitiveSimHits.size());} + + //Set of functions to get a given element from list of particles, hits and pixels from sim-hits on sensitive volumes + SimParticle_t GetASimParticle(int ParticleIdx) {return ListOfSimParticles[ParticleIdx];} + SimHit_t GetASimHit(int HitIdx) {return ListOfSimHits[HitIdx];} + SimPixel_t GetASimPixel(int PixelIdx) {return ListOfSimPixels[PixelIdx];} + + //Set of functions to get a given element from list of particles, hits and pixels from sim-hits on non-sensitive volumes + NonSensitiveSimParticle_t GetANonSensitiveSimParticle(int ParticleIdx) {return ListOfNonSensitiveSimParticles[ParticleIdx];} + NonSensitiveSimHit_t GetANonSensitiveSimHit(int HitIdx) {return ListOfNonSensitiveSimHits[HitIdx];} + + void DoHitTruthMatching(DHit* aHit, int &MCHitID, int &NpixelsMCHitID); //Truth matching of a reconstructed hit + + void DoTrackTruthMatching(DTrack* aTrack, int &MCPartID, int &NHitsMCPartID); //Truth matching of a reconstructed track + + + + ClassDef(DEventMC,3) // Describes EventMC + +}; + +#endif diff --git a/include/DGlobalTools.h b/include/DGlobalTools.h new file mode 100644 index 0000000..56c2636 --- /dev/null +++ b/include/DGlobalTools.h @@ -0,0 +1,226 @@ +// @(#)maf/dtools:$Name: $:$Id: GlobalTools.h,v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Dirk Meier 98/03/02 + +#ifndef _DGlobalTools_included_ +#define _DGlobalTools_included_ + + +//////////////////////////////////////////////////////////////// +// // +// Collection of Global Tools // +// // +//////////////////////////////////////////////////////////////// + + +#include +#include +#include "TSystem.h" +#include "TString.h" +#include "DR3.h" +#include "Riostream.h" +#include "TMath.h" + +using namespace std; + +// this important to tell about ClassDef() +#ifndef ROOT_Rtypes +#include "Rtypes.h" +#endif + +#ifndef M_PI +#define M_PI 3.14159265358979323846 +#endif + +////////////////// +// COLORS FOR PRINTF +////////////////// +#define PRINTF_RED printf("\033[31m"); +#define PRINTF_RED_HL printf("\033[31;01m"); +#define PRINTF_GREEN printf("\033[32m"); +#define PRINTF_GREEN_HL printf("\033[32;01m"); +#define PRINTF_BLUE printf("\033[34m"); +#define PRINTF_BLUE_HL printf("\033[34;01m"); +#define PRINTF_YELLOW printf("\033[33m"); +#define PRINTF_YELLOW_HL printf("\033[33;01m"); +#define PRINTF_DEFAULT printf("\033[00m"); + + + +// extern "C" Double_t denlan_(Float_t *x); // JB for Inline compilation +// here add more CERNLIB functions + +class DGlobalTools { + + private: + static DGlobalTools* fgInstance; + + float poly(float aArg ,float* aParameter, int aOrder); + float fParameter[20]; + int fNparameter; + + double fProbabilityTest[460]; // test variables + double fProbabilityPhiZ[460]; // probability integral values + + + float fChi2[40][16]; // array of chi2 values at degree of freedom and probability + float fChi2Probability[16]; // array of probabilities + + double gPI; + double gEULER; + float gSpeedOfLight; + + // QL 2016/05/26 Multiple scattering info + std::map fMass; // in GeV/c2 + std::map fCharge; // in units of electron charge + std::map fX0; // um + + + public: + DGlobalTools(); + virtual ~DGlobalTools(){;} + void Dummy(); + double GetPI() { return gPI; } + double GetEULER() { return gEULER; } + float GetSpeedOfLight() { return gSpeedOfLight; } + float gMyAge(); // does not work + float gPoly(float aArg ,float* aParameter, int aOrder); // does not work + void Swap(Float_t *a, Float_t *b); // swaps *a with *b + void OrderIndexDes(Int_t *aIndex, Float_t *aArg, Int_t aN); // order aIndex that aArg descending + void OrderIndexAsc(Int_t *aIndex, Float_t *aArg, Int_t aN); // order aIndex that aArg ascending + + float Poly(float* pArg, float* pParameter); + void SetOrder(int aOrder) { fNparameter = aOrder+1; } + void SetParameter(float* aParameter, int aNumber); + float *GetParameter() { return fParameter; } + + double ProbabilityIntegral(double aTestVariable); + + float P19(float aArg) { return poly(aArg, fParameter, 19); } + float P18(float aArg) { return poly(aArg, fParameter, 18); } + float P17(float aArg) { return poly(aArg, fParameter, 17); } + float P16(float aArg) { return poly(aArg, fParameter, 16); } + float P15(float aArg) { return poly(aArg, fParameter, 15); } + float P14(float aArg) { return poly(aArg, fParameter, 14); } + float P13(float aArg) { return poly(aArg, fParameter, 13); } + float P12(float aArg) { return poly(aArg, fParameter, 12); } + float P11(float aArg) { return poly(aArg, fParameter, 11); } + float P10(float aArg) { return poly(aArg, fParameter, 10); } + float P9(float aArg) { return poly(aArg, fParameter, 9); } + float P8(float aArg) { return poly(aArg, fParameter, 8); } + float P7(float aArg) { return poly(aArg, fParameter, 7); } + float P6(float aArg) { return poly(aArg, fParameter, 6); } + float P5(float aArg) { return poly(aArg, fParameter, 5); } + float P4(float aArg) { return poly(aArg, fParameter, 4); } + float P3(float aArg) { return poly(aArg, fParameter, 3); } + float P2(float aArg) { return poly(aArg, fParameter, 2); } + float P1(float aArg) { return poly(aArg, fParameter, 1); } + float P0(float aArg) { return poly(aArg, fParameter, 0); } + + void Confidence(int tGoodN, int tTotalN, float tConfidenceLimit, + float& tUpperError, float& tLowerError); + + double Chi2ToProbability(int tDegreeOfFreedom, double tChiSquare); // converts a chi2 at given degree of fredoom into a probabilty + double CLof7LegendrePol( double *x, double *coeff); // JB 2014/04/10 + //double TrackMultiplicity( int nPlanes, double *efficiencyPlane, double *trackMultiplicity); // JB 2014/11/15 + void TrackMultiplicity( Int_t nPlanes, Double_t *efficiencyPlane, Double_t *trackMultiplicity); // JB 2014/11/15 + + void ComputeStripPosition( Int_t mapping, Int_t col, Int_t lin, Double_t &u, Double_t &v, Double_t &w, Int_t stripsNu, Int_t stripsNv, Double_t pitchU, Double_t pitchV, Double_t pitchW); // JB 2015/04/01 + void ComputeStripPosition_UVToColRow( Int_t mapping, Double_t u, Double_t v, double &col, double &lin, Int_t stripsNu, Int_t stripsNv, Double_t pitchU, Double_t pitchV); // JB 2015/04/01 + + char* LocalizeDirName(const char *inputString); // JB 2011/07/07 + void LocalizeDirName( TString *inputString); // JB 2011/07/07 + + double BuildVertex( double *point11, double *point12, double *point21, double *point22, double *vertex); // JB 2011/07/26 + Double_t BuildVertex( DR3 &pointA1, DR3 &pointA2, DR3 &pointB1, DR3 &pointB2, DR3 &intersection); // VR 2014/06/29 + + bool (*VetoPixel)( int chipNb, int row, int col); // JB 2012/03/11 + void SetVetoPixel( int noiseRun); + + //Functions used for multiple scattering, both simulation and track fitting + double scatteringAngle(string particle = "proton", + double momentum = 120.0, + string material = "silicon", + double thickness = 50.0, + bool verbose = true); //AP 2015/03/11 + double Getb(string particle = "proton", + string material = "silicon", + double momentum = 120.0, + double thickness = 50.0); //AP 2015/04/24 + double GetBfromb(double b); //AP 2015/04/24 + double Getf0(double Theta); //AP 2015/04/24 + void Getf1Andf2(double Theta, + double& f1, + double& f2); //AP 2015/04/24 + double GetDistribution(double Theta, + double B); //AP 2015/04/24 + double GetMass(string particle); // QL 2016/05/26 + int GetCharge(string particle); // QL 2016/05/26 + double GetX0(string material); // QL 2016/05/26 + + int RoundOff(double a); + + double fpeaks(double *x, double *par, int npeaks); + double CBfunction(double x, double mean, double sigma, double alpha, double n); + double BifurcatedCBfunction(double x, double mean, double sigmaL, double sigmaR, double alpha, double n); + double DoublePeakCBFitFunction55Fe(double x, + double mean1, + double mean2, + double sigma1, + double sigma2, + double alpha1, + double alpha2, + double n1, + double n2, + double N1, + double N2); + double DoublePeakBifurcatedCBFitFunction55Fe(double x, + double mean1, + double mean2, + double sigmaL1, + double sigmaL2, + double sigmaR1, + double sigmaR2, + double alpha1, + double alpha2, + double n1, + double n2, + double N1, + double N2); + double fpeaksCB55Fe(double *x, double *par); + double fpeaksBifurcatedCB55Fe(double *x, double *par); + + + static DGlobalTools*& Instance() { + if (!fgInstance) fgInstance = new DGlobalTools(); + return fgInstance; + } + + ClassDef(DGlobalTools,1) // Collection of global tools + +}; + +inline double DGlobalTools::GetMass(string particle){ + std::map::iterator it = fMass.find(particle); + if(it != fMass.end()) + return it->second; + else + return -1; +} + +inline int DGlobalTools::GetCharge(string particle){ + std::map::iterator it = fCharge.find(particle); + if(it != fCharge.end()) + return it->second; + else + return 0; +} + +inline double DGlobalTools::GetX0(string material){ + std::map::iterator it = fX0.find(material); + if(it != fX0.end()) + return it->second; + else + return 0.; +} + +#endif diff --git a/include/DHelix.h b/include/DHelix.h new file mode 100644 index 0000000..37487fe --- /dev/null +++ b/include/DHelix.h @@ -0,0 +1,66 @@ +// Author : Daniel Cuesta + +#ifndef _DHelix_included_ +#define _DHelix_included_ + + //////////////////////////////////////////////////////////// + // // + // Class Description of DHit // + // // + //////////////////////////////////////////////////////////// + +#include "Riostream.h" +#include +#include + +// ROOT classes +#include "TObject.h" +#include "TArrayF.h" +#include "TAxis.h" +#include "DPixel.h" +#include "DR3.h" +//#include "DPlane.h" + +// class DTrack; // forward declarations +// class DStrip; +// class DPlane; +// class DCut; +class DR3; +class DHelix : public TObject { +private: + Double_t fTransverseMomentum; + Double_t fPhi0; + Double_t fDrho; + Double_t fDz; + Double_t fTanLambda; + Double_t fPhi; + Double_t fMagneticField; + DR3 fHelixPosition; + DR3 fPivotPosition; +public: + DHelix(); + DHelix(DR3 PivotPosition,double TransverseMomentum,double phi0,double drho,double dz,double TanLambda,double MagneticFiel); + ~DHelix(); + DR3 GetHelixPosition(double phi); + // DR3 GetPivotPosition() {return fPivotPosition;} + Double_t GetTransverseMomentum() {return fTransverseMomentum;} + Double_t GetMagneticField() {return fMagneticField;} + Double_t GetPhi0() {return fPhi0;} + Double_t Getdrho() {return fDrho;} + Double_t Getdz() {return fDz;} + Double_t GetTanLambda() {return fTanLambda;} + Double_t GetPhi() {return fPhi;} + + void SetPivotPosition(DR3 NewPivotPosition) {fPivotPosition=NewPivotPosition;} + void SetAllParameters(double TransverseMomentum,double phi0,double drho,double dz,double TanLambda); + void SetAllParameters(Double_t *par); + void SetTransverseMomentum(double SetValue) {fTransverseMomentum=SetValue;} + void SetMagneticField(double SetValue) {fMagneticField=SetValue;} + void SetPhi0(double SetValue) {fPhi0=SetValue;} + void Setdrho(double SetValue) {fDrho=SetValue;} + void Setdz(double SetValue) {fDz=SetValue;} + void SetTanLambda(double SetValue) {fTanLambda=SetValue;} + void SetPhi(double SetValue) {fPhi=SetValue;} + ClassDef(DHelix,1) +}; +#endif diff --git a/include/DHelixFitter.h b/include/DHelixFitter.h new file mode 100644 index 0000000..46a6272 --- /dev/null +++ b/include/DHelixFitter.h @@ -0,0 +1,103 @@ +#ifndef _DHelixFitter_included_ +#define _DHelixFitter_included_ + +// #include +// #include +#include "TLegend.h" +#include "TObject.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//TAF Include +// #include "DTracker.h" +#include "DTracker.h" +#include "DLadder.h" +#include "DPlane.h" +#include "DAlign.h" +#include "DHit.h" +#include "DHelix.h" +#include "DR3.h" +// #include "DBeaster.h" + +using namespace std; +class DHelix; +class DHelixFitter: public TObject { +private: +static DHelixFitter* fgInstance; +public: + DHelixFitter (DTracker *Tracker); + DLadder *aLadder; + DPlane *aPlane; + DHit *aHit; + DTracker *tTracker; + DEventMC *MCInfoHolder; + DSession *fSession; + DPrecAlign *Dprec; + DHelix *aHelix; + TMatrix Result; + TVector3 ListOfHitsToFitted_1; + int SensorId_1; + TVector3 ListOfHitsToFitted_2; + int SensorId_2; + double SigmaPos_X; + double SigmaPos_Y; + double SigmaPos_Z; + double SigmaPos_U; + double SigmaPos_V; + double SigmaPos_W; + double SigmaPos_1; + double SigmaPos_2; + double SigmaPos_3; + DR3 HelixPosXYZ; + DR3 HelixPosUVW; + double x; + double y; + double z; + double phi; + double xfit; + double yfit; + double zfit; + double alpha; + double dphi; + double eps; + double phi0; + double RootFind; + double chisquare; + + int NbFittedPoints; + TMinuit *ptMinuit; + int iNum; + + virtual ~DHelixFitter (); + virtual TVector3 GetHelixParameter(vector ListOfHits); + virtual TVector3 GetCircleParameters(TVector3 r1, TVector3 r2); + virtual void Helix_ChiSquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); + virtual TMatrixD GetResidual(Double_t *par,int MeasurmentIndex ); + virtual DTracker *GetTracker(){return tTracker;}; + virtual void BuiltCovarianceMatrix(TMatrixD &W,int MeasurmentIndex); + // virtual TMatrixD HelixEquation(Double_t *par,int MeasurmentIndex ); + virtual double GetWprime(double phi,DHelix *aHelix,DPlane *aPlane); + static DHelixFitter*& Instance() { + + return fgInstance; + } + virtual double GetIntersectionHelixPlane(DPlane *aPlane, DHelix *aHelix); +ClassDef(DHelixFitter,1) +}; + +void calc_chi_square_Circle(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); +void FCNHelix_ChiSquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag); +Double_t Circle_Fit(double x,double y,double *par); + +#endif diff --git a/include/DHit.h b/include/DHit.h new file mode 100644 index 0000000..55e9c4f --- /dev/null +++ b/include/DHit.h @@ -0,0 +1,224 @@ +// @(#)maf/dtools:$Name: $:$Id: DHit.h,v.1 2005/10/02 18:03:46 sha Exp $ +// Author : ? + +#ifndef _DHit_included_ +#define _DHit_included_ + + //////////////////////////////////////////////////////////// + // // + // Class Description of DHit // + // // + //////////////////////////////////////////////////////////// + +#include "Riostream.h" +#include +#include + +// ROOT classes +#include "TObject.h" +#include "TArrayF.h" +#include "TAxis.h" +#include "DPixel.h" +//#include "DPlane.h" + +class DTrack; // forward declarations +class DStrip; +class DPlane; +class DCut; +class DR3; + +class DHit : public TObject { + + private: + Int_t fTableSize; // Size of Arrays allocated in constructor // VR 2014.08.28 + Int_t fDebugHit; + Int_t fHitNumber; // hit number + Bool_t fFound; // kTRUE is associated to a track, JB 2009/05/22 + Int_t fPositionAlgorithm; // 1 = Center of Gravity, 2 = eta, 3= kappa, 4 = gamma + DPlane *fPlane; // pointer to the device which got this hit + DR3 *fPositionHit; // position of the hit, depends on fPositionAlgorithm + DR3 *fPositionHitCG; // position of the hit measured with center of gravity method + DR3 *fPositionHitEta; // position of the hit measured with eta correction from 3x3 cluster + DR3 *fPositionHitCG33; // position of the hit measured with center of gravity method over a 3x3 cluster + DR3 *fPositionHitCG22; // position of the hit measured with center of gravity method over a 2x2 cluster + DR3 *fPositionHitEta22; // position of the hit measured with eta correction from 2x2 cluster + DR3 *fResolutionHit; // position resolution of the hit, depends on resolution estimation, AP 24/11/2014 + Float_t fSeedU; // U position of hit seed strip + Float_t fSeedV; // V position of hit seed strip + Float_t fClusterPulseSum; // sum of pulseheight on strips in hit cluster, involves noise cuts + Float_t fClusterAreaPulseSum; // sum of pulseheight on strips in hit cluster area, no noise cuts + Float_t fClusterSignalToNoise; // hit cluster signal to noise ratio + Float_t fClusterNoiseAverage; // hit cluster signal noise average + Int_t fStripsInClusterFound; // number of strips in the hit cluster + Int_t fStripsInClusterArea; // # strips in cluster area + DR3 *fClusterLimit; // maximum extension in u,v,w for hit analysis + Float_t fClusterLimitRadius; // maximum search radius (in mm) from real center of gravity (in mm) to associate new pixels + DStrip *fSeed; // pointer to the hit seed strip + DPixel *fPSeed; // pointer to the hit seed pixel, JB 2009/05/01 + //DMonteCarlo *fPSeedMC; // pointer to the pixel Monte Carlo, LC 2014/12/15. + DCut *fCut; // pointer to cuts + DR3 *fStripPitch; // pointer to strip pitch in plane + Float_t fPhSeed; // pulseheight on seed strip + Float_t fPosSeed; // position of the seed strip + Float_t fPhLofSeed; // pulseheight on strip left from seed + Float_t fPosLofSeed; // position of strip left of seed + Float_t fPhRofSeed; // pulseheight on strip right from seed + Float_t fPosRofSeed; // position of strip right from seed + Int_t fIndexSeed; // index of seed strip + Int_t fIndexLofSeed; // index of strip left from seed + Int_t fIndexRofSeed; // index of strip right from seed + Float_t fPhLeft; // pulseheight on left most strip in two strip cluster + Float_t fPosLeft; // position of left most strip in two strip cluster + Float_t fPhRight; // pulseheight on right most strip in two strip cluster + Float_t fPosRight; // position of strip in right most cluster + Int_t fIndexLeft; // index of left most strip + Int_t fIndexRight; // index of right most strip + Int_t fStoNover2; // MB 2010/11/12 + + Float_t *fStripNoise; //! array of noise from strips in hit cluster YV 27/11/09 + Int_t *tPixelIndexList; //! array of pixel/strip index in the original list of pixels + Int_t *fStripIndexArray; //! array of indices to strips inside the hit + Int_t *fStripIndex; //| array of index of strip in the full plane matrix + Float_t *fStripPulseHeight; //! array of pulseheights from strips in hit cluster + Float_t *fStripDistanceU; //! array of seed distanceU from strips in hit cluster + Float_t *fStripDistanceV; //! array of seed distanceV from strips in hit cluster + Int_t fStripsInClusterDemanded; // exact number of strips required in Hit, set by user + Float_t evaluateChargeFraction(Float_t aChargeFraction); // evaluates the charge fraction on strip + TArrayF *fChargeFractionDensity; // Array of charge fraction densities for hit measurement + + Float_t fSNneighbour; // signal / noise of neighbours + Float_t fSNseed; // signal / noise of seed pixel, JB 2013/11/08 + Float_t fSeedPulseHeight; // pulseheight on seed, JB 2013/11/08 + Float_t fSeedNoise; // noise on seed, JB 2013/11/08 + Bool_t fIsFromPreviousEvent; // explicit // VR 2014.08.28 + Int_t fTimestamp; // timestamp of seed, JB 2015/05/25 + Bool_t fIfMonteCarlo; + std::vector _monteCarloInfo; // Vector of Monte Carlo Informations. Vector to reduce memory if no MC Info + Add new params easily + Int_t fMCHitID; // MC hit ID number. This number gives MC hit ID generating the hit. Default value is -1 + Int_t fStripsFromMCHitID; // This gives the number of strips/pixels from the MC hit with ID = fMCHitID. Default value if 0 + + //Main components analysis variables + Float_t fNormMaxStd; //RMS of pixel position along principal axis + Float_t fNormMinStd; //RMS of pixel position along axis perpendicualer to principal axis + Float_t fMainAxisPhi; //Phi angle of principal axis + + int fColMin; //Pixel with the lowest column value + int fColMax; //Pixel with the highest column value + int fRowMin; //Pixel with the lowest row value + int fRowMax; //Pixel with the highest row value + +public: + DHit(); + DHit(DR3 &aPosition, DPlane& aPlane, Int_t aHitNumber); + DHit(DR3 &aPosition, DPlane& aPlane, Int_t aHitNumber, std::vector& monteCarloVector); + void copy(DHit* aHit, DPlane* aPlane); // LC 2014/07/15 // Not full a copy :: just hit positions :) + void clone(DHit *original, Bool_t fullCopy=1);// VR 2014.08.28, cannot call it Clone otherwise hidden virtual function + //DHit(DR3 &aPosition, Int_t aHitNumber); + virtual ~DHit(); + Bool_t Analyse(DStrip *s); // cluster charge, noise, hit position + Bool_t Analyse_Iterative(DStrip *s, bool &IsBigCluster, int MaxClusterSize); //AP, 07/01/2014, Iterative clustering for digital output + Bool_t Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixels); // cluster charge, noise, hit position + Bool_t Analyse_2_cgo( Int_t aPixelIndexInList, std::vector *aListOfPixels); // make hit with pixels considering maximum search radius (in mm) from real center of gravity (in mm) to associate new pixels + Bool_t Analyse_Iterative( Int_t aPixelIndexInList, std::vector *aListOfPixels, bool &IsBigCluster, int MaxClusterSize); //AP, 07/01/2014, Iterative clustering for digital output + //Bool_t AnalyseMC( std::vector *aListOfPixelsMonteCarlo) //LC, 2014/12/15, Get MC Hit position + Int_t GetNumber() const { return fHitNumber; } + void SetNumber(Int_t aNb) { fHitNumber = aNb;}// VR 2014.08.28 + Bool_t GetFound() const { return fFound; } + void SetFound( Bool_t found=kTRUE) { fFound = found; } // JB 2011/03/14 to allow to free the hit + Int_t GetDebug() { return fDebugHit; } + void SetDebug( Int_t aDebug) { fDebugHit = aDebug; } + DPixel *GetPSeed() { return fPSeed; } // JB 2012/08/17 + DStrip *GetSeed() { return fSeed; } + DStrip *GetMinor(Int_t aSk); // strip with index lower pulseheight in neighourhood to seed + DR3 *GetPosition() const { return fPositionHit;} + DR3 *GetPositionCG() const { return fPositionHitCG;} + Float_t GetPositionUhit() const; + Float_t GetPositionVhit() const; + Float_t GetPositionWhit() const; + Float_t GetPositionUhitCG() const; + Float_t GetPositionVhitCG() const; + Float_t GetPositionWhitCG() const; + Float_t GetPositionUhitEta() const; + Float_t GetPositionVhitEta() const; + Float_t GetPositionUhitCG33() const; + Float_t GetPositionVhitCG33() const; + Float_t GetPositionUhitCG22() const; + Float_t GetPositionVhitCG22() const; + Float_t GetPositionUhitEta22() const; + Float_t GetPositionVhitEta22() const; + Float_t GetResolutionUhit() const; + Float_t GetResolutionVhit() const; + void SetResolutionUVhit(Float_t resolutionU,Float_t resolutionV); + Float_t GetClusterPulseSum() const { return fClusterPulseSum; } + Float_t GetClusterAreaPulseSum() const { return fClusterAreaPulseSum; } + Int_t GetIndex(Int_t tSk) const { return fStripIndex[fStripIndexArray[tSk]]; } // JB 2009/05/12 + Int_t GetIndexInOriginalList(Int_t tSk) const { return tPixelIndexList[tSk]; } //AP 2016/07/28 + Bool_t GetIsFromPreviousEvent() const { return fIsFromPreviousEvent;}// VR 2014.08.28 + void SetIsFromPreviousEvent(Bool_t value=1) {fIsFromPreviousEvent=value;}// VR 2014.08.28 + Float_t GetPulseHeight(Int_t tSk) const { return fStripPulseHeight[fStripIndexArray[tSk]];} // JB 2009/05/12 + Float_t GetNoise(Int_t tSk) const { return fStripNoise[fStripIndexArray[tSk]];} //YV 27/11/09 + Float_t GetClusterSignalToNoise() const { return fClusterSignalToNoise; } + Float_t GetClusterNoiseAverage() const { return fClusterNoiseAverage; } + Int_t GetStripsInCluster() const { return fStripsInClusterFound; } + DPlane *GetPlane() const { return fPlane; } + Float_t GetSeedU() const { return fSeedU; } + Float_t GetSeedV() const { return fSeedV; } + Float_t GetPulseHeightLeft() const { return fPhLeft; } + Float_t GetPulseHeightRight() const { return fPhRight; } + Float_t GetPulseHeightLeftOfSeed() const { return fPhLofSeed; } + Float_t GetPulseHeightRightOfSeed() const { return fPhRofSeed; } + Float_t GetPositionULeft() const { return fPosLeft; } + Int_t GetStoNover2() const { return fStoNover2; } + + Int_t GetIndexLeft() const { return fIndexLeft; } + Int_t GetIndexRight() const { return fIndexRight; } + Int_t GetIndexSeed() const { return fIndexSeed; } + + Float_t GetSNneighbour() const { return fSNneighbour; } + Float_t GetSNseed() const { return fSNseed; } // JB 2013/11/08 + Float_t GetSeedPulseHeight() const { return fSeedPulseHeight; } // JB 2013/11/08 + Float_t GetSeedNoise() const { return fSeedNoise; } // JB 2013/11/08 + + Float_t Distance( DHit *aHit); + Float_t Distance( DTrack *aTrack); // JB 2009/06/26 + Float_t Distance( DR3 *aPoint); // JB 2011/07/25 + + Int_t GetTimestamp() const { return fTimestamp; }; // JB 2015/05/25 + + Bool_t IfMonteCarlo() const { return fIfMonteCarlo; }; // LC 2014/12/15 -> Test if MC Infos are included. + + Float_t DistanceMC( DHit *aHit); // LC 2014/12/15 + Float_t DistanceMC( DTrack *aTrack); // LC 2014/12/15 + Float_t DistanceMC( DR3 *aPoint); // LC 2014/12/15 + + void SetMCHitID(Int_t aHitID) {fMCHitID = aHitID;} //AP 2015/07/30 + Int_t GetMCHitID() {return fMCHitID;} //AP 2015/07/30 + + void SetStripsFromMCHitID(Int_t aStripsFromMCHitID) {fStripsFromMCHitID = aStripsFromMCHitID;} //AP 2016/07/28 + Int_t GetStripsFromMCHitID() {return fStripsFromMCHitID;} //AP 2016/07/28 + + void SetHitPosition(DR3 aPosition,DR3 aResolution); + + DR3 GetMonteCarloPosition(); + std::vector& GetMonteCarloInfo() { return _monteCarloInfo; } // LC 2014/12/15 + + //Main components analysis functions + void DoMCA(void); //AP 2017/05/09 + Float_t GetNormMinStd() { return fNormMinStd; } //AP 2017/05/09 + Float_t GetNormMaxStd() { return fNormMaxStd; } //AP 2017/05/09 + Float_t GetMainAxisPhi() { return fMainAxisPhi; } //AP 2017/05/09 + + void CalcHitLimits(void); //AP 2017/05/11 + int GetColMin() { return fColMin; } //AP 2017/05/11 + int GetColMax() { return fColMax; } //AP 2017/05/11 + int GetRowMin() { return fRowMin; } //AP 2017/05/11 + int GetRowMax() { return fRowMax; } //AP 2017/05/11 + + Bool_t IsSortable() const { return kTRUE; } // QL 04/06/2016 + Int_t Compare( const TObject * obj) const; // QL 04/06/2016 + virtual void Print(const Option_t* ="") const; // QL 05/06/2016 + + ClassDef(DHit,1) // Hit in a Plane +}; + +#endif diff --git a/include/DLadder.h b/include/DLadder.h new file mode 100755 index 0000000..07b4c2c --- /dev/null +++ b/include/DLadder.h @@ -0,0 +1,166 @@ +#ifndef _DLadder_included_ +#define _DLadder_included_ + +#include +#include + +// ROOT classes +#include "TMath.h" +#include "DR3.h" +#include "DSession.h" +#include "TString.h" +#include "DPrecAlign.h" +#include "DPixel.h" +#include "DMiniVector.h" +#include "TH1F.h" +#include "TH2F.h" + +// Last Modified: LC 2014/12/18, Big code cleaning. Now custom ladders by default. +// Last Modified: LC 2014/12/18, Now use only DPrecAlign to recompute ladder+planes parameters. +// Last Modified: Lc 2014/12/19, Saving Mini-vectors in Dladder. With new class MiniVector. + +class DSetup; +class DTrack; +class DTracker; +class DAcq; +class DAcqModule; +class DInp; +class DHit; +class DPrecAlign; +class DAlign; +class DCut; +class DR3; +class DSession; + +class DLadder : public TObject { + + private: + + DSession* fSession; + DAcq* fAcq; // pointer to Data Acquisition + DSetup* fc; // pointer to Configuration + DTracker* fTracker; // pointer to the Tracker + + TString ladderType; + Int_t ladderID; // ID of the ladder + Int_t Status; // Ladder status + Int_t numberOfSensors; // Number of sensors in the ladder + Double_t separatorLengthU; + + std::map planeList; // map of the DPlane in the Ladder. + + //std::map planePosition; + //std::map planeRotation; + + std::map planeRelativePosition; // relative shift wrt ladder + std::map planeRelativeRotation; // relative rotation wrt ladder + std::map planeRelativePrecAlign; // relative alignment wrt ladder + + std::vector _miniVectors; // Vector of mini-vectors. (See class MiniVector). One event. + std::vector _associatedMiniVectors; // List of associated mini-vectors. Sum on all events. + + DR3 fTilt; // Ladder tilts + DR3 fPosition; // Ladder position (center position) + + DPrecAlign* fPrecAlign; // DPrecAlign = position + tilts of the ladder. + + Int_t fDebugLadder; + + Bool_t fIfAssociated; + + TCanvas* fCanvas; + TH1F* fhDU; + TH1F* fhDV; + TH1F* fhDW; + + TH2F* fhDU_U; + TH2F* fhDV_V; + TH2F* fhDU_V; + TH2F* fhDV_U; + TH2F* fhDU_W; + TH2F* fhDV_W; + TH2F* fhDW_U; + TH2F* fhDW_V; + TH2F* fhDW_W; + + + TH1F* fhSlopeX; + TH1F* fhSlopeY; + TH1F* fhDiffSlopeX; + + TProfile* myProfileX; + TProfile* myProfileY; + + TCanvas* fCanvasMC; + TH1F* fResMC_U; + TH1F* fResMC_V; + TH1F* fResMC_W; + + public: + + DLadder(); + DLadder(DTracker& aTracker, TString ladderName, Int_t aLadderID, Int_t aStatus, Double_t sensorLengthX, Double_t sensorSeparator, Double_t distanceFromFoam, Double_t rotationX, Double_t rotationY, Double_t rotationZ); + + ~DLadder(); + + Int_t GetLadderID() { return ladderID; } + +// DR3 GetPlanePosition(Int_t sensorID) { return planePosition[sensorID]; } +// DR3 GetPlaneRotation(Int_t sensorID) { return planeRotation[sensorID]; } + DPlane* GetPlane(Int_t sensorID) { return planeList[sensorID]; } + + Int_t GetNumberOfPlanes() { return planeList.size(); } + Int_t GetFirstPlane() { std::map::iterator iterPlane = planeList.begin(); return iterPlane->first; } + DR3 GetLadderPosition() { return fPosition; } + DR3 GetLadderRotation() { return fTilt; } + + Double_t GetSeparatorTotalLentgh() { return separatorLengthU*(planeList.size()/2-1); } + + Int_t GetStatus() { return Status; } + + void UpdateAlignment(); + + void GetRelativePosition( Int_t aPlaneNumber, DR3* aTilt, DR3* aShift); // JB 2014/02/10 + + void AlignLadder(std::vector& DataTemp, const Int_t ladderNumber, const Int_t planeNumber); + + DR3 PlaneToLadder(DR3& aPlaneCoordinate, Int_t aPlaneNumber); // JB 2014/02/17 + void MakeMiniVectors(); + + DR3 ComputeDirection(DR3& positionLeft, DR3& positionRight); + + void AddPlane(DPlane* aPlane, Int_t planeID); + void SetLadderType(TString aType) { ladderType = aType;}; + + TString GetLadderType() { return ladderType; } + + DTracker* GetTracker() { return fTracker; } + DPrecAlign* GetPrecAlign() { return fPrecAlign; } + DPrecAlign* GetRelativePlaneAlign(Int_t planeIndex) { return planeRelativePrecAlign[planeIndex]; } // planeIndex start from 1 (first plane in the ladder) to N. + + void AddMiniVector(MiniVector* myNewMiniVector); + void RemoveLastMiniVector(); + Int_t GetMiniVectorsSize() { return _miniVectors.size(); } + void ResetMiniVectors(); + void ResetMiniVectorsList(std::vector listOfDelete ); + std::vector& GetMiniVectors() { return _miniVectors; } + + Bool_t IfAssociated() { return fIfAssociated; } + void SetAssociated() { fIfAssociated = 1; } + Int_t GetAssociatedMiniVectorsSize() { return _associatedMiniVectors.size(); } + void AddAssociatedMiniVector(MiniVector* myAssociatedMV); + void ResetAssociatedMiniVectors(); + std::vector& GetAssociatedMiniVectors() { return _associatedMiniVectors; } + + void Display(const Int_t planeNumber); + void PrepareDisplay(); + + //void FillResidus(std::vector& Data, const Int_t planeNumber, DR3& dxdydz); // LC 2014/12/18 useless + void FillResidus(std::vector& Data, const Int_t planeNumber); + void FillResidusMC(std::vector& Res, const Int_t planeNumber); + + ClassDef(DLadder,3) // Detector Ladder + +}; + +#endif diff --git a/include/DLine.h b/include/DLine.h new file mode 100755 index 0000000..cdf1fd7 --- /dev/null +++ b/include/DLine.h @@ -0,0 +1,72 @@ +// @(#)maf/dtools:$Name: $:$Id: DLine.h,v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Dirk Meier 98/01/09 + +#ifndef _DLine_included_ +#define _DLine_included_ + + + + ////////////////////////////////////////////////////////////////////////////////////////////// + // // + // Class Description of DLine // + // // + // a Line object is defined by its // + // origin = (x_0,y_0,z_0), // + // direction = (dx,dy,dz), // + // and length. // + // Points on the line at r_i are given as a function // + // of the parameter beta. beta has no dimension. // + // r_i(beta) = origin_i + beta * direction_i // + // If one wants the pair (x,y) as a function of z along (0,0,dz) then beta = z/dz // + // and r_1(beta) = x_0 + z * dx/dz // + // r_2(beta) = y_0 + z * dy/dz // + // r_3(beta) = z_0 + z * 1 // + // In case one needs pair (x,y,z) as a function of l along (dx,dy,dz) then beta' = l/dl // + // and r_1(beta') = x_0 + l * dx/dl // + // r_2(beta') = y_0 + l * dy/dl // + // r_3(beta') = z_0 + l * dz/dl // + // with the relation beta^2 = beta'^2 * (1-x^2/l^2-y^2/l^2) / (1-dx^2/dl^2-dy^2/dl^2) // + // // + ////////////////////////////////////////////////////////////////////////////////////////////// + + +#include + +// ROOT classes +#include "TObject.h" + + +class DR3; + +class DLine : public TObject { + +private: + DR3 *fOrigin; // origin x0,y0,z0 + DR3 *fDirection; // direction dx,dy,dz in [mm] + DR3 *fSlope; // the slope (dx/dz, dy/dz, 1) this is redundant + Float_t fLength; + + +public: + DLine(); + DLine(DR3 &aOrigin, DR3 &aSlope, Float_t aLength); + ~DLine(); + void Zero(); + Float_t Distance(DR3 &p); + DR3& GetOrigin() const { return *fOrigin; } + DR3& GetDirection() const { return *fDirection; } + DR3& GetSlopeZ() const { return *fSlope; } + Float_t GetLength() const { return fLength; } + DR3 GetPoint(Float_t beta); // get point on line at beta, parameter along the line + DR3 GetIntersectZ(Float_t aZvalue); + + void SetValue(const DR3& aOrigin, + const DR3& aDirection, + const DR3& aSlope, + const Float_t aLength); + + ClassDef(DLine,1) // Describes DLine + +}; + +#endif diff --git a/include/DMiniVector.h b/include/DMiniVector.h new file mode 100755 index 0000000..db1c1a4 --- /dev/null +++ b/include/DMiniVector.h @@ -0,0 +1,109 @@ +// Author : L. Cousin 2014/12/19 +// Save, recompute and project mini-vectors + +#ifndef _MiniVector_included_ +#define _MiniVector_included_ + +// ROOT classes +#include "TObject.h" +#include "TClass.h" +#include "TList.h" +#include "DR3.h" + +#include "DPrecAlign.h" + +class MiniVector : public TObject { + + public: + + MiniVector() {;}; + MiniVector(DPrecAlign* ladderDPrecAlign, DR3& hitLeftPosition, DR3& hitRightPosition, DPrecAlign* alignPlaneLeft, DPrecAlign* alignPlaneRight, DR3& centerPosition, DR3& direction, DR3 planeFrameLeft, DR3 planeFrameRight); // In tracker frame. + + virtual ~MiniVector(){}; + + void SetMonteCarloMiniVector(DR3& hitLeftPositionMC, DR3& hitRightPositionMC, DR3& centerPositionMC, DR3& directionMC, DR3 planeFrameLeftMC, DR3 planeFrameRightMC ); + + void SetLadderDPrecAlign(DPrecAlign* ladderDPrecAlign) { _ladderDPrecAlign = ladderDPrecAlign; }; + void SetHitLeft(DR3& hitLeftPosition); + void SetHitRight(DR3& hitRightPosition); + void SetCenter(DR3& centerPosition); + void SetDirection(DR3& direction); + //void SetDPrecAlign(DPrecAlign* myNewDPrecAlign) { _ladderDPrecAlign = myNewDPrecAlign; }; + + void SetHitLeftMC(DR3& hitLeftPositionMC); + void SetHitRightMC(DR3& hitRightPositionMC); + void SetCenterMC(DR3& centerPositionMC); + void SetDirectionMC(DR3& directionMC); + + void PrintMiniVector(); + + DR3 CalculateMiniVectorIntersectionTracker(DPrecAlign* myDPrecAlign); // Compute intersection with a DPrecALign object. + DR3 CalculateMiniVectorIntersectionLadder(DPrecAlign* myDPrecAlign); // Compute intersection with a DprecAlign in the frame of these DPrecAlign. + + DR3 CalculateMiniVectorIntersectionTrackerMC(DPrecAlign* myDPrecAlign); + DR3 CalculateMiniVectorIntersectionLadderMC(DPrecAlign* myDPrecAlign); + + DR3 GetHitLeftPlanePosition(); + DR3 GetHitRightPlanePosition(); + DR3 GetMiniVectorLadderCenter(); + + DR3 GetHitLeftPlanePositionMC(); + DR3 GetHitRightPlanePositionMC(); + DR3 GetMiniVectorLadderCenterMC(); + + DR3 GetRealLeftPlaneFrame() { return _planeFrameLeft; }; + DR3 GetRealRightPlaneFrame() { return _planeFrameRight; }; + + DR3 GetRealLeftPlaneFrameMC() { return _planeFrameLeftMC; }; + DR3 GetRealRightPlaneFrameMC() { return _planeFrameRightMC; }; + + DR3 GetHitLeftTrackerPosition(); // Re-Compute hitLeft in function of _ladderDprecAlign; + DR3 GetHitRightTrackerPosition(); // Re-Compute hitRight in function of _ladderDprecAlign; + DR3 GetMiniVectorTrackerCenter(); // Re-Compute MV center in function of _ladderDprecAlign; + DR3 GetMiniVectorDirection(); // Re-Compute MV direction in function of _ladderDprecAlign; + DR3 GetMiniVectorOrigin(); + + DR3 GetHitLeftTrackerPositionMC(); // Re-Compute hitLeft in function of _ladderDprecAlign; + DR3 GetHitRightTrackerPositionMC(); // Re-Compute hitRight in function of _ladderDprecAlign; + DR3 GetMiniVectorTrackerCenterMC(); // Re-Compute MV center in function of _ladderDprecAlign; + DR3 GetMiniVectorDirectionMC(); // Re-Compute MV direction in function of _ladderDprecAlign; + DR3 GetMiniVectorOriginMC(); + + DPrecAlign* GetDPrecAlignLeft() { return _planesDPrecAlign.first; }; + DPrecAlign* GetDPrecAlignRight() { return _planesDPrecAlign.second; }; + + Bool_t IfMonteCarlo() { return monteCarloMiniVector; }; + + private: + + Bool_t monteCarloMiniVector; + + std::pair _planesDPrecAlign; + + std::vector _hitLeftPosition; // In the corresponding plane + std::vector _hitRightPosition; // In the corresponding plane + + std::vector _miniVectorCenterPosition; // In ladder frame + std::vector _miniVectorDirection; // In tracker frame + std::vector _miniVectorOrigin; + + DPrecAlign* _ladderDPrecAlign; // ladder DPrecAlign + + DR3 _planeFrameLeft; + DR3 _planeFrameRight; + + DR3 _planeFrameLeftMC; + DR3 _planeFrameRightMC; + + std::vector _hitLeftPositionMC; + std::vector _hitRightPositionMC; + + std::vector _miniVectorCenterPositionMC; // In ladder frame + std::vector _miniVectorDirectionMC; // In tracker frame + std::vector _miniVectorOriginMC; + + ClassDef(MiniVector,1) + +}; + +#endif diff --git a/include/DModule.h b/include/DModule.h new file mode 100644 index 0000000..5660328 --- /dev/null +++ b/include/DModule.h @@ -0,0 +1,74 @@ +#ifndef _DModule_included_ +#define _DModule_included_ + + + //////////////////////////////////////////////////////////////////////////////// + // // + // Class Description of DModule // + // // + // + DModule, may be used in future (>980322) to replace parts of DAcqModule // + // // + //////////////////////////////////////////////////////////////////////////////// + +// ROOT classes +#include "TObject.h" +#include "TArrayF.h" +#include "TArrayC.h" +#include "TString.h" + +class DModule : public TObject { + + private: + Bool_t fIsConnected; // flags initialization status of module + Int_t fValuesN; // number of values in data array + TArrayF *fData; // this is the converted data + + TString fName; // Name of this Module + TString fTitle; // Title of this Module + TArrayC *fLocation; // start of rawvalues in Acquisition buffer + Int_t fCodingValuesN; // number of channels in one input + Int_t fCodingBitsN; // number of Bits decoding value in channel + Int_t fSplitInputsN; // number of splitted inputs (e.g. 4 in Sirocco type A and 2 in B) + Int_t fSplitInput; // a CodingValue is split according to inputs of this module + + Int_t theValue(const Char_t *aLocation, Int_t aWidth); + + + public: + DModule(); + DModule(Int_t aValuesN); + ~DModule(); + void PrintDataToTerm(); + void SetCodeTable(const Char_t *aLocation, + Int_t aCodingValuesN, + Int_t aCodingBitsN, + Int_t aSplitInputsN, + Int_t aSplitInput); + void Update(); + void SetName(Text_t *aName) { fName = aName; } + void SetTitle(Text_t *aTitle) { fTitle = aTitle; } + + TArrayF *GetData() { return fData; } + Int_t GetCodingValuesN() { return fCodingValuesN; } + Int_t GetCodingBitsN() { return fCodingBitsN; } + Int_t GetSplitInput() { return fSplitInput; } + Int_t GetSplitInputsN() { return fSplitInputsN; } + + const char* GetName() const { return (const char*)fName; } + const char* GetTitle() const { return (const char*)fTitle; } + + + ClassDef(DModule,1) // Module like e.g. a Sirocco +}; + +#endif + + + + + + + + + + diff --git a/include/DMonteCarlo.h b/include/DMonteCarlo.h new file mode 100755 index 0000000..18636cc --- /dev/null +++ b/include/DMonteCarlo.h @@ -0,0 +1,58 @@ +#ifndef _DMonteCarlo_included_ +#define _DMonteCarlo_included_ + +#include + +// ROOT classes +#include "TObject.h" +#include "DR3.h" + +class DSetup; +class DPlane; +class TH1F; + +class DMonteCarlo : public TObject { + + public: + + DMonteCarlo(); + //DMonteCarlo( Int_t aNumber, const Int_t aIndex, Double_t aValue); + DMonteCarlo( Int_t aNumber, Double_t aMC_X, Double_t aMC_Y, Double_t aMC_Z, Double_t aValue); + //DPixel( Int_t aNumber, const Int_t aIndex, Double_t aValue, Int_t aLine, Int_t aColumn, DR3 aPosition, DR3 aSize); + ~DMonteCarlo(); + + void SetPlanenumber(Int_t aNumber) { fPlaneNumber = aNumber; } + + void SetMonteCarloX(Int_t aMonteCarloX) { fMonteCarloX = aMonteCarloX; } + void SetMonteCarloY(Int_t aMonteCarloY) { fMonteCarloY = aMonteCarloY; } + void SetMonteCarloZ(Int_t aMonteCarloZ) { fMonteCarloZ = aMonteCarloZ; } + void SetPosition( DR3 aPosition) { fPosition = aPosition; } + + void SetFound(Bool_t b) { fFound = b; } + Bool_t Found() { return fFound; } + + Double_t GetMonteCarloX() { return fMonteCarloX; } + Double_t GetMonteCarloY() { return fMonteCarloY; } + Double_t GetMonteCarloZ() { return fMonteCarloZ; } + Int_t GetPlaneNumber() { return fPlaneNumber; } + + private: + + Int_t fPlaneNumber; + + Double_t fMonteCarloX; + Double_t fMonteCarloY; + Double_t fMonteCarloZ; + + DR3 fPosition; + Double_t fRawValue; + Bool_t fFound; + Int_t fDebugMonteCarlo; + + ClassDef(DMonteCarlo,1) // Pixel or Pixel of a Detector Plane + +}; + +#endif + + diff --git a/include/DParticle.h b/include/DParticle.h new file mode 100755 index 0000000..32cc051 --- /dev/null +++ b/include/DParticle.h @@ -0,0 +1,45 @@ +// @(#)maf/dtools:$Name: $:$Id: DParticle.h,v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Dirk Meier 98/02/19 + +#ifndef _DParticle_included_ +#define _DParticle_included_ + + ///////////////////////////////////////////////////////////// + // // + // Class Description of Particle // + // // + // // + ///////////////////////////////////////////////////////////// + +#include +#include "Riostream.h" + +// ROOT classes +#include "TObject.h" +#include "TClonesArray.h" + +class DHit; +class DLine; +class DR3; +class DPlane; +class DTrack; + +class DParticle : public TObject { + private: + DR3 *fMomentum; // this should become four-momentum vector.... + DR3 *fPosition; + Float_t fCharge; + Float_t fPDGCode; +public: + DParticle(); + virtual ~DParticle(); + void Vacuum(); + DR3& GetMomentum(){ return *fMomentum; } + DR3& GetPosition(){ return *fPosition; } + Float_t GetCharge(){ return fCharge; } + Float_t GetPDGCode(){return fPDGCode; } + ClassDef(DParticle,1) // Describes Particle + +}; + +#endif diff --git a/include/DPixel.h b/include/DPixel.h new file mode 100644 index 0000000..9982e2d --- /dev/null +++ b/include/DPixel.h @@ -0,0 +1,120 @@ +#ifndef _DPixel_included_ +#define _DPixel_included_ + +#include +#include + +// ROOT classes +#include "TObject.h" +#include "DR3.h" + +class DSetup; +class DPlane; +class TH1F; +class DPixel : public TObject { + + public: + DPixel(); + DPixel( Int_t aNumber, const Int_t aIndex, Double_t aValue, Int_t aTime=0); + DPixel( Int_t aNumber, Int_t aLine, Int_t aColumn, Double_t aValue, Int_t aTime=0); // JB 2009/08/17 + //DPixel( Int_t aNumber, const Int_t aIndex, Double_t aValue, Int_t aLine, Int_t aColumn, DR3 aPosition, DR3 aSize); + + ~DPixel(); + + Double_t Distance( DPixel &aPixel); + Double_t Distance( const DR3& aPosition); + Double_t DistanceU( DPixel& aPixel); + Double_t DistanceU( const DR3& aPosition); + Double_t DistanceV( DPixel& aPixel); + Double_t DistanceV( const DR3& aPosition); + + void SetPlanenumber(Int_t aNumber) { fPlaneNumber = aNumber; } + void SetRawValue( Double_t aRV) { fRawValue = aRV; } + void SetPulseHeight( Double_t aPH) { fPulseHeight = aPH; } + void SetPedestal( Double_t aPed) { fPedestal = aPed; } + void SetNoise( Double_t aNoise) { fNoise = aNoise; } + void SetPixelLine( Int_t aLin) { fPixelLine = aLin; } + void SetPixelColumn( Int_t aCol) { fPixelColumn = aCol; } + void SetPosition( DR3 aPosition) { fPosition = aPosition; } + void SetSize( DR3 aSize) { fSize = aSize; } + void SetFound(Bool_t b) { fFound = b; } + + void SetPixelIndex(Int_t px) { fPixelIndex = px; } //RDM060809 + void SetDAQIndex(Int_t px) { fDAQIndex = px; } //JB 2015/03/25 + + Int_t GetDAQIndex() { return fDAQIndex; } // JB 2015/03/25 + Int_t GetPixelIndex() { return fPixelIndex;} + Int_t GetPixelLine() { return fPixelLine;} + Int_t GetPixelColumn() { return fPixelColumn;} + + Double_t GetRawValue() { return fRawValue; } + Double_t GetPulseHeight() { return fPulseHeight; } + Double_t GetNoise() { return fNoise; } + Double_t GetPedestal() { return fPedestal; } + Double_t GetCommonMode() { return fCommonMode; } + Double_t GetPulseHeightToNoise(); + + Int_t GetTimestamp() { return fTimestamp; } + + DR3& GetPosition() { return fPosition; } + DR3& GetSize() { return fSize; } + Bool_t Found() { return fFound; } + + Int_t GetPlaneNumber() { return fPlaneNumber; } + + Bool_t IfMonteCarlo() { return fIfMonteCarlo; } + void SetMonteCarlo( Double_t X, Double_t Y, Double_t Z, Int_t line, Int_t column ); + DR3 GetMonteCarloPosition(); + std::vector& GetMonteCarloInfo() { return _monteCarloInfo; }; + + Int_t GetPixelMCHitIdx() { return fMCHitIdx; } // AP 2016/04/15 + void SetPixelMCHitIdx(Int_t HitIdx) { fMCHitIdx = HitIdx; } // AP 2016/04/15 + + private: + + Int_t fDebugPixel; + Int_t fPlaneNumber; // number of the plane + DR3 fPosition; // position in uvw coordinates in the plane + DR3 fSize; // size in uvw directions + + Int_t fPixelIndex; // index of the pixel + Int_t fDAQIndex; // DAQ index of the pixel, JB 2015/03/25 + Int_t fPixelLine; // line in the matrix + Int_t fPixelColumn; // column in the matrix + Double_t fRawValue; // the rawvalue + Double_t fPulseHeight; // pulseheight on strip + Double_t fNoise; // noise on strip + Double_t fCommonMode; // the common mode value + Double_t fPedestal; // pedestal of strip + Int_t fTimestamp; // timestamp associated, 2013/06/22 + + Bool_t fFound; // flag, that strip is found in hit + + Bool_t fIfMonteCarlo; // if MC informations = 1 else = 0 + std::vector _monteCarloInfo; // MonteCarlo information. In a vector to limit the memory comsuption if MC not enable. + /* // Other parameters can be easily added. + _monteCarloInfo : Container values : + _monteCarloInfo[0] = fMonteCarloPositionX; + _monteCarloInfo[1] = fMonteCarloPositionY; + _monteCarloInfo[2] = fMonteCarloPositionZ; + _monteCarloInfo[3] = fMonteCarloPixelRow; + _monteCarloInfo[4] = fMonteCarloPixelColumn; + */ + + Int_t fMCHitIdx; //Index on the HitBlock of the hit turning on this pixel + + ClassDef(DPixel,1) // Pixel or Pixel of a Detector Plane + +}; + +#endif + + + + + + + + + + diff --git a/include/DPlane.h b/include/DPlane.h new file mode 100644 index 0000000..3baec60 --- /dev/null +++ b/include/DPlane.h @@ -0,0 +1,397 @@ +// @(#)maf/dtools:$Name: $:$Id: DPlane.h,v.3 2005/10/02 18:03:46 sha Exp $ +// Author : ? + +#ifndef _DPlane_included_ +#define _DPlane_included_ + + + ///////////////////////////////////////////////////////////// + // Class Description of DPlane // + // // + // + finds pedestal // + // + calculates pulseheight // + // + corrects for common mode (shift) // + // + calculates single noise // + // // + ///////////////////////////////////////////////////////////// + +#include +#include + +// ROOT classes +#include "TObject.h" +#include "TString.h" +#include "TBRIK.h" +#include "TNode.h" +#include "TRandom.h" +#include "TH1.h" +#include "TH2.h" +#include "TObjArray.h" +#include "TMath.h" + +#include "DSession.h" +#include "DPixel.h" +//#include "DMonteCarlo.h" +#include "DEventMC.h" + +class DSetup; +class DStrip; +class DTrack; +class DTracker; +class DAcq; +class DAcqModule; +class DInp; +class DHit; +//class DHitMonteCarlo; +class DPrecAlign; +class DAlign; +class DCut; +class DR3; +class DSession; +class DEventMC; +// class DCMOSReader +class DPlane : public TObject { + + private: + + Int_t fDebugPlane; // plane debug flag + DSession *fSession; // JB 2011/07/21 to get rid of global var + DGlobalTools fTool; // JB 2014/04/21 + Long_t *fChannel; //! pointer to Channels + Long_t *fStripIndices; //! pointer to strip indices + Bool_t fKillNoise; // flag in case of noise suppression (call to KillNoise) + + Float_t *fCommonShift; //! Common Signal shift in plane regions + Long_t *fCommonChannels; //! Number of Channels in these plane regions + Long_t *fChannelGood; //! list of good channels ( 1= good, 0 = bad) + DStrip **fStripList; //! list of pointers to strips + std::vector *fListOfPixels; // pointer to list of hit pixel + //vector *fListOfPixels; // pointer to list of hit pixels + //vector *fListOfMonteCarlo; + Int_t fPixelsN; // number of hit pixels + Int_t fStripsNu; // number of strips in u direction + Int_t fStripsNv; // number of strips in v direction + Int_t fStripsN; // sum of strips in u,v and w + Int_t fRegions; // number of regions for common mode correction (e.g. 2 if 2 readout chips) + Int_t fPlaneNumber; // the number given to the plane e.g. this Sirocco + Int_t fLadderNumber; // LC 2013/01/14. number of the ladder. + Char_t *fPlaneName; //! name of this device + Char_t *fPlanePurpose; // purpose e.g. reference or test or whatever + Float_t fPulseRangeMaximum; // maximum pulseheight expected on a strip in this plane + Int_t fAcqInputsN; // Number of inputs the plane is connected to + Int_t fAcqModuleTypeNumber; // this plane is connected to an input in fDacToolNumber + Int_t fAcqModuleNumber; // number of the Acquisition Module + Int_t fAcqInputNumber; // input number this plane is connected to in the Acquisition Module + Int_t fAcqChannelNumber; // first strip nb associated to the first channel number for this input (start at 1) + Int_t fAcqChannelOffset; // the number of the first channel related to the plane for this input (start at 1) + Int_t fAcqModuleChannels; // number of channels per input of the module type + Int_t fChannelsN; // number of channels in this plane + + DHit **fHit; //! list of pointers to hits + DHit **fHitUnTrackedLastEvent; //Explicit // VR 2014.08.28 + //DHit **fHitMonteCarlo; // list of pointer to Monte Carlo Hits. LC 2014/01/08 + Int_t fHitsN; // number of hits found in plane (total) + Int_t fHitsUnTrackedLastEventN; // number of hits not associated to a track in last event // VR 2014.08.28 + Int_t fHitsNew; // number of new hits for this event // VR 2014.08.28 + Int_t fHitsOld; // number of untracked hits from previous event added to the list // VR 2014.08.28 + + Int_t fHitMax; // maximum number of hits allowed in plane + Float_t fCDSvariance; // variance of signal distributon in the plane after CDS + Float_t fThreshold; // a threshold for measuring occupancy + Long_t fOverThresholdN; // the number of channels which exceed threshold + Float_t fOverThresholdC; // the pulseheight sum on strips over threshold + Int_t fKeepUnTrackedHitsBetw2evts; //explicit // VR 2014.08.28 + + DCut *fCut; + TBRIK *fGeometry; + TNode *fPlaneNode; + Char_t *fPlaneNodeName; //! + Int_t fStatus; // 1=Primary, 2=Secondary Reference, or 3=Test Plane + Int_t fAnalysisMode; // 0, 1=Strips, 2=Pixels + Int_t fReadout; // 1=normal (look Update() method) + Int_t fTimeLimit; // JB 2015/05/26 + Bool_t fUseTimestamp; // JB 2015/05/26 + Int_t fMimosaType; // RDM210509 + Int_t fMapping; // JB 2012/11/21 + Int_t fHitFinder; // type of hit finder, JB 2013/07/17 + Int_t fIfDigitize; // control digitization emulation, JB 2013/07/17 + //Bool_t fIfHitMonteCarlo; // Read hit Monte Carlo LC 2014/12/15. + Int_t *fDigitizeThresholds; // thresholds for digitization emulation, JB 2013/07/17 + DR3 *fPitch; // pitch of strips in u,v,w direction + Double_t fTiltW; // the tilt in W + Float_t fPositionU; // the distance between 0 plane and z, perpendicular to strips + Float_t fPositionV; // the distance between 0 plane and z, perpendicular to strips + DR3 *fPosition; // Position of the center in the tracker coordinate system + Int_t fIfDeformation; // Flag to model or not deformation, JB 2014/04/10 + Double_t fUDeformationCoef[8]; // Coeff. for U-deformation model, JB 2014/04/10 + Double_t fVDeformationCoef[8]; // Coeff. for V-deformation model, JB 2014/04/10 + + TH1F *fChargeFractionDensity; // Charge Fraction density distribution, not used (JB 2007) + TObjArray *fChargeFractionDensityList; // list of charge fraction densities + TObjArray *fChargeFractionDistributionList; // list of charge fraction distrubutions + Bool_t fDigitalStripResponse; // kTRUE = forces digital strip response, hitposition = seed + TH1F *fEtaIntU; // Histo for Eta algorithm in 2D, JB Sept 2007 + TH1F *fEtaIntV; // Histo for Eta algorithm in 2D, JB Sept 2007 + TH1F *fEtaIntU2; // Histo for Eta algorithm 2x2 in 2D, JB Novemb 2007 + TH1F *fEtaIntV2; // Histo for Eta algorithm 2x2 in 2D, JB Novemb 2007 + + // YV 21/10/09 + TH2F *fHNoise; // Histo for noise computation + TH2F *fHPedestal; // Histo for pedestal computation + Int_t fNoiseRun; // Id of noise run + TFile *fNoiseFile; // File containing histos with peds and noises + + // JB 2018/07/01 + TH2F *fHPixelGain; // 2d-histo map of pixel gains + Int_t fPixelGainRun; // Id of pixel gain file + TFile *fGainFile; // File containing histos with gains + + + DR3 *fSize; // rectangular extensions + DR3 *fTilt; // tilting angles [radian], three Euler angles, comes later + DAcq *fAcq; // pointer to Data Acquisition + DSetup *fc; // pointer to Configuration + DTracker *fTracker; // pointer to the Tracker + + Int_t *fRawData; //! pointer to Raw Data in Data Acquisition + Float_t *aCacheRawData; //! pointer to temporary copy of Raw Data + DAlign *fAlign; // plane alignement + DPrecAlign *fPrecAlign; // store plane precision alignement + DAcqModule *fAcqModule; // pointer to Acquisition Module (e.g. Sirocco) + DInp *fInput; // pointer to the Input in the Acquisition + // where this plane is plugged in + void analyze_basics(); // do basic calculation on raw data: + void CalculateCommonMode(); // calculates common mode in regions of the plane + void SetPedandNoiseFromHisto( Int_t col, Int_t row, DPixel *aPixel); // set the pixel ped and noise + void SetPixelGainFromHisto( Int_t col, Int_t row, DPixel *aPixel); // set the gain of each pixel + + Int_t fInitialStatus; // 0 before init, 1 after + Int_t fInitialCounter; // counter for intialization of pedestal + Int_t fInitialPedestal; // number of events for intialization of pedestal + Int_t fInitialNoise; // number of events for intialization of noise + + TRandom* rand; + + Float_t aHitSupressedMean(Float_t* data, const Int_t entries); + + Float_t aHitSupressedValue(Float_t* data, const Int_t entries); + Int_t extremumIndex(const Float_t* data, const Int_t N); + Float_t median(Float_t* data, const Int_t N); + Float_t mean(Float_t* data, const Int_t N); + Float_t minimum(const Float_t* data, const Int_t N); + + + Float_t runningMean(const Float_t om, // former mean + const Float_t o, // former value + const Float_t n, // new value + const Int_t N); // number of values + + Float_t runningVariance(const Float_t ov, // former variance + const Float_t o, // former value + const Float_t n, // new value + const Int_t N); // number of values + + void find_hits(); // finds hits in plane + //void find_hits_monte_carlo(); // finds hit montecarlo in this plane. + void UpdatePedestalAndNoise(); + Bool_t CheckSaturation(); // Checks if the event is saturated (both frames are at maximum -> CDS==0) + void FindNeighbours(); // finds neighbour pixels/strips for cluster building + + TRandom fRandomGenerator; // random generator (seed is set at initialization) + + Double_t resolutionU; + Double_t resolutionV; + + Double_t sigma_thetaMS; //RMS of scattering angle calculated from the PlaneMaterial and PlaneThickness variables + Double_t fPlaneThickness; + TString fPlaneMaterial; + + DEventMC* MCInfoHolder; // AP 2016/07/27 Object with all the MC information. i.e. the full list of particles, hits and pixels (both from physics and noise) + + public: + DPlane(); + DPlane(DTracker& aTracker, const Int_t aPlaneNumber, const Int_t aLadderNumber); + ~DPlane(); + + //FILE * GetFilePointer(); + + Bool_t Update(); + Bool_t Align(DTrack *aTrack, Bool_t ifFit=kTRUE, bool UseAllHits = false); // aligns this plane to the track + // AP 2015/06/10, added bool parameter (UseAllHits) to decide if doing algnment with all hits or the cloesest one. + Bool_t AlignAllHits(DTrack *aTrack, Bool_t ifFit=kTRUE); // aligns this plane to the track + + // LC + void AlignPrec(DTrack *aTrack, + const Float_t tiniBound, + bool UseAllHits); // LC 2012/09/06 : Fill data to align with Minuit method. + // AP 2015/06/08 : added bool parameter (UseAllHits) to decide if doing alignment with all hits or the closest one + void AlignData(DTrack *aTrack, const Double_t tiniBound, std::vector& myData); + void UpdatePositions(); // LC 2013/09/05 + + void AlignPrecUpdateConfig(); // LC 2012/09/06 : Update config file after Minuit. + + void ShowAlignment(); + DStrip *NearestStrip(DR3& aPosition); + DSetup& GetSetup() { return *fc; } +/* DAcqModule& GetAcqModule() { return *fAcqModule; } */ +/* DInp& GetInput() { return *fInput; } */ + Int_t GetMaxHits() const { return fHitMax; } + + Long_t GetChannelsN() { return fChannelsN; } + Int_t GetStripsN() { return fStripsN; } + Int_t GetStripsNu() { return fStripsNu; } + Int_t GetStripsNv() { return fStripsNv; } + void ComputeStripPosition( Int_t col, Int_t lin, Double_t &u, Double_t &v, Double_t &w); // JB 2012/11/21 + void ComputeStripPosition_UVToColRow( Double_t u, Double_t v, double &col, double &lin); // AP 2012/06/26 + + Long_t *GetStripIndices() { return fStripIndices; } + Long_t *GetChannelIndices() { return fChannel; } + Int_t *GetRawData() { return fRawData; } + std::vector *GetListOfPixels() { return fListOfPixels; } + DPixel* GetPixelFromList(Int_t aSk); + //vector *GetListOfMonteCarlo() { return fListOfMonteCarlo; } // LC 2014/12/15 : MonteCarlo informations included in DPixel + Long_t& GetChannel(Int_t aSk) { return fChannel[aSk-1]; } + Float_t GetCommonMode(Int_t aSk); + Float_t GetRawValue(Int_t aSk); + Float_t GetRawFrame1Value(Int_t aSk); + Float_t GetRawFrame2Value(Int_t aSk); + Float_t GetPedestal(Int_t aSk); + Float_t GetPulseHeight(Int_t aSk); + Float_t GetNoise(Int_t aSk); + Float_t GetPulseHeightToNoise(Int_t aSk); + Float_t GetPulseRangeMaximum(); + Int_t GetInitialNoise() const { return fInitialNoise; } //JB, Sept 2007 + Int_t GetCommonRegions() const { return fRegions; } + Int_t GetAcqInputNumber() const { return fAcqInputNumber;};// VR 2014/07/21 + + Int_t Digitize( Float_t aValue ); // JB 2013/08/29 + void DigitizeMatrix(); // JB 2013/08/29 + Int_t GetDigitalThresholdNb() { return fIfDigitize; } + Int_t *GetDigitialThresholds() { return fDigitizeThresholds; } + + DAlign *GetAlignment() { return fAlign; } + DPrecAlign *GetPrecAlignment() { return fPrecAlign; } // JB 2010/11/25 + DStrip *GetStrip(Int_t aStripNumber); + DR3& GetStripPitch() const { return *fPitch; } + + Int_t GetHitsN() const { return fHitsN; }// VR 2014.08.28 + Int_t GetHitsNewN() const { return fHitsNew; }// VR 2014.08.28 + Int_t GetHitsOldN() const { return fHitsOld; }// VR 2014.08.28 + Int_t GetHitsUnTrackedLastEventN() const { return fHitsUnTrackedLastEventN;}// VR 2014.08.28 + void SetHitsN (Int_t aNb) {fHitsN = aNb;}// VR 2014.08.28 + void SetHitsNewN (Int_t aNb) {fHitsNew = aNb;}// VR 2014.08.28 + void SetHitsOldN (Int_t aNb) {fHitsOld = aNb;}// VR 2014.08.28 + void SetHitsUnTrackedLastEventN(Int_t aNb) {fHitsUnTrackedLastEventN= aNb;}// VR 2014.08.28 + + DHit *GetPrincipalHit(); + + DHit *GetHit(Int_t aHk) const { return fHit[aHk-1]; } + DHit *GetHitUnTrackedLastEvent(Int_t aHk) const { return fHitUnTrackedLastEvent[aHk-1]; }// VR 2014.08.28 + //DHit *GetHitMonteCarlo(Int_t aHk) const {return fHitMonteCarlo[aHk-1]; } // LC 2014/12/15 + Char_t *GetPlaneName() const { return fPlaneName; } + Char_t *GetPlanePurpose() const { return fPlanePurpose;} + Int_t GetPlaneNumber() const { return fPlaneNumber; } + Int_t GetLadderNumber() const { return fLadderNumber;} + DCut *GetCut() const { return fCut; } + Int_t GetHitFinder() const { return fHitFinder;}//VR 2014/07/16 + + Float_t GetPositionU() const { return fPositionU; } + Float_t GetPositionV() const { return fPositionV; } + Float_t GetPositionZ() const { return (*fPosition)(2); } + Float_t GetTiltW() const { return fTiltW; } // changed from Z to W, JB 2010/11/25 + + Double_t GetPlaneThickness() const {return fPlaneThickness;}//QL 2016/06/07 + TString GetPlaneMaterial() const {return fPlaneMaterial;} + + void SetPositionU(Float_t posU); + void SetPositionV(Float_t posV); + void SetPositionZ(Float_t posZ); + void SetTiltW(Float_t tiltW); + + void ChangePositionByOffset(DR3& offset);//VR 2014/06/29 + void ChangePositionByValue(DR3& newvalue);//VR 2014/06/29 + void ChangeTiltByOffset(DR3& offset);//VR 2014/06/29 + void ChangeTiltByValue(DR3& newvalue);//VR 2014/06/29 + + void PrintPosition(void); + void PrintTilt(void); + + + DR3& GetPosition() const { return *fPosition; } + DR3& GetSize() const { return *fSize; } + DR3& GetTilt() const { return *fTilt; } + Int_t GetStatus() const { return fStatus; } + Int_t GetAnalysisMode() const { return fAnalysisMode;} + Int_t GetReadout() const { return fReadout;} + Int_t GetTimeLimit() const { return fTimeLimit;} // JB 2015/05/26 + Bool_t GetUseTimeStamp() const { return fUseTimestamp;} // JB 2015/05/26 + void SetUseTimeStamp( Bool_t aUsage) { fUseTimestamp = aUsage;} // JB 2015/05/26 + Int_t GetMimoType() const { return fMimosaType;}//RDM210509 + void SetStatus(Int_t aStatusValue){ fStatus = aStatusValue; } + DR3 TrackerToPlane(DR3& aTrackerCoordinate); // JB 2010/11/25 + DR3 PlaneToTracker(DR3& aPlaneCoordinate); // JB 2010/11/25 + DR3 Intersection(DTrack *aTrack); + DR3 DeformedLocalPoint(DR3& aPlaneCoordinate); + + Double_t GetResolutionU() const { return resolutionU; } // BEWARE, just the structure : don't return the resolution ! + Double_t GetResolutionV() const { return resolutionV; } // BEWARE, just the structure : don't return the resolution ! + + void SetSigmaThetaMS(double TheSigmaThetaMS) {sigma_thetaMS = TheSigmaThetaMS;} //Function to set the RMS value of the RMS of the multiple scattering angle + Double_t GetSigmaThetaMS() const { return sigma_thetaMS;} //Function to get the RMS value of the RMS of the multiple scattering angle + + // the five following methods are useless since we use DPrecAlign from 2010/11/25 + //DR3 Rotate_TrackerToPlane(DR3& aTrackerCoordinate); + //DR3 Rotate_PlaneToTracker(DR3& aPlaneCoordinate); + //void SetPositionU(Float_t aU); + //void SetPositionV(Float_t aV); + //void SetTiltZ(Float_t aTilt); // sets Z tilt [rad] + void SetCDSvariance(Float_t aVar); + Float_t GetCDSvariance() { return fCDSvariance; } + Float_t GetThreshold() { return fThreshold; } + Int_t GetOverThresholdN() { return fOverThresholdN; } + Float_t GetOverThresholdC() { return fOverThresholdC; } + DTracker *GetTracker() { return fTracker; } + + Float_t GetCommonModeRegion(Int_t aRegion) const; + + TH1F *GetChargeFractionUniv() {return fChargeFractionDensity; } + TH1F *GetEtaIntU() {return fEtaIntU; } + TH1F *GetEtaIntV() {return fEtaIntV; } + TH1F *GetEtaIntU2(){return fEtaIntU2; } + TH1F *GetEtaIntV2(){return fEtaIntV2; } + + TH1F *GetChargeFractionDensity(Int_t tSk); + TH1F *GetChargeFractionDistribution(Int_t tSk); + Bool_t GetStripResponseSetting() { return fDigitalStripResponse; } + + Double_t *GetCoeffLegendreU() {return fUDeformationCoef; } // BB 19/06/2014 + Double_t *GetCoeffLegendreV() {return fVDeformationCoef; } // BB 19/06/2014 + + //YV21/10/09 + TH2F *GetHNoise() { return fHNoise; } + TH2F *GetHPedestal() { return fHPedestal; } + Int_t GetNoiseRun() {return fNoiseRun; } + TFile *GetNoiseFile() {return fNoiseFile; } + + void SetDebug(Int_t aDebug); + Int_t GetDebug() { return fDebugPlane;} + + void AddMCGeneratedHit(DR3 aPosition = DR3(-999.0,-999.0,-999.0), + DR3 aResolution = DR3(-999.0,-999.0,-999.0), + Int_t partID = -1); + + int GetRegion(int col, int lin); //AP 2016/07/27: Function returns the regions index for position col,lin + int GenerateMCMultiplicity(int col, int lin); //AP 2016/07/27: Function to generate a MC multiplicity based in measurements + void GetHitResolution(int col, int lin, int ClusterMult, TVector2 &HitResolution); //AP 2016/07/27: Function to find the hit resolution depending on it position in plane + + void MCHitsTruthMatching(void); //AP 2016/07/27: Function to perform the truth matching of the reconstructed hits + void CheckNonDigitizedMCHits(void); //AP 2016/07/27: In case there are non digitized hits in this plane, this function generate a hit by smearing with the plane sigma_sp + + Bool_t IsSortable() const { return kTRUE; } // QL 04/06/2016 + Int_t Compare( const TObject * obj) const; // QL 04/06/2016 + virtual void Print(const Option_t* ="") const; // QL 05/06/2016 + ClassDef(DPlane,3) // Detector Plane + +}; + +#endif diff --git a/include/DPrecAlign.h b/include/DPrecAlign.h new file mode 100644 index 0000000..1756aa1 --- /dev/null +++ b/include/DPrecAlign.h @@ -0,0 +1,176 @@ +// @(#)maf/dtools:$Name: $:$Id: DPrecAlign.h,v.1 2005/10/02 18:03:46 sha Exp $ +// Author : G.Orazi 1/2/2000 +// LastModified: LC, 2014/12/20 : Now mini-vectors saved in DLadder with MiniVector Objects. +// LastModified: LC, New DPrecAlign Mecanism with good matrices definitions. (Before it was the transpose matrices) +// LastModified: AP, 2015/03/09: Adding spatial resolution to DataPoints class + +#ifndef _DPrecAlign_included_ +#define _DPrecAlign_included_ + +// ROOT classes +#include "TObject.h" +#include "TClass.h" +#include "TList.h" +#include "TBuffer.h" +#include "DR3.h" +#include "DGlobalTools.h" +#include "DTrack.h" + +class DataPoints : public TObject { + public: + DataPoints() {;} + DataPoints(Double_t auh,Double_t avh, + Double_t aresU,Double_t aresV, + Double_t atx,Double_t aty,Double_t atz,Double_t atdx, Double_t atdy); + virtual ~DataPoints(); + void Set(Double_t auh,Double_t avh, + Double_t aresU,Double_t aresV, + Double_t atx,Double_t aty,Double_t atz,Double_t atdx, Double_t atdy); + void PrintData(); + + DR3 GetHitPosition(); + DR3 GetHitResolution(); + DR3 GetTrackOrigin(); + DR3 GetTrackDirection(); + + private: + + Double_t _uh; // point in local system (hit position) + Double_t _vh; + + //AP, 2015/03/09. Adding spatial resolution to DataPoint + Double_t _resU; // spatial point resolution + Double_t _resV; + + Double_t _tx; // - + Double_t _ty; // | Track origin + Double_t _tz; // - + Double_t _tdx; // \ Track Direction + Double_t _tdy; // / + + ClassDef(DataPoints,1) +}; + +//______________________________________________________________________________ +// + +class DPrecAlign : public TObject { + private: + Int_t fDebugDPrecAlign; // DPrecAlign debug flag + Double_t _alpha[3][3] ; // rotation around z + Double_t _beta[3][3] ; // rotation around y' + Double_t _gamma[3][3] ; // rotation around x" + Double_t _rotmat[3][3] ;// gamma*beta*alpha + Double_t _ahpla[3][3] ; // inverse rotation around z + Double_t _ateb[3][3] ; // inverse rotation around y' + Double_t _ammag[3][3] ; // inverse rotation around x" + Double_t _tormat[3][3] ;// inverse rotation matrix + Double_t _Acoeff; // + Double_t _Bcoeff; // Parameters of the rotated plane + Double_t _Ccoeff; // (name changed, JB 2011/10/27) + Double_t _fTh[3] ; // Rotations 0=z 1=y 2=x R(tracker->Plan)=Rz.Ry.Rx + Double_t _fTr[3] ; // Translations + Int_t _fIfDeformation; // Flag to model or not deformation, JB 2015/10/31 + Double_t _fUDeformationCoef[8]; // Coeff. for U-deformation model, JB 2015/10/31 + Double_t _fVDeformationCoef[8]; // Coeff. for V-deformation model, JB 2015/10/31 + + + TList _data; // List of the points: u,v and x,y,z,dx/dz,dy/dz + TList _data1; + + Double_t _xh; // + Double_t _yh; // track point in xyz system at plane + Double_t _zh; // + Double_t _xtd; // + Double_t _ytd; // track slope in xyz system at plane, JB 2015/10/31 + Double_t _ztd; // + Double_t _initialRotations[3]; + Double_t _initialPosition[3]; + + DGlobalTools fTool; // JB 2015/10/31 + + Int_t DPrecAlignMethod; + +public: + DPrecAlign(); + DPrecAlign(Int_t method); + DPrecAlign(const DPrecAlign &aobj); + virtual ~DPrecAlign(); + + void NewData(Double_t auh,Double_t avh, + Double_t aresU,Double_t aresV, + Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy); + void NewData(DataPoints* myDataPoint); + void NewData1(DataPoints* myDataPoint); + void RemoveData(DataPoints* myDataPoint); // LC 2013/10/02 + void RemoveData1(DataPoints* myDataPoint); // LC 2013/10/02 + + void ListDataPoints(); + Int_t DataSize(); // LC 2012/09/06. + Int_t DataSize1(); // LC 2013/09/10 + + void ResetDataPoints() {_data.Delete();} // SS, 2012/09/05 + void ResetDataPoints1() {_data1.Delete();} + + void CopyAlignment( DPrecAlign *anAlign); // JB 2014/02/17 + void SetRotations(Double_t th0,Double_t th1,Double_t th2 ) ; + void SetRotations(DR3 tilt ) ; // JB 2010/11/25 + void ComputeRotationMatrix() ; + void ComputeTorationMatrix() ; // JB 2010/01/03 + void SetTranslation(Double_t t0,Double_t t1,Double_t t2 ) ; + void SetTranslation(DR3 tr ) ; // JB 2010/11/25 + void CalculatePlane(); + void CalculateIntersection(DataPoints* aDataPoint); + void SetDeformation( Double_t *coeffU, Double_t *coeffV=NULL); // JB 2015/10/31 + + void PrintAll(); + void PrintRotationMatrix(); + void PrintTorMatrix(); + void PrintTranslations(); + void PrintRotTimeInv(); + void PrintDeformations(); + DR3 RotateToPlane(DR3 xxx) ; + DR3 RotateToTracker( Double_t u, Double_t v, Double_t w) ; + DR3 RotateToTracker(DR3 uuu) ; + DR3 TransformHitToTracker(DR3 uuu); // JB 2010/01/03 + DR3 TransformHitToPlane(DR3 xxx); // JB 2010/11/25 + DR3 TransformTrackToPlane(); + DR3 TransformTrackToPlane( Double_t tx, Double_t ty, Double_t tz, Double_t tdx, Double_t tdy); + void SetTrackPosition( DR3 xxx); // JB 2010/11/25 + DR3 GetTrackPosition(); + DR3 GetTrackSlope(); + void ConvoluteRotation( Double_t tiltW); // JB 2010/11/25 + void ConvoluteRotation( DR3 aTilt); // JB 2014/02/16 + void ConvoluteUVWAlignment( Double_t u, Double_t v, Double_t tiltW); // JB 2010/11/25 + void ConvoluteAlignment( DPrecAlign *refAlignment); // JB 2010/11/25 + void DecomposeRotations(); // JB 2011/04/04 + void DeconvoluteAlignment( DPrecAlign *refAlignment); // JB 2014/11/24 + DR3 DeformedLocalPoint(DR3& aPlaneCoordinate); // JB 2015/10/31 + + DR3 GetCoeffs() { return DR3(_Acoeff, _Bcoeff, _Ccoeff); } // LC 2014/12/20 + Double_t* GetRotations() {return _fTh ;} + Double_t* GetTranslation() {return _fTr ;} + DR3 GetRotationsDR3() { return DR3(_fTh[0],_fTh[1],_fTh[2]); } + DR3 GetTranslationsDR3() {return DR3(_fTr[0], _fTr[1], _fTr[2]); } + Double_t* GetRotationMatrix() {return &_rotmat[0][0] ;} + Double_t* GetTorationMatrix() {return &_tormat[0][0] ;} + + TList* GetDataPoints() {return &_data ;} + TList* GetDataPoints1() {return &_data1 ;} + + Double_t* GetInitialRotations() {return _initialRotations;} + void SetInitialRotations(); + + Double_t* GetInitialPosition() {return _initialPosition;} + void SetInitialPosition(); + + void SetDebug(Int_t aDebug){fDebugDPrecAlign = aDebug;} + Int_t GetDebug() { return fDebugDPrecAlign;} + + void SetDPrecAlignMethod(Int_t method) { DPrecAlignMethod=method; } // LC 2015/01/31 + Int_t GetDPrecAlignMethod() { return DPrecAlignMethod; } // LC 2015/01/31 + + ClassDef(DPrecAlign,2) // DPrecAlign +}; + +#endif diff --git a/include/DPrecAlign_linkdef.h b/include/DPrecAlign_linkdef.h new file mode 100755 index 0000000..ec1962d --- /dev/null +++ b/include/DPrecAlign_linkdef.h @@ -0,0 +1 @@ +#pragma link C++ class DPrecAlign-; // custom streamer diff --git a/include/DR3.h b/include/DR3.h new file mode 100755 index 0000000..e426055 --- /dev/null +++ b/include/DR3.h @@ -0,0 +1,74 @@ +// @(#)maf/dtools:$Name: $:$Id: DR3.h,v.2 2005/10/02 18:03:46 sha Exp $ +//*-- Author : Dirk Meier 98/01/09 + +#ifndef _DR3_included_ +#define _DR3_included_ + + ///////////////////////////////////////////////////////////////////////// + // Class Description of DR3 // + // // + // this is a basic vector class, restricted to 3 dimensional vectors // + // could be replaced later by more general class // + // // + ///////////////////////////////////////////////////////////////////////// + + + +#include + +// ROOT classes +#include "TObject.h" + + +class DR3 : public TObject { + + private: + Double_t *fCoordinate; //[3] coordinate of the vector + void copy(const DR3 &aR3); // copies coordinate + + public: + DR3(); + DR3(Double_t aX, Double_t aY, Double_t aZ); + DR3(const DR3& aR3); + ~DR3(); + + virtual void Print(const Option_t* ="") const ; + Double_t Length(); + Double_t InnerProduct(DR3 &rhs); + Double_t& operator()(Int_t aIndex); + Double_t& operator()(Int_t aIndex) const; + DR3& operator-=(const DR3 &rhs); + DR3& operator+=(const DR3 &rhs); + DR3& operator/=(const Double_t s); + DR3& operator*=(const Double_t s); + DR3& operator=(const DR3& rhs); + DR3 operator*(const Double_t rhs); + DR3 operator/(const Double_t rhs); + DR3 operator+(const DR3& rhs); + DR3 operator-(const DR3& rhs); + DR3 ComputeWithSlopeAndDistance(const DR3& slope, const Double_t& distance);//VR 2014/06/29 + void Convert2DoubleArray(Double_t *vector3); //VR 2014/06/29 + void SetDifference(DR3 &v1, DR3 &v2); + void SetScale(DR3& vector, const Double_t s); + void SetBias(DR3& vector, const Double_t b); + void SetValue(Double_t u, Double_t v, Double_t w); + void SetValue(const Double_t* value); + void SetValue(const Float_t* value); + void SetValue(const DR3 &vector); + void Zero(); + + ClassDef(DR3,2) // Describes DR3 + +}; + +#endif + + + + + + + + + + diff --git a/include/DSession.h b/include/DSession.h new file mode 100644 index 0000000..8be665a --- /dev/null +++ b/include/DSession.h @@ -0,0 +1,164 @@ +// @(#)maf/dtools:$Name: $:$Id:DSession.h v.1 2005/10/02 18:03:46 sha Exp $ +// Author : ? + +#ifndef _DSession_included_ +#define _DSession_included_ + + + //////////////////////////////////////////////////////////// + // Class Description of DSession // + // // + // + frame for analysis of raw event data // + // + dumps data on standard output // + // + fills events for storing in .root file // + // // + //////////////////////////////////////////////////////////// + +// Root classes +#include "TObject.h" +#include "TString.h" +#include "TTree.h" +#include "TBranch.h" +#include "TFile.h" +#include "TCanvas.h" +#include "TStopwatch.h" +#include "TSystem.h" +#include "DEvent.h" // has to be included, because of return from inline functions +#include "DGlobalTools.h" // to have fTool has a data member + +using namespace std; + +class DSetup; // forwards +class DAcq; +//class DReader; +class DTracker; + +class DSession : public TObject { + + private: + static DSession* fgInstance; + Int_t fDebugSession; // session debug flag + Int_t fPlaneToScan; + Int_t fStatus; // Status, 0 = initalizing, >= 1 aligning, running + Int_t fEventsToDo; // number of events to read from tape/file + Int_t fCurrentEventNumber; // actual event number // VR 2014/07/13 renamed + Int_t fRunNumber; // the run number + TString fConfigPath; // the path to the directory that contains telescope configuration files + TString fConfigFileName; // name of the configuration file + TString fRawSourcePath; // path to the raw data source (input) + TString fSummaryFilePath; // path to the summary file (output) + TString fSummaryFileName; // name of the data summary file + TString fSummaryFilePathAndName; // name for the .root file (DSF) + TString fSummaryFileTitle; // title for the .root file (DSF) + TString fResultDir; // name of result dir + TString fResultsDirParent; + TString fOutputFilesPrefix; // Prefix for Output Files + TString fOutputFilesSuffix; // Suffix for Output Files + //TString fWeightFileName; // name of the file containings eta parameters, JB 2011/04/12 + //TFile *fWeightFile; // pointer to .root file, contains weights for accurate hit measurements + + Int_t fPlaneNumber; // ... a specific planenumber to look at + DTracker *fTracker; // pointer to the tracker + DSetup *fc; // pointer to configuration + DAcq *fAcq; // pointer to Acquisition +/* DReader *fReader; // pointer to Run Reader */ + DEvent *fEvent; // pointer to an Event + TTree *fEventTree; // pointer to the Tree + Int_t fFillLevel; // controls amount of info stored in Tree, JB 2011/07/21 + Int_t fEventBuildingMode; // To switch externally EventBuildingMode. SS 2011.11.14 + + Double_t fTrackLimitsForAlignX[2]; // min-max in X for tracks used in alignment procedure, JB 2013/06/10 + Double_t fTrackLimitsForAlignY[2]; // min-max in Y for tracks used in alignment procedure, JB 2013/06/10 + Double_t fTrackChi2LimitForAlign; // upper chi2 limit in alignment procedure, JB 2013/07/14 + + TStopwatch fWatch; // to monitor event processing time JB, 2008/08/08 + TString fBeamTime; + + TFile *fSummaryFile; // pointer to data summary file + DGlobalTools fTool; // JB 2011/07/18 + + Bool_t fDaqAbleToGoToAspecificEvent; // Is the DAQ able to go to a specific event ? // VR 2014/07/13 + + public: + DSession(); + DSession(const Int_t num); + DSession(Option_t*); + + void MakeTree(); + Bool_t NextRawEvent( Int_t aTrigger=-1); // get next event from run + Int_t GoToEvent(Int_t anEvent); // Specific method to ask the DAQ for a given event // VR 2014/07/13 + Int_t GoToNextEvent(void); // Specific method to ask the DAQ for a given event // VR 2014/07/13 + void ResetDaq(); // Restart event reading from the beginning, JB 2015/03/02 + void Loop(); // loop over events and fill .root + void SetPlaneToScan(Int_t aPlnb) {fPlaneToScan = aPlnb ;} + void Scan() ; // loop and plot plane data + void Finish(); + void InitSession(); + void FillTree(); + + Int_t GetDebug() { return fDebugSession;} + DEvent *GetEvent() { return fEvent; } + TTree *GetEventTree() { return fEventTree; } + TFile *GetSummaryFile() { return fSummaryFile; } + DTracker *GetTracker() { return fTracker; } + DAcq *GetDataAcquisition() { return fAcq; } + DSetup *GetSetup() { return fc; } + Int_t GetStatus() { return fStatus; } + + TString GetSummaryFileName() { return fSummaryFileName; } + TString GetSummaryFileTitle() { return fSummaryFileTitle; } + TString GetSummaryFilePath() { return fSummaryFilePath; } + TString GetRawSourcePath() { return fRawSourcePath; } + TString GetConfigPath() { return fConfigPath;} + TString GetConfigFileName() { return fConfigFileName;}//VR 2014/06/29 + TString GetResultDirName() { return fResultDir; } // JB 2009/09/14 + TString GetResultsDirParent() { return fResultsDirParent; } + TString GetOutputFilesPrefix() { return fOutputFilesPrefix; } + TString GetOutputFilesSuffix() { return fOutputFilesSuffix; } + //TFile *GetWeightFile() { return fWeightFile; } // JB 2011/04/12 + //TString GetWeightFileName() { return fWeightFileName; } // Jb 2011/04/12 + Int_t GetRunNumber() { return fRunNumber; } + Int_t GetPlaneNumber() { return fPlaneNumber; } + Int_t GetCurrentEventNumber() { return fCurrentEventNumber; } // VR 2014/07/13 + + void SetRunNumber(Int_t aRunNumber) { fRunNumber = aRunNumber; } + void SetEvents(Int_t aNumberOfEvents) { fEventsToDo += aNumberOfEvents; } + void SetEventsToDo(Int_t aNumberOfEventsToDo) { fEventsToDo = aNumberOfEventsToDo;};//VR 2014/06/29 + void SetStatus(Int_t aStatus) { fStatus = aStatus; cout << endl << "The Session status just changed to " << aStatus << endl; +} // JB 2009/07/17 + void SetFillLevel( Int_t aLevel) { fFillLevel = aLevel; } // JB 2011/07/21 + void SetEventBuildingMode (Int_t aEventBuildingMode) {fEventBuildingMode = aEventBuildingMode; } //SS 2011.11.14 + + void SetConfigPath(TString aConfigPath){ fConfigPath = aConfigPath; } + void SetConfigFileName(TString aConfigFileName){ fConfigFileName = aConfigFileName; } // VR 2014/06/30 + void SetResultsDir(TString aPath){ fResultDir = aPath; gSystem->mkdir( fResultDir, 1);} // JB 2011/04/12 + void SetResultsDirParent(TString aPath){ fResultsDirParent = aPath; gSystem->mkdir( fResultsDirParent, 1);} + void SetOutputFilesPrefix(TString aString) {fOutputFilesPrefix = aString;} + void SetOutputFilesSuffix(TString aString) {fOutputFilesSuffix = aString;} + void SetRawSourcePath(TString aRawSourcePath){ fRawSourcePath = aRawSourcePath; } + void SetSummaryFilePath(TString aSummaryFilePath){ fSummaryFilePath = aSummaryFilePath; gSystem->mkdir( fSummaryFilePath, 1); } + void SetSummaryFileName(TString aSummaryFileName){ fSummaryFileName = aSummaryFileName; } + void SetSummaryFilePathAndName() { fSummaryFilePathAndName = fSummaryFilePath + "/" + fSummaryFileName; } + //void SetWeightFile( TString aFileName); // JB 2011/04/12 + + void SetPlaneNumber(Int_t aPlaneNumber){ fPlaneNumber = aPlaneNumber;}; + void SetDebug(Int_t aDebug); + void SetTrackGeoLimitsForAlign(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax); // JB 2013/06/11 + void GetTrackGeoLimitsForAlign(Double_t &xmin, Double_t &xmax, Double_t &ymin, Double_t &ymax); // JB 2013/06/11 + void SetTrackChi2LimitForAlign( Double_t aLimit); // JB 2013/07/14 + Double_t GetTrackChi2LimitForAlign() { return fTrackChi2LimitForAlign; } // JB 2013/07/14 + + static DSession*& Instance() { + if (!fgInstance) fgInstance = new DSession("options"/*'s'*/); + return fgInstance; + } + + ClassDef(DSession,1) // Frame for event loops +}; + +//R__EXTERN DSession *tSession; + +//#define tSession DSession::Instance() + + +#endif diff --git a/include/DSetup.h b/include/DSetup.h new file mode 100644 index 0000000..e5a6c4b --- /dev/null +++ b/include/DSetup.h @@ -0,0 +1,460 @@ +// @(#)maf/dtools:$Name: $:$Id:DSetup.h v.1 2005/10/02 18:03:46 sha Exp $ +// Author : ? + +#ifndef _DSetup_included_ +#define _DSetup_included_ + + //////////////////////////////////////////////////////////// + // Class Description of DSetup // + // // + // + Read Setup of the Acquisition, Telescope and Analysis// + // for a run. // + // // + //////////////////////////////////////////////////////////// + +#include "Riostream.h" + +// ROOT classes +#include "TString.h" +#include "TObject.h" +#include "TVector.h" +#include "TFile.h" +#include "TMath.h" + +#include "DSession.h" +#include "DR3.h" +#include "TSystem.h" + +using namespace std; + +#define fMaxSubmatrices 10 +#define fMaxGeomatrices 10 +#define fMaxModules 60 +#define fMaxDigitalThresholds 16 + +class DSession; +class DR3; + +class DSetup : public TObject { + + public: + //Defining a region for multiplicity dependent resolution information, added AP 2014/11/20 + struct Region_t { + int R_col[2]; + int R_lin[2]; + }; + + + private: + void copy(const DSetup& a); + + DSession *fSession; // pointer to the current session + + void ReadRunParameters(); // READ functions added JB 2012/12/21 + void ReadTrackerParameters(); + void ReadExperimentGeometryParameters(); + void ReadLadderParameters( Int_t aLadderNumber=-1); + void ReadGlobalAlignmentParameters(); + void ReadPlaneParameters( Int_t aPlaneNumber=-1); + void ReadDAQParameters(); + void ReadDAQBoardParameters(Int_t aBoardNumber=-1); + void ReadAnalysisParameters(); + void ReadSubmatrixParameters(Int_t aSubmatrixNumber=-1); + void nextField(); + void nextItem(Char_t delimiter); + void read_r3(DR3 &arg); + void read_item(Int_t &arg); + void read_item(UInt_t &arg); + void read_item(Float_t &arg); + void read_strings(Char_t *aString, Int_t aLength); + void read_TStrings(TString &TheString, Int_t aLength); + void getRidOfLine(); + void read_list(std::vector& arg); + ifstream fConfigFileStream; + + TString fConfigPath; // name of the configuration path + TString fConfigFileName; // name of the configuration file + TString fConfigPathAndFileName; // both path and file name appended + TString fSourcePath; // name of the data path (if not provided in config file) + + Int_t DSetupDebug; + + Int_t fFieldMaxLength; + Int_t fAddedPlanes; // counter of planes added in config + Int_t fAddedLadders; // counter of ladders added in config + Char_t *fFieldName; + + struct APixel_t { + int col; + int lin; + double fake; + }; + + std::vector _ResolutionList; + std::vector _ResolutionUList; + std::vector _ResolutionVList; + std::vector _RegionList; + std::vector _ResolutionFileList; + std::vector _FractionToMaskList; + std::vector _FakeRateCutList; + + void InitializePerformancesParams(int aPlaneNumber); + + void CheckRegionsOverlaps(int aPlaneNumber); + void CheckForBadRegions(int aPlaneNumber); + + void GetListOfHotPixelsToMask_FracToMask(int aPlaneNumber, + TString HotPixelMapFile); + void GetListOfHotPixelsToMask_FakeRateCut(int aPlaneNumber, + TString HotPixelMapFile); + + void PrintListOfHotPixelsToMask(int aPlaneNumber); + + public: + + DSetup(); + DSetup(DSession& aSession); + DSetup(const DSetup& c); + + DSetup& operator=(const DSetup&); + + //~DSetup() {}; // BEWARE No Destructor ! Structure Added, Destructor should be implemented, LC 2015/03/10 + ~DSetup(); + + void SetConfigPath(TString aCP) ; + void SetConfigFileName(TString aCFN) ; + void SetSourcePath(TString aSP) ; + void SetDebug(Int_t aDebug) { DSetupDebug = aDebug; cout << "DSetup debug updated to " << DSetupDebug << endl;} + DSession *GetSession() { return fSession;} + Int_t GetDebug() { return DSetupDebug;} + TString GetConfigPath() { return fConfigPath; } + + void ReadConfiguration(); + + + struct AnalysisParameter_t { + bool SavePlots; + bool DoTelResolutionMC; + int MCEvents; + int MCSeed; + bool MCDoDisplay; + bool DoGaussianMS; + int ResolutionScanSteps; + Float_t ResolutionScanInit; + Float_t ResolutionScanEnd; + Int_t CacheSize; + Int_t StatisticCells; + Int_t CmsNoiseCut; + Int_t MaxNbOfHits; + Int_t MinNbOfHits; + Float_t TrackChi2Limit; + Int_t MinHitsPerTrack; // JB 2013/06/22 + Int_t MaxTracksExGeom; // JB 2013/06/21 + Int_t ExGeomatrix; // JB 2013/06/21 + Int_t Submatrices; + Float_t HistoChargeRange; // JB 2013/09/12 + Float_t HistoSNRRange; + Float_t HistoNoiseRange; + Char_t AnalysisGoal[50]; // Jb 2014/01/16 + Float_t PixelSizeU[fMaxSubmatrices]; + Float_t PixelSizeV[fMaxSubmatrices]; + Int_t PixelsInRaw[fMaxSubmatrices]; + Int_t PixelsInColumn[fMaxSubmatrices]; + Int_t Matrixtype[fMaxSubmatrices]; // JB 2013/07/17 + Int_t MinSeedIndex[fMaxSubmatrices]; // JB 2013/08/21 + Int_t MaxSeedIndex[fMaxSubmatrices]; // JB 2013/08/21 + Int_t MinSeedCol[fMaxSubmatrices]; // JB 2013/08/22 + Int_t MaxSeedCol[fMaxSubmatrices]; // JB 2013/08/22 + Int_t MinSeedRow[fMaxSubmatrices]; // JB 2013/08/22 + Int_t MaxSeedRow[fMaxSubmatrices]; // JB 2013/08/22 + Int_t MaxNofPixelsInCluster[fMaxSubmatrices]; + Int_t MinNofPixelsInCluster[fMaxSubmatrices]; // JB 2013/09/12 + Float_t MinSeedCharge[fMaxSubmatrices]; // JB 2013/11/08 + Float_t MinClusterCharge[fMaxSubmatrices]; // JB 2014/01/21 + Float_t MinNeighbourCharge[fMaxSubmatrices]; // JB 2013/11/08 + Float_t NoiseScope[fMaxSubmatrices]; + Float_t Calibration[fMaxSubmatrices]; + Int_t Geomatrices[fMaxSubmatrices]; // JB 2013/01/16 + Float_t Umin[fMaxSubmatrices][fMaxGeomatrices]; + Float_t Umax[fMaxSubmatrices][fMaxGeomatrices]; + Float_t Vmin[fMaxSubmatrices][fMaxGeomatrices]; + Float_t Vmax[fMaxSubmatrices][fMaxGeomatrices]; + Int_t UserFlag; // JB 2013/07/17 + }; + + AnalysisParameter_t AnalysisParameter; + AnalysisParameter_t& GetAnalysisPar(){return AnalysisParameter;} + + struct TrackerParameter_t { + enum {tpsz = 20}; + Int_t Planes; // # planes in this tracker + Int_t Ladders; // # ladders in this tracker + Int_t TracksMaximum; // maximum number of tracks to be allowed + Int_t TracksFinder; // method for track finding + Int_t TrackFittingAlg; // method for track fitting + Int_t PlanesForTrackMinimum; // min # planes to build a track in an event + Int_t HitsInPlaneTrackMaximum;// max # hits allowed per plane to do tracking + Float_t SearchHitDistance; // max distance hit-track to add hit to track + Float_t SearchMoreHitDistance; // max distance hit-track to add hit to a pre-track + Int_t HitsInPlaneMaximum; // maximum number of hits per plane to be allowed + Float_t Resolution; // estimated spatial resolution of ref planes + TString BeamType; // nature of the particles making the beam + Float_t BeamMomentum; // momentum of the beam particles (in GeV/c) + TString MediumMaterial; // Material of the medium containing the sensors. E.g. DryAir of Vacuum + Int_t VertexMaximum; // maximum number of tracks to be allowed + Int_t VertexConstraint; // use a vertex constraint to start track + Int_t UseSlopeInTrackFinder; // use the track slope to extrapolate track + Int_t TrackingPlaneOrderType; // the planes ordering type for finding tracks + Int_t EventsForAlignmentFit; // minimum number of events to fit alignement parameters + Int_t TimeLimit; // maximum frame length (in 10ns units) //RDM260609 from Float to Int RDM250809 + Int_t HitMonteCarlo; // Enable/Disable Hit Monte Carlo (Default = 0) + Int_t KeepUnTrackedHitsBetw2evts; // explicit // VR 2014.08.28 + Int_t DPrecAlignMethod; // Default : (0) Old method | (1) New method + // For TracksFinder=2 : + Int_t TrackingPass; // nb of pass in the tracking loop + Int_t* PreTrackHitsNbMinimum; // explicit + Int_t* PreTrackHitsTypeUsed; // explicit + Float_t* PreTrackHitsMaxDist; // explicit + Int_t* ExtTrackHitsNbMinimum; // explicit + Int_t* ExtTrackHitsTypeUsed; // explicit + Float_t* ExtTrackHitsMaxDist; // explicit + Int_t* FullTrackHitsNbMinimum; // explicit + Int_t TrackingOrderLines; // Number of Lines to define planes tracking order + Int_t** TrackingOrderPreTrack; // Planes'order to build pre-tracks + Int_t** TrackingOrderExtTrack; // Planes'order to build ext-tracks + Int_t SubtrackNplanes; // Number of planes in subtrack, JB 2014/12/22 + Int_t* SubtrackPlanes; // List of planes used in subtrack + }; + + TrackerParameter_t TrackerParameter; + TrackerParameter_t& GetTrackerPar(){return TrackerParameter;} + + struct IviGeometryParameter_t + { + enum {tpsz = 256}; + Char_t GeometryName[tpsz]; + Char_t GeometryVersion[tpsz]; + DR3 BeamOrigin; + DR3 BeamSlope; + DR3 BeamDisplayStrongBegin; + DR3 BeamDisplayStrongStop; + DR3 BeamDisplayMediumBegin; + DR3 BeamDisplayMediumStop; + DR3 BeamDisplayLightBegin; + DR3 BeamDisplayLightStop; + Char_t TargetType[tpsz]; + DR3 TargetSize; + Float_t TargetRadius; + Float_t TargetLength; + Char_t TargetAxis[1]; + DR3 TargetCenter; + DR3 TrackerOrigin; + DR3 TrackerTilt; + Char_t VertexingMethod[tpsz]; + }; + + IviGeometryParameter_t IviGeometryParameter; + IviGeometryParameter_t& GetIviGeometryParameter() {return IviGeometryParameter;} + + + // Ladder information, added JB 2013/01/16 + struct LadderParameter_t { + enum {tpsz = 20}; + Int_t LadderID; + Int_t Status; // ladder status + Char_t Name[tpsz]; // name of device + Int_t Planes; // # planes in this ladder + DR3 Position; // center position of the device in x,y,z system + DR3 Tilt; // tilting angles [degree] in x,y,z system + Int_t* PlaneList; // array of plane number associated + DR3* PlaneShift; // array of shift vectors from plane center to ladder center + DR3* PlaneTilt; // array of rotation vectors from plane orientation to ladder orientation + }; + + LadderParameter_t *pLadderParameter; + LadderParameter_t& GetLadderPar(Int_t anID){return pLadderParameter[anID];} + + // Global Alignment Information, added LC 2015/08/31 + struct GlobalAlignmentParameter_t { + enum {tpsz = 20}; + Float_t FixTrackParamX; + Float_t FixTrackParamY; + Float_t ResoTrackParamX; + Float_t ResoTrackParamY; + Float_t ResoAlignParamTr; + Float_t ResoAlignParamRot; + Float_t ResoFixPlaneTr; + Float_t ResoFixPlaneRot; + Float_t ResoAlignParamZ; + }; + + GlobalAlignmentParameter_t pGlobalAlignmentParameter; + GlobalAlignmentParameter_t& GetGlobalAlignPar() {return pGlobalAlignmentParameter;} + + // Multiplicity dependent resolution informaton, added AP 2014/11/20 + struct PlanePerformances_t { + Region_t Region; + Float_t GlobalPlaneResolution; + Float_t GlobalPlaneResolutionU; + Float_t GlobalPlaneResolutionV; + std::vector MultProb; + std::vector MultProbCumul; + std::vector ResolutionU; + std::vector ResolutionV; + }; + + struct PlaneParameter_t { + enum {tpsz = 20}; + Int_t Inputs; // Number of inputs used for this plane max 4, JB 2009/05/07 + Int_t ModuleType[fMaxModules]; // the Module (Sirocco type 1, or 2 or something else) + Int_t ModuleNumber[fMaxModules]; // connected to which acquisition module number + Int_t InputNumber[fMaxModules]; // number of the input plug + Int_t ChannelNumber[fMaxModules]; // first strip nb associated to the first channel number for this input (start at 1) + Int_t ChannelOffset[fMaxModules]; // the number of the first channel related to the plane for this input (start at 1) + Int_t Channels[fMaxModules]; // Number of channels taken for this input + Int_t TimeLimit; // limit in timestamp distance + Char_t Name[tpsz]; // name of device + Char_t Purpose[tpsz]; // purpose of device e.g. reference + Int_t Readout; // readout status Alice128c + Int_t MimosaType; // pitch of Mimo25 RDM210509 + Int_t AnalysisMode; // normal 0 , read noise file 1... + Int_t HitFinder; // method for the hit finder2 + Int_t FixedGlobalAlign; // To fix the plane for global alignment. // LC 2015/08/20. + Int_t InitialPedestal; // nb of events required for pedestal + Int_t InitialNoise; // nb of events required for noise + Int_t CacheSize ; // Size of the cache for the hit suppression in pedestal and noise computation + Float_t DistanceZero; // distance to zero in [mm] // old + DR3 Position; // center position of the device in x,y,z system + DR3 Tilt; // tilting angles [degree], u,v,w vectors rotated to x,y,z vectors + Float_t AlignmentU; // offset perpendicular to strip direction, to be added to position + Float_t AlignmentV; // offset parallel to strip direction, to be added to position + Float_t AlignmentTilt; // w-tilting angle about 0 in the device coordinates + DR3 Size; // assume rectangular shape, extensions in a,b,c + DR3 Strips; // number of strips in u,v,w directions + DR3 Pitch; // pitch in mm in u,v,w directions + DR3 StripSize; // size of a strip in u,v,w directions + Float_t PlaneResolution; // expected resolution, JB 2013/06/22 + Float_t PlaneResolutionU; // expected resolution in U, AP 2014/11/20 + Float_t PlaneResolutionV; // expected resolution in V, AP 2014/11/20 + Float_t PlaneThickness; // plane thickness in mu, AP 2015/03/10 + TString PlaneMaterial; // plane material, AP 2015/03/10 + bool UsingTrackerResolution; //Bool to decide if using tracker resolution + std::vector PlanePerformancesList; //Resolution map vs multiplicity, added AP 2014/11/20 + Int_t Mapping; // 980106: only Mapping = 1 is supported + Float_t MaximalNoise; // Maximum noise for seed strip + Float_t MinimalNoise; // Minimal noise for seed strip + Float_t ThreshNeighbourSN; // threshold of mean Signal-to-Noise on neighbour strips (adjcnt seed) + Float_t ThreshSeedSN; // threshold of mean Signal-to-Noise on seed strip + Int_t MaxNStrips; // maximum number of strips in the cluster + Int_t MinNStrips; // maximum number of strips in the cluster + DR3 ClusterLimit; // maximum extension of clusters in u,v,w direction + Float_t ClusterLimitRadius; // maximum radius from center of gravity to associate a pixel to a cluster + Int_t CommonRegions; // number of regions for common mode/shift correction (2 in case of 2 VA) + Int_t Status; // Status: Primary Reference = 1., Secondary Reference = 2. Test = 3. + Int_t ParentLadderID; // ID of parent ladder, -1 if none, JB 2013/01/16 + Int_t HitPositionAlgorithm; // 1= Center of Gravity, 2 = eta, 3 = kappa + Int_t EtaCoefficientsN; // number of eta correction coefficients + Float_t EtaCoefficient[tpsz]; // the coefficients + Float_t EtaLowLimit; // use eta correction from lower limit + Float_t EtaHighLimit; // .. to high limit + Int_t KappaCoefficientsN; // number of kappa correction coefficients + Float_t KappaCoefficient[tpsz]; // the coefficients + Float_t KappaLowLimit; // use kappa correction from lower limit + Float_t KappaHighLimit; // .. to high limi + Int_t GammaCoefficientsN; // number of gamma correction coefficients + Float_t GammaCoefficient[tpsz];// the coefficients + Float_t GammaLowLimit; // kappa-to-eta limit, low limit + Float_t GammaHighLimit; // eta-to-kappa limit, high limit + Int_t NoisyStripsN; // number of noisy strips + Float_t NoisyStripsIndex[tpsz]; // noisy strips index + Int_t IfDigitize; // >0 if to emulate digitization over IfDigitization(<=4) bits + Int_t DigitizeThresholds[fMaxDigitalThresholds]; // 2^(IfDigitization) thresholds to emulate digitization + Int_t IfDeformed; // >0 to take deformation into account + Float_t CoeffLegendreU[7]; // Deformation coeff, U-direction + Float_t CoeffLegendreV[7]; // Deformation coeff, V-direction + + std::vector HotPixelList_lin; //List of hot pixels: line + std::vector HotPixelList_col; //List of hot pixels: column + std::vector HotPixelList_index; //List of hot pixels: index + }; + + PlaneParameter_t *pPlaneParameter; + PlaneParameter_t& GetPlanePar(Int_t aPN) {return pPlaneParameter[aPN-1];} + + Int_t** ChannelUse; //! pointer to bits on good channels + Int_t* ChannelAllUse; //! use all channels in DAcq + + struct AcqParameter_t { + Int_t FileHeaderSize; // size of the FileHeader + Int_t EventBufferSize; // size given by ExaByte format + Int_t FileHeaderLine; // size of event header in Bytes (same as below, kept for bkw comp) + Int_t EventHeaderSize; // size of event header in Bytes + Int_t EventTrailerSize; // size of event trailer in Bytes + Int_t ModuleTypes; // number of acquisition modul types + // e.g. a Sirocco of Type A, B, or LBL-Pixel device + Int_t BinaryCoding; // 0 for BigEndian, 1 for LittleEndian + Int_t TriggerMode; // Expect a Trigger (1) or not (0) to separate event, JB 2010/08/23 + Int_t EventBuildingMode; // SS 2011.11.14 + Char_t TimeRefFile[100]; // JB 2018/02/11 + Int_t IfExternalTimeRef; + } AcqParameter; + + AcqParameter_t& GetAcqPar(){return AcqParameter;} + + struct AcqModuleParameter_t { + enum {tpsz = 100}; + Char_t Name[tpsz]; // Name of the Acquisition Module (e.g. Sirocco Type A) + Int_t Devices; // Quantity of Devices of this Module type + Int_t Type; // Type of this Module ( e.g. 1 = Sirocco Type A... ) + Int_t EventBuildingBoardMode; // JB 2013.06.22 + Int_t Inputs; // Number of Inputs per Module + Int_t Channels[fMaxModules];// Number of Channels acquired via an input + Int_t Bits[fMaxModules]; // Number of Bits reserved for value + Int_t SigBits[fMaxModules]; // Number of significant bits, coding the value + Int_t NColumns; // Number of columns of sensor + Int_t NMultiFrames; // Nb of frames stored when MultiFraming + Char_t *DeviceDataFile[fMaxModules]; // Data file name for each device, JB 2009/05/25 + Int_t NbOfFramesPerChannel[fMaxModules]; + Int_t PixelShiftMod[fMaxModules]; // JB 2015/05/12 + Int_t FirstTriggerChannel; + Int_t LastTriggerChannel; + Int_t PixelShift; // JB,CB,PLR 2015/03/24 + Int_t AmpOffset; // JB,CB,PLR 2015/03/24 + Float_t AmpFactor; // JB,CB,PLR 2015/03/24 + UInt_t Trailer; // JB,CB,PLR 2015/03/24 + TString MCTreeName; //AP 2016/05/18 + Int_t IfZeroSuppress; // >0 if to suppress rawdata values below a threshold + Int_t ThresholdZero; // threshold for zero suppression + }; + + //Char_t* GetModuleDataFile( Int_t aMod) { return pModuleDataFile[aMod]; } + + AcqModuleParameter_t *pAcqModuleParameter; //! don''t put in Streamer + AcqModuleParameter_t& GetModulePar(Int_t aMTN) { return pAcqModuleParameter[aMTN-1]; } + + struct RunParameter_t { + enum {tpsz = 250}; + Char_t Affiliation[tpsz]; // your group + Char_t Signature[tpsz]; // whom to blame on this analysis result + Char_t BeamTime[tpsz]; // when this data was taken + Char_t Confidence[tpsz*3]; // state of alignement or other comments + Char_t DataPath[tpsz*3]; // Path to the data + Char_t DataSubDirPrefix[tpsz];// Prefix of the subdir that contains data files, concatenated with run number + Char_t Extension[tpsz]; // Extension for a data file + Int_t Number; // Run Number to be analysed as a String + Int_t EventsInFile; // How many events are in a file + Int_t StartIndex; // start index of the file for processing + Int_t EndIndex; // end index + Int_t NoiseRun; // Run number of noise run YV 27/11/09 + Int_t PixelGainRun; // Run number of gain calibration JB 2018/07/04 + // Int_t FileCountOut; // maximum number of files possible + } RunParameter; + + RunParameter_t& GetRunPar() {return RunParameter;} + + + ClassDef(DSetup,2) // Configuration of the Telescope and Detectors under Test + +}; + +#endif diff --git a/include/DStrip.h b/include/DStrip.h new file mode 100755 index 0000000..3889178 --- /dev/null +++ b/include/DStrip.h @@ -0,0 +1,161 @@ +#ifndef _DStrip_included_ +#define _DStrip_included_ + +#include + +// ROOT classes +#include "TObject.h" +#include "TH1.h" +#include "DR3.h" +//#include "DPixel.h" //YV 04/06/09 + +class DSetup; +class DPlane; +class TH1F; + +//YV 04/06/09 make DStrip class inherit from DPixel +class DStrip : public TObject { + //class DStrip : public DPixel { + + + public: + DStrip(); + DStrip(DPlane& aPlane, const Int_t aStripIndex, DR3& aPosition, DR3& aSize); + ~DStrip(); + + Int_t Introduce( DStrip &aStrip); + Float_t Distance( DStrip &aStrip); + Float_t Distance(const DR3& aPosition); + Float_t DistanceU(DStrip& aStrip); + Float_t DistanceU(const DR3& aPosition); + Float_t DistanceV(DStrip& aStrip); + Float_t DistanceV(const DR3& aPosition); + + void SumValue(); // sums the value and increments a counter + void SumSquareValue(); // sums the square of the value and increments counter + void InitPedestal(); + void InitNoiseAndPedestal(); + void SetNoise(Float_t tNV ); // set noise to the value + void SetPedestal(Float_t tPV); // set pedestal to the value + void InitNoise(); + void SetCommonMode(Float_t tCM) { fCommonMode = tCM; } + void SetRawValue(Float_t tRV); // sets raw value and updates; + //---addition 10/1/01 + void SetRawFrame1Value(Float_t tRF1); // sets raw value and updates; + void SetRawFrame2Value(Float_t tRF2); // sets raw value and updates; + Float_t GetRawFrame1Value() { return fRawFrame1Value; } + Float_t GetRawFrame2Value() { return fRawFrame2Value; } + + void Update(); + void UpdatePedestalAndNoise(); + void UpdatePedestal(Float_t tRV); + void UpdateSignal(); + void UpdateSignal(Float_t tRV); + void UpdateNoise(Float_t tSV); + + Int_t GetStripIndex() { return fStripIndex; } + Int_t GetPixelIndex() { return fPixelIndex; } // JB 2012/08/18 + void SetPixelIndex( Int_t anIndex) { fPixelIndex = anIndex; } // JB 2012/08/18 + Int_t GetPlaneNumber() { return fPlaneNumber; } + Float_t GetRawValue() { return fRawValue; } + Float_t GetPulseHeight() { return fPulseHeight; } + Float_t GetPulseHeightToNoise(); + Float_t GetNoise() { return fNoise; } + Float_t GetPedestal() { return fPedestal; } + Float_t GetCommonMode() { return fCommonMode; } + Int_t GetPedestalCounts() { return fSumCount; } // JB 2010/10/16 + Int_t GetNoiseCounts() { return fSumSquareCount;} // JB 2010/10/16 + /* + //YV 04/06/09 change floats to double + Double_t GetRawValue() { return fRawValue; } + Double_t GetPulseHeight() { return fPulseHeight; } + Double_t GetPulseHeightToNoise(); + Double_t GetNoise() { return fNoise; } + Double_t GetPedestal() { return fPedestal; } + Double_t GetCommonMode() { return fCommonMode; } + */ + + + DR3& GetPosition() { return fPosition; } + DR3& GetSize() { return fSize; } + DPlane *GetPlane() { return fPlane; } + //---abesson september 2005 + DSetup *GetSetup() { return fc; } + DStrip *GetNeighbour(Int_t aNI); + Int_t GetNeighbourCount() { return fNeighbourCount;} + Bool_t Found() { return fFound; } + void SetFound(Bool_t b) { fFound = b; } + Bool_t KillNoise(); + + private: + Int_t fDebugStrip; + Float_t fRawValue; // the rawvalue + //Double_t fRawValue; // the rawvalue YV 04/06/09 + Float_t fRawFrame1Value; // the rawvalue w/o CDS (1st frame) + Float_t fRawFrame2Value; // the rawvalue w/o CDS (2nd frame) + Float_t fSumValue; // sum of values for pedestal/noise initialization + Float_t fSumSquareValue; // sum of squares of raw values for noise initialization + Float_t fInitialPedestal; // initial pedestal value + Float_t fInitialTMS; // initial variance (the mean square) + Int_t fSumCount; // counter for raw signal summation + Int_t fSumSquareCount; // counter for squared raw signal summation + + Int_t fPlaneNumber; // number of the plane + DPlane *fPlane; // pointer to the plane + DSetup *fc; // pointer to the configuration + DR3 fPosition; // position in uvw coordinates in the plane + DR3 fSize; // size in uvw directions + + Int_t fStripIndex; // number of this strip + Int_t fPixelIndex; // corresponding index in the pixel List, JB 2012/08/18 + Float_t fPulseHeight; // pulseheight on strip + Float_t fNoise; // noise on strip + Float_t fCommonMode; // the common mode value + Float_t fPedestal; + /* + //YV 04/06/09 + Double_t fPulseHeight; // pulseheight on strip + Double_t fNoise; // noise on strip + Double_t fCommonMode; // the common mode value + Double_t fPedestal; + */ + Int_t fWeightPedestal; // a weight (e.g. 100) for pedestal follower + Int_t fWeightNoise; // a weight (e.g. 100) for pedestal follower + + //YV ends + + Int_t fCallCount; // Number of events in long term noise calc. + Int_t fCallCountMaximum; // how many events to include + + Bool_t fFound; // flag, that strip is found in hit + Bool_t fUsePulse; // flag, that strip can be used in analysis + + DStrip** fNeighbourList; //! array of strips in the neighbourhood + Int_t fNeighbourCount; + Int_t fNeighbourCountMaximum; // max. # of neighbours in bound + Float_t fBound; // circle in mm around seed center + + Float_t aSignalSupressedValue(Float_t* data, const Int_t entries); + Int_t extremumIndex(const Float_t* data, const Int_t N); + Int_t fCacheSize; // the size for the noise and pedestal buffer = 5; + Float_t fNoiseCache[50]; // FIFO buffer for noise measurement + Int_t fNoiseCacheIndex; // counter + Float_t fPedestalCache[50]; // FIFO buffer for noise measurement + Int_t fPedestalCacheIndex; // counter + Float_t median(Float_t* data, const Int_t N); + + ClassDef(DStrip,3) // Strip or Pixel of a Detector Plane + +}; + +#endif + + + + + + + + + + diff --git a/include/DTLinkDef.h b/include/DTLinkDef.h new file mode 100644 index 0000000..e9c054c --- /dev/null +++ b/include/DTLinkDef.h @@ -0,0 +1,79 @@ +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class DSession+; +#pragma link C++ class TNTBoardReader+; +#pragma link C++ class TNTEvent+; +#pragma link C++ class TNTPixel+; +#pragma link C++ class PXIBoardReader+; +#pragma link C++ class PXIEvent+; +#pragma link C++ class PXIPixel+; +#pragma link C++ class PXIeBoardReader+; +#pragma link C++ class PXIeEvent+; +#pragma link C++ class PXIePixel+; +#pragma link C++ class GIGBoardReader+; +#pragma link C++ class GIGEvent+; +#pragma link C++ class GIGPixel+; +#pragma link C++ class GIGMonteCarlo+; +#pragma link C++ class IMGBoardReader+; +#pragma link C++ class IMGEvent+; +#pragma link C++ class IMGPixel+; +#pragma link C++ class BoardReaderEvent+; +#pragma link C++ class BoardReaderPixel+; +#pragma link C++ class VMEBoardReader+; +#pragma link C++ class MCBoardReader+; +#pragma link C++ class BoardReaderIHEP+; // 2018/10/09 +#pragma link C++ class BoardReaderMIMOSIS+; // 2021/05/01 +#pragma link C++ class AliMIMOSA22RawStreamVASingle+; +#pragma link C++ class DecoderM18+; +#pragma link C++ class DecoderGeant+; +#pragma link C++ class DSetup+; +#pragma link C++ class DAcq+; +#pragma link C++ class DTracker+; +#pragma link C++ class DPlane+; +#pragma link C++ class DStrip+; +#pragma link C++ class DTrack+; +#pragma link C++ class DLine+; +#pragma link C++ class DHit+; +#pragma link C++ class DR3+; +#pragma link C++ class DCut+; +#pragma link C++ class DAlign+; +#pragma link C++ class DParticle+; +#pragma link C++ class DEventHeader+; +#pragma link C++ class DEvent+; +#pragma link C++ class DAuthenticPlane+; +#pragma link C++ class DTransparentPlane+; +#pragma link C++ class DAuthenticHit+; +#pragma link C++ class DEventMC+; +#pragma link C++ class DGlobalTools+; +#pragma link C++ class DataPoints+; +#pragma link C++ class DPrecAlign-; // custom streamer +#pragma link C++ class DPixel+; +//#pragma link C++ class DMonteCarlo+; // LC : 2014/12/15 : Removed +#pragma link C++ class DLadder+; +//#pragma link C++ class DHitMonteCarlo+; // LC : 2014/12/15 : Removed +#pragma link C++ class MiniVector+; // LC : 2014/12/19 +#pragma link C++ class DBeaster+; // DC : 2017/03/08 +#pragma link C++ class DHelixFitter+; // DC : 2017/07 +#pragma link C++ class DHelix+; // DC : 2017/09 +//#pragma link C++ class BoardReaderIHEP+; // JB, 2018/06/20 + +#ifdef UseROOFIT +//#pragma link C++ class DXRay2DPdf+; +#endif + +//#pragma link C++ global gPI; +//#pragma link C++ global gEULER; +//#pragma link C++ global gSpeedOfLight; +//#pragma link C++ function gPoly(float,float*,int); +//#pragma link C++ global gTool; + +// and add more CERNLIB functions +//#pragma link C++ function denlan_; + +//#pragma link C++ global tSession; + +#endif diff --git a/include/DTrack.h b/include/DTrack.h new file mode 100644 index 0000000..e3187fa --- /dev/null +++ b/include/DTrack.h @@ -0,0 +1,129 @@ +// @(#)maf/dtools:$Name: $:$Id:DTrack.h v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Dirk Meier 98/01/07 + +#ifndef _DTrack_included_ +#define _DTrack_included_ + + ////////////////////////////////////////////////////////////////// + // Class Description of DTrack // + // // + // A particle track from e.g. accelerator passing the tracker // + // The track is measured by the tracker with its silicon // + // reference planes // + // The track is e.g. a straight line // + // The line is found by a fit to the hits in the silicon planes // + // // + ////////////////////////////////////////////////////////////////// + + +#include + +// ROOT classes +#include "TObject.h" + +class DHit; +//class DHitMonteCarlo; +class DLine; +class DR3; +class DPlane; +class DParticle; + +class DTrack : public TObject { + private: + Int_t fDebugTrack; + Bool_t fValid; // TRUE = track is valid/good track + Float_t fChiSquare; // chisquare/ndf of track fit in 2D + Float_t fChiSquareU; // chisquare/ndf of track fit, U dim + Float_t fChiSquareV; // chisquare/ndf of track fit, V dim + Float_t fDistTr2Hit; // Mean distance between hits to track + Int_t fTrackNumber; // number of the track + DParticle *fParticle; // particle, not implemented + DLine *fLineTrajectory; // line trajectory + DR3 *fTangent; // tangent to the track + Bool_t fit_trajectory(Float_t resol); // does fit to hits in planes + void makeChiSquare(Float_t resol); // calculates the chi square of the track fit + //void makeChiSquareMC(Float_t resol); // calculates the chi square of the track fit //LC 2014/12/08 + + Int_t fHits; // number of hits to be used in track + Int_t fHitsMemorized; // number of memorized untracked hits (from the previous event) + Int_t fMaxNHits; // maximum nb of hits in a track + DHit **fHitList; //! pointer to list of hits to be used in track + //DHitMonteCarlo **fHitListMC; // LC 2014/12/08 : Monte Carlo Hits in current track. + Int_t fShareHit; // number of the track with common hit(s), 0 otherwise, CD, Nov 2007 + Int_t fMaxHitsPerPlane; // max number of hits allowed per plane to accept the track, JB 2009/05/25 + + Float_t fDeltaOrigineX ; // Sigma_x + Float_t fDeltaOrigineY ; // Sigma_y + + Float_t fVertexX; // LC 2012/12/17. + Float_t fVertexY; // Vertex position. + Float_t fVertexZ; + + Int_t fMCPartID; // MC particle ID number. This number gives MC particle ID of this reconstructed track. Default value is -1 + Int_t fHitsFromMCPartID; // This gives the number of hits of this reconstructed track from the MC particle with ID = fMCPartID. Default value if 0 + + void vzero(Double_t *array, Int_t length); + void invert(Int_t n, Double_t *a, Double_t *b); + void copy(const DTrack& aTrack); + + public: + DTrack( Int_t maxNHits); + ~DTrack(); + DTrack(const DTrack& aTrack); + DTrack(); + DTrack(DTrack* aTrack); // LC 2014/12/08. + DTrack(DR3 Origin, DR3 Slope); // AP 2015/03/10. + + + void SetLinearFit(DLine* aLine) {fLineTrajectory = aLine;} + void SetLinearFit2(DLine* aLine); + Bool_t Analyze( Int_t aNumber, DHit** aHitList, Int_t nHits, Float_t resol); + //Bool_t Analyze( Int_t aNumber, DHitMonteCarlo** aHitList, Int_t nHits, Float_t resol); // LC 2014/07/03 Analyze for Monte Carlo Hits. + Bool_t ReFit( Int_t nPlanes, Int_t *ListOfPlanes); // refit with subset of planes, JB 2013/08/24 + DR3 Intersection(DPlane *aPlane); + void Reset(); + Int_t GetNumber() const { return fTrackNumber; } + DLine& GetLinearFit() const { return *fLineTrajectory; } + DLine* GetLinearFit2() const { return fLineTrajectory; } + Float_t GetChiSquare() const { return fChiSquare; } + Float_t GetChiSquareU() const { return fChiSquareU; } + Float_t GetChiSquareV() const { return fChiSquareV; } + Float_t GetDistTr2Hit() const { return fDistTr2Hit; } + DParticle& GetParticle() const { return *fParticle; } + DR3& GetTangent() const { return *fTangent; } + Int_t GetHitsNumber() const { return fHits; } + Int_t GetHitsMemorizedNumber() const {return fHitsMemorized;} //VR 2014.11.07 + Int_t GetMaxNHits() const { return fMaxNHits; } // JB 2012/05/07 + //DHit& GetHitArray() { return **fHitList; } // Replace by DHit** GetHitdArray() // LC : 2014/12/08 + DHit** GetHitArray() { return fHitList; } // LC 2014/07/11 + DHit* GetHit( Int_t iHit) { return fHitList[iHit]; } // JB 2011/07/26 + Bool_t IsValid() const { return fValid; } + Int_t GetShareHit() const { return fShareHit; }// CD, Nov 2007 + Int_t GetMaxHitsPerPlane() const{ return fMaxHitsPerPlane; } // JB 2009/05/25 + void SetMaxHitsPerPlane( Int_t maxHits) { fMaxHitsPerPlane=maxHits; } // JB 2009/05/25 + + Float_t GetDeltaOrigineX() {return fDeltaOrigineX;} + Float_t GetDeltaOrigineY() {return fDeltaOrigineY;} + void SetDeltaOrigineX(Float_t sig_x) {fDeltaOrigineX=sig_x;} + void SetDeltaOrigineY(Float_t sig_y) {fDeltaOrigineY=sig_y;} + + void SetVertex( Float_t vertexX, Float_t vertexY, Float_t vertexZ); // Set vertex position. LC 2012/12/17. + Float_t GetVertexX() { return fVertexX;} + Float_t GetVertexY() { return fVertexY;} + Float_t GetVertexZ() { return fVertexZ;} + + void SetMCPartID(Int_t aPartID) {fMCPartID = aPartID;} //AP 2016/08/08 + Int_t GetMCPartID() {return fMCPartID;} //AP 2016/08/08 + + void SetHitsFromMCPartID(Int_t aHitsFromMCPartID) {fHitsFromMCPartID = aHitsFromMCPartID;} //AP 2016/08/08 + Int_t GetHitsFromMCPartID() {return fHitsFromMCPartID;} //AP 2016/08/08 + + + void SetDebug( Int_t aLevel) { fDebugTrack = aLevel;} // JB 2012/0820 + Int_t GetDebug() const {return fDebugTrack;} // JB 2012/0820 + + ClassDef(DTrack,1) // Describes DTrack +}; + +#endif + diff --git a/include/DTrackFitter.h b/include/DTrackFitter.h new file mode 100755 index 0000000..4adc267 --- /dev/null +++ b/include/DTrackFitter.h @@ -0,0 +1,110 @@ +// Author: L. Cousin && Liu Q + +#ifndef _DTrackFitter_included_ +#define _DTrackFitter_included_ + + ///////////////////////////////////////////////////////////// + // // + // Track fiiting class // + // // + // // + ///////////////////////////////////////////////////////////// + +#include "Riostream.h" +#include "TMath.h" +#include "TMatrixD.h" +#include "TVectorD.h" +//#include "TMatrixDLazy.h" +#include "TVectorD.h" +#include "TDecompLU.h" +#include "TDecompSVD.h" + +#include "DPrecAlign.h" +#include "DTrack.h" +#include "DPlane.h" + +class DTrackFitter : public TObject { + + // Track Fitting : Least Square Fit with matrix form. // LC 2015/06/24 + private: + + Bool_t _multipleScatteringFit; + + Int_t _hitNumber; + Int_t _localAxisNumber; + Int_t _trackParametersNumber; + + DHit** _fHitList; + + TMatrixD* _derivativeTrackMatrix; + + TMatrixD* _covarianceMatrix; + TMatrixD* _covarianceMatrixMS; + + TMatrixD* _inverseCovarianceMatrix; + + TMatrixD* _finalMatrix; + TMatrixD* _inverseFinalMatrix; + + TVectorD* _residualsVector; + TVectorD* _residualsVectorMS; + + TVectorD* _trackParameters; + TVectorD* _trackParametersCorrections; + + TVectorD* _finalVector; + + std::map _map_DPrecAlign; + std::map _map_Planes; + + std::vector _trackExtrapolation; + std::vector _thetaMS; + + DR3 _initialTrackParameters; + DR3 _initialTrackOrigin; + + public: + + Double_t ComputeResidualDerivative_U_AboutTrackDirectionX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeResidualDerivative_U_AboutTrackDirectionY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + + Double_t ComputeResidualDerivative_V_AboutTrackDirectionX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeResidualDerivative_V_AboutTrackDirectionY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + + Double_t ComputeResidualDerivative_U_AboutTrackPointX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_U_AboutTrackPointY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_U_AboutTrackPointZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + + Double_t ComputeResidualDerivative_V_AboutTrackPointX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_V_AboutTrackPointY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_V_AboutTrackPointZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + + Double_t ComputeTrackIntersectionU(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeTrackIntersectionV(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + + void DeleteMatricesAndVectors(); + + DTrackFitter(Int_t trackParameters, Int_t hitNumber, Int_t localAxisNumber, Bool_t ifMultipleScattering, DHit** hitList, DR3 initialTrackParameters, DR3 initialTrackOrigin); + ~DTrackFitter(); + + void SetCovarianceMatrixToIdentity(); + + void SetCovarianceMatrixMS(); + void ComputeResidualsMS(); + + void ProcessHits(); // Fill Vectors and Matrices. + + void ComputeTrackParameters(); // Matrix Inversion included. + + void RedefineTrackParameters(); + + void PrintTrackParameters(); + + Double_t ComputeDistance(DR3 firstPlane, DR3 lastPlane); + + DR3 GetTrackDirections(); + DR3 GetTrackOrigin(); + +}; + +#endif diff --git a/include/DTracker.h b/include/DTracker.h new file mode 100644 index 0000000..bed9ea7 --- /dev/null +++ b/include/DTracker.h @@ -0,0 +1,258 @@ +// @(#)maf/dtools:$Name: $:$Id:DTracker.h v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Dirk Meier 97/12/10 + +#ifndef _DTracker_included_ +#define _DTracker_included_ + + + //////////////////////////////////////////////////////////// + // Class Description of DTracker // + // // + //////////////////////////////////////////////////////////// + + +#include "TObject.h" +#include "TBRIK.h" +#include "TNode.h" +#include "TObjArray.h" +#include "Riostream.h" +#include "DLadder.h" +#include "TList.h" +#include "MKalmanFilter.h" +#include "MLeastChiSquare.h" +#include "DEventMC.h" + +#include "DBeaster.h" + + +using namespace std; + +class DSetup; +class DPlane; +class DTrack; +class DHit; +class DAcq; +class DLadder; +class DEventMC; +class DBeaster; //DC 2017/03/08 +void FCNAlignVertex(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); //LC. 2012/12/13. + +class DTracker : public TObject { + + private: + DAcq *fAcq; // pointer to acquisition + DSetup *fc; // pointer to the configuration + + Int_t fTracksMaximum; // maximum number of tracks allowed + Int_t fTracksFinder; // select track finding method + Int_t fTracksN; // number of tracks found + DTrack **fTrack; //! pointer to track list + DTrack *fTrackVoid; // this is an "empty" track + + Int_t fVertexMaximum; // maximum number of vertex allowed, JB 2013/06/11 + + DTrack **fSubTrack; // pointer to subtrack list, JB 2014/12/15 + Int_t fSubTrackPlanesN; // number of planes in subtrack, JB 2014/12/15 + Int_t *fSubTrackPlaneIds; // array of ids for planes in subtrack, JB 2014/12/15 + + Int_t fTrackFittingAlg; // Track fitting algorithm, QL 2016/06/06 + //Bool_t fKalEnabled; // Enable Kalman filter&smoother or not. + //DTrack *fKalTrack; // pointer to tracks fitted by Kal. + + Int_t fHitsMaximum; // maximum number of hits allowed + Int_t fHits; // number of hits found + DHit **fHitList; //! pointer to hit list + + Int_t fPlanesStatus ; // init status of the planes + Int_t fAlignmentStatus; // status of the alignement + + Int_t fPlanesN; // number of planes + TObjArray *fPlaneArray; // pointer to array of planes + TObjArray *fLadderArray; // pointer to array of Ladders + Int_t fNumberOfLadders; // LC 2013/01/15. + + TString fTrackerName; // name of this tracker + TNode *fTrackerNode; // pointer to the node of the tracker + TBRIK *fTrackerGeometry; // pointer to the geometry + + void find_tracks(); // original method to find tracks + + + void find_tracks_1_opt();// method to find tracks like find_tracks() but with more options VR 2014/07/14 + Int_t fTrackingPlaneOrderType; // the planes ordering type for finding tracks VR 2014/07/14 + + void find_tracks_2_ivi(); // method to tracks adapted for IVI VR 2014/07/14 + // see DSetup.h or DSetup.cxx for above member relative to find_tracks_2_ivi() + + void find_tracks_Beast(); // method to tracks adapted to Beast Experiment DC 2017/02 + + Int_t fTrackingPass; + Int_t* fPreTrackHitsNbMinimum; + Int_t* fPreTrackHitsTypeUsed; + Float_t* fPreTrackHitsMaxDist; + Int_t* fExtTrackHitsNbMinimum; + Int_t* fExtTrackHitsTypeUsed; + Float_t* fExtTrackHitsMaxDist; + Int_t* fFullTrackHitsNbMinimum; + Int_t fTrackingOrderLines; + Int_t** fTrackingOrderPreTrack; + Int_t** fTrackingOrderExtTrack; + + Int_t fKeepUnTrackedHitsBetw2evts; //explicit // VR 2014.08.28 + Double_t fSearchMoreHitDistance; // Max distance to associate a hit to a pre-track, VR 2014/06/29 + + void find_tracks_withStrips(); // finds the track in the strip-tracker + void find_tracks_and_vertex(); + void find_vertex(); // finds the vertex for the tracks in the event. LC 2012/12/13. + + Int_t fTrackSeedDevs; // amount of track seed planes (e.g. 2 Silicon planes) + Int_t fFixRefDevs; // amount of fixed reference planes (e.g. 4 Silicon planes) + Int_t fVarRefDevs; // amount of variable reference planes (e.g. 4 other Silicon planes) + Int_t fTestDevs; // amount of DUT planes + Int_t *fListTrackSeedDevs; //! list with numbers of fixed reference planes + Int_t *fListFixRefDevs; //! list with numbers of fixed reference planes + Int_t *fListVarRefDevs; //! list with numbers of variable reference planes + Int_t *fListTestDevs; //! list with numbers of det. under test + + + Int_t fRequiredHits; //! number of hits required to make a track, Jb 2009/05/21 + Double_t fSearchHitDistance; //! Max distance to associate a track and a hit, JB 2009/05/21 + Int_t fUseSlopeInExtrapolation; // JB 2013/06/21 + Int_t fUseVertexConstraint; // JB 2013/06/21 + + Int_t *fTrackCount; // Counter of tracks with # hits per track, JB 2009/09/08 + Int_t *fTrackCountPerPlane; // Counter of tracks per plane, JB 2014/08/29 + + Int_t fDebugTracker; // debug flag + + static DTracker* fgInstance; + + DEventMC* MCInfoHolder; // AP 2016/07/27 Object with all the MC information. i.e. the full list of particles, hits and pixels (both from physics and noise) + + DBeaster* fBeaster; + + + public: + DTracker(); + DTracker(DSetup& c, DAcq& aAcq); + ~DTracker(); + + enum {kSimpleChi2, kKalman, kChi2MS}; // QL 2016/06/06 + Int_t Update(); + Int_t UpdateMC(); + Int_t GetAlignmentStatus() { return fAlignmentStatus; } + void SetAlignmentStatus(Int_t aStatusValue); + void SetRequiredHits(Int_t aNumber); + Int_t GetRequiredHits() { return fRequiredHits; } // JB 2011/03/14 + void Align(DTrack *aTrack); // align planes in telescope with respect to track + + DAcq *GetAcq() { return fAcq; } + DBeaster *GetBeaster() { return fBeaster; } + DSetup *GetSetup() { return fc; } + DTrack *GetTrack(Int_t aTN); + DTrack *GetSubTrack(Int_t aTN); // JB 2014/12/15 + DTrack *GetPrincipalTrack() { return fTrack[0]; } + DTrack *nearest_track( DHit *aHit); // JB, 2009/07/17 + DHit *nearest_hit( DTrack *aTrack, Int_t aPlaneNumber, Bool_t &hitAssociated); // JB 2009/07/17, JB 2014/08/29 + DPlane *GetPlane(Int_t aPk); + DLadder *GetLadder(Int_t aLadder); + Int_t GetNumberOfLadders() { return fNumberOfLadders;} + TString GetTrackerName() { return fTrackerName; } + Int_t GetPlanesN() { return fPlanesN; } + Int_t GetTracksN() { return fTracksN; } + Int_t GetTracksMaximum() { return fTracksMaximum;} + Int_t GetNTrackSeed() { return fTrackSeedDevs; } + Int_t GetNFixRef() { return fFixRefDevs; } + Int_t GetNVarRef() { return fVarRefDevs; } + Int_t *GetListTrackSeed() { return fListTrackSeedDevs; } + Int_t *GetListFixRef() { return fListFixRefDevs; } + Int_t *GetListVarRef() { return fListVarRefDevs; } + Int_t GetNDUT() { return fTestDevs; } + Int_t *GetListDUT() { return fListTestDevs; } + Int_t GetTrackCount( Int_t i) { return fTrackCount[i]; } + Int_t GetTrackCountPerPlane( Int_t iPlane) { if( iPlane children; + std::map classment; + + public: + + TreeNode() {}; + //Int_t GetNumberOfNodes() { return numberOfNodes; }; + NodeData* GetData() { return data; }; + TreeNode* GetNode(Int_t hitNumber) { std::map::iterator iter = children.find(hitNumber); return iter->second; }; + Int_t GetHitnumberWithChi2Min() { return classment[0]; }; + + void SetData(NodeData* myData) { data = myData; }; + void AddChildren(Int_t hitNumber, NodeData* myData) { TreeNode* T = new TreeNode(); T->SetData(myData); children.insert(std::pair(hitNumber,T)); + classment.insert(std::pair(myData->GetChi2(), myData->GetHitNumber()) ); }; + +}; +*/ +#endif diff --git a/include/DXRay2DPdf.h b/include/DXRay2DPdf.h new file mode 100755 index 0000000..7e26fc9 --- /dev/null +++ b/include/DXRay2DPdf.h @@ -0,0 +1,75 @@ +/***************************************************************************** + * Project: RooFit * + * * + * This code was autogenerated by RooClassFactory * + *****************************************************************************/ + +#ifndef _DXRay2DPdf_included_ +#define _DXRay2DPdf_included_ + +#include "RooAbsPdf.h" +#include "RooRealProxy.h" +#include "RooCategoryProxy.h" +#include "RooAbsReal.h" +#include "RooRealVar.h" +#include "RooAbsCategory.h" +#include "TObject.h" +#include "TMath.h" + +class DXRay2DPdf : public RooAbsPdf { +public: + + DXRay2DPdf(); + + DXRay2DPdf(const char *name, const char *title, + RooAbsReal& _x, + RooAbsReal& _y, + RooAbsReal& _X0, + RooAbsReal& _sigma, + RooAbsReal& _beta, + RooAbsReal& _alpha, + RooAbsReal& _phi, + RooAbsReal& _W1, + RooAbsReal& _W2, + RooAbsReal& _W3, + RooAbsReal& _W4, + RooAbsReal& _W5, + RooAbsReal& _S2, + RooAbsReal& _S3, + RooAbsReal& _S4, + RooAbsReal& _S5); + + DXRay2DPdf(const DXRay2DPdf& other, const char* name=0); + + virtual TObject* clone(const char* newname) const; + + inline virtual ~DXRay2DPdf(); + + +protected: + + RooRealProxy x; + RooRealProxy y; + RooRealProxy X0; + RooRealProxy sigma; + RooRealProxy beta; + RooRealProxy alpha; + RooRealProxy phi; + RooRealProxy W1; + RooRealProxy W2; + RooRealProxy W3; + RooRealProxy W4; + RooRealProxy W5; + RooRealProxy S2; + RooRealProxy S3; + RooRealProxy S4; + RooRealProxy S5; + + double evaluate() const ; + +private: + + ClassDef(DXRay2DPdf,1) // 2D pdf for X-ray data +}; + +#endif diff --git a/include/DecoderGeant.h b/include/DecoderGeant.h new file mode 100644 index 0000000..b1e7b73 --- /dev/null +++ b/include/DecoderGeant.h @@ -0,0 +1,82 @@ +#ifndef DECODERGeant_H +#define DECODERGeant_H + +/* $Id: DecoderGeant.h 0 2014 fb $ */ + +/////////////////////////////////////////////////////////////////////////////// +/// +/// This class provides access to MIMOSA 18 in raw data. +/// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +using namespace std; + +class DecoderGeant: public TObject { + public : + DecoderGeant(Int_t aBoardNumber, Int_t aRunNumber); + DecoderGeant(const DecoderGeant& rstream); + DecoderGeant& operator=(const DecoderGeant& rstream); + ~DecoderGeant() {}; + + void SetInputFile(const char *filename="data.txt"){ + fFileInput = fopen(filename,"r"); + printf("your file is ok!! \n"); }; + + Int_t Get_Nevent(); // n of total event + Int_t Get_NHitPixel() {return fIndex.size();}; + Int_t GetRow(Int_t iPix) {return fRow[iPix];}; + Int_t Get_NRow() {return fRowPerChip;}; + Int_t GetCol(Int_t iPix) {return fCol[iPix];}; + Int_t Get_NCol() {return fColPerChip;}; + Double_t GetAmp(Int_t iPix) {return fAmp[iPix];}; + Int_t GetIndex(Int_t iPix) {return fIndex[iPix];}; + + Bool_t ReadData(); + + Int_t Get_EvNumber(){return fEvCounterCDH;};// current event number + + + void SetDebugLevel( int aLevel) { fDebugLevel = aLevel; }; + void PrintStatistics(ostream &stream); + Bool_t ReadNextLine(); + + + private: + + Int_t fRowPerChip; + Int_t fColPerChip; + void NewEvent(); + + Int_t fNEvent; + FILE *fFileInput; + UInt_t fDataChar; + Int_t fEvCounterCDH; // counter read in CDH + Int_t fNHitPixel; + Int_t fRowtmp[3]; + Int_t fColtmp[3]; + Double_t fAmptmp[3]; + + Int_t CalculateIndex(int ipixel); + Bool_t ReadCDH(); + + std::vector fRow; + std::vector fCol; + std::vector fIndex; + std::vector fAmp; + + Int_t fBoardNumber; + Int_t fRunNumber; + Bool_t fFlag; + + Int_t fDebugLevel; // debug level + + ClassDef(DecoderGeant, 0) // class for reading MIMOSA raw digits + +}; + +#endif \ No newline at end of file diff --git a/include/DecoderM18.h b/include/DecoderM18.h new file mode 100644 index 0000000..b7ae673 --- /dev/null +++ b/include/DecoderM18.h @@ -0,0 +1,103 @@ +#ifndef DECODERM18_H +#define DECODERM18_H + +/* $Id: DecoderM18.h 0 2014 fb $ */ + +/////////////////////////////////////////////////////////////////////////////// +/// +/// This class provides access to MIMOSA 18 in raw data. +/// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include + +using namespace std; + +class DecoderM18: public TObject { + public : + DecoderM18(Int_t aBoardNumber, Int_t aRunNumber, Int_t aSensorNumber); + DecoderM18(const DecoderM18& rstream); + DecoderM18& operator=(const DecoderM18& rstream); + ~DecoderM18() {}; + + void SetInputFile(const char *filename="data.txt"){ + fFileInput = fopen(filename,"rb"); + if( fFileInput) { + printf("your file %s is ok!! .... pay attention--> read option: rb \n", filename); + } + else { + printf("WARNING: your file %s cannot be opened!!\n", filename); + } + }; + + Int_t Get_Nevent(); // n of total event + Int_t Get_NHitPixel() {return fIndex.size();}; + Int_t GetRow(Int_t iPix) {return fIndex[iPix]/kRowPerChip;}; + Int_t GetCol(Int_t iPix) {return fIndex[iPix]%kRowPerChip;}; + Int_t GetAmp(Int_t iPix) {return fAmp[iPix];}; + Int_t GetIndex(Int_t iPix) {return fIndex[iPix];}; + Int_t GetOMKDTransition() {return kOMKDTransitionRead;}; + Int_t GetStopPointerTransition() {return kStopPointerTransitionRead;}; + + Bool_t ReadData( ); + + Int_t Get_EvNumber(){return fEvCounterCDH;};// current event number + + void SetShift( Int_t aShift); + void SetOffset( Int_t aOffset); + void SetMulFactor( Int_t aFactor); + void SetTrailer( UInt_t aTrailer); + void SetOMKDTransition( Int_t aTransition ) { kOMKDTransitionSet = aTransition; }; + void SetStopPointerTransition( Int_t bTransition ) { kStopPointerTransitionSet = bTransition; }; + + void SetDebugLevel( int aLevel) { fDebugLevel = aLevel; }; + void PrintStatistics(ostream &stream); + + private: + + enum {kRowPerChip=256}; + enum {kColPerChip=256}; +// enum {kShift=3}; +// enum {kToBeSutractedFromAmp=32768}; +// enum {kTrailer=0xfafafafa}; + + Int_t kShift; + Int_t kToBeSutractedFromAmp; + Int_t kAmpMultFactor; + UInt_t kTrailer; + Int_t kOMKDTransitionRead; + Int_t kOMKDTransitionSet; + Int_t kStopPointerTransitionRead; + Int_t kStopPointerTransitionSet; + + Int_t CalculateIndex(); + void NewEvent(); + Bool_t ReadNextInt(); + Bool_t ReadCDH(); + + Int_t fNEvent; + FILE *fFileInput; + UInt_t fDataChar; + Int_t fcountEv; //counter incremented when reading CDH + Int_t fEvCounterCDH; // counter read in CDH + + + std::vector fIndex; + std::vector fAmp; + + + Int_t fBoardNumber; + Int_t fRunNumber; + Int_t fSensorNumber; + + + Int_t fDebugLevel; // debug level + + ClassDef(DecoderM18, 0) // class for reading MIMOSA raw digits + +}; + +#endif diff --git a/include/DecoderM18_fb.h b/include/DecoderM18_fb.h new file mode 100755 index 0000000..98a4c28 --- /dev/null +++ b/include/DecoderM18_fb.h @@ -0,0 +1,185 @@ +#ifndef DecoderM18_fb_H +#define DecoderM18_fb_H + +/* $Id: DecoderM18_fb.h 0 2014 fb $ */ + +/////////////////////////////////////////////////////////////////////////////// +/// +/// This class provides access to MIMOSA 18 in raw data. +/// +/////////////////////////////////////////////////////////////////////////////// + +#include "Riostream.h" +#include "TObject.h" +#include "BoardReader.h" + +class DecoderM18_fb: public TObject { + public : + DecoderM18_fb( Int_t aBoardNumber, Int_t aRunNumber, Int_t aSensorNumber); + DecoderM18_fb(const DecoderM18_fb& rstream); + DecoderM18_fb& operator=(const DecoderM18_fb& rstream); + ~DecoderM18_fb() {}; + + void SetDebugLevel( int aLevel) { fDebugLevel = aLevel; } + BoardReaderEvent* GetEvent() { return fCurrentEvent; } + void PrintStatistics(ostream &stream); + Bool_t HasData(); + Bool_t ReadCDH(); + Int_t Get_NeventTOT(){return fCount;}; // n of total event + Int_t Get_Nevent(); // n of total event + + Int_t Get_Event_Info(); // info on the n evt + Int_t Read_Evento(Int_t evt); // info on the n evt + Bool_t GetPixeltrs(unsigned int WORD, Int_t FCOL, Int_t FROW, Int_t FAMP, Int_t FEVENT); + UInt_t GetEventNumber(){ return fEvent2;}; + UInt_t GetRow(){ return frow;}; + UInt_t GetCol(){ return fcol;}; + UInt_t GetAmp(){ return famp;}; + UInt_t GetPixel() { + for(Int_t fb=0; fb <=1000; fb++) + { + //if(PIXEL[fb]!=0x2bc){ + UInt_t word_simple=0; + word_simple=PIXEL[fb]; + printf("CURRENT PIXEL :---> %x \n",word_simple); + //Trasf(word_simple); + //} + } + return 0; + } + UInt_t GetPixel_i(Int_t i) { return PIXEL[i];} + Int_t GetPixel_i_index(Int_t i); + Int_t GetPixel_i_row(Int_t i) { return PIXEL[i] & 0x000000FF; } + Int_t GetPixel_i_col(Int_t i) { return (PIXEL[i] & 0x0000FF00) >> 8; } + Int_t GetPixel_i_value(Int_t i) { return (PIXEL[i] & 0xFFFF0000) >> 16; } + + + + void Trasf(UInt_t parola){ + Int_t froww = parola & 0x000000FF; + Int_t fcolw = (parola & 0x0000FF00) >> 8; + Int_t fampw = (parola & 0xFFFF0000) >> 16; + printf("...pixel info: --------------------> %d \n", froww); + printf("...pixel info: --------------------> %d \n", fcolw); + printf("...pixel info: --------------------> %d \n", fampw); + } + Int_t GetIndexMax(){ return Index_Max;}; + //UInt_t GetRowF(){ return froww;}; + //UInt_t GetColF(){ return fcolw;}; + //UInt_t GetAmpF(){ return fampw;}; + + UInt_t GetPixel1(){ return PIXEL[0];} + UInt_t GetPixel2(){ return PIXEL[1];} + UInt_t GetPixel3(){ return PIXEL[2];} + + //UInt_t ReadCDH(); + //Bool_t ReadData(); + Bool_t ReadData(); + + void SetInputFile(const char *filename="data.txt"){ + fFileInput = NULL; + fFileInput = fopen(filename,"rb"); + if( fFileInput && ReadCDH() ) printf("your file %s is ok!! .... pay attention--> read option: rb \n", filename); + else printf("ERROR cannot open file %s !!\n", filename);}; + + UInt_t GetEventCounterCDH() {return fEventCounterCDH;}; // get last read event counter value from CDH + UInt_t GetWordCounterCDH() {return fWordCounterCDH;}; // get last read word counter value from CDH + Bool_t IsLastEvent() {return fLastEvt;}; + Bool_t IsRunWithTrigger() {return fTrigger;}; + Int_t GetMimosaModRead() {return fModeRead;}; + UInt_t GetMimosaFrameType() {return fMimosaMode;}; + Int_t GetChipNumber() {return fChipNbr;}; + Int_t GetNbrChipActive() {return fNbrChip;}; // get number of chip in data-taking, value from CDH + UInt_t GetEventCounterLH() {return fEventCounterLH;}; // get last read event counter value from CDH + UInt_t GetWordCounterLH() {return fWordCounterLH;}; // get last read word counter value from CDH + UInt_t GetExternalTriggerCounter() {return fTriggerExternalCounter;}; + Bool_t IsChipActive(Int_t key){ + if(key<0 || key>3){ + printf("IsChipActive: you asked for no existing chip\n"); + return 0;} + else{ + return fChipKey[key];} }; + Short_t GetADCCounts(Int_t row, Int_t col){ + if(row<0 || row>63 || col<0 || col>15){ + printf("GetADCCounts1: you asked for no existing pixel\n"); + return -1;} + else{ + return fDataFrame[row][col];} }; + Short_t GetADCCounts2(Int_t row, Int_t col){ + if(row<0 || row>63 || col<0 || col>15){ + printf("GetADCCounts2: you asked for no existing pixel\n"); + return -1;} + else{ + return fDataFrame2[row][col];} }; + Short_t GetADCCounts3(Int_t row, Int_t col){ + if(row<0 || row>63 || col<0 || col>15){ + printf("GetADCCounts3: you asked for no existing pixel\n"); + return -1;} + else{ + return fDataFrame3[row][col];} }; + + + + + + enum {kDDLsNumber = 20}; // number of DDLs + enum {kChipsPerDDL = 4}; // number of chips in each DDL + enum {kRowPerChip = 64}; // number of rows per chip + enum {kColPerChip = 16}; //number of columns per chip + + private : + + Int_t fDebugLevel; // debug level + + Int_t fBoardNumber; + Int_t fRunNumber; + Int_t fSensorNumber; + + BoardReaderEvent *fCurrentEvent; + std::vector ListOfPixels; + + //Bool_t ReadNextInt(); + UInt_t ReadNextInt(); + + void NewEvent(); + FILE *fFileInput; + + UInt_t fDataChar1; + UInt_t fDataChar2; + UInt_t fDataChar3; + UInt_t fDataChar4; // temps part of a 32bit word + UInt_t fEventCounterCDH; // event number read by CDH + UInt_t fWordCounterCDH; // number of words of the event from CDH + UInt_t fTriggerExternalCounter; + Bool_t fLastEvt; // check if it is the last event + Bool_t fTrigger; + Bool_t fActiveChip[kChipsPerDDL]; + Bool_t fChipKey[kChipsPerDDL]; + + Int_t fModeRead; + UInt_t fMimosaMode; + Int_t fChipNbr; + Int_t fNbrChip; + UInt_t fEventCounterLH; // event number read by LH + UInt_t fWordCounterLH; // number of words of the event from LH + + Short_t fDataFrame[kRowPerChip][kColPerChip]; + Short_t fDataFrame2[kRowPerChip][kColPerChip]; + Short_t fDataFrame3[kRowPerChip][kColPerChip]; + Int_t fEvent; // event nb read from header + Int_t fEvent2; // event nb read from header + Int_t fCount; // count of events read + Int_t fEvt; // number of evt ? set to 0 and unchanged! + Int_t fjump; // jump + Int_t fcol; // + Int_t frow; // + Int_t famp; // + Int_t Index_Max; // + + UInt_t PIXEL[1000]; + + + ClassDef(DecoderM18_fb, 0) // class for reading MIMOSA raw digits +}; + +#endif diff --git a/include/GIGBoardReader.h b/include/GIGBoardReader.h new file mode 100644 index 0000000..76c3e50 --- /dev/null +++ b/include/GIGBoardReader.h @@ -0,0 +1,166 @@ +#ifndef _GIGBoardReader_included_ +#define _GIGBoardReader_included_ + +#include "Riostream.h" +#include "TObject.h" +#include "TH1.h" +#include +#include +#include "DGlobalTools.h" // to have fTool has a data member + +// Last Modified: LC, 2014/12/16 : passing by ref + vectors of pointers. +// -------------------------------------------------------------------------------------- + +class GIGPixel : public TObject { + + // Container for a simple pixel + // JB, 2009/08/13 + + private: + + int Input; + int Value; + int LineNumber; + int ColumnNumber; + + public: + + GIGPixel() { Input = 0; Value = 0; LineNumber = 0; ColumnNumber = 0; } + GIGPixel( int input, int value, int row, int col ) { Input = input; Value = value; LineNumber = row; ColumnNumber = col; } + virtual ~GIGPixel() {;} + int GetInput() { return Input; } + int GetValue() { return Value; } + int GetLineNumber() { return LineNumber; } + int GetColumnNumber() { return ColumnNumber; } + + ClassDef(GIGPixel,1) +}; + +// -------------------------------------------------------------------------------------- + + +class GIGMonteCarlo : public TObject { + + // Container for the monte carlo + // LC 2012/10/17 + + private: + + int Input; + int Value; + double monteCarloX; + double monteCarloY; + double monteCarloZ; + int aLine; + int aColumn; + + public: + + GIGMonteCarlo() { Input = 0; Value = 0; monteCarloX = 0; monteCarloY = 0; monteCarloZ = 0; aLine=0; aColumn=0; } + GIGMonteCarlo( int input, int value, double XmonteCarlo, double YmonteCarlo, double ZmonteCarlo, int Line, int Column) { Input = input; Value = value; monteCarloX = XmonteCarlo; monteCarloY = YmonteCarlo; monteCarloZ = ZmonteCarlo; aLine = Line; aColumn = Column; } + virtual ~GIGMonteCarlo() {;} + int GetInput() { return Input; } + int GetValue() { return Value; } + double GetMonteCarloX() { return monteCarloX; } + double GetMonteCarloY() { return monteCarloY; } + double GetMonteCarloZ() { return monteCarloZ; } + int GetLine() { return aLine; } + int GetColumn() { return aColumn; } + + ClassDef(GIGMonteCarlo,1) +}; + + +class GIGEvent : public TObject { + + private: + + int EventNumber; + int BoardNumber; + std::vector ListOfPixels; // LC 2014/12/15 --> Now passing by ref + std::vector ListOfMonteCarlo; + + public: + + GIGEvent() {;} + GIGEvent( int EventNumber, int boardNumber, vector& listOfPixels, vector& listOfMonteCarlo); // why * ? + ~GIGEvent(); + + int GetEventNumber() { return EventNumber; } + int GetBoardNumber() { return BoardNumber; } + int GetNumberOfPixels() { return ListOfPixels.size(); } + int GetNumberOfMonteCarlo() { return ListOfMonteCarlo.size(); } + std::vector& GetPixels() { return ListOfPixels;} + GIGPixel* GetPixelAt( int index) { return ListOfPixels.at(index); } + std::vector& GetMonteCarlo() { return ListOfMonteCarlo;} + GIGMonteCarlo* GetMonteCarloAt( int index) { return (ListOfMonteCarlo.at(index)); } + + + ClassDef(GIGEvent,1) +}; + +// -------------------------------------------------------------------------------------- + +class GIGBoardReader : public TObject { + + private: + + int DebugLevel; + DGlobalTools fTool; + + int BoardNumber; + int NSensors; + + bool ReadingOK; + bool EventReady; + bool EventStarted; + GIGEvent *CurrentEvent; + int CurrentEventID; + int NewEventID; + std::vector ListOfPixels; + std::vector ListOfMonteCarlo; + + int EventsCount; + int AveragePixelCountTotal; + int AveragePixelCountTotalTemp; + int *AveragePixelCount; + int *AveragePixelCountTemp; + + ifstream RawFileStream; + char* InputFileName; + char* PrefixFileName; + char* SuffixFileName; + int CurrentFileNumber; + int NumberOfFiles; + + int bufferPlane; + + void AddPixel( int input, int value, int aLine, int aColumn, double coordX, double CoordY, double CoordZ); + void GenerateNewEvent(); + + public: + + GIGBoardReader() {;} + GIGBoardReader( int boardNumber, int nSensors); + ~GIGBoardReader(); + + void SetDebugLevel( int level) { DebugLevel = level; cout << "GIGBoardReader " << BoardNumber << " debug updated to " << DebugLevel << endl;} + //void AddFileList(const char *prefixFileName, int firstIndex, int endIndex, const char *suffixFileName); + bool AddFile(char *fileName); + void ReadLine(); + bool HasData(); + void SkipNextEvent(); + int GetBoardNumber() { return BoardNumber; } + int GetNSensors() { return NSensors; } + GIGEvent* GetEvent() { return CurrentEvent; } + int GetEventNumber() { return EventsCount;} + char* GetInputFileName() { return InputFileName;} + char* GetSuffixFileName() { return SuffixFileName;} + char* GetPrefixFileName() { return PrefixFileName;} + void Close(); + void PrintStatistics(ostream &stream=cout); + + ClassDef(GIGBoardReader,1); +}; + +# endif diff --git a/include/IMGBoardReader.h b/include/IMGBoardReader.h new file mode 100644 index 0000000..1c8b8f4 --- /dev/null +++ b/include/IMGBoardReader.h @@ -0,0 +1,222 @@ +#ifndef _IMGBoardReader_included_ +#define _IMGBoardReader_included_ + +//#define STANDALONE + +#include "Riostream.h" +#include "TObject.h" +#include "TMath.h" +//#include +#include +#include +#include +#ifndef STANDALONE + #include "DGlobalTools.h" // to have fTool has a data member + #include "img_daq_lib/event_header.typ" +#else + #include "event_header.typ" +#endif + +using namespace std; + + +// -------------------------------------------------------------------------------------- + +class IMGPixel : public TObject { + + // Container for a simple pixel + // only 3 values + // JB, 2008/09/27 + // Modified: JB, 2013/06/19 include timestamp + +private: + + int Input; + int Value; + int Index; + int TimeStamp; + +public: + + IMGPixel() { Input = 0; Value = 0; Index = 0; TimeStamp = 0; } + IMGPixel( int input, int value, int index) { Input = input; Value = value; Index = index; TimeStamp = 0; } + IMGPixel( int input, int value, int index, int time) { Input = input; Value = value; Index = index; TimeStamp = time; } + virtual ~IMGPixel() {;} + int GetInput() { return Input; } + int GetValue() { return Value; } + int GetIndex() { return Index; } + int GetTimeStamp() { return TimeStamp; } + + ClassDef(IMGPixel,1) +}; + +// -------------------------------------------------------------------------------------- + +class IMGEvent : public TObject { + + private: + + int EventNumber; + int BoardNumber; + std::vector *ListOfPixels; + std::vector *ListOfTriggers; + std::vector *ListOfTimestamps; + std::vector *ListOfFrames; + int *RawDataArray; + + public: + + IMGEvent() {;} + IMGEvent( int currentEventNumber, int boardNumber, vector *ListOfTriggers, vector *ListOfTimestamps, vector *ListOfFrames, vector *ListOfPixels); + ~IMGEvent(); + + int GetEventNumber() { return EventNumber; } + int GetBoardNumber() { return BoardNumber; } + int GetNumberOfPixels() { return ListOfPixels->size(); } + std::vector *GetPixels() { return ListOfPixels;} + IMGPixel *GetPixelAt( int index) { return &(ListOfPixels->at(index)); } + int GetNumberOfTriggers() { return ListOfTriggers->size(); } + int GetNumberOfTimestamps() { return ListOfTimestamps->size(); }//RDM150509 + std::vector *GetTriggers() { return ListOfTriggers;} + std::vector *GetTimestamps() { return ListOfTimestamps;} //RDM150509 + int GetTriggerAt( int index) { return ListOfTriggers->at(index);} + int GetTimestampAt( int index) { return ListOfTimestamps->at(index);}//RDM150509 + int GetNumberOfFrames() { return ListOfFrames->size(); } + std::vector *GetFrames() { return ListOfFrames;} //JB 2010/06/16 + int GetFrameAt( int index) { return ListOfFrames->at(index);} + int *GetRawDataArray() { return RawDataArray;} + //int *GetRawDataArray( int anInput); + + ClassDef(IMGEvent,1) +}; + +// -------------------------------------------------------------------------------------- + +class IMGBoardReader : public TObject { + + private: + + int DebugLevel; +#ifndef STANDALONE + DGlobalTools fTool; +#endif + + int BoardNumber; + int NbOfInputs; // nb of inputs in this acquisition board + int SizeOfHeader; + int SizeOfTrailer; + + bool ReadingEvent; + Int_t TriggerMode; + IMGEvent *CurrentEvent; + int CurrentEventNumber; + int CurrentTriggerNumber; + int CurrentFrameNumber; + int CurrentTimestamp; + int TriggerLine; + std::vector ListOfTriggers; + std::vector ListOfTimestamps; + int maxNumberOfTriggersPerEvent; + std::vector ListOfFrames; + std::vector ListOfPixels; + + // management of input files + ifstream RawFileStream; + char *InputFileName; + char** ListOfInputFileNames; + char* PrefixFileName; + char* SuffixFileName; + int CurrentFileNumber; + int NumberOfFiles; + int BuffersRead; + bool NoMoreFile; + int EventsInFile; // JB 2012/08/18 + + // management of data buffer + size_t SizeOfEvent; // nb of bytes in an event + char *Data; + int Endianness; // 0= do not swap bytes, 1= swap bytes + + int EventTrailer; + TEventHeader *EventHeader; + + // Parameteres to decode each input + int ifStripTelescope; // indicate if strip-telescope data + int ifMultiFrame; // indicate more than 2 frames per value + int ifSplitFrames; // when all pixel frame1 values come before all frame2 values + int if16outputs; // when 16 parallel outputs are used (PXI NI6562 board) + int ifBlocReading; // indicate that data are organized + int *NbOfChannels; // nb of channels in one input + int *NumberOfBitsValue; // nb of bits encoding one value, may be several channels + int *SignificantBits; // nb of bits encoding one channel + bool *SignedValues; + int *InputDataAdress; + unsigned int *MaxSignedValue; + size_t *SizeOfInputData; // total nb of bytes for an input + size_t *SizeOfValue; // nb of bytes for one value for an input + int *NChannelsPerValue; + int *NValuesToRead; + bool *WithCDS; // if 2 values are encoded in one channel for CDS + int *NValuesPerChannel; // >1 if ifMultiFrame + int *NValuesToJumpPerChannel; // if ifMultiFrame + int *FirstExcludedChannel; // exclude some channels from analysis + int *LastExcludedChannel; // JB 2013/06/22 + + // Parameters to decode trigger info embedded in pixel data + double triggerLowThreshold; // JB 2013/06/19 + double triggerHighThreshold; + int *FirstTriggerChannel; + int *LastTriggerChannel; + std::vector ListOfTriggersFromData; + + // For statistics + int EventsCount; + int FramesRead; + + + bool CloseRawFile(); + bool OpenRawFile(const char *fileName); + bool LookUpRawFile(); + bool GetNextBuffer(); + bool SetBufferPointers(); + void GetInputData( int mode=0); + void GetTriggerData(); + int DecodeTriggerFromData( int input, int rowNumber, unsigned int *rawdatas, int nFrames); // 2013/06/19 + unsigned int BuildValue( int anAddress, int wordSize ); + void AddPixel( int input, unsigned int rawdata, int index); + void AddPixel( int input, unsigned int *rawdatas, int nFrames, int index); // JB 2013/06/19 + + int NumberOfColumns; //AP, 2016/08/22 + int IfZeroSupress; // JB 2017/11/20 + int ZeroThreshold; // JB 2017/11/20 + + public: + + IMGBoardReader() {;} + IMGBoardReader( int boardNumber, int nInputs, int *nChannels, int sizeOfEvent, int eventsInFile, int headerSize, int trailerSize, int *numberOfBits, int *sigBits, int endian=0, int triggermode=0, int daqmode=0, int Ncolumns=64, int Nframes=5); + ~IMGBoardReader(); + void SetDebugLevel( int level) { DebugLevel = level; cout << "IMGBoardReader " << BoardNumber << " debug updated to " << DebugLevel << endl;} + void SetEndiannes( int endian) { Endianness = endian; } + bool AddFile(char *inputFileName); + bool AddFileList(const char *prefixFileName, int startIndex, int endIndex,const char *suffixFileName); + bool HasData(); + void SkipNextEvent(); + int GetBoardNumber() { return BoardNumber; } + IMGEvent* GetEvent() { return CurrentEvent; } + int GetEventNumber() { return CurrentEventNumber;} + char* GetInputFileName() { return InputFileName;} + char* GetSuffixFileName() { return SuffixFileName;} + char* GetPrefixFileName() { return PrefixFileName;} + void PrintEventHeader(); + void PrintStatistics(ostream &stream=cout); + void DumpEventHeaders( int nFrames); + + int GetNumberOfColumns() { return NumberOfColumns; } //AP, 2016/08/22 + void SetNumberOfColumns(int ColumnNum) { NumberOfColumns = ColumnNum; return;} //AP, 2016/08/22 + void SetZeroSuppression(int aThreshold); // JB 2017/11/20 + int GetZeroSuppression() { return ZeroThreshold; } // JB 2017/11/20 + + ClassDef(IMGBoardReader,1); +}; + +# endif diff --git a/include/MAlign.h b/include/MAlign.h new file mode 100644 index 0000000..a6ff717 --- /dev/null +++ b/include/MAlign.h @@ -0,0 +1,207 @@ +// @(#)MAlign.h $:$Id: MAlign.h v.1 2005/10/02 18:03:46 sha Exp $ +// Author: A. Shabetai + +#ifndef _MimosaAlignAnalysis_included_ +#define _MimosaAlignAnalysis_included_ + + + ///////////////////////////////////////////////////////////// + // // + // Mimosa chip and ref. system alignement class // + // // + // // + //////////////////////////////////////////////////////////// + +#include "Riostream.h" + +//align Mimosa +#include "TMinuit.h" +#include "TPostScript.h" +#include "DPrecAlign.h" +#include "TH1F.h" +#include "TCanvas.h" +#include "TF2.h" +#include "TGraph.h" +#include "TSystem.h" +#include "TLegend.h" + +//align tracker +#include "DTrack.h" +#include "DTracker.h" +#include "TTree.h" +#include "DPlane.h" +#include "DSession.h" +#include "TPaveLabel.h" +#include "TText.h" +#include "DAlign.h" +#include "DSetup.h" + +#include "TStyle.h" +#include "TVectorD.h" +#include "MAlignment.h" +#include +#include "DMiniVector.h" + +using namespace std; + +void FCNAlignMimosa(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); +void FCNAlignMimosaLadder(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); +void FCNAlignMimosaLadder2(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); +//void FCNAlignMimosaMV(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); + +class TFile; + +class MimosaAlignAnalysis : public TObject { + private: + + Int_t AlignDebug; + DSession* fSession; // JB 2011/07/21 to get rid of global var + DPrecAlign* fAlignement; + DPrecAlign* fGeom; + Double_t fLimitsX[2]; // min-max in X for tracks, JB 2013/06/10 + Double_t fLimitsY[2]; // min-max in Y for tracks, JB 2013/06/10 + Double_t fChi2Limit; // JB 2013/07/14 + + TCanvas* fCnv ; + TCanvas* fCcr ; + TCanvas* fCanvasChiSquare; + + TH1F* fDu ; + TH1F* fDv ; + TH1F* fDw; + TH1F* fDdu ; + TH1F* fDdv ; + TH1F* fDdw; + + TH1F* fDx; // qyliu: ladder + TH1F* fDy; + TH1F* fDz; + + TH1F* fChiSquareX; + TH1F* fChiSquareY; + TH1F* fChiSquareZ; + TH1F* fChiSquareTiltX; + TH1F* fChiSquareTiltY; + + TGraph fGraph[9]; //qyliu: changed from [6] for ladder + TF1* fMyfit; + MAlignment* fAlignment; + DPrecAlign* fAlignement0; + //DPrecAlign** myPrecAlignments; + std::vector fLadders; + DLadder* ladderToAlign; + DLadder* ladder0; + Int_t aChi2Limit; + ofstream file; + ofstream trackIndexFile; + + // Minimization tool : + Bool_t printResiduals; + TString algoName; + TString minimizerName; + Int_t printLevel; + + TGraph** alignParametersIterations; + TCanvas** alignParamsCanvas; + + static MimosaAlignAnalysis* fgInstance; + + + public: + + MimosaAlignAnalysis( DSession *aSession); + virtual ~MimosaAlignAnalysis(); + void SetDebug(Int_t aDebug) { AlignDebug = aDebug; cout << "MAlign debug updated to " << AlignDebug << endl; +} // JB 2011/06/18 + + void fcn(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); + void fcnLadder(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); + void fcnLadder2(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); + + //void fcnMiniVectors(Int_t &n, Double_t *gin, Double_t &f, Double_t *par , Int_t iflag); // LC 2014/12/23 + void SetTrackGeoLimits(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax); // JB 2013/06/10 + Bool_t CheckTrackInGeoLimits( DTrack *aTrack); // JB 2013/06/11 + + void SetTrackChi2Limit( Double_t aChi2Limit); // JB 2013/07/14 + + //DPrecAlign* AlignMimosa(TVectorD aGetParamVect, TFile* aCorfile, int save_result, const char* MimosaResultDir); + DPrecAlign* AlignMimosa(DPrecAlign* initAlignment, TFile* aCorFile, const char* MimosaResultDir, Double_t aDistance); // new parameter, JB 2012/05/11 + DPrecAlign* AlignPrecMimosa(DPrecAlign* initAlignment, Bool_t modeAuto, Double_t aDistance=150.); // LC 2012/09/06. + //DPrecAlign* AlignMimosaMV( Bool_t modeAuto ); // LC 2013/09/05. + //DPrecAlign* AlignMimosaMV(DLadder* myLadderToAlign, DPrecAlign* initAlignment, DPrecAlign* fAlignmentLadder0, Bool_t modeAuto, Int_t chi2Limit); + + void FitInterface( Bool_t modeAuto, const Double_t& aDistance, const Double_t& aSlopeMax); + void MakeFit(TString minimizerName, TString algoName, Int_t maxCall, Int_t maxIter, Double_t tolerance, Int_t printLevel, Int_t strategy); + void DrawResiduals(); + Double_t ComputeTotalChiSquareMV(const Double_t* par); + Int_t PrintMinimizationChoice(); + std::string PrintMenu(); + std::string ShowAndSetParameters(); + Int_t SetPrintLevel(); + + DPrecAlign* AlignPrecMimosaLadder(DLadder* myLadder, Bool_t modeAuto, Double_t aDistance=150.); + DPrecAlign* AlignPrecMimosaLadder2(DLadder* myLadder, Bool_t modeAuto, Double_t aDistance=150.); + + //std::vector& AlignMimosaAssociationMV(DLadder* myLadderToAlign, DPrecAlign* initAlignment, DPrecAlign* fAlignmentLadder0, Bool_t modeAuto, Int_t chi2Limit); // LC 2014/02/11 + + //void cutData(Int_t nSigmas, Double_t* par); // LC 2014/02/10 + void AlignTracker(const Double_t tiniBoundU, + const Double_t tiniBoundV, + Int_t nAlignEvents=4000, + Int_t nAdditionalEvents=2000, + bool UseAllHits = false); // U,V bounds added, JB 2013/06/10, # events added by JB, 2007 June + // AP 2015/06/10: added bool parameter (UseAllHits) to decide if doing alignment with all hits or the closest one. + void AlignTracker(const Double_t tiniBound=1000., Int_t nAlignEvents=4000, Int_t nAdditionalEvents=2000, bool UseAllHits = false) { AlignTracker( tiniBound, tiniBound, nAlignEvents, nAdditionalEvents, UseAllHits); } + void AlignTrackerMinuit(Bool_t modeAuto=1, + const Double_t tiniBound=480., + Int_t nAlignEvents=5000, + Int_t nAlignHitsInPlane=800, + Int_t nAdditionalEvents=2000, + Double_t chi2Limit=0, + bool UseAllHits = true); // LC 2012/09/06 // LC 2012/10/08 chiLimit to select track with good chi2. + // AP 2015/06/08 : Added bool parameter (UseAllHits) to decide if doing alignment with all hits or with closest one. + void AlignTrackerMinuitLadder(Bool_t modeAuto =1, const Double_t tiniBound=480., Int_t nAlignEvents=5000, Int_t nAlignHitsInPlane=4000, Int_t nAdditionalEvents=2000, Double_t chi2Limit=0); // LC 2013/01/16. + //void AlignLadder(Bool_t modeAuto=1, const Double_t tiniBound=480., Int_t nAlignEvents=5000, Int_t nAlignHitsInPlane=4000, Int_t nAdditionalEvents=2000, Int_t ladderFace=1, Double_t chi2Limit=0.); // OUTDATED, LC: 2014/12/18 + void AlignLadderMV(Bool_t modeAuto=1, const Double_t tiniBound=480., const Double_t boundSlopes=100., Int_t nAlignEvents=5000, Int_t nGoodTracks=1000, Int_t nAdditionalEvents=2000, Int_t chi2Limit=40, Int_t mode=0); // LC 2013/09/30. + void AlignTrackerGlobal(const Int_t refPlane=1, const Int_t nEvents=4000, const Int_t nIterations=10, const Bool_t alignConstrainsts=true, const Bool_t trackConstrainsts=true, const Bool_t multipleScatteringFit=true); // LC & LiuQ 2015/02/06 + void AlignTrackerMillepede(Int_t nAlignEvents); // LC 24/12/2012. + void UpdateConfAlignUVW(fstream &fileIn, fstream &fileOut, DPlane* SecPlane); + void UpdateConfAlign2D(Int_t nSecPlanes, DPlane** SecPlane); + void Gener(Double_t* xp, Double_t* yp, Double_t& aX, Double_t& bX, Double_t& aY, Double_t& bY, Double_t* sigX, Double_t* disX, Double_t* sigY, Double_t* disY, Double_t* z, Double_t* phi); + void AssociateMiniVectors( Double_t boundDistance, Double_t boundSlopes, Int_t mode); // LC 2014/12/20. + void SplitString(const string& s, char c, vector& v); + + void FillMiniVectorsResiduals( std::vector MV0, std::vector MV1 ); // LC 2015/06/04 + void FillMiniVectorsResidualsMC( std::vector MV0, std::vector MV1 ); // LC 2015/06/04 + void StudyDeformation(const Float_t tiniBound=1000, Int_t nEvents=2000, Bool_t fitMode=0, Float_t minU=0., Float_t maxU=0., Float_t minV=0., Float_t maxV=0.);// Method to study shape of a plane with possibility of fitting the shape with a Legendre polynomials : BB 2014/05/20, updated JB 2015/10/31 + + + // Convert string to type T :: usage StringToNumber ( String ); + template + T StringToNumber ( const string &Text ) + { + istringstream ss(Text); + T result; + return ss >> result ? result : 0; + } + + static MimosaAlignAnalysis*& Instance( DSession *aSession) { + // Modified: JB 2011/07/21 to pass session pointer + if (!fgInstance) + { + cout << "MimosaAlignAnalysis::Instance: No current Mimosa Alignement session detected! Creating a new one..." << endl; + fgInstance = new MimosaAlignAnalysis( aSession); ; + } + return fgInstance; + } + + static MimosaAlignAnalysis*& Instance() { + // Modified: JB 2011/07/21 to pass session pointer + return fgInstance; + } + + ClassDef(MimosaAlignAnalysis,1) + +}; + +#endif diff --git a/include/MAlignment.h b/include/MAlignment.h new file mode 100755 index 0000000..62940a9 --- /dev/null +++ b/include/MAlignment.h @@ -0,0 +1,106 @@ +#ifndef _MAlignment_included_ +#define _MAlignment_included_ + +#include + +/** + MAlignment class for alignment of CMOS planes + 4 local parameters and 3 global parameters for maximum of 10 planes + + Alignment class which interface to AliMillepede. + for each track ProcessTrack calculates the local and global derivatives + at each cluster and fill the corresponding local equations. Provide methods + for fixing or constraining detection planes for best results. + + \author Bruce Becker, Javier Castillo & Ch. Finck (transcription) + */ + +class MMillepede; +class DTrack; +class DHit; +class DLine; + +class MAlignment:public TObject +{ + +public: + MAlignment(); + virtual ~MAlignment(); + + void ProcessTrack(DTrack *track, Double_t* param = 0x0); + + void AllowVariations(Bool_t *bPlaneOnOff); + void SetNonLinear(Bool_t *bPlaneOnOff, Bool_t *bVarXYT); + + void FixPlane(Int_t iPlane); + void FixParameter(Int_t param, Double_t value); + void SetNonLinear(Int_t param); + void AddConstraint(Double_t *factor, Double_t value ); + void InitGlobalParameters(Double_t *par); + void Init(Int_t nGlobal, Int_t nLocal, Int_t nStdDev, Int_t nPlanes); + void SetIterations(Int_t iter); + + //! Set array of local derivatives + void SetLocalDerivative(Int_t index, Double_t value) { + fLocalDerivatives[index] = value; + } + + //! Set array of global derivatives + void SetGlobalDerivative(Int_t index, Double_t value) { + fGlobalDerivatives[index] = value; + } + + void LocalFit(Int_t iTrack, Double_t *lTrackParam, Int_t lSingleFit); + void GlobalFit(Double_t *parameters,Double_t *errors,Double_t *pulls); + void PrintGlobalParameters(); + Double_t GetParError(Int_t iPar); + + Int_t GetNParPlane() const {return fNParPlane;} + +private: + /// Not implemented + MAlignment(const MAlignment& right); + /// Not implemented + MAlignment& operator = (const MAlignment& right); + + void ResetLocalEquation(); + void LocalEquationX(Double_t* param = 0x0); + void LocalEquationY(Double_t* param = 0x0); + +private: + + Bool_t fDoF[3]; // Flags degrees of freedom to align (x,y,phi) + Double_t fAllowVar[3]; // "Encouraged" variation for degrees of freedom + Double_t fStartFac; // Initial value for chi2 cut + // if > 1 Iterations in AliMillepede are turned on + Double_t fResCutInitial; // Cut on residual for first iteration + Double_t fResCut; // Cut on residual for other iterations + + MMillepede *fMillepede; // Detector independent alignment class + + DTrack *fTrack; // AliMUONTrack + DLine *fTrackParam; // AliMUONVHit + DHit *fHit; // AliMUONVHit + + Int_t fNGlobal; // Number of global parameters + Int_t fNLocal; // Number of local parameters + Int_t fNStdDev; // Number of standard deviations for chi2 cut + Int_t fNParPlane; // Number of degrees of freedom per chamber + Int_t fNPlanes; // Total number of detection elements + + Double_t fMeas[2]; // Current measurement (depend on B field On/Off) + Double_t fSigma[2]; // Estimated resolution on measurement + + Double_t fGlobalDerivatives[30]; // Array of global derivatives + Double_t fLocalDerivatives[4]; // Array of local derivatives + + + Double_t fPhi; // Azimuthal tilt of detection element + Double_t fCosPhi; // Cosine of fPhi + Double_t fSinPhi; // Sine of fPhi + Int_t fDebugLevel; // debug level + + ClassDef(MAlignment, 0) //Class for alignment of muon spectrometer +}; + +#endif diff --git a/include/MAnalysis.h b/include/MAnalysis.h new file mode 100644 index 0000000..a5419fe --- /dev/null +++ b/include/MAnalysis.h @@ -0,0 +1,890 @@ +// @(#)maf/maf:$Name: $:$Id: MAnalysis.h v.1 2005/10/02 18:03:46 sha Exp $ +// Author: A. Shabetai + +#ifndef _MimosaAnalysis_included_ +#define _MimosaAnalysis_included_ + +// Choose your environment +//#define LINUX +#define MAC +//#define WINDOWS + + ///////////////////////////////////////////////////////////// + // // + // TAF - Main header file // + // Defines all user accessible analysis methods // + // // + //////////////////////////////////////////////////////////// + + + +#include "Riostream.h" +#include "TControlBar.h" +#include "TSystem.h" +#include "TFile.h" +#include "TTree.h" +#include "TBranch.h" +#include "DEvent.h" +#include "DPrecAlign.h" +#include "DSession.h" +#include "TPaveLabel.h" +#include "TProfile.h" +#include "TStyle.h" +#include "TROOT.h" +#include "TF1.h" +#include "TStopwatch.h" +#include "TVectorD.h" +#include "TVector3.h" +#include "TGraph.h" +#include "TGraph2D.h" + +#include "TError.h" +#include "TEnv.h" +#include "TInterpreter.h" + +#include "DGlobalTools.h" // to have fTool has a data member + +// pre +#include "DLadder.h" // JB 2014/02/10 +#ifdef UseROOFIT +#include "DXRay2DPdf.h" // AP 2014/12/08 +#endif +#include "DTracker.h" +#include "DPlane.h" +#include "DAlign.h" +#include "DHit.h" +#include "DR3.h" + + +// post +#include "TPad.h" +#include "TFrame.h" +#include "TText.h" +#include "TPaveStats.h" +#include "TPaveText.h" +#include "TPave.h" +#include "TLatex.h" +#include "TLegend.h" + +//Results store +#include "TNtuple.h" + +// align Mimosa +#include "MAlign.h" +#include "MHist.h" + +// MRaw/x +#include "MRaw.h" +#include "MRax.h" + +//---ADC +#include "DSetup.h" +//---ADC + +class MRaw; +class MRax; + +//---ADC +class DSetup; // forwards +//---ADC + +class DR3; + +class MimosaAnalysis : public MHist { + + //==================== + private: + //==================== + static MimosaAnalysis* fgInstance; // global pointer to the TAF object +#ifdef MAC + MimosaAnalysis *gTAF;// for MAC +#endif + + // ------------------------ + // Files and directories + // ------------------------ + TFile *fileInputTree; + ofstream outFileGoodEvt; //! + ofstream outFileBadEvt; //! + ofstream csvfile; //! + TFile* theCorFile; //! + TString DTDIR; // set from the environment variable DTDIR = TAF installation directory + TString fLaunchedDirectory; // directory where taf has been launched // VR 2014/06/30 + TString fWorkingDirectory; // directory where taf will work, choose in MimosaAnalysis::MimosaAnalysis() // VR 2014/06/30 + //TString ROOTDIR; // removed by JB 2011/04/12 + TString ResultDirName; // JB 2011/04/12 + DGlobalTools fTool; // JB 2011/07/18 + char RootFile[300]; //name of the input DSF file + + // ------------------------ + // Input tree + // ------------------------ + // JB 2010/08/30 + TTree *t; + DEvent *Evt; + TBranch *branch; + + // ------------------------ + // Parameters for sensor, alignment, geometry, analysis + // ------------------------ + + DSession *fSession; // JB 2011/07/21 to get rid of global var tSession + Double_t trU, trV, trW; // alignment + Double_t theta[3]; + DPrecAlign *alignement; + + Float_t calibration; + Float_t NoiseScope; + + Int_t MimosaType; + Int_t RunNumber ; + Int_t ThePlaneNumber; + Int_t ThePlaneNumber2; // JB 2011/10/30 + Int_t TheLadderNumber; // JB 2014/01/10 + Int_t Nevt ,User_MaxEvt; + + Int_t ThesubmatrixNumber; + Int_t ThesubmatrixNumber2; // JB 2015/12/15 + + Float_t MimosaSizeU, MimosaSizeV; + Float_t PixelSize; + Float_t PixelSizeU; + Float_t PixelSizeV; + Int_t Matrixtype; + Int_t NofPixelInColumn; + Int_t NofPixelInRaw ; + Int_t NofPixels ; + Float_t FirstPixelShiftU ,FirstPixelShiftV; + Int_t Thegeomatrix; + Int_t Thegeomatrix2; // JB 2015/12/15 + // Float_t geomUmin, geomUmax; + // Float_t geomVmin, geomVmax; + Float_t geomUmin2, geomUmax2; + Float_t geomVmin2, geomVmax2; + Float_t exgeomUmin, exgeomUmax; // JB 2013/06/22 + Float_t exgeomVmin, exgeomVmax; + + Int_t UserFlag; // parameter transmitted through config file, free for user, JB 2013/07/17 + + // ------------------------ + // flags + // ------------------------ + Int_t UsedMacro[50]; // to be modified + Int_t MimoDebug; + Int_t fWriteHistos; + Int_t fUserFileNumber; + Bool_t fInitDone; + Bool_t fMimosaDone; // for general purpose histo JB 2010/09/10 + Bool_t fMimosaProDone; + Bool_t fMimosaFakerateDone; // JB 2010/07/26 + Bool_t fMimosaCalibrationDone; // JB 2010/07/27 + Bool_t fMimosaMiniVectorsDone; // JB 2010/08/30 + Bool_t fMimosaPro2PlanesDone; // JB 2013/05/01 + Bool_t fMimosaImagingDone; // JH 2014/06/16 + Bool_t fClearDone; + // The following flags indicate the purpose of the analysis + // JB 2014/01/11 + Bool_t fIfReferenceTrack; + Bool_t fIfCalibration; + Bool_t fIfImaging; + Bool_t fIfLaserSpot; + Bool_t fIfMiniVector; + Bool_t fIfVertex; + Bool_t fIfFake; + Bool_t fIfBinary; // for binary output sensor, JB 2014/03/15 + Bool_t fIfMCGeneration; //for MC generation, AP 2015/04/02 + + // ------------------------ + // Hot pixel map + // ------------------------ + Int_t TheUsePixelMap; // use pixel map or not + Int_t Option_read_Pixel_map; // Hot hit map read=1/write=0 option + TH2F *h2HotPixelMap; // pointer to the histogram containing pixel hit rate + Char_t HotPixelFileName[40]; + TFile *HotPixelFile; // pointer to file containing the previous histogram + + // ------------------------ + // cuts + // ------------------------ + Float_t TrackChi2Limit; + Int_t MinHitsPerTrack; // JB 2013/06/22 + Int_t MaxNbOfTracksInGeom; // JB 2012/08/30 + Int_t GeoMatrixForTrackCut; // JB 2012/08/30 + Int_t CUT_MaxNbOfHits; + Int_t CUT_MinNbOfHits; + Float_t TrackToHitDistanceLimit; + Float_t TrackToHitDistanceLimit2; // JB 2015/12/15 + Float_t CUT_S2N_seed; + Float_t CUT_S2N_neighbour ; + Float_t CUT_Q_seed; // JB 2013/11/08 + Float_t CUT_Q_cluster; // JB 2014/01/21 + Float_t CUT_MinQ_neighbour; // JB 2010/07/27 + Float_t CUT_MaxQ_neighbour; // JB 2013/11/08 + Double_t CUT_MaxHitRatePerPixel; + Double_t CUT_MinHitRatePerPixel; + Int_t CUT_MinSeedIndex; // JB 2013/08/21 + Int_t CUT_MaxSeedIndex; // JB 2013/08/21 + Int_t CUT_MinSeedCol; // JB 2013/08/22 + Int_t CUT_MaxSeedCol; // JB 2013/08/22 + Int_t CUT_MinSeedRow; // JB 2013/08/22 + Int_t CUT_MaxSeedRow; // JB 2013/08/22 + + // ------------------------ + // counters & efficiency + // JB 2011/11/04 + // ------------------------ + Double_t MimosaEfficiency; + Double_t MimosaEfficiency_ERR; + + Int_t NofClMatchTrack; // # good tracks in the DUT WITH a matched hit + Int_t NtrkInMimo; // Number of tracks in the MIMOSA aperture + + Int_t NeventRangeForEfficiency; //binning for the efficiency during the run + Int_t temp_maxarray; + Int_t ievt_array; // counter of bunches + Float_t *temp_Efficiency_array; + Float_t *temp_NofClMatchTrack; + Float_t *temp_NtrkInMimo; + + // ------------------------ + // + // ------------------------ + + Float_t* ResolutionPoint; // better in MHIst ?? + + + // ------------------------ + // pixel data inside cluster, JB 2010/06/03 + // ------------------------ + Int_t NofPixelsInCluster; + Float_t* qonly; + Float_t* snonly; + Float_t* noise; + Float_t* UofPix; + Float_t* VofPix; + Int_t *LineInCluster; + Int_t *ColumnInCluster; + Int_t* IndexofPix; + Int_t* IndexInCluster; + Int_t LineSizeOfCluster; // JB 2014/03/31 + Int_t ColumnSizeOfCluster; + + typedef enum { + one_pix = 1, + two_pix_row, + two_pix_col, + three_pix_L, + three_pix_row, + three_pix_col, + four_pix_square, + four_pix_L_row, + four_pix_L_col, + four_others, + more_than_four, + five_pix_squarerow, + five_pix_squarecol, + five_others, + six_pix_3col2row, + six_pix_2col3row, + six_others, + more_than_six + } clusterTypeDef; + clusterTypeDef ClusterGeometricalType; + clusterTypeDef ClusterGeometricalTypeBeyond4; + + Int_t IndexOfMaxPixel; // index of the pixel with the highest charge (in qonly array) + + Float_t snOptimal; // Largest S/N obtained by summing q ordered pixel + Int_t optimalSize; // number of pixels in the largest S/N + + Float_t MinUofPix; // position of lower left pixel + Float_t MinVofPix; + + Float_t TotalCharge; // all the pixels in the cluster + Float_t ChargeAroundSeed; // all the pixels except the seed + Float_t ChargeInCross; // the 4 pixels direct neighbours of the seed + Float_t ChargeInX; // the 4 pixels in the corner of the seed + Float_t ChargeInCrown1; // the 16 pixels after the first neighbours of the seed + Float_t ChargeInCrown2; // the 24 pixels next to next neighbours of the seed + + Float_t TotalCharge2x2; // Cluster charge limited to 2x2 sub-cluster + Float_t ExternalCharge2x2; // 2x2 cluster charge without the seed (Qof3x3[0]) + Float_t Qof2x2[4]; + Float_t UofPix2x2[4]; + Float_t VofPix2x2[4]; + Int_t IndexU2x2[4]; + Int_t IndexV2x2[4]; + Short_t IndexOfCluster2x2; + + Float_t TotalCharge3x3; // Cluster charge limited to 3x3 sub-cluster + Float_t Qof3x3[9]; + Float_t UofPix3x3[9]; + Float_t VofPix3x3[9]; + Int_t IndexofPix3x3[9]; + + Float_t TotalCharge5x5; // Cluster charge limited to 5x5 sub-cluster + Float_t Qof5x5[25]; + Float_t UofPix5x5[25]; + Float_t VofPix5x5[25]; + Int_t IndexofPix5x5[25]; + + Float_t* qqordered; // charge ordered pixels + Float_t* nqordered; + Float_t* snqordered; + Int_t* IndexofPixqordered; + Float_t* UofPixqordered; + Float_t* VofPixqordered; + Int_t *LineInClusterqordered; + Int_t *ColumnInClusterqordered; + + Float_t* q; // cumulated q,n,sn with charge ordered pixels + Float_t* n; + Float_t* sn; + + Float_t* qsnordered; // sn ordered pixels + Float_t* nsnordered; + Float_t* snsnordered; + Int_t* IndexofPixsnordered; + Float_t* UofPixsnordered; + Float_t* VofPixsnordered; + Int_t *LineInClustersnordered; + Int_t *ColumnInClustersnordered; + + Float_t* qsumsn; // cumulated q,n,sn with s/n ordered pixels + Float_t* nsumsn; + Float_t* snsumsn; + + Float_t* qspiral; // geometry ordered pixels + Float_t* nspiral; + Float_t* snspiral; + Int_t* IndexofPixspiral; + Float_t* UofPixspiral; + Float_t* VofPixspiral; + Int_t *LineInClusterspiral; + Int_t *ColumnInClusterspiral; + + Float_t* qsumspiral; // cumulated q,n,sn with s/n ordered pixels + Float_t* nsumspiral; + Float_t* snsumspiral; + + // ------------------------ + // Track information, JB 2010/06/03 + // ------------------------ + Float_t TrackToHitDistance; + Float_t TrackToHit2ndDistance; + Float_t chi2; + Float_t tu; // track position in plane + Float_t tv; + Float_t tw; + Float_t tdu; // track slope in plane coord. + Float_t tdv; + Float_t tk1; // index of nearest strip to seed + Float_t tx; // track position in telescope + Float_t ty; + Float_t tz; + Float_t tdx; // track slope in tracker coord. + Float_t tdy; + + // ------------------------ + // MiniVector information, JB 2010/08/30 + // ------------------------ + DR3 trackPosUVW[2]; + DR3 trackPosXYZ[2]; + DR3 trackMeanPosXYZ; + Double_t trackAngleXZ; + Double_t trackAngleYZ; + + DR3 hitPosUVW[2]; + DR3 hitPosXYZ[2]; + + DR3 vectorPosXYZ; + Double_t vectorSlopeXZ; + Double_t vectorSlopeYZ; + Double_t vectorAngleXZ; + Double_t vectorAngleYZ; + + // ------------------------ + // cluster positions + // ------------------------ + Int_t hitCounterPos; // JB 2014/01/10 + + Float_t hX, hY, hZ; // position in tracker frame, JB 2010/08/30 + Float_t hU; // position in plane frame + Float_t hV; + Float_t hW; + Float_t hUdigital; // seed or digital position + Float_t hVdigital; + Float_t UCG2x2; // CoG 2x2 ?? + Float_t VCG2x2; + Float_t UofHitCG3; // CoG using only 3x3 pixels + Float_t VofHitCG3; + Float_t UofHitCG5; // CoG using only 5x5 pixels + Float_t VofHitCG5; + Float_t UofHitCG; // CoG using all pixels + Float_t VofHitCG; + Float_t UCGcorr; // CoG corrected by correlation plot + Float_t VCGcorr; + Float_t UofHitEta3; // Eta algo. + Float_t VofHitEta3; + Float_t Eta2x2U; + Float_t Eta2x2V; + Float_t UofHitEta2x2; + Float_t VofHitEta2x2; + Float_t UofHitEta2x2_new; + Float_t VofHitEta2x2_new; + Float_t UofHitEta5x5_new; + Float_t VofHitEta5x5_new; + Float_t UofHitEta2x2_newR; + Float_t VofHitEta2x2_newR; + Float_t UofHitEta5x5_newR; + Float_t VofHitEta5x5_newR; + Double_t Uaht; + Double_t Vaht; + + + // ------------------------ + // used in getmieta and create new eta + // ------------------------ + Int_t NBins2x2; + Float_t* Edges2x2; //! + Float_t* Contents2x2U; //! + Float_t* Contents2x2V; //! + Float_t* Edges3x3; //! + Int_t NBins3x3; + Float_t* Contents3x3U; //! + Float_t* Contents3x3V; //! + static const Int_t PolDeg = 7; + Float_t FitParEta3U[PolDeg]; + Float_t FitParEta3V[PolDeg]; + Float_t FitParamU[PolDeg]; + Float_t FitParamV[PolDeg]; + + + // ------------------------ + // For cluster shape studies, cdritsa & JB 2010/04/13 + // ------------------------ + Int_t hitCounter; + + Int_t nThresholds; // <10 + Float_t thresholds[10]; + Float_t snrThresholds[10]; + Int_t clusterMultiplicity[10]; + Int_t clusterMultiplicityCounter[10]; + Float_t multV[10]; + Float_t multU[10]; + Float_t mult[10]; + Float_t formFactor[10]; + + Double_t ChargeTimesPositionU[50]; + Double_t ChargeTimesPositionV[50]; + Double_t ChargeTimesPositionUmean[50]; + Double_t ChargeTimesPositionVmean[50]; + + Double_t ChargeInCluster[50]; + Double_t sumChargeTimesPositionU[50]; + Double_t sumChargeTimesPositionV[50]; + Double_t sumChargeTimesPositionUmean[50]; + Double_t sumChargeTimesPositionVmean[50]; + + Double_t RMSV; + Double_t RMSU; + Double_t RMSVmean; + Double_t RMSUmean; + // end for cluster shape + + int NPages; + + int NTracksPerEventInSensor; + double AverageEffic[2]; + + Int_t GetFileNumber(); + void GetParameters(); + void GetAnalysisGoal(); // JB 2014/01/17 + void ComputePixelPosition(Int_t col, Int_t lin, Float_t &u, Float_t &v); // JB 2012/11/21 + void ComputePixelPosition_UVToColRow( Double_t u, Double_t v, double &col, double &lin); // JH 2014/07/30 + void PrepareOnlineDisplay(); // JB 2010/08/30 + void BookingHistograms() { MHist::BookingHistograms(RunNumber, PixelSizeU, PixelSizeV, NofPixelInRaw, NofPixelInColumn, TrackToHitDistanceLimit, fSession->GetSetup(), fIfReferenceTrack, fIfCalibration, fIfLaserSpot, fIfMiniVector, fIfVertex, fIfFake, fIfImaging);}; + void CreateNewEta(); + Bool_t TrackInMimo( Int_t aGeoMatrix, Float_t tuVal, Float_t tvVal, Int_t aSubMatrix=0); + //void Zero(TObject** ptr,int size=0) {/*for(int ind=0;indGetRunNumber();} + Int_t GetPlaneNumber() { return ThePlaneNumber;} + void SetPlaneNumber(Int_t aPlaneNumber); + void SetLadderNumber(Int_t aNumber); // JB 2014/01/10 + void InitPlaneNumber() { ThePlaneNumber = fSession->GetPlaneNumber(); } + Int_t GetMimosaType() { return MimosaType;} + void SetMimosaType(Int_t aMimosaType) { MimosaType = aMimosaType;} + Int_t GetAlignStatus() { return fSession->GetTracker()->GetAlignmentStatus(); } + void SetDebug(Int_t aMimoDebug); + void SetAlignStatus(Int_t aStatus) { fSession->GetTracker()->SetAlignmentStatus( aStatus); } // See DTracker + + Double_t GetCUT_MaxHitRatePerPixel() { return CUT_MaxHitRatePerPixel;} + Double_t GetCUT_MinHitRatePerPixel() { return CUT_MinHitRatePerPixel;} + void SetCUT_MaxHitRatePerPixel(Double_t aRate) { CUT_MaxHitRatePerPixel = aRate;} + void SetCUT_MinHitRatePerPixel(Double_t aRate) { CUT_MinHitRatePerPixel = aRate;} + + void InitMimosaType() { MimosaType = (Int_t)(RunNumber/1000.); if(RunNumber==2110) MimosaType=4; else if(RunNumber<1000) MimosaType = 99;} // JB 2012/05/04 deal with RunNumber<1000 case + + void SetFileNumber(Int_t aUserFileNumber=0) {fUserFileNumber = aUserFileNumber;}; + void SetDSFFile(const Char_t *aFileName) {sprintf( RootFile, "%s", aFileName);}; // JB 2013/09/19 + DPrecAlign* AlignMimosa( Int_t aDistance); + //DPrecAlign* AlignPrecMimosa(DPrecAlign* initAlignment, Bool_t modeAuto); // LC 2012/09/06. + //TFile* InitCorPar(Int_t aRun, Int_t aPlane, Int_t &aStatus); + //void InitCorPar(Int_t aRun, Int_t aPlane); // Jb 2009/05/18 + void InitCorPar(Int_t aRun, Int_t aPlane, const char* objType="plane"); // JB 2014/02/10 + Bool_t IsPlaneInLadder(Int_t aPlaneNumber, Int_t aLadderNumber); // JB 2014/02/10 + + int ResultsStrore(); + + Float_t GetCalibration() {return calibration;}; + + //prepare + void PrepareRun(int RunNumberBigin, Option_t* aType,int NumberOfFilesPerRun=0, int RunNumberEnd=0, int RunNumberStep=1 ); + + + Float_t GetMimosaEfficiency() {return MimosaEfficiency;} + Float_t GetMimosaEfficiency_ERR() {return MimosaEfficiency_ERR;} + + Int_t GetNtrkInMimo() {return NtrkInMimo;} // Number of tracks in the MIMOSA aperture + + + TFile* GetCorParFile() { + if (!theCorFile) { InitCorPar(GetRunNumber(),GetPlaneNumber()); } + return theCorFile; + } + + + //----ADC + Float_t tVect[100]; //n res + // Int_t *fChannel; //! pointer to Channels + //Int_t& GetChannel(Int_t aSk) { return fChannel[aSk-1]; } + Float_t* GettVect() {return tVect;} ; //n res + //----ADC + + //MC simulation parameters + bool UsingTrackerResolution; + int Bins_GlobalResolution; + double DUT_residualU_CGDSF[2]; + double DUT_residualV_CGDSF[2]; + double DUT_resolutionU_CGDSF[2]; + double DUT_resolutionV_CGDSF[2]; + double Tel_resolutionU_CGDSF[2]; + double Tel_resolutionV_CGDSF[2]; + double From_mu_to_mm; + int _PrintFreq; + std::vector _PlaneList; //Plane indexes in orderer by Z coordinate, from lower to higher. + std::vector _PlaneListZ; + std::vector _PlaneThickness; + std::vector _PlaneMaterial; + std::vector _RU_min; + std::vector _RU_max; + std::vector _RV_min; + std::vector _RV_max; + double MyRX[2]; + double MyRY[2]; + double MyRZ[2]; + double DUTGeomMatrixX[2]; + double DUTGeomMatrixY[2]; + double RGlobalResolution[2]; + Color_t color[500]; + double Nsigma; + int *TracksPerEvt; + int *NRectracks; + + // ************************************ + // Arrays for eta correction + + TArrayF Liste_CoGU; + TArrayF Liste_CoGV; + Int_t nListe_CoG; + TArrayF READListe_CoGU; + TArrayF READListe_CoGV; + Int_t READnListe_CoG; + + TArrayF Liste_CoGU_eta2x2; + TArrayF Liste_CoGV_eta2x2; + Int_t nListe_CoG_eta2x2; + TArrayF READListe_CoGU_eta2x2; + TArrayF READListe_CoGV_eta2x2; + Int_t READnListe_CoG_eta2x2; + + TArrayF Liste_CoGU_eta5x5; + TArrayF Liste_CoGV_eta5x5; + Int_t nListe_CoG_eta5x5; + TArrayF READListe_CoGU_eta5x5; + TArrayF READListe_CoGV_eta5x5; + Int_t READnListe_CoG_eta5x5; + + // Int_t GetREADnListe_CoG() { return READnListe_CoG; } + // void SetREADnListe_CoG(Int_t aREADnListe_CoG) { READnListe_CoG = aREADnListe_CoG; } + + + // ************************************ + // Comonly used commands + + void CDHist() { if(!CheckIfDone("mimosapro")) {return;} else { MHist::Dir();}} + void Help(); + + void InitSession(const Int_t TheRun,const unsigned int ThePlane=0, Int_t EventBuildingMode=-1,TString ConfigFile="", TString ConfigDir="", TString DataDir=""); + //EventBuildingMode key by default is at -1 meaning that it will not override the value taken in DSetup::ReadConfiguration(), SS 2011/11/14 + // VR 2014/06/30 Add optional args + + // ************************************ + // Raw data reconstruction commands + + void MakeEta(int NEvt = 10000); + + void SetTrackGeoLimitsForAlign(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax) { fSession->SetTrackGeoLimitsForAlign(xmin, xmax, ymin, ymax); } // JB 2013/06/11 + void SetTrackChi2LimitForAlign( Double_t aLimit) { fSession->SetTrackChi2LimitForAlign( aLimit); } // JB 2013/07/14 + void AlignTracker(const Double_t tiniBoundU, + const Double_t tiniBoundV, + Int_t nAlignEvents=4000, + Int_t nAdditionalEvents=2000, + bool UseAllHits = false); // 2013/06/10. + // AP 2015/06/10: added bool parameter (UseAllHits) to decide if doing alignement with all hits or the closest one to the track. + void AlignTracker(const Double_t tiniBound = 480., + Int_t nAlignEvents=4000, + Int_t nAdditionalEvents=2000, + bool UseAllHits = false) { AlignTracker( tiniBound, tiniBound, nAlignEvents, nAdditionalEvents, UseAllHits); } + void AlignTrackerMinuit(Bool_t modeAuto=1, + const Double_t tiniBound=480., + Int_t nAlignEvents=5000, + Int_t nAlignHitsInPlane=4000, + Int_t nAdditionalEvents=2000, + Double_t chi2Limit=0., + bool UseAllHits = true); // LC 2012/09/06 + // AP 2015/06/08 : adding bool parameter (UseAllHits) to decide if doing alignment with all hits or the closest one + void AlignTrackerMinuitLadder(Bool_t modeAuto =1, const Double_t tiniBound=480., Int_t nAlignEvents=5000, Int_t nAlignHitsInPlane=4000, Int_t nAdditionalEvents=2000, Double_t chi2Limit=0.); + //void AlignLadder(Bool_t modeAuto=1, const Double_t tiniBound=480., Int_t nAlignEvents=5000, Int_t nAlignHitsInPlane=4000, Int_t nAdditionalEvents=2000, Int_t ladderFace=1, Double_t chi2Limit=0.); // Commented 2014/12/18 + void AlignLadderMV(Bool_t modeAuto=1, const Double_t tiniBound=480., const Double_t boundSlopes=100., Int_t nAlignEvents=5000, Int_t nGoodTracks=1000, Int_t nAdditionalEvents=2000, Int_t chi2Limit=40, Int_t mode=0); // LC 2013/09/10 + void AlignTrackerGlobal(const Int_t refPlane=1, const Int_t nEvents=4000, const Int_t nIterations=10, const Bool_t alignConstrainsts=true, const Bool_t trackConstrainsts=true, const Bool_t multipleScatteringFit=true); // LC && LiuQ 2015/02/06. + void AlignTrackerMillepede(Int_t nAlignEvents=4000); // LC 2012/12/24. +// void Gener(Double_t* xp, Double_t* yp, Double_t& aX, Double_t& bX, Double_t& aY, Double_t& bY, Double_t* sigX, Double_t* disX, Double_t* sigY, Double_t* disY, Double_t* z, Double_t* phi); // LC 2012/01/07 + + void DSFProduction(Int_t NEvt = 500000, Int_t fillLevel=1); + void StudyDeformation(const Float_t tiniBound = 480., Int_t nEvents=2000, Bool_t fitAuto=0); // BB 2014/05/20 + + + // ************************************ + // Analysis commands + + DSession* GetSession() {return fSession;} // JB 2013/06/23 + MRaw* GetRaw(); + MRax* GetRax(); + void MimosaPro(Int_t MaxEvt, Float_t TrackHitDist, Float_t S2N_seed, Float_t S2N_neighbour, Int_t submatrix, Int_t GeoMatrix, Option_t* SaveAlign, Int_t UseHitMap=0, Int_t WriteMissedHits=0, Int_t WriteGoodHits=0); + void MimosaFakerate(Int_t MaxEvt, Float_t S2N_seed, Float_t S2N_neighbour, Int_t submatrix=0, Int_t GeoMatrix=0); + void MimosaCalibration(Int_t MaxEvt, Float_t S2N_seed = 0., Float_t S2N_neighbour = 0., Float_t ChargeAroundSeedCutMax = 5000., Int_t submatrix=0, Int_t GeoMatrix=0); + void MimosaMiniVectors(Int_t MaxEvt, Int_t TrackHitDist, Short_t plane0, Float_t S2N_seed0, Float_t S2N_neighbour0, Int_t submatrix0, Int_t GeoMatrix0, Short_t plane1, Float_t S2N_seed1, Float_t S2N_neighbour1, Int_t submatrix1, Int_t GeoMatrix1); + void MimosaPro2Planes(Int_t MaxEvt, Int_t TrackHitDist, Short_t plane0, Float_t S2N_seed0, Float_t S2N_neighbour0, Int_t submatrix0, Short_t plane1, Float_t S2N_seed1, Float_t S2N_neighbour1, Int_t submatrix1, Int_t GeoMatrix); + void MimosaVertex(Int_t MaxEvt, Short_t plane1, Short_t plane2); + void MimosaVertexFinder(Int_t MaxEvt, Int_t submatrix , Int_t GeoMatrix, Float_t chi2Cut); + void MimosaCluster(Int_t MaxEvt, Float_t S2N_seed = 0., Float_t S2N_neighbour = 0., Int_t submatrix=0, Int_t GeoMatrix=0); // JB 2014/01/17 + void MimosaProLadder(Int_t MaxEvt, Int_t TrackHitDist, Float_t S2N_seed, Float_t S2N_neighbour , Int_t submatrix , Int_t GeoMatrix ,Option_t* SaveAlign, Int_t UseHitMap, Int_t WriteMissedHits, Int_t WriteGoodHits); // JB 2014/02/1 + + void MimosaImaging(Int_t MaxEvt, Int_t submatrix=0, Int_t GeoMatrix=0, Double_t theta_init=0.0, Int_t Npeak=1, Double_t S=100, Double_t W=100, Bool_t FirstLoop=kTRUE, Bool_t chooseFit=kTRUE); // JH 2014/06/13 + + void MimosaGeneration_ToyMC(Int_t MaxEvt = 10000, + Int_t PlaneNumber = 1, + Int_t Submatrix = 0, + Int_t Geomatrix = 0, + bool DoGaussianMS = true, + Int_t seed = 8292894, + bool DoDisplay = false, + double XMeanDiv = 0.0, + double XRMSDiv = 1.0e-20, + double YMeanDiv = 0.0, + double YRMSDiv = 1.0e-20, + bool CalledFromMimosaPro = false, + bool verbose = false); //AP 2015/03/11 + + void MimosaGeneration_LoicG4Simu(Int_t MaxEvt = 10000, + Int_t PlaneNumber = 1, + Int_t Submatrix = 0, + Int_t Geomatrix = 0, + Int_t seed = 8292894, + bool DoDisplay = false, + bool verbose = false); //AP 2015/07/08 + + void MimosaGeneration_APG4Simu(Int_t MaxEvt = 10000, + Int_t PlaneNumber = 1, + Int_t Submatrix = 0, + Int_t Geomatrix = 0, + Int_t seed = 8292894, + bool DoDisplay = false, + bool verbose = false); //AP 2015/07/29 + + void BookingMC(Int_t PlaneNumber = 1, + Int_t Submatrix = 0, + Int_t Geomatrix = 0, + bool CalledFromMimosaPro = false); //AP 2015/07/29 + void DoMCDisplay(int NDisplay,bool verbose); //AP 2015/07/29 + void DoMCDisplay3D(int NDisplay,bool verbose, + const char* file_gdml); //AP 2015/07/31 + double DistanceOfPointToPlane(const int PlaneNumber, + DR3 Point); //AP 2015/08/03 + DR3 ClosestPointInPlaneToPoint(const int PlaneNumber, + DR3 Point); //AP 2015/08/03 + + float GetTrackDistantToClosestDiode(float tu, + float tv); + + // ************************************ + // Plotting functions + + void MimosaResolution(); + void CheckMCSimulation(bool StandAlone = false); + void MimosaClusterCharge( TString fitOption="landau" ); + void MimosaBinaryplots(); + void CheckMimosaAlign(); + void CheckAsymmetry(); + void InspectEfficiency(); + void checkRefPlane(); + void CompareBadGoodRaw(); + void CheckClusters(); + void Checkreferencetracks(); + void pixelcharge(); + void MimosaSN(); + void ClusterShape(); //cdritsa feb 2008, JB 2010 + void HitMap(); // JB 2010/10/06 + void MimosaPixelHomogeneity(); + void MimosaOptimize(); + void FakeRate(); + void Calibration(); // JB 2010/07/27 + TPad* PlotCalibration(TH1F* h, Int_t manualFitRange=0); + void MiniVectors(); // Jb 2010/08/21 + void UserAnalysis(); + void SaveGifFile(); + void Clear(Option_t* /*option = ""*/); + void CheckImaging(Double_t theta_init=62.0, Int_t Npeak=1, Double_t S=100, Double_t W=100, Bool_t FirstLoop=kTRUE, Bool_t chooseFit=kTRUE); // JH 2014/06/16 + + // ************************************ + + + + ClassDef(MimosaAnalysis,2) + }; + +//R__EXTERN MimosaAnalysis *gTAF; // JB, for inline compilation + + +#ifndef MAC +//#define gTAF MimosaAnalysis::Instance() // to comment for MAC +#endif + + +#endif diff --git a/include/MCBoardReader.h b/include/MCBoardReader.h new file mode 100644 index 0000000..ab36a63 --- /dev/null +++ b/include/MCBoardReader.h @@ -0,0 +1,287 @@ +#ifndef _MCBoardReader_HXX +#define _MCBoardReader_HXX +/*! + \file + \version $Id: MCBoardReader.hxx,v 1.8 2003/07/08 18:54:19 mueller Exp $ + \brief Declaration of MCBoardReader. +*/ +/*------------------------------------------+---------------------------------*/ + +#include "BoardReader.h" // withROOT is define therein +#include +#include +#include +//using namespace std; +#include "TH2F.h" +#include "TString.h" +#include "TTree.h" +#include "TChain.h" +#include "TFile.h" +#include "DGlobalTools.h" +#include "DEventMC.h" +#include "DSetup.h" + +class TH2F; +class TH1F; + +#define withROOT + +const Int_t kMaxHits = 4000; + +const Int_t NMaxParticle = 100; //Maximum number of particle save in the TAFTree +const Int_t NMaxHit = 10000; //Maximum number of hit save in the TAFTree +const Int_t NMaxPixel = 10000000; //Maximum number of pixel save in the TAFTree +const Int_t NMaxSatu = 10000; //Maximum number of saturated lines + +struct MCHitPixel_t { + int GlobalIdx; + int col; + int row; + float ChargeAnalog; + int sensorID; + TVector2 PosUVmm; + int status; + int frame; +}; + +struct MCParticleHit_t { + int sensorID; + TVector3 PosInXYZmm; + TVector2 PosAveUVmm; + TVector2 PosAveUVLaddermm; + TVector2 PosRecoAveUVmm; + TVector2 PosRecoAveUVLaddermm; + TVector3 MomentumInXYZMeV; + float ThetaLoc; + float PhiLoc; + float Geant4EdepMeV; + float GlobalTime; + float ClusterPhiPrincipalAxis; + float ClusterRMSPrincipalAxis; + float ClusterSizeCol; + float ClusterSizeRow; + int frame; + int Npixels; + std::vector ListOfHitPixels; +}; + +struct MCParticle_t { + int pdgID; + int BKGType; + TVector3 ProdVtx; + int frame; + std::vector ListOfParticleHits; +}; + +//Non-sensitive sim-hits +struct MCNonSensitiveParticleHit_t { + float GlobalTime; + TVector3 PosInXYZmm; + TVector3 MomentumInXYZMeV; + float EnergyInMeV; + TVector3 PosOutXYZmm; + TVector3 MomentumOutXYZMeV; + float EnergyOutMeV; + float Geant4EdepMeV; + int frame; +}; + +struct MCNonSensitiveParticle_t { + int sensitiveIdx; + int pdgID; + TVector3 ProdVtx; + int frame; + std::vector ListOfNonSensitiveParticleHits; +}; + +//############################################################################## +class MCBoardReader : public TObject { + +public: + + MCBoardReader(int boardNumber, int Runnumber, TString pathName, TString fileName, TString TreeName, DSetup* aSetup); + ~MCBoardReader(); + + void SetDebugLevel( int aLevel); + bool HasData(); + bool ValidHistogram() { return fDisplay; } + int GetBoardNumber() { return fBoardNumber; } + int GetEventNumber() { return fEventNumber; } + BoardReaderEvent* GetEvent() { return fCurrentEvent; } + void PrintStatistics(ostream &stream); + + void SetMCInforHolder(DEventMC* AnMCInfoHolder) {MCInfoHolder = AnMCInfoHolder;}; + + void FillUpMCParticlesFromFrame(int TheFrame); //AP, 2016/04/21. Fill up the particle list for frame TheFrame + void FillUpMCInfoHolderForThisEvent(void); //AP, 2016/04/21. Fill up the MCInfoHolder for the current event + +private: + + DSetup *fSetup; // pointer to the configuration + + int fDebugLevel; // debug level + DGlobalTools fTool; + + int fRunNumber; + int fBoardNumber; + int fNumberOfSensors; + TString fPathName; // base file name + TString fFileName; // base file name + TString fTreeName; // base file name + //TString TheFullFileName; + std::vector ListOfInputROOTFiles; + + bool GotNonSensitiveInfo; + DEventMC* MCInfoHolder; + + TFile* file_in; + + //The MC tree + //TTree* fTree; + TChain* fChain; + Int_t fCurrent; //!current Tree number in a TChain + + //The MC tree structure + //Particles Branch + Int_t ParticleNb; + Int_t ParticleBKGType[NMaxParticle]; + Int_t ParticlepdgID[NMaxParticle]; + Float_t ParticleTrkVtX[NMaxParticle]; + Float_t ParticleTrkVtY[NMaxParticle]; + Float_t ParticleTrkVtZ[NMaxParticle]; + Int_t ParticleNHits[NMaxParticle]; + Int_t ParticleFirstHitIdx[NMaxParticle]; + + //Hits Branch + Int_t HitNb; + Int_t HitParticleIdx[NMaxHit]; + Int_t HitsensorID[NMaxHit]; + Int_t HitladderID[NMaxHit]; + Int_t HitmoduleID[NMaxHit]; + Float_t HitposINmmX[NMaxHit]; + Float_t HitposINmmY[NMaxHit]; + Float_t HitposINmmZ[NMaxHit]; + Float_t HitposAVRmmU[NMaxHit]; + Float_t HitposAVRmmV[NMaxHit]; + Float_t HitposAVRmmW[NMaxHit]; + Float_t HitposAVRmmULadder[NMaxHit]; + Float_t HitposAVRmmVLadder[NMaxHit]; + Float_t HitmomMeVX[NMaxHit]; + Float_t HitmomMeVY[NMaxHit]; + Float_t HitmomMeVZ[NMaxHit]; + Float_t HitthetaLoc[NMaxHit]; + Float_t HitphiLoc[NMaxHit]; + Float_t HitglobalTime[NMaxHit]; + Float_t HitGeant4EdepMeV[NMaxHit]; + Float_t HitClusterSizeCol[NMaxHit]; + Float_t HitClusterSizeRow[NMaxHit]; + Float_t HitRecoUmm[NMaxHit]; + Float_t HitRecoVmm[NMaxHit]; + Float_t HitRecoULaddermm[NMaxHit]; + Float_t HitRecoVLaddermm[NMaxHit]; + Float_t HitPhiPrincipalAxis[NMaxHit]; + Float_t HitRMSPrincipalAxis[NMaxHit]; + Int_t HitNPixels[NMaxHit]; + Int_t HitFirstPixelIdx[NMaxHit]; + + //Pixels Branch + Int_t PixelNb; + Int_t PixelHitIdx[NMaxPixel]; + Int_t PixelGlobalIdx[NMaxPixel]; + Int_t PixelColumn[NMaxPixel]; + Int_t PixelRow[NMaxPixel]; + Float_t PixelAnalogCharge[NMaxPixel]; + Int_t PixelSensorID[NMaxPixel]; + Float_t PixelUmm[NMaxPixel]; + Float_t PixelVmm[NMaxPixel]; + Int_t PixelStatus[NMaxPixel]; + + //Saturated line branch + Int_t SatuNb; + Int_t SatuLinIdx[NMaxSatu]; + Int_t SatuSensorID[NMaxSatu]; + + //Non-sensitive Hit variables + //Definition of Particles Branch + Int_t NonSensitiveParticleNb; // number of particles hitting non-sensitive volumes in event + Int_t NonSensitiveParticleSensitiveIdx[NMaxParticle]; // index of this particle in Mimosa particle list + Int_t NonSensitiveParticlepdgID[NMaxParticle]; // particle pdg ID + Float_t NonSensitiveParticleTrkVtX[NMaxParticle]; // particle's origin vertex, X coordinate, in mm + Float_t NonSensitiveParticleTrkVtY[NMaxParticle]; // particle's origin vertex, Y coordinate, in mm + Float_t NonSensitiveParticleTrkVtZ[NMaxParticle]; // particle's origin vertex, Z coordinate, in mm + Int_t NonSensitiveParticleNHits[NMaxParticle]; // particle's number of hits + Int_t NonSensitiveParticleFirstHitIdx[NMaxParticle]; // index on hit block of particle's 1st hit + + //Definition of Hits Branch + Int_t NonSensitiveHitNb; // Number of hits in non-sensitive volumes in event + Int_t NonSensitiveHitParticleIdx[kMaxHits]; // index in particle block of particle producing this hit + + Float_t NonSensitiveHitposINmmX[kMaxHits]; // enter position in global ref. frame, X coordinate, in mm + Float_t NonSensitiveHitposINmmY[kMaxHits]; // enter position in global ref. frame, Y coordinate, in mm + Float_t NonSensitiveHitposINmmZ[kMaxHits]; // enter position in global ref. frame, Z coordinate, in mm + Float_t NonSensitiveHitglobalTimeINns[kMaxHits]; // enter global time, in ns + Float_t NonSensitiveHitmomINMeVX[kMaxHits]; // enter momentum, X coordinate, in MeV + Float_t NonSensitiveHitmomINMeVY[kMaxHits]; // enter momentum, Y coordinate, in MeV + Float_t NonSensitiveHitmomINMeVZ[kMaxHits]; // enter momentum, Z coordinate, in MeV + Float_t NonSensitiveHitEnergyINMeV[kMaxHits]; // enter Energy, in MeV + Float_t NonSensitiveHitposOUTmmX[kMaxHits]; // exit position in global ref. frame, X coordinate, in mm + Float_t NonSensitiveHitposOUTmmY[kMaxHits]; // exit position in global ref. frame, Y coordinate, in mm + Float_t NonSensitiveHitposOUTmmZ[kMaxHits]; // exit position in global ref. frame, Z coordinate, in mm + Float_t NonSensitiveHitmomOUTMeVX[kMaxHits]; // exit momentum, X coordinate, in MeV + Float_t NonSensitiveHitmomOUTMeVY[kMaxHits]; // exit momentum, Y coordinate, in MeV + Float_t NonSensitiveHitmomOUTMeVZ[kMaxHits]; // exit momentum, Z coordinate, in MeV + Float_t NonSensitiveHitEnergyOUTMeV[kMaxHits]; // exit Energy, in MeV + Float_t NonSensitiveHitGeant4EdepMeV[kMaxHits]; // particles deposited energy by ionization, in MeV + + std::vector TheListOfMCParticles; + std::vector ListOfNoisePixels; + std::vector TheListOfMCNonSensitiveParticles; + + TH1F **hLineOverFlowDist; //Distribution of line Overflow + + int fEventSize; // size of the event + bool fDisplay; // decide histo display or not + + unsigned int fCurrentTriggerCnt; + int fEventNumber; + int fFrameCounter; + + BoardReaderEvent *fCurrentEvent; + vector ListOfPixels; + vector ListOfTriggers; + vector ListOfFrames; + vector ListOfLineOverflow; + + bool fOverflow; // flag to indicate overflow + int fEventsOverflow; // count total events with overflow + int fNStatesInLine; // count total # states + int fFramesReadFromFile; // count total # frames read + + //Opening the MC data file + bool Open(); + void Init(const char* ROOTfilename, const int num); + bool GetAFrame(Long64_t aFrame); + Long64_t LoadTree(Long64_t entry); + + //! Build event by creating the list of frames of the event + bool FetchEvent(); + + //! Loop over the event's list of frames + bool DecodeFrames(); + + // Add the pixels of frame TheFrame to the list of pixels of the event + void FillPixelsFromFrame(int TheFrame); + + //! Add pixel to list + void AddPixel(int input, int value, int aLine, int aColumn); + + //! Check trigger counts + bool CheckTriggerCnt(unsigned int trig); + + bool CheckIfNonSensitiveVariables(TTree* tree); + + ClassDef(MCBoardReader,0) + +}; + +#endif diff --git a/include/MGlobalAlign.h b/include/MGlobalAlign.h new file mode 100755 index 0000000..c970cf2 --- /dev/null +++ b/include/MGlobalAlign.h @@ -0,0 +1,212 @@ +// Author: L. Cousin && Liu Q + +#ifndef _MimosaGlobalAlign_included_ +#define _MimosaGlobalAlign_included_ + + ///////////////////////////////////////////////////////////// + // // + // Mimosa chip and ref. global alignement class // + // // + // // + ///////////////////////////////////////////////////////////// + +#include "Riostream.h" +#include "TMath.h" +#include "TMatrixD.h" +#include "TVectorD.h" +//#include "TMatrixDLazy.h" +#include "TVectorD.h" +#include "TDecompLU.h" +#include "TDecompSVD.h" + +#include "DPrecAlign.h" +#include "DTrack.h" +#include "DPlane.h" + +class MimosaGlobalAlign : public TObject { + + private: + + Int_t _debugLevel; + + Bool_t _trackParametersConstrainsts; + Bool_t _alignParametersConstrainsts; + Bool_t _multipleScatteringFit; + + Double_t _bound; + + std::map _map_DPrecAlign; + std::map _map_Planes; + std::map _map_PlanesIndex; + + std::vector _hitsPerPlane; + + std::map _mapParameterName; + + Int_t _indexResiduals; + Int_t _indexAlignmentParams; + Int_t _indexTrackParams; + + Int_t _planeNumber; + Int_t _axisNumber; + Int_t _trackParametersNumber; + Int_t _degreeOfFreedom; + + Double_t _fixedTrackDirectionX; + Double_t _fixedTrackDirectionY; + Double_t _sigmaTrackDirectionX; + Double_t _sigmaTrackDirectionY; + Double_t _sigmaTrackOriginX; + Double_t _sigmaTrackOriginY; + Double_t _sigmaTrackOriginZ; + + TVectorD* _alignmentVector; + TMatrixD* _covarianceMatrix; + TMatrixD* _covarianceMatrixMS; + TMatrixD* _inverseCovarianceMatrix; + + TVectorD* _residualsVector; + TVectorD* _residualsVectorMS; + + TMatrixD* _derivativesAlignmentMatrix; + TMatrixD* _derivativesTracksMatrix; + + TMatrixD* _saveDerivativesAlignmentMatrix; + TMatrixD* _saveDerivativesTracksMatrix; + + TMatrixD* _saveTransposeDerivativesAlignmentMatrix; + TMatrixD* _saveTransposeDerivativesTracksMatrix; + + TMatrixD* _matrixB; + TMatrixD* _matrixI; + TMatrixD* _matrixG; + + TMatrixD* _identity; + + TMatrixD* _finalMatrix; + TVectorD* _finalVector; + TMatrixD* _finalInverseMatrix; + + TVectorD* _alignmentCorrections; + //TVectorD* _trackParametersCorrections; COMMENTED. TO BE UPDATED :) + TVectorD* _trackParameters; + + TMatrixD* _covarianceMatrixAlignementConstrainsts; + TMatrixD* _inverseCovMatAlignConstraints; + TMatrixD* _identityMatrix; + TVectorD* _vectorAlignmentConstraints; + + TMatrixD* _covarianceMatrixTrackConstraints; + TMatrixD* _inverseCovMatTrackConstraints; + TMatrixD* _identidyMatrixTrack; + TVectorD* _vectorTrackConstraints; + + TMatrixD* _saveFinalMatrix; + + TMatrixD* _matrixU; // for SVD decomp + TMatrixD* _matrixV; // for SVD decomp + TVectorD* _singularValues; // for SVD decomp + TMatrixD* _singularMatrix; // for SVD decomp + + TCanvas** canvasResiduals; + TH1F** residualsU; + TH1F** residualsV; + TH1F* trackParameterX; + TH1F* trackParameterY; + + std::vector _trackExtrapolation; + std::vector _thetaMS; + + public: + + MimosaGlobalAlign(const Int_t& planeNumber, const Int_t& DoF, const Int_t& NbTrackPrameters, const Int_t& axisNumberInPlane, const Double_t& bound, const Bool_t alignConstrainsts, const Bool_t trackConstrainsts, const Bool_t _multipleScatteringFit); + virtual ~MimosaGlobalAlign(); + + void SetInitialAlignementParameters(std::map& planeList, const Double_t& ResoAlignParamTr, const Double_t& ResoAlignParamRot); + void SetDisplay(); + void ProcessTrack(DTrack*); + + Double_t ComputeResidualDerivative_U_AboutTranslationX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_U_AboutTranslationY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_U_AboutTranslationZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + + Double_t ComputeResidualDerivative_U_AboutTrackDirectionX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeResidualDerivative_U_AboutTrackDirectionY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + + Double_t ComputeResidualDerivative_U_AboutTrackPointX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_U_AboutTrackPointY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_U_AboutTrackPointZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + + Double_t ComputeResidualDerivative_U_AboutRotationX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeResidualDerivative_U_AboutRotationY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeResidualDerivative_U_AboutRotationZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + + Double_t ComputeResidualDerivative_V_AboutTranslationX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_V_AboutTranslationY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_V_AboutTranslationZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + + Double_t ComputeResidualDerivative_V_AboutTrackDirectionX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeResidualDerivative_V_AboutTrackDirectionY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + + Double_t ComputeResidualDerivative_V_AboutTrackPointX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_V_AboutTrackPointY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + Double_t ComputeResidualDerivative_V_AboutTrackPointZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY); + + Double_t ComputeResidualDerivative_V_AboutRotationX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeResidualDerivative_V_AboutRotationY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeResidualDerivative_V_AboutRotationZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + + Double_t ComputeTrackIntersectionU(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + Double_t ComputeTrackIntersectionV(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint); + + void FixPlane(Int_t planeIndex, Double_t sigma); + void FixParameter(Int_t planeIndex, Int_t parameterIndex, Double_t sigma); + void SetConstraintValueOnParameter(Int_t planeIndex, Int_t parameterIndex, Double_t value); + + void SetCovarianceMatrixToIdentity(); + void SetCovarianceMatrixMS(); + + void ComputeResidualsMS(); + Double_t ComputeDistance(DR3 firstPlane, DR3 lastPlane); + + void SetIdentityForTrackConstraint(); + void SetCovMatrixAlignConstraintToIdentity(); + + void FillMatrixB(); + void FillFinalGlobalMatrix(); + void FillGlobalFinalVector(); + + void InvertFinalMatrix(); + void ComputeAlignmentCorrections(); + + void DecomposeSVD_FinalMatrix(); + + void FixTrackDirections(Double_t dirX, Double_t dirY) { _fixedTrackDirectionX = dirX; _fixedTrackDirectionY = dirY; }; + void SetTrackDirectionResolution(Double_t sigmaX, Double_t sigmaY) {_sigmaTrackDirectionX = sigmaX; _sigmaTrackDirectionY = sigmaY; }; + void SetTrackOriginResolution(Double_t sigmaTrackOriginX, Double_t sigmaTrackOriginY, Double_t sigmaTrackOriginZ) {_sigmaTrackOriginX = sigmaTrackOriginX; _sigmaTrackOriginY = sigmaTrackOriginY; _sigmaTrackOriginZ = sigmaTrackOriginZ; }; + + void SetTrackParameters(DR3 trackDirection, DR3 trackOrigin); + void FixTrackParameters(Double_t directionX, Double_t directionY, Double_t sigmaX, Double_t sigmaY); + void FixTrackOrigin( DR3 fixedTrackOrigin, DR3 sigmaOrigin); + + void SetNewAlignmentParameters(); + + void PrintAlignmentCorrections(); + void PrintNewAlignmentParameters(); + void PrintResults(Int_t iteration); + + void FillResidualsPlots(); + void FillTrackParametersPlots(DR3 trackDirections); + void PrintResiduals(); + + Double_t GetParameterNewValue(Int_t planeNumber, Int_t parameterNumber); + + Bool_t IfAlignConstrainsts() { return _alignParametersConstrainsts; }; + Bool_t IfTrackConstrainsts() { return _trackParametersConstrainsts; }; + + void SetDebug(Int_t debug) { _debugLevel=debug; }; + + ClassDef(MimosaGlobalAlign,1); + +}; +#endif diff --git a/include/MHist.h b/include/MHist.h new file mode 100755 index 0000000..93c80d7 --- /dev/null +++ b/include/MHist.h @@ -0,0 +1,950 @@ +// @(#)maf/maf:$Name: $:$Id: MHist.h,v.1 2005/10/02 18:03:46 sha Exp $ +// Author: A. Shabetai + +#ifndef _MHist_included_ +#define _MHist_included_ + + + ///////////////////////////////////////////////////////////// + // // + // Contains all analysis histograms and canvas // + // (those which are filled by MimosaPro()) // + // // + //////////////////////////////////////////////////////////// + + +#include "TH3F.h" +#include "TCanvas.h" +#include "TText.h" +#include "TGraphErrors.h" +#include "TObject.h" +#include "TProfile.h" +#include "TProfile2D.h" +#include "Riostream.h" +#include "TRefArray.h" +#include "TEllipse.h" +#include "TLine.h" +#include "TLatex.h" +#include "TGraph.h" +#include "TPolyLine3D.h" +#include "TPolyMarker3D.h" + +#include "TSystem.h" +#include "TInterpreter.h" + +#include "TControlBar.h" + +//---ADC +#include "DSetup.h" +#include "DSession.h" +#include "DTracker.h" +#include "DPlane.h" +#include "DAlign.h" +#include "DHit.h" +//#include "MAnalysis.h" +//---ADC +//class MimosaAnalysis; +class DSetup; // forwards +class DSession; // forwards +//---ADC +//---ADC + +class MHist : public TObject { + + public: + + MHist(); + virtual ~MHist(); + + TObject** Zero(TObject** ptr,int size=0) {for(int ind=0;indcd(); if(ptr) {delete ptr;ptr=0;}return ptr; }; + TCanvas* Zero(TCanvas* ptr) { dir->cd(); if(ptr) {delete ptr;ptr=0;}return ptr; }; + TProfile* Zero(TProfile* ptr){ dir->cd(); if(ptr) {delete ptr;ptr=0;}return ptr; }; + TProfile2D* Zero(TProfile2D* ptr){ dir->cd(); if(ptr) {delete ptr;ptr=0;}return ptr; }; + TH1F* Zero(TH1F* ptr) { dir->cd(); if(ptr) {delete ptr;ptr=0;}return ptr;}; + TH2F* Zero(TH2F* ptr) { dir->cd(); if(ptr) {delete ptr;ptr=0;}return ptr;}; + TH3F* Zero(TH3F* ptr) { dir->cd(); if(ptr) {delete ptr;ptr=0;}return ptr;}; + TGraphErrors* Zero(TGraphErrors* ptr) { dir->cd(); if(ptr) {delete ptr;ptr=0;}return ptr; }; + + TH1F* AutoZoom(TH1F* H,Option_t* aType="all", Int_t EntryMin=0); + TH2F* AutoZoom(TH2F* H,Option_t* aType="all", Int_t EntryMin=0); + void Dir(); + void Clear(Option_t* /*option*/ = ""); + void BookingHistograms(Int_t RunNumber, Float_t PixelSizeU, Float_t PixelSizeV, Int_t NofPixelInRaw, Int_t NofPixelInColumn, Float_t TrackToHitDistanceLimit, DSetup *aSetup, Bool_t ifReferenceTrack=kFALSE, + Bool_t ifCalibration=kFALSE, Bool_t ifLaserSpot=kFALSE, Bool_t ifMiniVector=kFALSE, Bool_t ifVertex=kFALSE, Bool_t ifFake=kFALSE, Bool_t ifImaging=kTRUE); + MHist* theHist; + + protected: + TDirectory *saved; + TDirectory *dir; + + Char_t titre[150]; + Char_t nom[50]; + + Int_t MaxNofPixelsInCluster; + Int_t MinNofPixelsInCluster; // JB 2013/09/12 + static const int MaxNofPixelsInClusterMax=361; // a nodif + + TH1F *hdummy ; + + + //------------------------------------------------------------------------------ + //----- general control + //------------------------------------------------------------------------------ + + TH1F *selection ; + TText *textLabel[9]; + + TCanvas *MainCanvas; + + Float_t geomUmin, geomUmax; + Float_t geomVmin, geomVmax; + + //------------------------------------------------------------------------------ + // Charges, noise, S/N, pixel multiplicity plots for SELECTED clusters + //------------------------------------------------------------------------------ + + // seed + TH1F *hChargeInSeed ; + TH1F *hRealTrackNoise; + TH1F *hsn ; + TH1F *hSNReal; + + // 2nd higest S/N pixel + TH1F *hS2N2ndRH ; + TH1F *hSNNReal; + TH1F *hind ; + + // all pixels + TH1F *hChargeInCluster; + TH1F* hqcn[MaxNofPixelsInClusterMax] ; + TH1F* hqcngeom[MaxNofPixelsInClusterMax] ; + TH1F* hindivq[MaxNofPixelsInClusterMax] ; + TH1F* hsnn[MaxNofPixelsInClusterMax] ; + + TH1F *hChargeOrder1 ; + TH1F *hChargeOrder2 ; + TH1F *hChargeOrder3 ; + TH1F *hChargeOrder4; + TH1F *hChargeOrder5 ; + TH1F *hChargeOrder6 ; + TH1F *hChargeOrder7; + TH1F *hChargeOrder8 ; + TH1F *hChargeOrder9; + + TH2F *hChargeCor_1_2; + TH2F *hChargeCor_1_3 ; + TH2F *hChargeCor_1_4 ; + TH2F *hChargeCor_2_3 ; + + TH1F *hChargeRap_1_over_2; + TH1F *hChargeRap_1_over_3; + TH1F *hChargeRap_1_over_4; + TH1F *hChargeRap_2_over_3 ; + + TH1F *hQofPix3x3 ; + TH1F *hQ3x34 ; + TH1F *hQ3x35 ; + TH1F *hQ3x345 ; + TH1F *hQ3x327 ; + TH1F *hQ3x345r; + TH1F *hQ3x327r ; + + // cluster wise + TH1F *hsnc; + TH1F *hChargeSum_4 ; + TH1F *hqc_c ; + TH1F *hqc ; + TH1F *hChargeInCross ; + TH1F *hChargeInX ; + TH1F *hChargeInCrown1 ; + TH1F *hChargeInCrown2 ; + TH1F *hqcel ; + TH1F *hsnc1 ; + TH1F *hoptimalsize; + TH1F *hSNneighbour; + TH2F *hSNseedvsSNneighbour; // JB 2013/11/07 + TH2F *hQseedvsQcluster; // JB 2014/05/22 + TH2F *hQseedvsQneighbour; // JB 2013/11/08 + TH2F *hSNseedvsQcluster; // JB 2014/05/22 + TH1F *hnpix_c ; + TH1F *hnWindows_c; //AP 2015/05/30, Histograms with the number of 4x2 (colxlin) withdows needed for each associated cluster + TH2F* h2DWindows; //AP 2015/05/30, Histograms with super bins of 4x2 (colxlin) pixels + TH1F *hnpixCumul_c; + TH1F* hNomEffic; + + //Histograms related with duplicated hits associated to a track: try to quantify the effect of te duplicated hits (same position but different time-stamps) + TH2F* hDuplicate_2DMult; //AP 2015/06/09, 2D Histogram with the cluster multiplicity of the earliest vs the latest hit of a duplicated hit + TH1F* hDuplicate_DeltaTS; //AP 2015/06/09, Histogram with the Delta-Time-Stamp between the earliest and the latest hit of a duplicated hit + TH1F* hDuplicate_npixc; //AP 2015/06/09, Histogram with the prob of having a duplicated hit vs the earliest hit pixel multiplicity + TH2F* hDuplicate_npixc_vs_TrkDistToDiode; //AP 2015/06/09, 2D Histogram with the prob of having a duplicated hit vs the eatliest hit pixel multiplicity and + // the distance of the associated track to the closest diode + + static const Int_t jpixmax=8; + TH1F *hsn_pix_0[jpixmax] ; + TH1F *hsn_pix_1[jpixmax] ; + TH2F *hsn_seed_vs_pix_0[jpixmax]; + TH2F *hsn_seed_vs_pix_1[jpixmax]; + + // canvas + TCanvas *cClusterCharge; + + //------------------------------------------------------------------------------ + //--- Charges for calibration peak + //------------------------------------------------------------------------------ + + TH1F* hqSeedCalibration; + TH1F* hqNeighbourCalibration; + TH2F* hqSeedVsNeighbourCalibration; + + TCanvas *cCalibration; + TCanvas* Calib_distr1; + TCanvas* Calib_distr2; + TCanvas* Calib_distr3; + + + //------------------------------------------------------------------------------ + //----- Comparebadgoodraw() + //------------------------------------------------------------------------------ + TH1F *hraw1badone ; + TH1F *hraw1goodone ; + TH2F *hraw1goodone_time ; + TH2F *hraw1badone_time ; + TH2F *hraw1goodoneNoise_time; + TH2F *hraw1badoneNoise_time; + TH2F *hRealTrackNoise_time ; + + TH1F *hraw1PFrfr1GOOD; + TH1F *hraw1PFrfr1BAD; + TH2F *hraw1PFrfr1GOOD_time; + TH2F *hraw1PFrfr1BAD_time; + TH1F *hraw1PFrfr2GOOD; + TH1F *hraw1PFrfr2BAD; + TH2F *hraw1PFrfr2GOOD_time; + TH2F *hraw1PFrfr2BAD_time; + TH2F *hraw1NoiseGOOD_time; + TH2F *hraw1NoiseBAD_time; + + TH1F *hraw1Noise; + TH1F *hraw1Pedestal; + TH1F *hraw1CDS; + TH1F *hraw1Signal; + TH2F *hraw1Noise_time; + TH2F *hraw1Pedestal_time; + TH2F *hraw1CDS_time; + TH2F *hraw1Signal_time; + + + //------------------------------------------------------------------------------ + //--- efficiency + // MG 2010/06/04 + //------------------------------------------------------------------------------ + + TH2F *effimap; + TH1F *effi_vs_TrkHitDist; //AP, 13/01/2015 + TH1F *effiCorr_vs_TrkHitDist; //AP, 13/01/2015 + TH2F *goodtracks; + TH2F *TrkInMimo; + + //------------------------------------------------------------------------------ + //--- hit position + //------------------------------------------------------------------------------ + + TCanvas *cHitMap; + TCanvas *cHitMap2; + TCanvas *cPixEvent; + TCanvas *cPosStudy1; + TCanvas *cPosStudy2; + TCanvas *cPosStudy_TrackhitPos_vs_Mult; + TCanvas *cPosStudy_TrackhitPos_vs_Mult2; + TEllipse **Diodes; + + //------------------------------------------------------------------------------ + //--- ? + //------------------------------------------------------------------------------ + + TH2F *hseedQvsS2NAll; + TH2F *hseedQvsS2NGood ; + TH1F *hQseedAll ; + TH1F *hIndex2x2 ; + TH1F *hnhit ; + TH2F *vec ; + TH2F *tudv ; + TH2F *tvdu ; + TH2F *hudv ; + TH2F *hvdu ; + TH1F *tuhu1 ; + TH1F *tvhv1 ; + TH2F *tuhu ; + TH2F *tvhv ; + TH2F *tuhv ; + TH2F *tvhu ; + + TH2F *hAllHvvsAllTv ; + TH2F *hAllHuvsAllTv ; + TH2F *hAllHvvsAllTu ; + TH2F *hAllHuvsAllTu ; + + TH2F *huCG5tu ; + TH2F *hvCG5tv ; + TH2F *huCGtu ; + TH2F *hvCGtv ; + TH2F *huCGtuInPix ; + TH2F *hvCGtvInPix; + TH2F *huCGtuInPix5 ; + TH2F *hvCGtvInPix5 ; + TH2F *htuvInPix ; + TProfile *ProfUCG ; + TProfile *ProfVCG ; + TProfile *ProfACGn; + TH2F *hUeta3TuInPix; + TH2F *hVeta3TvInPix ; + TH2F *hUcorTuInPix ; + TH2F *hVcorTvInPix ; + TH2F *huCGtuInPix4; + TH2F *huCG2x2tuInPix ; + TH2F *hvCG2x2tvInPix; + TH1F *hEta2x2tu1L ; + TH1F *hEta2x2tv1L ; + TH2F *hEta2x2tu2L ; + TH2F *hEta2x2tv2L ; + TH1F *hCG2x2tu1L; + TH1F *hCG2x2tv1L ; + + TH1F *hEta2x2 ; + TH1F *hEta2x2U; + TH1F *hEta2x2V ; + TH1F *hEta2x2m ; + + TH1F *hEta2x2UL ; + TH1F *hEta2x2VL; + + + TH1F *hdCGEtaU ; + TH1F *hdCGEtaV ; + TH1F *hdCGDigU; + TH1F *hdCGDigV; + TH2F *hdCGDigUV; + TH1F *htmp5; + TH2F *hEta2x2tu2 ; + TH2F *hEta2x2tv2 ; + TH2F *hTHCorr2 ; + TH1F *hDifCorU ; + TH1F *hDifCorV ; + TH1F *hAllHuvsAllTu2 ; + TH1F *hAllHvvsAllTv2 ; + TH1F *hAlignHuTu ; //JB 2010/03/12 + TH1F *hAlignHvTv ; //JB 2010/03/12 + TH2F *hAlignHuTuvsTv; //JB 2010/03/12 + TH2F *hAlignHvTvvsTu; //JB 2010/03/12 + TH2F *hAlignHuTuvsTu; //JB 2013/07/16 + TH2F *hAlignHvTvvsTv; //JB 2013/07/16 + TH2F *hAlignHuTuvsHv; //JB 2010/03/12 + TH2F *hAlignHvTvvsHu; //JB 2010/03/12 + TH1F *hAllHvvsAllTv3 ; + TH2F *h2dallhits ; + TH2F *h2dgoodhits ; + TH2F *h2dmatchedhits ; + TH2F *h2DpictureMatched ; // JB 2014/01/10 + TH2F *hEta2x2vsInd ; + TH2F *hChargeVsPosition; + TH1F *hChargeVsDistance; // clm 2013/07/16 + TH2F *hNorm ; + TH2F *hAllHitsInPixel; + TH1F *h1RmsOnTheta; // JH 2014/06/16 + TH2F *h2RmsOnThetaScanVsThetaCut; // JH 2014/07/30 + TH1F *h1ProjectionOnX; // JH 2014/06/17 + TH1F *h1ProjectionOnY; // JH 2014/06/19 + TH1F *h1ProjectionOnXMult[4]; // JH 2014/06/19 + TH1F *h1ProjectionOnYMult[4]; // JH 2014/06/19 + TH1F *h1NumberOfHitsMult; // JH 2014/06/25 + TH2F *h2GoodHitsMult[4]; // JH 2014/06/25 + TH1F *h1Sigma; // JH 2014/06/19 + TH2F *hdCGDigUVMult[6]; // JH 2014/07/22 + TH1F *h1SigmaSlices; // JH 2014/07/29 + TH1F *h1SigmaSlices_Pull; // JH 2014/07/29 + TH2F *h2DXprimeVsYprime; // AP 2014/09/08 + + + TH2F *huv ; + TH2F *huv_rate; // AP 2014/09/25 + TH1F *h_pixels_event; // AP 2014/10/07 + TH2F *hxy ; + TH2F *huvBad ; + TH2F *hxyBad ; + TH2F *tuv ; + TH2F *tuv1 ; + + TH1F *hhu ; + TH1F *hhv ; + TH1F *hhx ; + TH1F *hhy ; + TH1F *hhuS ; + TH1F *hhvS ; + TH1F *htu; + TH1F *htv ; + //---ab + TH2F *htuhtv ; + TH1F *hGOODqcel ; + + TH1F *hgoodSeedPixel; + TH2F *h2DgoodSeedPixel ; + TH1F *hSeedBetweenDist ; + TH1F *hEta3DigU ; + TH1F *hEta3DigV ; + TH1F *hqc_nc ; + + TH1F *hnpix ; + TH1F *hnpix_nc; + + TH2F *FalseHitMap; + TH1F *hClusterChargeProfile; + TH1F *hClusterChargeNorm ; + TH1F *etal[2] ; + TH1F *etal1[2] ; + TH1F *vecu[25]; + TH1F *vecv[25] ; + TH1F *hChargeInSeedInGroup[64]; + TH1F *DuvCG ; + TH1F *duvall ; + + TH1F *hCDSvar ; + TH2F *CDSVarvsTime; + TH1F *dtime ; + + //------------------------------------------------------------------------------ + //----- Spatial Resolution + //------------------------------------------------------------------------------ + TH1F *hAllHuvsAllTu1; + TH1F *hAllHvvsAllTv1 ; + TH1F *huCGtu1; + TH1F *hvCGtv1; + TH1F **huCGtu1_vs_Mult; //AP, 2014/10/23, u CG residual distribution vs multiplicity + TH1F **hvCGtv1_vs_Mult; //AP, 2014/10/23, v CG residual distribution vs multiplicity + TH2F *huvCGtuv; //AP, 2015/04/02, position of associated tracks wrt sensing diodes + TH2F *huvCGtuv_NoAsso; //AP, 2015/04/02, position of non-associated tracks wrt sensing diodes + TH1F *hDist_Trck_Diode_Asso; //AB, 2015/04/20, distribution of the distance of the associated tracks to closest diode + TH1F *hDist_Trck_Diode_NoAsso; //AB, 2015/04/20, distribution of the distance of the non-associated tracks to closest diode + TH1F *hEffic_vs_Dist_Trck_Diode; //AP, 2015/04/22, detection efficiency vs distance of tracks to closest diode + TH1F **hDist_Trck_Diode_Asso_vs_Mult; //AP, 2015/06/11, distribution of the distance of the associated tracks to closest diode vs associated cluster multiplicity + TH2F* hnpixc_vs_TrkDistToDiode; //AP 2015/06/09, 2D distribution of associated cluster multiplicity vs the associated track distance to closest diode + + TH2F **huvCGtuv_vs_Mult; //AP, 2014/10/23, position of associated tracks wrt sensing diodes vs multiplicity + TH1F *huCGwidth_vs_Mult; //AP, 2014/10/23, u CG residual distribution width vs multiplicity + TH1F *hvCGwidth_vs_Mult; //AP, 2014/10/23, u CG residual distribution width vs multiplicity + TH1F *huCGmean_vs_Mult; //AP, 2014/10/23, u CG residual distribution width vs multiplicity + TH1F *hvCGmean_vs_Mult; //AP, 2014/10/23, u CG residual distribution width vs multiplicity + TH1F **huCGtu1_vs_TracksPerEvent; //AP, 2014/10/31, u CG residual distribution vs Tracks per event in sensor + TH1F **hvCGtv1_vs_TracksPerEvent; //AP, 2014/10/31, u CG residual distribution vs Tracks per event in sensor + TH1F *grvCGVsMult; + TH1F *huCGtu2 ; + TH1F *hvCGtv2 ; + TH1F *hCG2x2tu1; + TH1F *hCG2x2tv1 ; + TH1F *hCG5URes ; + TH1F *hCG5VRes ; + TH1F *hTuHuCorr; + TH1F *hTvHvCorr; + TH1F *hEta2x2tu1; + TH1F *hEta2x2tv1 ; + TH1F *hEtaURes; + TH1F *hEtaVRes ; + TH1F *hEta3URes ; + TH1F *hEta3VRes ; + TH1F *hEtaU_2x2Res; + TH1F *hEtaV_2x2Res; + TH1F *hEtaU_5x5Res; + TH1F *hEtaV_5x5Res; + TH1F *hAHTURes; + TH1F *hAHTVRes; + + TCanvas *cres; + TCanvas **cresfit; // JB 2009/09/14 + TCanvas **cresfit_CG_vs_Mult; //AP, 2014/10/23 + TCanvas *cresfit_CGWidth_vs_Mult; //AP, 2014/10/23 + TCanvas *cresfit_CGMean_vs_Mult; //AP, 2014/10/23 + TLegend* leg_CGWidth_vs_Mult; //AP, 2014/10/23 + TCanvas **cresfit_CG_vs_TracksPerEvent; //AP, 2014/10/31 + TCanvas *cresfit_CGWidth_vs_TracksPerEvent; //AP, 2014/10/31 + + + //------------------------------------------------------------------------------ + // Fake rate study + //------------------------------------------------------------------------------ + TH1F *hNhitperpixel; + TH1F *hNhitRateperpixel; + TH1F *hPixelsPerFakeRate; + + TCanvas *cfake; + + //------------------------------------------------------------------------------ + // tracks properties and chi2 + //------------------------------------------------------------------------------ + + TH1F *hNTracksPerEvent; + TH1F *hNTracksPerEventievt; + TH1F *hNGoodGeomTracksPerEvent; + + TH2F *hAllTvTu; + TH1F *hAllTu ; + TH1F *hAllTv ; + TH2F *hGoodChi2TvTu; + TH1F *hGoodChi2Tu ; + TH1F *hGoodChi2Tv ; + TH1F *hGoodChi2Tx ; + TH1F *hGoodChi2Ty ; + TH1F *hGoodChi2AngleXZ; + TH1F *hGoodChi2AngleYZ; + + TH1F *hchi2_c; + TH1F *hchi2_nc ; + TH1F *hchi2 ; + + TH1F *hTrackToClusterMinDistance ; + TH1F *hTrackTo2ndclosestClusterDistance ; + TH1F *hWrongAssociationProba ; + TH2F *hMinDistance_vs_2ndDistance; + + TH1F *hNhitsPerTrack_all; + TH1F *hNhitsPerTrack_good; + TH1F *hNhitsPerTrack_matched; + + static const Int_t NRefPlane = 10; + TH2F *hRef_Tud_vs_Tv[NRefPlane]; + TH2F *hRef_Tud_vs_Tu[NRefPlane]; + TH2F *hRef_Tud_vs_TDOX[NRefPlane]; + TH2F *hRef_Tud_vs_TDOY[NRefPlane]; + TH2F *hRef_Tud_vs_Chi2[NRefPlane]; + TH2F *hRef_Tud_vs_Tu1[NRefPlane]; + TH2F *hRef_Tud_vs_Tk1[NRefPlane]; + + Char_t titreref[100] ; + Char_t nomRef[50]; + + //------------------------------------------------------------------------------ + // Good/All hits. + //------------------------------------------------------------------------------ + TH1F *hnhitievt ; + TH2F *hnahitievt; + TH1F *hnGOODhit ; + TH1F *hnGOODhitwhentrack; + TH1F *hnTracksinSensorPerEvent; //AP, 2014/10/29, #tracks per event in Sensor + TH1F *hTrackDensity; //AP, 2014/10/29, track density per event in geomatrix + TH1F *hnTracksInGeomatrixVsTrackPerEvent; //AP, 2014/10/29, #tracks vs tracks per event in sensor + TH1F *hnGOODhitInGeomatrixVsTrackPerEvent; //AP, 2014/10/29, #GOOD hits vs tracks per event in sensor + TH1F *hEfficiencyInGeomatrixVsTrackPerEvent; //AP, 2014/10/29, Efficiency vs tracks per event in sensor + TH1F *hResidueUInGeomatrixVsTrackPerEvent; //AP, 2014/10/29, Residue in U vs tracks per event in sensor + TH1F *hResidueVInGeomatrixVsTrackPerEvent; //AP, 2014/10/29, Residue in V vs tracks per event in sensor + TLegend* leg_TracksinSensorPerEvent; //AP, 2014/10/29, Legend for efficiency vs tracks per event in sensor + TLine* l_average_Effic; //AP, 2014/10/29, Line with average efficiency + TLine* l_average_Effic_PErr; //AP, 2014/10/29, Line with average efficiency + Error + TLine* l_average_Effic_MErr; //AP, 2014/10/29, Line with average efficiency - Error + + TH1F *hAllS2N ; + TH1F *hallhitSN ; + TH1F *hallSNneighbour; + TH1F *hgoodSNneighbour; + TH2F *hgoodSN_vs_SNN ; + TH2F *hallSN_vs_SNN; + + TH2F *hallSN_minus_hgoodSN_vs_SNN ; + TH2F *hdistchi2 ; + + //------------------------------------------------------------------------------ + // REAL S/N NEIGHBOURS ----ab25072005 + //------------------------------------------------------------------------------ + + TH2F *hSN_vs_SNNReal; + + //------------------------------------------------------------------------------ + // Charge by ordered pixels Histos. + //------------------------------------------------------------------------------ + //------------- + TH1F *hGOODChargeOrder1 ; + TH1F *hGOODChargeOrder2 ; + TH1F *hGOODChargeOrder3; + TH1F *hGOODChargeOrder4 ; + TH1F *hGOODChargeOrder5 ; + TH1F *hGOODChargeOrder6 ; + TH1F *hGOODChargeOrder7; + TH1F *hGOODChargeOrder8 ; + TH1F *hGOODChargeOrder9 ; + TH2F *hGOODChargeCor_1_2 ; + TH2F *hGOODChargeCor_1_3; + TH2F *hGOODChargeCor_1_4; + TH2F *hGOODChargeCor_2_3 ; + TH1F *hGOODChargeSum_4 ; + TH1F *hGOODChargeRap_1_over_2; + TH1F *hGOODChargeRap_1_over_3 ; + TH1F *hGOODChargeRap_1_over_4; + TH1F *hGOODChargeRap_2_over_3; + + //------------------------------------------------------------------------------ + //----- ? + //------------------------------------------------------------------------------ + + // histograms needed for charge distribution function: + TH2F *hS2N2All; + TH1F *hS2N2nd ; + TH2F *hS2N2RH ; + //Int_t nb=25; Int_t SpreadRange=100; + TH1F *hPedestal; + + //----ALL HITS: Signal / noise seed vs Signal / noise in the pixel range [i-j] + TH2F *hsnALL_seed_vs_pix_0[jpixmax]; + TH2F *hsnALL_seed_vs_pix_1[jpixmax]; + + TH2F *hChargeIntegral1; + TH2F *hChargeNorm1; + TH2F *hChargeIntegral2; + TH2F *hChargeNorm2 ; + TH2F *hChargeIntegral3 ; + TH2F *hChargeNorm3 ; + TH2F *hChargeIntegral4; + TH2F *hChargeNorm4 ; + TH2F *hChargeIntegral; + TH2F *hChargeIntSmoothed; + + //------------------------------------------------------------------------------ + // Check pixel homogeneity depending on real track position + //------------------------------------------------------------------------------ + TH2F *hHOM_tu_tv_modulo; + TH2F *hHOM_ResU_tu; + TH2F *hHOM_ResV_tv; + TProfile *ProfHOM_ResU_tu; + TProfile *ProfHOM_ResV_tv; + + TH2F *hHOM_modUCG_modtu; + TH2F *hHOM_modVCG_modtv; + TH2F *hHOM_modUeta3_modtu; + TH2F *hHOM_modVeta3_modtv; + TH2F *hHOM_modUeta3_realtu; + TH2F *hHOM_modVeta3_realtv; + TH2F *hHOM_modUCG_realtu; + TH2F *hHOM_modVCG_realtv; + TH2F *hHOM_modUeta3_Eta3U; + TH2F *hHOM_modVeta3_Eta3V; + TH2F *hHOM_modUeta3_modVeta3; + TH2F *hHOM_modUCG_modVCG; + TH2F *hHOM_modUeta3_modUCG; + TH2F *hHOM_modVeta3_modVCG; + + TH2F *hHOM_Charge_diodedist_alg; + TH2F *hHOM_Charge_diodedist_alg_u;//clm + TH2F *hHOM_Charge_diodedist_alg_v;//clm + TH2F *hHOM_Charge_diodedist; + TH2F *hHOM_Charge2_diodedist; + TH2F *hHOM_Charge4_diodedist; + TH2F *hHOM_Charge9_diodedist; + TH2F *hHOM_Charge25_diodedist; + TH2F *hHOM_Noise_diodedist; + + // start CLM 2013/01/23 + TProfile2D *ProfhGOODCharge_Charge_DiodePosition; + TProfile2D *ProfhGOODCharge_Charge_DiodePositionSeedQLT300; + TProfile2D *ProfhGOODCharge_Charge_DiodePositionSeedQGT2000; + //clm + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_evencol_evenrow; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_evencol_oddrow; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_oddcol_evenrow; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_oddcol_oddrow; + //clm + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_evencol_evenrow_seed; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_evencol_oddrow_seed; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_oddcol_evenrow_seed; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_oddcol_oddrow_seed; + //clm + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_evencol_evenrow_1stcrown; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_evencol_oddrow_1stcrown; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_oddcol_evenrow_1stcrown; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_oddcol_oddrow_1stcrown; + //clm + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_evencol_evenrow_2ndcrown; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_evencol_oddrow_2ndcrown; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_oddcol_evenrow_2ndcrown; + TProfile2D *ProfhGOODCharge_Charge_DiodePosition_oddcol_oddrow_2ndcrown; + + TH2F* hDistVSeedOtherOldCalc; + TH2F* hDistVSeedOtherNewCalc; + + TH2F* h2dCharge_Charge_DiodePosition_Track; + TH2F* h2dCharge_Charge_DiodePosition_CluSize; + + TH1F* hNpixInClu; + TH1F* hQpixInClu; + + TProfile2D *ProfhGOODCharge_Charge_DiodePositionSimpDist; + + TH3F *hHOM_Charge_diodedist3D; + TH3F *hHOM_Charge2_diodedist3D; + TH3F *hHOM_Charge4_diodedist3D; + TH3F *hHOM_Charge9_diodedist3D; + TH3F *hHOM_Charge25_diodedist3D; + // end CLM 2013/01/23 + + TProfile *ProfHOM_Charge_diodedist_alg; // JB 2010/03/11 + TProfile *ProfHOM_Charge_diodedist_alg_v; //clm 2013/01/23 + TProfile *ProfHOM_Charge_diodedist_alg_u; //clm 2013/01/23 + TProfile *ProfHOM_Charge_diodedist; + TProfile *ProfHOM_Charge2_diodedist; + TProfile *ProfHOM_Charge4_diodedist; + TProfile *ProfHOM_Charge9_diodedist; + TProfile *ProfHOM_Charge25_diodedist; + + TH2F *hHOM_SNseed_diodedist; + TProfile *ProfHOM_SNseed_diodedist; + + TH1F *hHOM_Charge_diodedist_00_10; + TH1F *hHOM_Charge_diodedist_10_20; + TH1F *hHOM_Charge_diodedist_20_30; + TH1F *hHOM_Charge_diodedist_30_40; + TH1F *hHOM_Charge_diodedist_40_50; + TH1F *hHOM_Charge_diodedist_50_60; + TH1F *hHOM_Charge_diodedist_60_70; + TH1F *hHOM_Charge_diodedist_70_80; + TH1F *hHOM_Charge_diodedist_80_90; + TH1F *hHOM_Charge_diodedist_90_inf; + + TH2F *hHOM_DU_Nevent; + TH2F *hHOM_DV_Nevent; + TH2F *hHOM_modtu_Nevent; + TH2F *hHOM_modtv_Nevent; + + TH2F *hHOM_modUCG_Nevent; + TH2F *hHOM_modVCG_Nevent; + + TH1F *hHOM_ResEta25_U; + TH1F *hHOM_ResEta25_V; + + + TH2F *hHOM_modUeta2x2_modVeta2x2; + TH2F *hHOM_modUCG2x2_modVCG2x2; + TH2F *hHOM_modUeta5x5_modVeta5x5; + TH2F *hHOM_modUCG5x5_modVCG5x5; + + + //-------------------------------------------------------------------------- + // cluster shape study, JB 2010/04/13 based on cdritsa stuff + //-------------------------------------------------------------------------- + + TH2F *hClusterMeanForm; + TH1D *hprojLForm; + TH1D *hprojCForm; + TH1F *hCountPixels[10]; + TH2F *hPixelsOverSNR[10]; + TH2F *hPixelsOverCharge[10]; + TH1D *hprojL[10]; + TH1D *hprojC[10]; + TH2F *Cluster[10]; + TH2F *hMultVsFormFactor[10]; + TH1F *hMultVsFormFactor1D[10]; //clm added back 1D clu mult. 2013.08.25 + TH2F *hChargeCoG_Correl; + TH2F *hChargeCoG_Correl2; + TH1F *h_SNRratioL; + TH1F *hClusterTest1; + TH1F *hClusterTest2; + TH1F *hClusterSizeInLines; // JB 2014/03/31 + TH1F *hClusterSizeInColumns; + TH2F *hClusterSize2DInLineAndColumns; // AP 2014/09/25 + TH1F *hChargeDistrInSeed; + TH1F *hChargeDistrInLine; + TH1F *hChargeDistrIn3rdLeftNeigh; + TH1F *hChargeDistrIn2ndLeftNeigh; + TH1F *hChargeDistrIn1stLeftNeigh; + TH1F *hChargeDistrIn3rdRightNeigh; + TH1F *hChargeDistrIn2ndRightNeigh; + TH1F *hChargeDistrIn1stRightNeigh; + TH1F *hClusterTypes; // JB 2014/03/31 + TH1F *hClusterTypesBeyond4; // JB 2015/05/12 + + TCanvas *ang1; + TCanvas *ang2; + TCanvas *ang3; + TCanvas *ang4; + TCanvas *ang5; + TCanvas *ang5v2; + TCanvas *ang6; //clm added back 1D clu mult. 2013.08.25 + TCanvas *shape; + TCanvas *solo; + TCanvas *projL; + TCanvas *projC; + + + //------------------------------------------------------------------------------ + // Binary output histos. + //------------------------------------------------------------------------------ + TH1F *hBinary_test; + TH1F *hBinary_NumberOf_1_ALL; + TH1F *hBinary_NumberOf_1_goodhit; + TH1F *hBinary_NumberOf_1_submatrix; + TH1F *hBinary_Nhitperpixel_submatrix; + TH1F *hBinary_NhitRateperpixel_submatrix; + + + //------------------------------------------------------------------------------ + // MiniVectors Histograms ; NCS , 2010/01/21 + //------------------------------------------------------------------------------ + TH1F* hDiffPosX; // NCS 210110 + TH1F* hDiffPosY;// NCS 210110 + TH1F* hDiffAngleX; // NCS 210110 + TH1F* hDiffAngleY;// NCS 210110 + TH1F* hDiffAngleX11; // JB 2011/11/01 + TH1F* hDiffAngleY11; + TH1F* hDiffAngleX12; // JB 2011/11/01 + TH1F* hDiffAngleY12; + TH1F* hDiffAngleX21; // JB 2011/11/01 + TH1F* hDiffAngleY21; + TH1F* hDiffAngleX22; // JB 2011/11/01 + TH1F* hDiffAngleY22; + TH1F* hDiffAngleXg1g1; // JB 2011/11/01 + TH1F* hDiffAngleYg1g1; + TH1F* hxtxPL3 ; // NCS 260110 not CG position only Hu Hv + TH1F* hytyPL3 ; // NCS 260110 + TH1F* hxtxPL4 ; // NCS 260110 + TH1F* hytyPL4 ; // NCS 260110 + TH1F* hutuPL3 ; // NCS 260110 not CG position only Hu Hv + TH1F* hvtvPL3 ; // NCS 260110 + TH1F* hutuPL4 ; // NCS 260110 + TH1F* hvtvPL4 ; // NCS 260110 + TH2F* hdiffydiffx; // JB 2011/11/01 + TH2F* hdiffydiffx11; // JB 2011/11/01 + TH2F* hdiffydiffx12; // JB 2011/11/01 + TH2F* hdiffydiffx21; // JB 2011/11/01 + TH2F* hdiffydiffx22; // JB 2011/11/01 + TH2F* hdiffydiffxg1g1; // JB 2011/11/01 + + //------------------------------------------------------------------------------ + // MimosaVertexFinder Histograms ; LC , 2012/09/06 + //------------------------------------------------------------------------------ + + TH1F* hVertexPosX; + TH1F* hVertexPosY; + TH1F* hVertexPosZ; + TH1F* hVertexTrackDistance; + TH2F* hVertexPosXY; + TH1F* hVertexTrackChi2; + + TCanvas *cVertexFinder; + + TCanvas *cMiniVec; + TCanvas *cMiniVec1; + + //------------------------------------------------------------------------------ + // canvas + //------------------------------------------------------------------------------ + TCanvas *c2; + TCanvas *casym; + TCanvas *ceffi; + TCanvas *ccomp; + TCanvas *ccomp2; + TCanvas *ccomp3; + TCanvas *c3; + TCanvas *c3_2; + TCanvas *c4; + TCanvas *cClusterProperties2; + TCanvas *cClusterProperties3; + TCanvas *cClusterProperties4; + TCanvas *c4_2; + TCanvas *c5; + TCanvas *c6; + TCanvas *c7; + + static const Int_t numcanvas=4; + static const Int_t numcanvasSN=6; + static const Int_t numcanvasOptimize=1; + TCanvas *cSN[numcanvasSN]; //! + TCanvas *cRef[numcanvas]; //! + TCanvas *cOptimize[numcanvasOptimize]; //! + + TCanvas *cM8; + + + TCanvas *PixHom; + TCanvas *PixHom2; + TCanvas *PixHom3; + TCanvas *PixHom4; + TCanvas *PixHom5; + TCanvas *PixHom6; + + //graphs + TGraphErrors* greff ; + TGraphErrors* grnum ; + TGraphErrors* grevt ; + TGraphErrors* ChargeSpread; + + TControlBar* bar2; + + //------------------------------------------------------------------------------ + // MC Geneation for telescope resolution evaluation + //------------------------------------------------------------------------------ + TH1F *hTrackChi2_MC; + TH1F *hTrackSlopeX_MC; + TH1F *hTrackSlopeY_MC; + TH1F *hTrackNHits_MC; + TH1F *hTrackPlanesUsed_MC; + + static const Int_t MynPlanes = 20; + TH1F *hResidualU_MC[MynPlanes]; + TH1F *hResidualV_MC[MynPlanes]; + + static const Int_t MyBins_GlobalResolution = 50; + TH1F *hTrackResidualAtDUT_U[MyBins_GlobalResolution]; + TH1F *hTrackResidualAtDUT_V[MyBins_GlobalResolution]; + + TH1F* h_TelescopeResolution_Scan_U; + TH1F* h_TelescopeResolution_Scan_V; + TH1F* h_ResidualAtDUT_Scan_U; + TH1F* h_ResidualAtDUT_Scan_V; + + TLine* lSolResolutionU1; + TLine* lSolResolutionU2; + TLine* lSolResolutionU3; + TLine* lSolResolutionV1; + TLine* lSolResolutionV2; + TLine* lSolResolutionV3; + + TCanvas *cgeometry; + TCanvas *cgeometry3D; + TCanvas *ccumultrack3; + TCanvas *ccumultrack4; + TCanvas *ccumultrack5; + TCanvas *cresAtDUT[MyBins_GlobalResolution]; + TCanvas *cresAtDUT_vs_SensorSP; + + static const Int_t MyMaxEventDisplay = 30; + static const Int_t MyMaxNumberOfTracks = 100; + TLine* RectracksXZ[MyMaxEventDisplay][MyMaxNumberOfTracks]; + TLine* RectracksYZ[MyMaxEventDisplay][MyMaxNumberOfTracks]; + TLegend* leg_TelResMC; + TGraph* gtracksXZ[MyMaxEventDisplay][MyMaxNumberOfTracks]; + TGraph* gtracksYZ[MyMaxEventDisplay][MyMaxNumberOfTracks]; + TPolyLine3D* gtracksXYZ[MyMaxEventDisplay][MyMaxNumberOfTracks]; + TPolyMarker3D* gtracksXYZ_mark[MyMaxEventDisplay][MyMaxNumberOfTracks]; + TPolyLine3D* RectracksXYZ[MyMaxEventDisplay][MyMaxNumberOfTracks]; + + TLine **lineXZ; + TLine **lineYZ; + TText* number; + TLatex* latex; + + TH2F* hXZ_MC; + TH2F* hYZ_MC; + + //------------------------------------------------------------------------------ + // User histograms + //------------------------------------------------------------------------------ + TCanvas *cUser; + TH1F* hUserHitCorrelationLine; + TH1F* hUserHitCorrelationCol; + + ClassDef(MHist, 2) +}; + +#endif diff --git a/include/MKalmanFilter.h b/include/MKalmanFilter.h new file mode 100644 index 0000000..07d3e69 --- /dev/null +++ b/include/MKalmanFilter.h @@ -0,0 +1,224 @@ +/***************************************************************************//** + * SVN File: $Id$ + * + * Project: Kalman Filter & Smoother + * + * @class: MKalmanFilter + * + * @brief: + * + * Description: A Kalman filter and smoother implementation + * + * + * @createdby: LIU Qingyuan at 2016-05-20 11:19:00 + * @copyright: (c)2016 IPHC & HEPG - Shandong University. All Rights Reserved. + * + * @lastchange: $Revision$ + * $Author$ + * $Date$ + * + *******************************************************************************/ +#ifndef MKalmanFilter_h +#define MKalmanFilter_h + +#include "TMath.h" +#include +#include + +#include +#include + +class MKalmanFilter { +public: + /// constructor(s) + MKalmanFilter(Double_t mass = 0, Double_t energy = 0, Float_t charge = 1); + + /// destructor + ~MKalmanFilter(); + + /// Reset for next track + void reset(); + + /// Results + const Double_t* getPar()const{return fPar.GetMatrixArray();} + const Double_t* getCov()const{return fCov.GetMatrixArray();} + + Double_t getZ()const{return fZ;} + Bool_t isSmootherEnabled() const{return fSmootherEnabled;} + void initTelescopeTracking(); + /// setting + void setZ(const Double_t z){fZ = z;} + void setSmootherEnabled(const Bool_t enabled){fSmootherEnabled = enabled;} + //void setLayerX(Double_t x){fLayerX = x;} + //void setLayerXOverX0(Double_t xOverX0){fLayerXOverX0 = xOverX0;} + void setBeam(const Double_t mass, const Double_t energy, const Float_t charge=1.){fMass = mass;fEnergy=energy;fCharge = charge;} + + void initKalZParCov(const Double_t z, const Double_t* dataPar, const Double_t * dataCov){ + fZ = z; + fZ0 = z; + fPar.SetMatrixArray(dataPar); + fCov.SetMatrixArray(dataCov); + } + void setPar(const Double_t* data){fPar.SetMatrixArray(data);} + void setCov(const Double_t* data){fCov.SetMatrixArray(data);} + void setHmatrix(const Double_t* data){fHmatrix.SetMatrixArray(data);} + void setFmatrix(const Double_t* data){fFmatrix.SetMatrixArray(data);} + void setMvector(const Double_t* data){fMvector.SetMatrixArray(data);} + void setVmatrix(const Double_t* data){fVmatrix.SetMatrixArray(data);} + void setQmatrix(const Double_t* data){fQmatrix.SetMatrixArray(data);} + + /// KF init, call initKalZParCov(); + //setZ + //setPar + //setCov + + /// KF update + //setZ + //setMvector + //setVmatrix + // forward filter + void update(const Double_t z, const Double_t* meas, const Double_t* measCov=NULL);// + void updateAlt(const Double_t z, const Double_t* meas, const Double_t* measCov=NULL);// Alternative Kalman Filter, uesfull to keep fCov symmetric + // backward filter + void updateBack(const Double_t z, const Double_t* meas, const Double_t* measCov=NULL);// + + /// KF predict/propagate + void prepareFmatrix(const Double_t dz){fFmatrix(0,1) = fFmatrix(2,3) = dz;} + void prepareQmatrix(const Double_t x, const Double_t xOverX0); + // forward filter + void propagateTo(const Double_t z, const Double_t x, const Double_t xOverX0); + // backward filter + void propagateBackTo(const Double_t z, const Double_t x, const Double_t xOverX0); + + /// KF smoother + Bool_t smoothTo(const Double_t z); + void clearSmoother(); + void prepare_propagate(); + void prepare_afterPropagate(); + void prepare_beforeUpdate(); + void prepare_afterUpdate(); + + /// ChiSquare in filtering + Double_t getChiSquare()const{return fChiSquare;} + + + /// tools + void checkCov(TMatrixDSym &m)const; + void print()const; + void setDebugLevel(const Int_t l){fDebugLevel = l;} + +// void makeMatrixSymmetric(TMatrixD &m){ +// TMatrixD tmpMt(TMatrixD::kTransposed,m); +// m = 0.5*(m + tmpMt); +//} + +protected: + + TMatrixD fPar; // State/Parameter vector: ResizeTo(n, 1) latter {x, tanX, y, tanY}; + TMatrixDSym fCov; // Covariance matrix of fPar + + TMatrixD fHmatrix; // Measurement matrix H + TMatrixD fFmatrix; // Propagation function F + TMatrixD fMvector; // Measurement vector + TMatrixDSym fVmatrix; // Covariance matrix of fMvector + + TMatrixDSym fQmatrix; // Covariance matrix of the propagation noise(MCS, Energy loss) + TMatrixD fKmatrix; // Kalman gain + + TMatrixD fResidual; // residual = fMvector - fHmatrix * fPar; + Double_t fChiSquare; + + Double_t fZ; // current telescope plane position + Double_t fZ0; // the first z, which is used to calculate Qmatrix(MS)!! + //Double_t fLayerX; // thickness (mm) + //Double_t fLayerXOverX0; // thickness in radiation length (mm) + + ///Beam + Double_t fMass; // GeV + Double_t fEnergy; // GeV + Float_t fCharge; // charge number + + /// Smoothing related + Bool_t fSmootherEnabled; + Bool_t fSmoothed; + Bool_t fUpdatedBeforePre;// updated before prediction + + // push_back in KF update + std::vector fCovPreArr; // predicted + std::vector fParPreArr; // + std::vector fCovArr; // filtered + std::vector fParArr; // + std::vector fZArr; // fZ(Used as plane index) array ' + // push_back in KF propagateTo + std::vector fFmatrixArr; // propagation matrices + ///iterators + std::vector::iterator itZArr ; + std::vector::iterator itCovPreArr; + std::vector::iterator itCovArr ; + std::vector::iterator itParPreArr; + std::vector::iterator itParArr ; + std::vector::iterator itFmatrixArr; + + ///Tool + Int_t fDebugLevel; +//private: + + + + +}; + +inline void MKalmanFilter::prepare_propagate(){ + if(fSmootherEnabled){ + if (!fSmoothed) + fFmatrixArr.push_back(fFmatrix); + } +} + +inline void MKalmanFilter::prepare_afterPropagate(){ + if(fSmootherEnabled){ + if (!fUpdatedBeforePre && !fSmoothed){ + prepare_beforeUpdate(); + prepare_afterUpdate(); + } + } + fUpdatedBeforePre = kFALSE; +} + +inline void MKalmanFilter::prepare_beforeUpdate(){ + if(fSmootherEnabled){ + if (fSmoothed){ + printf("ERROR: Smoother Already exists! No more updates acceptable!\n"); + exit(0); + } + fZArr.push_back(fZ); + fCovPreArr.push_back(fCov); + fParPreArr.push_back(fPar); + } +} + +inline void MKalmanFilter::prepare_afterUpdate(){ + if(fSmootherEnabled){ + fCovArr.push_back(fCov); + fParArr.push_back(fPar); + } + TMatrixDSym tmpHCHt(fCov); + tmpHCHt.Similarity(fHmatrix); + TMatrixDSym ResidErr(fVmatrix,TMatrixDSym::kMinus, tmpHCHt); + TMatrixDSym ResidErrInv(TMatrixDSym::kInverted, ResidErr); + TMatrixD Increment(1,1); + Increment = ResidErrInv.SimilarityT(fResidual); + fChiSquare += Increment(0,0); + fUpdatedBeforePre = kTRUE; +} + +/// tools +inline void MKalmanFilter::checkCov(TMatrixDSym &m)const{ + for(int i = 0; i< 4; i++){ + for(int j =0; j < i; j++){ + m(j,i) = m(i,j); + } + m(i,i) = TMath::Abs(m(i,i)); + } +} +#endif //~ MKalmanFilter_h diff --git a/include/MLeastChiSquare.h b/include/MLeastChiSquare.h new file mode 100644 index 0000000..39835ae --- /dev/null +++ b/include/MLeastChiSquare.h @@ -0,0 +1,81 @@ +/***************************************************************************//** + * SVN File: $Id$ + * + * Project: PandaX DAQ + * + * @class: MLeastChiSquare + * + * @brief: + * + * Description: Least Chi-square fitting + * + * + * @createdby: LIU Qingyuan at 2016-06-01 14:07:38 + * @copyright: (c)2016 HEPG - Shandong University. All Rights Reserved. + * + * @lastchange: $Revision$ + * $Author$ + * $Date$ + * + *******************************************************************************/ +#ifndef MLeastChiSquare_h +#define MLeastChiSquare_h + +#include "TMath.h" +#include +#include + +#include +#include + + + +class MLeastChiSquare { +public: + /// constructor(s) + MLeastChiSquare(); + + /// destructor + ~MLeastChiSquare(); + + /// Results + Double_t* GetPar(){return fPar.GetMatrixArray();} + Double_t* GetCov(){return fCov.GetMatrixArray();} + + /// Inputs + std::vector* GetPtrMeasArray() {return &fMeasArray;} + std::vector* GetPtrSigmaArray() {return &fSigmaArray;} + std::vector* GetPtrZArray() {return &fZArray;} + std::vector* GetPtrSigmaMSArray() {return &fSigmaMSArray;} + std::vector* GetPtrZScatterArray() {return &fZScatterArray;} + + void Estimate(); + Double_t GetSigmaAtZ(const Double_t &z) const; // calculate the uncertainty of the extrapolated track postition at z + void Print() const; + +protected: + + //Int_t nHits; // number of hits, also used to define fA dimension + /// Inputs + std::vector fMeasArray; // dimension should be n + std::vector fSigmaArray; // measurements uncertainties + std::vector fZArray; // z position of detecting layers + std::vector fSigmaMSArray; // multiple scattering + std::vector fZScatterArray; // z position of scattering layers + + ///Matrices + TMatrixD fPar; // x = x_0 + k * z, fpar = {x_0, slopeX}^T with dimension (2,1) + TMatrixDSym fCov; // Covariance matrix of fPar, dimension(2,2); + TMatrixD fA; // Auxiliary matrix with dimension (n, 2) + // 1, z1, 1, z2, 1, z3 ..., 1, zn + TMatrixD fMeas; // Measurements fMeas = {y1, y2, ..., ynHits}^T with dimentsion (n, 1) + TMatrixDSym fMeasCov; // Covariance matrix of fMeas with dimension (n,n) + + + void PrepareMatrices(); +//private: + + +}; + +#endif //~ MLeastChiSquare_h diff --git a/include/MLinkDef.h b/include/MLinkDef.h new file mode 100644 index 0000000..34d9c5c --- /dev/null +++ b/include/MLinkDef.h @@ -0,0 +1,16 @@ +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class MimosaAnalysis++; +#pragma link C++ class MimosaAlignAnalysis++; +#pragma link C++ class MHist++; +#pragma link C++ class MRaw++; +#pragma link C++ class MRax++; +#pragma link C++ class MAlignment+; +#pragma link C++ class MMillepede+; +#pragma link C++ class MimosaGlobalAlign++; +#pragma link C++ global gTAF; +#endif diff --git a/include/MMillepede.h b/include/MMillepede.h new file mode 100755 index 0000000..d27701d --- /dev/null +++ b/include/MMillepede.h @@ -0,0 +1,122 @@ +#ifndef _MMillepede_included_ +#define _MMillepede_included_ + + +/** MMillepede class for detector alignment - modified C++ implementation of original + millepede package + + \author: Javier Castillo, Ch. Fnck + */ + +#include +#include +#include + +class MMillepede : public TObject { + +public: + /// Standard constructor + MMillepede(); + + virtual ~MMillepede( ); /// Destructor + + /// Initialization + virtual Int_t InitMille(int nglo, int nloc, int nstd, double lResCut, double lResCutInit); + virtual Int_t GlobalFit(double par[], double error[], double pull[]); + virtual Int_t SetGlobalParameters(double *param); + virtual Int_t SetGlobalParameter(int iPar, double vPar); + virtual Int_t SetParSigma(int iPar, double sigma); + virtual Int_t SetNonLinear(int index); + virtual Int_t SetGlobalConstraint(double dercs[], double rhs); + virtual Int_t SetLocalEquation(double dergb[], double derlc[], double rmeas, double sigma); + virtual Int_t LocalFit(int n, double localParams[], Bool_t bSingleFit); + /// Get number of local equations + virtual Int_t GetNLocalEquations() const {return fNLocalEquations;}; + /// Set number of local equations + virtual void SetNLocalEquations(int value) {fNLocalEquations = value;}; + virtual Int_t PrintGlobalParameters() const; + virtual Int_t SetIterations (double cutfac); + virtual Double_t GetParError(int iPar) const; + +private: + + // Max. dimensions + + static const int fgkMaxGlobalPar = 1000; // Max. number of global parameters + static const int fgkMaxLocalPar = 20; // Max. number of local parameters + static const int fgkMaxGloCsts = 20; // Max. number of constraint equations + static const int fgkMaxGloPC = 1020; // fgkMaxGlobalPar+fgkMaxGloCsts + + + // Private methods + + // Double_t GetParCorrelation(int i, int j); + + int SpmInv(double v[][fgkMaxGloPC], double b[], int n); + int SpmInv(double v[][fgkMaxLocalPar], double b[], int n); + int SpAVAt(double v[][fgkMaxLocalPar], double a[][fgkMaxLocalPar], double w[][fgkMaxGlobalPar], int n, int m); + int SpAX(double a[][fgkMaxLocalPar], double x[], double y[], int n, int m); + double Chi2DoFLim(int n, int nd); + + // Matrices + + double fMatCGlo[fgkMaxGloPC][fgkMaxGloPC]; // Matrix C global + double fMatCLoc[fgkMaxLocalPar][fgkMaxLocalPar]; // Matrix C local + double fMatCGloLoc[fgkMaxGlobalPar][fgkMaxLocalPar]; // Rectangular matrix C g*l + double fMatCGloCorr[fgkMaxGlobalPar][fgkMaxGlobalPar];// Correction of matrix C global + double fMatDerConstr[fgkMaxGloCsts][fgkMaxGlobalPar]; // Constrained derivatives + + // Vectors and useful variables + + double fDiagCGlo[fgkMaxGloPC]; // Initial diagonal elements of C global matrix + double fVecBGlo[fgkMaxGloPC]; // Vector B global (parameters) + double fVecBGloCorr[fgkMaxGlobalPar]; // Correction of vector B global + double fVecBLoc[fgkMaxLocalPar]; // Vector B local (parameters) + + double fInitPar[fgkMaxGlobalPar]; // Initial global parameters + double fDeltaPar[fgkMaxGlobalPar]; // Variation of global parameters + double fSigmaPar[fgkMaxGlobalPar]; // Sigma of allowed variation of global parameter + + double fLagMult[fgkMaxGloCsts]; // Lagrange multipliers of constrained equations + + Bool_t fIsNonLinear[fgkMaxGlobalPar]; // Flag for non linear parameters + int fGlo2CGLRow[fgkMaxGlobalPar]; // Global parameter to row in "used" g*l matrix + int fCGLRow2Glo[fgkMaxGlobalPar]; // Row in "used" g*l matrix to global parameter + + TArrayI fIndexLocEq; // Table of parameter indexes in local equation + TArrayD fDerivLocEq; // Table of local equation derivatives wrt. parameter + TArrayI fIndexAllEqs; // Index in all loc. eq. storage for iterations + TArrayD fDerivAllEqs; // derivative in all loc. eq. storage for iterations + TArrayI fLocEqPlace; // Loc. Eq. position in AllEqs storage + + Int_t fNIndexLocEq; // Number of entries in fIndexLocEq + Int_t fNDerivLocEq; // Number of entries in fDerivLocEq + Int_t fNIndexAllEqs; // Number of entries in fIndexAllEqs + Int_t fNDerivAllEqs; // Number of entries in fDerivAllEqs + Int_t fNLocEqPlace; // Number of entries in fLocEqPlace + + + int fNLocalEquations; // Number of local equations + double fResCutInit; // Cut in residual for first iterartion + double fResCut; // Cut in residual for other iterartiona + + double fChi2CutFactor; // Cut factor for chi2 cut to accept local fit + double fChi2CutRef; // Reference cut for chi2 cut to accept local fit + + int fIter; // Current iteration + int fMaxIter; // Maximum number of iterations + int fNStdDev; // Number of standard deviations for chi2 cut + int fNGlobalConstraints; // Number of constraint equations + int fNLocalFits; // Number of local fits + int fNLocalFitsRejected; // Number of local fits rejected + int fNGlobalPar; // Number of global parameters + int fNLocalPar; // Number of local parameters + Int_t fDebugLevel; // debug level + + ClassDef(MMillepede, 0) // Millepede Class +}; + +#endif + + + diff --git a/include/MRaw.h b/include/MRaw.h new file mode 100644 index 0000000..1dab88f --- /dev/null +++ b/include/MRaw.h @@ -0,0 +1,312 @@ +// @(#)MRaw.h $:$Id: MRaw.h,v.1 2005/10/02 18:03:46 sha Exp $ +// Author: A. Shabetai + +#ifndef _MRaw_included_ +#define _MRaw_included_ + + ///////////////////////////////////////////////////////////// + // // + // Describes all Raw data analysis methods // + // // + ///////////////////////////////////////////////////////////// + +#include "TObject.h" +#include "DTracker.h" +#include "DSession.h" +#include "Riostream.h" +#include "DPlane.h" +#include "TStyle.h" +#include "TTree.h" +#include "TH2F.h" +#include "TCanvas.h" +#include "DHit.h" +#include "DStrip.h" +#include "TPolyMarker.h" +#include "TF1.h" +#include "TText.h" +#include +#include "TControlBar.h" +#include "MAnalysis.h" +#include "DPixel.h" +#include "DBeaster.h" +//#include "DMonteCarlo.h" +#include "DAcq.h" +#include "DGlobalTools.h" // to have fTool has a data member +#include "tiffio.h" + +class MRaw : public TObject { + + private: + + static MRaw* fgInstanceRaw; + + //-------- Control parameters + Bool_t fVerbose; + Int_t fDebugRaw; // JB 2014/05/29 + DGlobalTools fTool; // JB 2011/07/18 to use global tools + DSession *fSession; // JB 2011/07/21 to get rid of global var tSession + + Float_t NbinsReductionFactor; // JB 2014/12/08 + Int_t MultiFramePlane; // JB 2013/07/18 + Int_t MultiFrameNFrames; + + TH1F *hnnois1; + TH1F *hraw1; + TH1F *hson1; + TH1F *hson; + TH1F *hpu; + TH1F *hpu1; + TH1F *hnoisd; + TH1F *hped; + TH1F *hpedd; + TH1F *raww1; + TH2F *raw1; + TH2F *raw2; + TH2F *raww; + TH2F *hit0; + TH2F *hit; + TH2F *hnnois; + TH2F *hNoisyChannels; + + + DTracker *tTracker; + Bool_t startMIMOSA; + Bool_t startRS; + Bool_t showit; + + TH1F* hson_iterated; + TH1F* hson_iterated2; //ADAPTED FOR MI5 + TH1F* hson_iterated3; //ADAPTED FOR MI5 + TH1F* hson_iterated4 ; //ADAPTED FOR MI5 + TH1F* hson_substract2_3; //ADAPTED FOR MI5 + TH1F* hson_substract3_4; + TH2F* hhitmap; + + Int_t nh; + TCanvas *cnv; + + //-------iterated histogram setting: + Int_t iterated_bin_number; + Float_t iterated_xmin_number; + Float_t iterated_xmax_number; + + TControlBar* bar3; + Bool_t fInitDone; + Bool_t fMDisplayDone; + + Bool_t CheckIfDone(const Option_t* Option); + TH1F* Zero(TH1F* ptr) { if(ptr) {delete ptr;ptr=0;}return ptr;}; + + Int_t fUserFileNumber; + Int_t GetFileNumber(); + + // Sitrineo + struct sitrihitpair_t { + int plane1; + int hitid1; + double x1; + double y1; + double z1; + int plane2; + int hitid2; + double x2; + double y2; + double z2; + double deltaX; + double deltaY; + double deltaZ; + double slopeX; + double slopeY; + }; + struct sitritrack_t { + int id; + int firstTrackID; + int secondTrackID; + int plane[4]; + int hit[4]; + double secondtrack_DX ; + double secondtrack_DY ; + double secondtrack_DZ ; + double secondtrack_slopeX; + double secondtrack_slopeY; + double firsttrack_DX ; + double firsttrack_DY ; + double firsttrack_DZ ; + double firsttrack_slopeX; + double firsttrack_slopeY; + double Dslope_X; + double Dslope_Y; + double momentum_X; + double momentum_Y; + double fit_origin_X; + double fit_origin_Y; + double fit_slope_X; + double fit_slope_Y; + double fit_momentum; + double fit_chi2X; + double fit_chi2Y; + }; + + + public: + MRaw( DSession *aSession); + virtual ~MRaw(){;} + void InitScan(Int_t Events2Scan = 400,Float_t SignalOverNoiseCut = 5); // Accumulate certain amount of events for scanning + void MimosaDisplay(Int_t NEVENT = 1); // event display. + void RSDisplay(); //Display Ref.system events + void InspectScan(); // inspects events + void Inspectfake(); //inspects fakes + void MimosaJump(Int_t Njump =10); // jumps events + void PrepareRaw(); + void Clear(const Option_t* /*option*/ = ""); + void InspectRawChannels( Int_t nEvents=1000, Int_t thePlaneNumber=1, Int_t firstChannel=0, Int_t nChannels=1, Int_t maxAutoCorr=20); // JB 2012/09/20 + void DisplayRawData( Float_t nChanToDisplay = .5); + void DisplayRawData2D(Float_t minSN=-65536., Bool_t withHits=kTRUE, Bool_t withTracks=kTRUE, Int_t triggerNb=-1, Int_t clusterMultiplicity=-1, + double Rminu = -1.0e10, + double Rmaxu = -1.0e10, + double Rminv = -1.0e10, + double Rmaxv = -1.0e10); + void DisplayHits2D( Int_t ifIndex=2, Int_t ifTrack=1, Int_t geomatrix=0); //JB 2012/04/02 + void DisplayTracks(); // JB 2011/07/26 + void DisplayCumulatedTracks( Int_t nEvents=1000); + void DisplayCumulatedSubtracks( Int_t nEvents=1000, Int_t dutPlaneNb=-1); //JB 2014/12/23 + void DisplayCumulatedHits2D(Int_t nEvents=1000, + Bool_t ifDrawTrack=kTRUE, + Bool_t Define_Range=kFALSE, + int bins = 100, + double Xmin = -1.0e10, + double Xmax = -1.0e10, + double Ymin = -1.0e10, + double Ymax = -1.0e10, + Bool_t Define_QRange=kFALSE, + int qbins = 1000, + double qmax = 1000); + void DisplayLadderCumulatedHits2D( Int_t nEvents=1000, + Bool_t ifDrawTrack=kTRUE, + Bool_t Define_Range=kTRUE, + Int_t bins=100, + Double_t Xmin=-1.0e-10, + Double_t Xmax=-1.0e-10, + Double_t Ymin=-1.0e-10, + Double_t Ymax=-1.0e-10); // LC 2015/02/17 +///////////////////////////////////////// +/////// Methods For Beast /////////////// +void DisplayBeast(); +void DisplayCumulatedBeast(int MaxEvt); +void BeastStatStudy(); +int GetBeastModuleId(int SensorId); +int GetBeastLadderId(int SensorId); +void BeastCheckPosition(); +///////////////////////////////////////// + + + + void DisplayCumulatedRawData2D(Int_t nEvents=500, TString str_EvtParsingMode="continuous", Float_t minSN=-65536., Float_t occurence_min=.001, + Float_t occurence_max=1., + Int_t nOccurences=20, + Float_t minOccurence=0., + Bool_t storeOccurence=kFALSE, + double Colmin = -1.0e10, double Colmax = -1.0e10, + double Linmin = -1.0e10, double Linmax = -1.0e10); //RDM280509, JB 2011/03/14 + void DisplayCumulatedOverflow( Int_t nEvents=500); //MG 2012/03/14 + void DisplayNoise( Int_t thePlaneNumber=-1, Float_t calibFactor=-1., Float_t maxAxisNoise=0., Float_t maxAxisPed=0., Bool_t ifPixelHistory=kFALSE); + void SkipEvent( Int_t nEventsToSkip); + void DisplaySpectrum(Int_t nEvents, Int_t minSN=3, Int_t minValue=0, Int_t maxValue=4096); //26/05/09 YV + void DisplayCumulatedClusters(Int_t planeNumber, Int_t nEvents); //JB 2011/02/07 + void LaserStudy( Int_t Xpixel=125, Int_t Ypixel=125, Int_t nPixels=50, Int_t nEvents=1000, Int_t cycleLength=20, Int_t nSpots=10); //JB+MB 2011/02/25 + void VertexStudy( Int_t nEvents=1000, Double_t lineX=0., Double_t lineY=0., Double_t beamTilt=0.); //JB 2011/07/26 + void DisplayGeometry(); // JB 2011/11/01 + void MakeLadderGeometry( Int_t *planeList, Int_t numberOfPlanes, Int_t aRefPlaneNumber); // JB 2014/02/12 + void FakeRateBinaryFromRawData( Int_t nEvents, Int_t aPLaneNumber, Int_t maxPixPerEvent = 100, Double_t maxRateForTruncation=0.01, Int_t lowestCol=0, Int_t highestCol=0, Int_t lowestRow=0, Int_t highestRow=0); // JB 2011/11/22 + void DumpEventHeader( Int_t nEvents); // JB 2012/05/03 + void UserPlot( Int_t nEvents=1000 ); // JB 2009/09/08 + void ToggleVerbosity(); // JB 2011/02/09 + void DisplayCumulatedMonteCarlo2D( Int_t nEvents=1000, Bool_t ifDrawTrack=kTRUE); // LC 2012/10/19 + void SetMultiFrame( Int_t aPlane, Int_t nFrames ); // JB 2013/07/18 + void SetNbinsReductionFactor( Float_t aFactor); // JB 2014/12/08 + void DisplayHistory( Int_t nEvents=50000, Int_t nCumul=500); // JB 2014/05/27 + void SetDebugLevel( Int_t aLevel) { fDebugRaw = aLevel; }; // JB 2014/05/29 + void DisplayImage( Int_t nEvents=1, Int_t planeToPlot=4, TString data=TString("raw"), TString format=TString("gif"), Bool_t displayImage=1, Bool_t saveImage=1, Float_t minValue=-65536, Float_t NBins=1., Bool_t greyScale=kTRUE, TString flip=TString("Y")); + void StudyTrackMultiplicity( TH1F *hNTracksPerPlanes, TH1F *hNHitsPerTrack, Int_t nEvents); + void StudyTrackingEfficiency(Int_t nEvents, + Double_t nHitsMax = -1/*Default: Set default nHitsMax from conf file*/, + Double_t Xmin = -1e6, Double_t Xmax = 1e6, + Double_t Ymin = -1e6, Double_t Ymax = 1e6); // QL, 2015/04/10 + void StudyMultipleScattering( Int_t nEvents, Int_t set0plane0, Int_t set0plane1, Int_t set1plane0, Int_t set1plane1 ); // JB 2015/08/21 + void StudyBeamProfile(Int_t nEvents = 1000, + Bool_t ifFit2DGaus = false, // time consuming + double Xmin = -1.0e10, + double Xmax = 1.0e10, + double Ymin = -1.0e10, + double Ymax = 1.0e10); // QL, 2015/10/26 + void XrayAnalysis(Int_t nEvents=1000, + Bool_t ProduceTree = kFALSE, + Bool_t ifDrawTrack=kTRUE, + Bool_t Define_Range=kFALSE, + int bins = 100, + double Xmin = -1.0e10, + double Xmax = -1.0e10, + double Ymin = -1.0e10, + double Ymax = -1.0e10, + Float_t HighestPeakPositionEv=0, + Float_t MinSpectrum=1000, + Float_t MaxSpectrum=7000, + Bool_t readNormFromFile=kFALSE, + Bool_t normalizeADCspectrum=kFALSE, + Float_t cutLimit=0.95, + Int_t fitXray=0); + + void SeedCuts(Int_t nEvents=1000); + + void BuildPixelGainMap( Int_t nEvents=100000, Double_t min=850, Double_t max=960, Double_t maxcharge=2500 ); // JB 2018/07/04 + + void BetaSourceMultiFrameAnalysis(int aPlane = 0, + int nFrames = 0, + Int_t nEvents=1000, + Bool_t ProduceTree = kFALSE, + int Npixel_TimeSpaceCut = 5, + double SAveN_cutFit = 12.0, + int Fiducial_col_min = -1, + int Fiducial_col_max = -1, + int Fiducial_row_min = -1, + int Fiducial_row_max = -1); + + void CumulateTxtFrames( Int_t nEvents=1000, Int_t nCumulFrames=100); + + void FillnTupleForTMVA(int nEvents = 100, + double my_theta_mean = 0.0, + double my_phi_mean = 0.0); + + void TrainTMVA(TString myMethodList = "", + TString fname = "", + TString TreeName = "T", + TString OutputFile = "TMVAReg.root", + int Nevts_training = 10000, + int Nevts_testing = 10000); + + void SitrineoByEvent( Int_t lastPlaneOfFirstTracker=2, Double_t maxX1=20000, Double_t maxY1=20000, Double_t maxSlopeX1=3.2, Double_t maxSlopeY1=3.2, Double_t maxDX2=20000, Double_t maxDY2=20000, Double_t maxSlopeX2=3.2, Double_t maxSlopeY2=3.2); + void SitrineoCumul( Int_t nEvents=1000, Int_t lastPlaneOfFirstTracker=2, Double_t maxX1=20000, Double_t maxY1=20000, Double_t maxSlopeX1=3.2, Double_t maxSlopeY1=3.2, Double_t maxDX2=20000, Double_t maxDY2=20000, Double_t maxSlopeX2=3.2, Double_t maxSlopeY2=3.2); + void SitrineoAnalysis( Int_t lastPlaneOfFirstTracker, vector *tracklist); + int SitrineoAnalysisFromHits( Int_t lastPlaneOfFirstTracker, vector *tracklist, Double_t minX1=-10000, Double_t maxX1=10000, Double_t minY1=-10000, Double_t maxY1=10000, Double_t maxSlope1=30.); + + + using TObject::Clear; + + static MRaw*& InstanceRaw( DSession *aSession) { + // Modified: JB 2011/07/21 to pass session pointer + if (!fgInstanceRaw) + { + cout<<"No current Mimosa Raw session detected! Creating a new one..."< +#include +#include + + +class MRax : public TObject +{ +//______________________________________________________________________________________________________ +// +// MRAX configuration +//______________________________________________________________________________________________________ + //**************************************************************** + // General configuration + //**************************************************************** +private: + Int_t ConfigureGeneral(void); + + //**************************************************************** + // Displays configuration + //**************************************************************** +private: + Int_t ConfigureDisplays(void); + +private: + Int_t configDisplaysPadDivideX; + Int_t configDisplaysPadDivideY; + std::vector configPlanesDrawOrder_default; + std::vector configPlanesLeftRight_default; + std::vector configPlanesDrawOrder_custom1; + std::vector configPlanesLeftRight_custom1; + Int_t configOverlapLineRowNumber; + + +//______________________________________________________________________________________________________ +// +// Display functions : pixels, hits, tracks, vertices +//______________________________________________________________________________________________________ + //**************************************************************** + // Pixels in Cmos Frame [Pixels] + //**************************************************************** +public: + Int_t DisplayPixelsInCmosFrameInPixel_Init(void); + Int_t DisplayPixelsInCmosFrameInPixel_Fill(void); + Int_t DisplayPixelsInCmosFrameInPixel_Show(Bool_t WithHits=1, Bool_t WithOverlapLine=1,Bool_t WithZbar=1, Int_t minPixOccu=0); + Int_t DisplayPixelsInCmosFrameInPixel_Save(vector &vectorStringFilesExtensions); + Int_t DisplayPixelsInCmosFrameInPixel_SaveHistos(void); + Int_t DisplayPixelsInCmosFrameInPixel_Reset(void); + Int_t DisplayPixelsInCmosFrameInPixel_Kill(void); + +private: + Bool_t flagDisplayPixelsInCmosFrameInPixel_Init; + Int_t *DisplayPixelsInCmosFrameInPixel_PlanesDrawOrder; + TCanvas *canvasDisplayPixelsInCmosFrameInPixel; + TPaveLabel *labelDisplayPixelsInCmosFrameInPixel; + TPad *padDisplayPixelsInCmosFrameInPixel; + TH2I **histoDisplayPixelsInCmosFrameInPixel_RAW; + TH2I **histoDisplayPixelsInCmosFrameInPixel_HIT; + TLine **lineDisplayPixelsInCmosFrameInPixel; + Int_t eventsProcessedDisplayPixelsInCmosFrameInPixel; + + //**************************************************************** + // Noisy Pixels + //**************************************************************** +public: + Int_t DisplayNoiseStudy_Init(void); + Int_t DisplayNoiseStudy_Show(Float_t relOccur_min=0.01, Float_t relOccur_max=1, UInt_t relOccur_steps=20, Bool_t xAxisLog0_Lin1=0); + Int_t DisplayNoiseStudy_Save(vector &vectorStringFilesExtensions); + Int_t DisplayNoiseStudy_SaveHistos(); + Int_t DisplayNoiseStudy_Reset(void); + Int_t DisplayNoiseStudy_Kill(void); + +private: + Bool_t flagDisplayNoiseStudy_Init; + Int_t *DisplayNoiseStudy_PlanesDrawOrder; + TCanvas *canvasDisplayNoiseStudy; + TPaveLabel *labelDisplayNoiseStudy; + TPad *padDisplayNoiseStudy; + TGraph **graphDisplayNoiseStudy; + + //**************************************************************** + // Pixels in FIRST board Frame [Pixels] + //**************************************************************** +public: + Int_t DisplayPixelsInFirstBoardFrameInPixel_Init(void); + Int_t DisplayPixelsInFirstBoardFrameInPixel_Fill(void); + Int_t DisplayPixelsInFirstBoardFrameInPixel_Show(Bool_t WithHits=1, Bool_t WithOverlapLine=1,Bool_t WithZbar=1, Int_t minPixOccu=0); + Int_t DisplayPixelsInFirstBoardFrameInPixel_Save(vector &vectorStringFilesExtensions); + Int_t DisplayPixelsInFirstBoardFrameInPixel_Reset(void); + Int_t DisplayPixelsInFirstBoardFrameInPixel_Kill(void); + +private: + Bool_t flagDisplayPixelsInFirstBoardFrameInPixel_Init; + Int_t *DisplayPixelsInFirstBoardFrameInPixel_PlanesDrawOrder; + Char_t *DisplayPixelsInFirstBoardFrameInPixel_PlanePosition; + TCanvas *canvasDisplayPixelsInFirstBoardFrameInPixel; + TPaveLabel *labelDisplayPixelsInFirstBoardFrameInPixel; + TPad *padDisplayPixelsInFirstBoardFrameInPixel; + TH2I **histoDisplayPixelsInFirstBoardFrameInPixel_RAW; + TH2I **histoDisplayPixelsInFirstBoardFrameInPixel_HIT; + TLine **lineDisplayPixelsInFirstBoardFrameInPixel; + TGaxis **axisDisplayPixelsInFirstBoardFrameInPixel; + TF1 *faxisDisplayPixelsInFirstBoardFrameInPixel_XLeft; + TF1 *faxisDisplayPixelsInFirstBoardFrameInPixel_YLeft; + TF1 *faxisDisplayPixelsInFirstBoardFrameInPixel_XRight; + TF1 *faxisDisplayPixelsInFirstBoardFrameInPixel_YRight; + Int_t eventsProcessedDisplayPixelsInFirstBoardFrameInPixel; + + //**************************************************************** + // Hits in Cmos Frame [Pixels] + //**************************************************************** +public: + Int_t DisplayHitsInCmosFrameInPixel_Init(void); + Int_t DisplayHitsInCmosFrameInPixel_Fill(void); + Int_t DisplayHitsInCmosFrameInPixel_Show(Bool_t ShowAsso2TrackHits=1, Bool_t WithOverlapLine=1,Bool_t HitShowedAsPix=0, Int_t minHitOccu=0); + Int_t DisplayHitsInCmosFrameInPixel_Save(vector &vectorStringFilesExtensions); + Int_t DisplayHitsInCmosFrameInPixel_Reset(void); + Int_t DisplayHitsInCmosFrameInPixel_Kill(void); + +private: + Bool_t flagDisplayHitsInCmosFrameInPixel_Init; + Int_t *DisplayHitsInCmosFrameInPixel_PlanesDrawOrder; + TCanvas *canvasDisplayHitsInCmosFrameInPixel; + TPaveLabel *labelDisplayHitsInCmosFrameInPixel; + TPad *padDisplayHitsInCmosFrameInPixel; + TH2I **histoDisplayHitsInCmosFrameInPixel_unTrack, **histoDisplayHitsInCmosFrameInPixel_Track; + TLine **lineDisplayHitsInCmosFrameInPixel; + Int_t eventsProcessedDisplayHitsInCmosFrameInPixel; + + //**************************************************************** + // Hits in FIRST board Frame [Pixels] + //**************************************************************** +public: + Int_t DisplayHitsInFirstBoardFrameInPixel_Init(void); + Int_t DisplayHitsInFirstBoardFrameInPixel_Fill(void); + Int_t DisplayHitsInFirstBoardFrameInPixel_Show(Bool_t ShowAsso2TrackHits=1, Bool_t WithOverlapLine=1,Bool_t HitShowedAsPix=0, Int_t minHitOccu=0); + Int_t DisplayHitsInFirstBoardFrameInPixel_Save(vector &vectorStringFilesExtensions); + Int_t DisplayHitsInFirstBoardFrameInPixel_Reset(void); + Int_t DisplayHitsInFirstBoardFrameInPixel_Kill(void); + +private: + Bool_t flagDisplayHitsInFirstBoardFrameInPixel_Init; + Int_t *DisplayHitsInFirstBoardFrameInPixel_PlanesDrawOrder; + Char_t *DisplayHitsInFirstBoardFrameInPixel_PlanePosition; + TCanvas *canvasDisplayHitsInFirstBoardFrameInPixel; + TPaveLabel *labelDisplayHitsInFirstBoardFrameInPixel; + TPad *padDisplayHitsInFirstBoardFrameInPixel; + TH2I **histoDisplayHitsInFirstBoardFrameInPixel_unTrack, **histoDisplayHitsInFirstBoardFrameInPixel_Track; + TLine **lineDisplayHitsInFirstBoardFrameInPixel; + TGaxis **axisDisplayHitsInFirstBoardFrameInPixel; + TF1 *faxisDisplayHitsInFirstBoardFrameInPixel_XLeft; + TF1 *faxisDisplayHitsInFirstBoardFrameInPixel_YLeft; + TF1 *faxisDisplayHitsInFirstBoardFrameInPixel_XRight; + TF1 *faxisDisplayHitsInFirstBoardFrameInPixel_YRight; + Int_t eventsProcessedDisplayHitsInFirstBoardFrameInPixel; + + //**************************************************************** + // Hits in Tracker Frame [um] + //**************************************************************** +public: + Int_t DisplayHitsInTrackerFrameInUm_Init(void); + Int_t DisplayHitsInTrackerFrameInUm_Fill(void); + Int_t DisplayHitsInTrackerFrameInUm_Show(Int_t TrackDisplayMode=1 /*0:0; 1:circle; 2:text*/); + Int_t DisplayHitsInTrackerFrameInUm_Save(vector &vectorStringFilesExtensions); + Int_t DisplayHitsInTrackerFrameInUm_Reset(void); + Int_t DisplayHitsInTrackerFrameInUm_Kill(void); + +private: + Bool_t flagDisplayHitsInTrackerFrameInUm_Init; + Int_t *DisplayHitsInTrackerFrameInUm_PlanesDrawOrder; + TCanvas *canvasDisplayHitsInTrackerFrameInUm; + TPaveLabel *labelDisplayHitsInTrackerFrameInUm; + TPad *padDisplayHitsInTrackerFrameInUm; + TH2I **histoDisplayHitsInTrackerFrameInUm_HIT; + TH2I **histoDisplayHitsInTrackerFrameInUm_HITasso2track; + TH2I **histoDisplayHitsInTrackerFrameInUm_HITintersecTrackPlane; + Int_t eventsProcessedDisplayHitsInTrackerFrameInUm; + + //**************************************************************** + // Hits in Tracker Frame Overlay view [um] + //**************************************************************** +public: + Int_t DisplayHitsInTrackerFrameInUmOverlayed_Init(Bool_t alignMode=1); + Int_t DisplayHitsInTrackerFrameInUmOverlayed_Fill(void); + Int_t DisplayHitsInTrackerFrameInUmOverlayed_Show(Bool_t *planes2display=NULL); + Int_t DisplayHitsInTrackerFrameInUmOverlayed_Save(vector &vectorStringFilesExtensions); + Int_t DisplayHitsInTrackerFrameInUmOverlayed_Reset(void); + Int_t DisplayHitsInTrackerFrameInUmOverlayed_Kill(void); + +private: + Bool_t flagDisplayHitsInTrackerFrameInUmOverlayed_Init; + TCanvas *canvasDisplayHitsInTrackerFrameInUmOverlayed; + TPaveLabel *labelDisplayHitsInTrackerFrameInUmOverlayed; + TPad *padDisplayHitsInTrackerFrameInUmOverlayed; + TH2I **histoDisplayHitsInTrackerFrameInUmOverlayed; + Bool_t *flagsDisplayHitsInTrackerFrameInUmOverlayed_plan2disp; + Int_t eventsProcessedDisplayHitsInTrackerFrameInUmOverlayed; + + //**************************************************************** + // Tracks in 3D (obviously in Tracker Frame [um]) + //**************************************************************** +public: + Int_t DisplayTracksIn3D_Init(void); + Int_t DisplayTracksIn3D_Show(Bool_t DrawTracks=1, Bool_t DrawSensors=1, Bool_t DrawTrackedHits=1, Bool_t DrawAllHits=1); + Int_t DisplayTracksIn3D_Save(vector &vectorStringFilesExtensions); + Int_t DisplayTracksIn3D_Reset(void); + Int_t DisplayTracksIn3D_Kill(void); + +private: + Bool_t flagDisplayTracksIn3D_Init; + TCanvas *canvasDisplayTracksIn3D; + TPaveLabel *labelDisplayTracksIn3D; + TPad *padDisplayTracksIn3D; + TH3I *histoDisplayTracksIn3D; + Double_t DisplayTracksIn3DViewLimitZmin,DisplayTracksIn3DViewLimitZmax; + Double_t DisplayTracksIn3DViewLimitXmin,DisplayTracksIn3DViewLimitXmax; + Double_t DisplayTracksIn3DViewLimitYmin,DisplayTracksIn3DViewLimitYmax; + + //**************************************************************** + // Tracks in 2D (obviously in Tracker Frame [um]) + //**************************************************************** +public: + Int_t DisplayTracksIn2D_Init(void); + Int_t DisplayTracksIn2D_Show(Bool_t DrawTracks=1, Bool_t DrawSensors=1, Bool_t DrawTrackedHits=1, Bool_t DrawAllHits=1); + Int_t DisplayTracksIn2D_Save(vector &vectorStringFilesExtensions); + Int_t DisplayTracksIn2D_Reset(void); + Int_t DisplayTracksIn2D_Kill(void); + +private: + Bool_t flagDisplayTracksIn2D_Init; + TCanvas *canvasDisplayTracksIn2D; + TPaveLabel *labelDisplayTracksIn2D; + TPad *padDisplayTracksIn2D; + TH2I **histoDisplayTracksIn2D_XZ; + TH2I **histoDisplayTracksIn2D_YZ; + Double_t DisplayTracksIn2DViewLimitZmin,DisplayTracksIn2DViewLimitZmax; + Double_t DisplayTracksIn2DViewLimitXmin,DisplayTracksIn2DViewLimitXmax; + Double_t DisplayTracksIn2DViewLimitYmin,DisplayTracksIn2DViewLimitYmax; + + //**************************************************************** + // Vertices Projections (obviously in Beam Frame [um]) + //**************************************************************** +public: + Int_t DisplayVerticesProjs_Init(void); + Int_t DisplayVerticesProjs_Show(Bool_t DrawTarget=1); + Int_t DisplayVerticesProjs_Save(vector &vectorStringFilesExtensions); + Int_t DisplayVerticesProjs_Reset(void); + Int_t DisplayVerticesProjs_Kill(void); + +private: + Bool_t flagDisplayVerticesProjs_Init; + TCanvas *canvasDisplayVerticesProjs; + TPaveLabel *labelDisplayVerticesProjs; + TPad *padDisplayVerticesProjs; + TH1F **histoDisplayVerticesProjections; + + Double_t confDisplayVerticesProjsImin,confDisplayVerticesProjsImax; + Int_t confDisplayVerticesProjsIbin; + Double_t confDisplayVerticesProjsJmin,confDisplayVerticesProjsJmax; + Int_t confDisplayVerticesProjsJbin; + Double_t confDisplayVerticesProjsKmin,confDisplayVerticesProjsKmax; + Int_t confDisplayVerticesProjsKbin; + + + //**************************************************************** + // Vertices in 3D (obviously in Beam Frame [um]) + //**************************************************************** +public: + Int_t DisplayVerticesIn3D_Init(void); + Int_t DisplayVerticesIn3D_Show(Bool_t DrawSensors=1, Bool_t DrawTracks=1, Bool_t DrawTrackerDir=1, Bool_t DrawTarget=1, Bool_t DrawBeam=1, Bool_t DrawVerticesPoints=1, Bool_t DrawVerticesPointsSmall=1, Bool_t DrawAcceptance=1); + Int_t DisplayVerticesIn3D_Save(vector &vectorStringFilesExtensions); + Int_t DisplayVerticesIn3D_Reset(void); + Int_t DisplayVerticesIn3D_Kill(void); + +private: + Bool_t flagDisplayVerticesIn3D_Init; + TCanvas *canvasDisplayVerticesIn3D; + TPaveLabel *labelDisplayVerticesIn3D; + TPad *padDisplayVerticesIn3D; + TH3I *histoDisplayVerticesIn3D; + // Draw objects + TPolyLine3D *linesTraget[12]; // 3 times 4 lines to draw a cube + TPolyLine3D *lineBeamDisplayStrong, *lineBeamDisplayMedium, *lineBeamDisplayLight; + TPolyLine3D **lineBoxPlane; + TPolyLine3D *lineTrackDir; + TPolyLine3D *lineTrack; + // Geometry + Int_t id_i, id_j, id_k; + Double_t distDisplayedTracks; + Double_t DispVer3DViewLimitImin,DispVer3DViewLimitImax; + Double_t DispVer3DViewLimitJmin,DispVer3DViewLimitJmax; + Double_t DispVer3DViewLimitKmin,DispVer3DViewLimitKmax; + Double_t aPosition[3]; + DR3 DispVer3D_TrackerTilt, DispVer3D_TrackerTranslation; + Double_t coord_i[2],coord_j[2],coord_k[2]; + +//______________________________________________________________________________________________________ +// +// Display statistics +//______________________________________________________________________________________________________ + //**************************************************************** + // CMOS overflow lines + //**************************************************************** +public: + Int_t DisplayCmosOverFlow_Init(void); + Int_t DisplayCmosOverFlow_Fill(void); + Int_t DisplayCmosOverFlow_Show(); + Int_t DisplayCmosOverFlow_Save(vector &vectorStringFilesExtensions); + Int_t DisplayCmosOverFlow_Reset(void); + Int_t DisplayCmosOverFlow_Kill(void); + +private: + Bool_t flagDisplayCmosOverFlow_Init; + Int_t *DisplayCmosOverFlow_PlanesDrawOrder; + TCanvas *canvasDisplayCmosOverFlow; + TPaveLabel *labelDisplayCmosOverFlow; + TPad *padDisplayCmosOverFlow; + TH1I **histoDisplayCmosOverFlowRows,**histoDisplayCmosOverFlowRowsNb; + Int_t eventsProcessedDisplayCmosOverFlow; + + //**************************************************************** + // Clusters size (a hit is the center of a cluster) + //**************************************************************** +public: + Int_t DisplayClustersSize_Init(Int_t nbBinX = 30); + Int_t DisplayClustersSize_Fill(void); + Int_t DisplayClustersSize_Show(Bool_t All=1,Bool_t Tracked=1, Bool_t Untracked=1); + Int_t DisplayClustersSize_Save(vector &vectorStringFilesExtensions); + Int_t DisplayClustersSize_SaveHistos(); + Int_t DisplayClustersSize_Reset(void); + Int_t DisplayClustersSize_Kill(void); + +private: + Bool_t flagDisplayClustersSize_Init; + Int_t *DisplayClustersSize_PlanesDrawOrder; + TCanvas *canvasDisplayClustersSize; + TPaveLabel *labelDisplayClustersSize; + TPad *padDisplayClustersSize; + TH1I **histoDisplayClustersSizeAll,**histoDisplayClustersSizeTracked, **histoDisplayClustersSizeUnTracked; + Int_t eventsProcessedDisplayClustersSize; + + //**************************************************************** + // Hits By EVent + //**************************************************************** +public: + Int_t DisplayHitsByEvent_Init(Int_t nbBinX = 100); + Int_t DisplayHitsByEvent_Fill(void); + Int_t DisplayHitsByEvent_Show(void); + Int_t DisplayHitsByEvent_Save(vector &vectorStringFilesExtensions); + Int_t DisplayHitsByEvent_Reset(void); + Int_t DisplayHitsByEvent_Kill(void); + +private: + Bool_t flagDisplayHitsByEvent_Init; + Int_t *DisplayHitsByEvent_PlanesDrawOrder; + TCanvas *canvasDisplayHitsByEvent; + TPaveLabel *labelDisplayHitsByEvent; + TPad *padDisplayHitsByEvent; + TH1I **histoDisplayHitsByEvent; + Int_t eventsProcessedDisplayHitsByEvent; + + //**************************************************************** + // Association of hits to tracks + //**************************************************************** +public: + Int_t DisplayHitsTracksAssociation_Init(Int_t nbBinX = 30); + Int_t DisplayHitsTracksAssociation_Fill(void); + Int_t DisplayHitsTracksAssociation_Show(void); + Int_t DisplayHitsTracksAssociation_Save(vector &vectorStringFilesExtensions); + Int_t DisplayHitsTracksAssociation_SaveHistos(void); + Int_t DisplayHitsTracksAssociation_Reset(void); + Int_t DisplayHitsTracksAssociation_Kill(void); + +private: + Bool_t flagDisplayHitsTracksAssociation_Init; + Bool_t flagDisplayTracksAndTriggersProperties_withTrigger; + Int_t *DisplayHitsTracksAssociation_PlanesDrawOrder; + TCanvas *canvasDisplayHitsTracksAssociation; + TPaveLabel *labelDisplayHitsTracksAssociation; + TPad *padDisplayHitsTracksAssociation; + TH1I **histoDisplayHitsTracksAssociation; + Int_t eventsProcessedDisplayHitsTracksAssociation; + + //**************************************************************** + // Tracks and Triggers Properties + //**************************************************************** +public: + Int_t DisplayTracksAndTriggersProperties_Init(Bool_t withTriggers=0, Int_t Chi2Max=10000,Int_t SlopeMax=30); + Int_t DisplayTracksAndTriggersProperties_Fill(void); + Int_t DisplayTracksAndTriggersProperties_Show(void); + Int_t DisplayTracksAndTriggersProperties_Save(vector &vectorStringFilesExtensions); + Int_t DisplayTracksAndTriggersProperties_SaveHistos(void); + Int_t DisplayTracksAndTriggersProperties_Reset(void); + Int_t DisplayTracksAndTriggersProperties_Kill(void); + +private: + Bool_t flagDisplayTracksAndTriggersProperties_Init; + TCanvas *canvasDisplayTracksAndTriggersProperties; + TPaveLabel *labelDisplayTracksAndTriggersProperties; + TPad *padDisplayTracksAndTriggersProperties; + TH1D *histoDisplayTracksAndTriggersProperties_Chi2; + TH1D *histoDisplayTracksAndTriggersProperties_DistTr2Hit; + TH1D *histoDisplayTracksAndTriggersProperties_SlopesX; + TH1D *histoDisplayTracksAndTriggersProperties_SlopesY; + TH1I *histoDisplayTracksAndTriggersProperties_HitsByTrack; + TH1I *histoDisplayTracksAndTriggersProperties_TrackWithMemorizedHits; + TH1I *histoDisplayTracksAndTriggersProperties_MemorizedHitsByTrack; + TH1I *histoDisplayTracksAndTriggersProperties_TracksByEvent; + TH1I *histoDisplayTracksAndTriggersProperties_TriggersByEvent; + TH1I *histoDisplayTracksAndTriggersProperties_TriggersPosition; + Int_t eventsProcessedDisplayTracksAndTriggersProperties; + + //**************************************************************** + // Display Chronogram : Hits Tracks Triggers numbers vs time/events + //**************************************************************** +public: + Int_t DisplayChronogram_Init(Bool_t withTriggers=0); + Int_t DisplayChronogram_Fill(void); + Int_t DisplayChronogram_Show(void); + Int_t DisplayChronogram_Save(vector &vectorStringFilesExtensions); + Int_t DisplayChronogram_Reset(void); + Int_t DisplayChronogram_Kill(void); + +private: + Bool_t flagDisplayChronogram_Init; + Bool_t flagDisplayChronogramWithTriggers; + TCanvas *canvasDisplayChronogram; + TPaveLabel *labelDisplayChronogram; + TPad *padDisplayChronogram; + TGraph *graphDisplayChronogram_TracksByEvent, **graphDisplayChronogram_HitsByEvent, **graphDisplayChronogram_OFlinesNbByEvent, *graphDisplayChronogram_TriggersByEvent; + std::vector vectorStatsAlongEvents_eventNb; + std::vector< vector > vectorStatsAlongEvents_HitsNb; + std::vector< vector > vectorStatsAlongEvents_OFlinesNb; + std::vector vectorStatsAlongEvents_nbOfTracks; + std::vector vectorStatsAlongEvents_nbOfTriggers; + TLegend *legendDisplayChronogram_HitsByEvent; + TLegend *legendDisplayChronogram_OFlinesNbByEvent; + Int_t eventsProcessedDisplayChronogram; + Int_t maxOFlinesDisplayChronogram; + +//______________________________________________________________________________________________________ +// +// Store and compute functions +//______________________________________________________________________________________________________ + //**************************************************************** + // Store tracks in memory / save on HDD if asked + //**************************************************************** +public : + struct trackStruct + { + Int_t TracksNbInEvent; + DR3 TrackOrigin; + DR3 TrackSlopeZ; + Double_t TrackChi2; + Int_t NbMemorizedHits; + std::vector HitsPositions; + std::vector HitsPlanes; + std::vector HitsPixsNb; + std::vector HitsMemorized; + }; + struct hitsStruct + { + std::vector HitsPositions; + std::vector HitsPlanes; + }; + + Int_t StoreTracks_Init(void); + Int_t StoreTracks_Fill(Bool_t FillHitsVector=1); + Int_t StoreTracks_Reset(void); + Int_t StoreTracks_Kill(void); + Int_t StoreTracks_SaveTracks(TString &filenameSaveTracks); + +private : + Bool_t flagStoreTracks_Init; + + hitsStruct aHitsStruct; + std::vector hitsVector; + + trackStruct aTrackStruct; + std::vector tracksVector; + + struct trackStructExportV20 + { + Int_t TracksNbInEvent; + Double_t TrackOrigin_x; + Double_t TrackOrigin_y; + Double_t TrackOrigin_z; + Double_t TrackSlope_x; + Double_t TrackSlope_y; + Double_t TrackSlope_z; + Double_t TrackChi2; + Int_t TotalHitsNb; + Int_t MemorizedHitsNb; + Int_t CMOS_1L_PixInClust; + Int_t CMOS_2L_PixInClust; + Int_t CMOS_3L_PixInClust; + Int_t CMOS_4L_PixInClust; + Int_t CMOS_1R_PixInClust; + Int_t CMOS_2R_PixInClust; + Int_t CMOS_3R_PixInClust; + Int_t CMOS_4R_PixInClust; + Bool_t CMOS_1L_HitMemorized; + Bool_t CMOS_2L_HitMemorized; + Bool_t CMOS_3L_HitMemorized; + Bool_t CMOS_4L_HitMemorized; + Bool_t CMOS_1R_HitMemorized; + Bool_t CMOS_2R_HitMemorized; + Bool_t CMOS_3R_HitMemorized; + Bool_t CMOS_4R_HitMemorized; + }; + trackStructExportV20 aTrackStructExportV20; + + Int_t eventsProcessedStoreTracks; + + //**************************************************************** + // Compute Vertices + //**************************************************************** +public : + struct vertexStruct + { + Int_t TracksNbInEvent; + DR3 TrackOriginTrFr; + DR3 TrackSlopeZTrFr; + Double_t TrackChi2; + Int_t HitsNbInTrack; + DR3 VertexPositionBeamFr; + Double_t VertexSegmentSize; + }; + + Int_t ComputeVertices_Init(void); + Int_t ComputeVertices_Do(void); + Int_t ComputeVertices_Reset(void); + Int_t ComputeVertices_Kill(void); + Int_t ComputeVertices_SaveVertices(TString &filenameSaveVertices); + +private : + Bool_t flagComputeVertices_Init; + Bool_t flagComputeVertices_Done; + +// From DSetup : struct IviGeometryParameter_t +// Char_t GeometryName[tpsz]; +// Char_t GeometryVersion[tpsz]; +// DR3 BeamOrigin; +// DR3 BeamSlope; +// Char_t TargetType[tpsz]; +// DR3 TargetCenter; +// DR3 TargetSize; +// DR3 TrackerOrigin; +// DR3 TrackerTilt; +// Char_t VertexingMethod[tpsz]; + + TString ComputeVertices_GeometryName; + TString ComputeVertices_GeometryVersion; + DR3 ComputeVertices_BeamOrigin; + DR3 ComputeVertices_BeamSlope; + Int_t ComputeVertices_TargetType; + TString ComputeVertices_TargetTypeString; + DR3 ComputeVertices_TargetSize; + Float_t ComputeVertices_TargetRadius; + Float_t ComputeVertices_TargetLength; + TString ComputeVertices_TargetAxis; + DR3 ComputeVertices_TargetCenter; + DR3 ComputeVertices_TrackerOrigin; + DR3 ComputeVertices_TrackerTilt; + Int_t ComputeVertices_VertexingMethod; + TString ComputeVertices_VertexingMethodString; + + DR3 Beam2points_ExperimentFrame[2]; + DR3 Track2points_TrackerFrame[2]; + DR3 Track2points_ExpermtFrame[2]; + DR3 Intersection; + + + + DPrecAlign *frameChange_Expe2Tracker; + + + vertexStruct aVertexStruct; + std::vectorverticesVector; + + struct vertexStructExport + { + Int_t TracksNbInEvent; + Double_t TrackOriginTrFr[3]; + Double_t TrackSlopeZTrFr[3]; + Double_t TrackChi2; + Int_t HitsNbInTrack; + Double_t VertexPositionBeamFr[3]; + Double_t VertexSegmentSize; + }; + vertexStructExport aVertexStructExport; + + //**************************************************************** + // Misc + //**************************************************************** +public: + void ComputeOverlap(void); + Int_t GenerateVetoPixelsCode(UInt_t absoluteThreshold = 100); + + + +//______________________________________________________________________________________________________ +// +// PRINT Statistics & Numbers +//______________________________________________________________________________________________________ + + //**************************************************************** + // Print Cumulated Statistics Along events + //**************************************************************** +public: + void PrintCumulatedStatistics_Reset(void); + void PrintCumulatedStatistics_Fill(void); + void PrintCumulatedStatistics_Print(void); + +private : + struct structStatsCumulatedAlongEvents + { + Int_t eventsAnalysed; + Int_t triggersTotal; + Int_t triggersEventsWith; + Int_t triggersEventsWithout; + Int_t tracksTotal; + Int_t tracksEventsWith; + Int_t tracksEventsWithout; + Int_t hitsTotalAllPlanes; + Int_t hitsTotalByPlane[20]; + }; + structStatsCumulatedAlongEvents astructStatsCumulatedAlongEvents ; + + //**************************************************************** + // Print Event Informations + //**************************************************************** +public : + void PrintEventInfos(void); + void PrintPXIeStats(void); + void PrintCurrentEventNumber(void); + Int_t GetCurrentEventNumber(void); + Int_t PrintLogFile(void); + +//______________________________________________________________________________________________________ +// +// Events navigation and processing +//______________________________________________________________________________________________________ +// + //**************************************************************** + // Events navigation (without processing !) + //**************************************************************** +public: + Int_t GoToNextEvent(Bool_t updateTracker=1); + Int_t GoToAnEvent(Int_t EventNbToGo, Bool_t updateTracker=1); + Int_t GoToNextEventWithHits(Int_t hitsNbMinimumToStop=1); + Int_t GoToNextEventWithTracks(Int_t tracksNbMinimumToStop=1); + Int_t SkipEvents(Int_t nbEventsToSkip=1, Bool_t updateTracker=1); + +//**************************************************************** +// Events processing +//**************************************************************** +public: + Int_t ProcessEvents(Int_t aNbOfEvents=1,Bool_t resetBefore=1, Bool_t showDisplays=0); + Int_t ProcessAllEvents(Int_t refreshDisplaysEveryXevents=0, Bool_t resetBefore=1); + + //**************************************************************** + // Global Actions + //**************************************************************** +public: + Int_t FillAllDisplays(void); + Int_t ShowAllDisplays(void); + Int_t SaveAllDisplays(const Char_t *fileExtension1=NULL, const Char_t *fileExtension2=NULL, const Char_t *fileExtension3=NULL, const Char_t *fileExtension4=NULL, const Char_t *fileExtension5=NULL, const Char_t *fileExtension6=NULL); + Int_t SaveAllDisplays(vector &aVectorStringFilesExtensions /*= vector()*/); + Int_t SaveAllHistograms(void); + Int_t SaveResults(void); + Int_t ResetAllDisplays(void); + Int_t KillAllDisplays(void); + + +//______________________________________________________________________________________________________ +// +// GUI +//______________________________________________________________________________________________________ + + //**************************************************************** + // GUI fuctions <-> button + //**************************************************************** + // Analysis control tab + // Analysis control group frame + // Process Events zone + //**************************************************************** +public: //GuiButton MUST be public + Int_t GuiButtonProcess1event(void); + Int_t GuiButtonProcess10events(void); + Int_t GuiButtonProcess100events(void); + Int_t GuiButtonProcessXevents(void); + Int_t GuiButtonProcessAllEvents(void); + + //**************************************************************** + // Go to event with ... zone + //**************************************************************** +public: //GuiButton MUST be public + Int_t GuiButtonGoToEventWithNtracks(void); + Int_t GuiButtonGoToEventWithNhits(void); + Int_t GuiButtonGoToEventNb(void); + + //**************************************************************** + // Actions zone + //**************************************************************** +public: //GuiButton MUST be public + Int_t GuiButtonToggleVerbosity(void); + Int_t GuiButtonSetTafDebugLevel(void); + Int_t GuiButtonResetDisplays(void); + Int_t GuiButtonSaveDisplays(void); + Int_t GuiButtonSaveHistograms(void); + Int_t GuiButtonSaveResults(void); + Int_t GuiButtonQuitTaf(void); + + //**************************************************************** + // GUI SubFunctions + //**************************************************************** +public: + Int_t GuiProcessEvents(Int_t nbEventsToProcess=1, Int_t refreshDisplaysEveryXevents=0/*see GuiProcessEvents()*/); + Int_t GuiInitDisplays(void); + void GuiShowDisplays(void); + Int_t GuiResetDisplays(void); + Int_t GuiReProcessLastEvent(void); + Int_t GuiActualizeEventNumber(void); + Int_t GuiActualizeTextsDislays(void); + + //**************************************************************** + // Allignment tab + //**************************************************************** +public: //GuiButton MUST be public + Int_t GuiButtonAlignResetValues(void); + Int_t GuiButtonAlignDoTranslateTurn(void); + Int_t GuiButtonAlignDisplayPosTilt(void); + Int_t GuiButtonAlignUpdatePosTilt(void); + Int_t GuiButtonAlignUpdateCfgFile(void); + Int_t GuiButtonRefreshDisplays(void); + + //**************************************************************** + // Noise tab + //**************************************************************** + Int_t GuiButtonGenerateVetoPixelsCode(void); + +// + //**************************************************************** + // GUI windows : Lauch, Display, Connect + //**************************************************************** +public : + Int_t GuiLauch(void); +private : + Int_t GuiCreate(void); + Int_t GuiConnectButtons(void); + Int_t GuiInitParameters(void); + + //**************************************************************** + // GUI Create + //**************************************************************** + +private : + // Display Event / + // / Views selection / + // / Raw data / + TGNumberEntry *fNumberEntry_RawMinPixOccu; + // / CMOS native frame + TGCheckButton *fTextButtonDisRawDatCmoNatGeoInPix, *fTextButtonDisRawDatCmoNatGeoInPix_Cumul, *fTextButtonDisRawDatCmoNatGeoInPix_Hit, *fTextButtonDisRawDatCmoNatGeoInPix_OlLine, *fTextButtonDisRawDatCmoNatGeoInPix_ColBar; + // / Tracker Frame + TGCheckButton *fTextButtonDisRawDatTrackerFraInPix, *fTextButtonDisRawDatTrackerFraInPix_Cumul, *fTextButtonDisRawDatTrackerFraInPix_Hit, *fTextButtonDisRawDatTrackerFraInPix_OlLine, *fTextButtonDisRawDatTrackerFraInPix_ColBar; + // / Hits in Pix / + TGNumberEntry *fNumberEntry_HitMinOccu; + // / CMOS native frame + TGCheckButton *fTextButtonDisHitsCmoNatGeoInPix, *fTextButtonDisHitsCmoNatGeoInPix_Cumul, *fTextButtonDisHitsCmoNatGeoInPix_HitShowedAsPix, *fTextButtonDisHitsCmoNatGeoInPix_OlLine, *fTextButtonDisHitsCmoNatGeoInPix_AssoTrack; + // / Tracker Frame + TGCheckButton *fTextButtonDisHitsInTrackerFrameInPix, *fTextButtonDisHitsInTrackerFrameInPix_Cumul, *fTextButtonDisHitsInTrackerFrameInPix_HitShowedAsPix, *fTextButtonDisHitsInTrackerFrameInPix_OlLine, *fTextButtonDisHitsInTrackerFrameInPix_AssoTrack; + // / Hits in Um / + // / Tracker Frame + TGCheckButton *fTextButtonDisHitsInTrackerFrameInUm, *fTextButtonDisHitsInTrackerFrameInUm_Cumul; + TGButtonGroup *fGButtonGroupHitTrackInter; + TGRadioButton *fGRadioButton_HitTrackInter_none,*fGRadioButton_HitTrackInter_cross; + // / Overlay view + TGCheckButton *fTextButtonDisHitsInTrackerFrameInUmOv, *fTextButtonDisHitsInTrackerFrameInUmOv_Cumul; + TGListBox *fListBoxOverlayHitsInTrackerFrameInUm; + TList *fListOverlayHitsInTrackerFrameInUm; + // / Tracks + TGCheckButton *fTextButtonDisTracks_Cumul; + // / 3D View + TGCheckButton *fTextButtonDisTracks3D, *fTextButtonDisTracks3D_DrawSensor,*fTextButtonDisTracks3D_DrawAllHits, *fTextButtonDisTracks3D_DrawTrackedHits, *fTextButtonDisTracks3D_DrawTracks; + // / 2D View + TGCheckButton *fTextButtonDisTracks2D, *fTextButtonDisTracks2D_DrawSensor,*fTextButtonDisTracks2D_DrawAllHits, *fTextButtonDisTracks2D_DrawTrackedHits, *fTextButtonDisTracks2D_DrawTracks; + // / Vertices + TGCheckButton *fTextButtonDisVertices_Cumul; + // / 3D + TGCheckButton *fTextButtonDisVertices3D, *fTextButtonDisVertices3D_DrawSensor, *fTextButtonDisVertices3D_DrawTracks, *fTextButtonDisVertices3D_DrawTrackDir, *fTextButtonDisVertices3D_DrawTarget; + TGCheckButton *fTextButtonDisVertices3D_DrawBeam, *fTextButtonDisVertices3D_DrawVerticesPoints, *fTextButtonDisVertices3D_DrawVerticesPointsSmall, *fTextButtonDisVertices3D_DrawAcceptance; + // / 2D + TGCheckButton *fTextButtonDisVerticesProjs, *fTextButtonDisVerticesProjs_DrawTarget; + // / Statistics + // / CMOS + TGCheckButton *fTextButtonDisCMOSoverflowLines, *fTextButtonDisCMOSoverflowLines_Cumul; + // / Clusters + TGCheckButton *fTextButtonDisHitsSize, *fTextButtonDisHitsSize_Cumul,*fTextButtonDisHitsSizeAll,*fTextButtonDisHitsSizeTracked,*fTextButtonDisHitsSizeUnTracked,*fTextButtonDisHitsByEvent, *fTextButtonDisHitsByEvent_Cumul, *fTextButtonDisHitsAssociation, *fTextButtonDisHitsAssociation_Cumul; + TGNumberEntry *fNumberEntry_HitsByEventBinMax; + // / Tracks +Triggers + TGCheckButton *fTextButtonDisStats, *fTextButtonDisStats_Cumul, *fTextButtonDisStats_withTriggers; + TGNumberEntry *fNumberEntry_TracksHistoChi2Max, *fNumberEntry_TracksHistoSlopeMax, *fNumberEntry_ClustersBinMax; + // / Along Events + TGCheckButton *fTextButtonDisStatsAlongEvents, *fTextButtonDisStatsAlongEvents_Cumul, *fTextButtonDisStatsAlongEvents_withTriggers; + // + // Noise + TGCheckButton *fTextButtonNoiseDisRawDatCmoNatGeoInPix, *fTextButtonNoiseDisRawDatCmoNatGeoInPix_Hit, *fTextButtonNoiseDisRawDatCmoNatGeoInPix_ColBar; + TGNumberEntry *fNumberEntry_NoiseRawMinPixOccu; + TGLabel *fLabelNoiseMinPixOccuRelValue, *fLabelNoiseNbOfEvents; + TGCheckButton *fTextButtonDisNoiseStudy; + TGTextButton *fTextButtonGenerateVetoPixelsCode; + TGNumberEntry *fNumberEntry_NoiseThresholdsMin, *fNumberEntry_NoiseThresholdsMax, *fNumberEntry_NoiseThresholdsNb; + // Alignment + // / Display + TList *fListAlignPlanesToDisp, *fListAlignPlanesToMove; + TGListBox *fListBoxAlignPlanesToDisp, *fListBoxAlignPlanesToMove; + // Translate & Turn + TGNumberEntry *fNumberEntry_AlignTranslatX, *fNumberEntry_AlignTranslatY, *fNumberEntry_AlignTranslatZ; + TGNumberEntry *fNumberEntry_AlignTurnX, *fNumberEntry_AlignTurnY, *fNumberEntry_AlignTurnZ; + // Positions & Tilts + TGNumberEntry *fNumberEntry_AlignPosX, *fNumberEntry_AlignPosY, *fNumberEntry_AlignPosZ; + TGNumberEntry *fNumberEntry_AlignTiltX, *fNumberEntry_AlignTiltY, *fNumberEntry_AlignTiltZ; + // / Control + TGCheckButton *fTextButtonAlignViewOverHits, *fTextButtonAlignViewOverHits_Cumul; + TGTextButton *fTextButtonAlignResetValues, *fTextButtonAlignDoTranslatTurn, *fTextButtonAlignDisplayActualPosTilt, *fTextButtonAlignUpdateActualPosTilt, *fTextButtonAlignUpdateCfgFile; + TGButtonGroup *fTextButtonAlignUpdateCfgFile_UpdateMode; + TGRadioButton *fGRadioButton_AnalyseModeUpWithBck, *fGRadioButton_AnalyseModeUpNoBck, *fGRadioButton_AnalyseModeNewFile; + TGTextEntry *fTextEntry_NewCfgFileName; + + // Analysis control/ + // / Process events/ + TGTextButton *fTextButtonProcess1event, *fTextButtonProcess10events, *fTextButtonProcess100events, *fTextButtonProcessXevents, *fTextButtonProcessAllEvents; + TGNumberEntry *fNumberEntry_EventsToProcess; + // / Go to / + TGTextButton *fTextButtonGoToEventWithNhits,*fTextButtonGoToEventWithNtracks,*fTextButtonGoToEventNb; + TGNumberEntry *fNumberEntryGoToEventWithNhits, *fNumberEntryGoToEventWithNtracks; + // / Action + TGTextButton *fTextButtonTurnVerbose, *fTextButtonSaveDisplays, *fTextButtonSaveHistograms, *fTextButtonQuitTaf, *fTextButtonSetTafDebugLevel; + TGNumberEntry *fNumberEntryTafDebugLevel; + TGCheckButton *fTextButtonBeepWhenFinished; + TGNumberEntry *fNumberEntry_GoToEvent; + // / Display + TGNumberEntry *fNumberEntry_RefreshFreq; + TGTextButton *fTextButtonRefreshView, *fTextButtonResetView; + // / Save + TGCheckButton *fTextButtonSaveCanvas_inPDF,*fTextButtonSaveCanvas_inPNG, *fTextButtonSaveCanvas_inROOT; + TGCheckButton *fTextButtonSaveTracks, *fTextButtonSaveVertice; + TGTextEntry *fTextEntry_FilesPrefix, *fTextEntry_FilesSuffix; + TGTextButton *fTextButtonSaveResults; + + +//______________________________________________________________________________________________________ +// +// MISC TOOLS +//______________________________________________________________________________________________________ +// + + //**************************************************************** + // Print messages with colors + //**************************************************************** +private : + void printf_info (const Char_t *text=""); + void printf_warning (const Char_t *text=""); + void printf_error(const Char_t *text=""); + + +//______________________________________________________________________________________________________ +// +// Commons variables +//______________________________________________________________________________________________________ +// +private: + //**************************************************************** + // Display functions + //**************************************************************** + // ROOT Display + Char_t name[200]; + Char_t title[200]; + Char_t canvasTitle[200]; + TCanvas *aCanvas; + + TString aFileName; + TString resultsDirPath; + TString FileNamePrefix; + TString FileNameSuffix; + + TString canvasName; + TString canvasFileFullPath; + + TString histosName; + TString histosFileFullPath; + TFile *histosFile; + + TString FileNameTreeTracks; + TString FileNameTreeVertex; + + TString treeTracksFileFullPath; + TString treeVertexFileFullPath; + + Int_t HitMarkerStyle_Cluster[8]; + Int_t HitMarkerStyle_Tracked[8]; + Int_t HitMarkerStyle_UnTracked[8]; + Int_t HitMarkerColor[8]; + Int_t LineColor[8]; + Int_t TracksLinesColor[9]; + + Bool_t configBoolVerbose; + + + //**************************************************************** + // Tracker system + //**************************************************************** + Int_t eventsProcessed; + Int_t RunNumber; + DTracker *tTracker; + DAcq *tDAcq; + Int_t nbPlanes; + DPlane *tPlane; + std::vector *aList; + DHit *aHit; + DTrack *aTrack; + DR3 aHitPos; + Int_t iPlane, jPlane; + Int_t iHit; + Int_t iTrack; + Int_t iEventWithHits; + Int_t nbHits; + Int_t nbTracks; + Int_t nbTriggers; + + //**************************************************************** + // Misc + //**************************************************************** + DGlobalTools fTool; + DSession *fSession; + DSetup *fSetup; + + +//______________________________________________________________________________________________________ +// +// MRax class gestion (contructor, init functions, ...) +//______________________________________________________________________________________________________ +// +private: + static MRax* fgInstanceRax; + +public: + MRax(DSession *aSession); + virtual ~MRax(){;} + static MRax*& InstanceRax( DSession *aSession); + ClassDef(MRax,1) // Integrate MRax classe into the ROOT system, see http://root.cern.ch/root/Using.html +}; + + + +#endif diff --git a/include/PXIBoardReader.h b/include/PXIBoardReader.h new file mode 100644 index 0000000..b3f065d --- /dev/null +++ b/include/PXIBoardReader.h @@ -0,0 +1,167 @@ +#ifndef _PXIBoardReader_included_ +#define _PXIBoardReader_included_ + +#include "Riostream.h" +#include "TObject.h" +#include "TH1.h" +//#include +#include +#include +#include "DGlobalTools.h" // to have fTool has a data member +using namespace std; + + +// -------------------------------------------------------------------------------------- + +class PXIPixel : public TObject { + + // Container for a simple pixel + // JB, 2009/08/13 + + private: + + int Input; + int Value; + int LineNumber; + int ColumnNumber; + + public: + + PXIPixel() { Input = 0; Value = 0; LineNumber = 0; ColumnNumber = 0;} + PXIPixel( int input, int value, int line, int col) { Input = input; Value = value; LineNumber = line; ColumnNumber = col;} + virtual ~PXIPixel() {;} + int GetInput() { return Input; } + int GetValue() { return Value; } + int GetLineNumber() { return LineNumber; } + int GetColumnNumber() { return ColumnNumber; } + + ClassDef(PXIPixel,1) +}; + +// -------------------------------------------------------------------------------------- + +class PXIEvent : public TObject { + + private: + + int EventNumber; + int BoardNumber; + int RunNumber; + std::vector *ListOfPixels; + std::vector *ListOfTriggerPos; //JB 2010/06/16 + std::vector *ListOfFrames; //JB 2010/06/16 + + public: + + PXIEvent() {;} + PXIEvent( int EventNumber, int boardNumber, int runNumber, vector *ListOfPixels, vector *ListOfTriggerPos, vector *ListOfFrames); + ~PXIEvent(); + + int GetEventNumber() { return EventNumber; } + int GetBoardNumber() { return BoardNumber; } + int GetRunNumber() { return RunNumber; } + int GetNumberOfPixels() { return ListOfPixels->size(); } + std::vector *GetPixels() { return ListOfPixels;} + PXIPixel *GetPixelAt( int index) { return &(ListOfPixels->at(index)); } + int GetNumberOfFrames() { return ListOfFrames->size(); } //JB 2010/06/16 + std::vector *GetFrames() { return ListOfFrames;} //JB 2010/06/16 + int GetNumberOfTriggers() { return ListOfTriggerPos->size(); } //JB 2010/06/16 + std::vector *GetTriggers() { return ListOfTriggerPos;} //JB 2010/06/16 + + ClassDef(PXIEvent,1) +}; + +// -------------------------------------------------------------------------------------- + +class PXIBoardReader : public TObject { + + private: + + int DebugLevel; + DGlobalTools fTool; // JB 2011/07/18 + + int BoardNumber; + int NSensors; + int TriggerMode; + int TriggerLineOffset; + int FramesPostTrigger; + int NextFirstLineToKeep; + int NextFirstFrame; + int FirstLineToKeep; + int FirstFrame; + int LastLineToKeep; + int LastFrame; + int NumberOfLines; + int RunNumber; + int EventsPerFile; + int FramesReadFromFile; + + bool ReadingEvent; + bool ReadTwice; + bool Overflow; // JB 2009/09/08 + bool EventReady; + PXIEvent *CurrentEvent; + int CurrentEventNumber; + std::vector ListOfPixels; + std::vector ListOfTriggerPos; //JB 2010/06/16 + std::vector ListOfFrames; //JB 2010/06/16 + + int EventsCount; // JB 2009/09/09 + int EventsOverflow; // JB 2009/09/09 + int EventsAborted; // JB 2009/09/16 + int FramesReadTwice; // JB 2009/10/14 + int NStatesInBlock[100]; // up to 100 blocks + int NStatesInLine; // up to 100 blocks + TH1S *h1BlockOccupancy; // JB 2009/09/10 + TH1S *h1LineOccupancy; // JB 2009/09/10 + + ifstream RawFileStream; + char *InputFileName; + char* PrefixFileName; + char* SuffixFileName; + + FILE *ConfigFile; + char ConfigFileName[300]; + int CurrentFileNumber; + int NumberOfFiles; + + size_t SizeOfDaqEvent; + unsigned int *Data; + int Endianness; // 0= do not swap bytes, 1= swap bytes + + void AddPixel( int input, int value, int aLine, int aColumn); + + public: + + PXIBoardReader() {;} + PXIBoardReader( int boardNumber, const char *configFileName, int triggerMode, int endian=0); + ~PXIBoardReader(); + + bool ReadConfiguration(); + void SetDebugLevel( int level) { DebugLevel = level; cout << "PXIBoardReader " << BoardNumber << " debug updated to " << DebugLevel << endl;} + void SetEndiannes( int endian) { Endianness = endian; } + void AddFileList( const char *prefixFileName, int firstIndex, int endIndex,const char *suffixFileName); + bool OpenNextFile(); + bool GetNextDaqEvent(); + bool DecodeFrame(int iSensor); + bool HasData(); + void SkipNextEvent(); + int GetBoardNumber() { return BoardNumber; } + int GetNSensors() { return NSensors; } + int GetTriggerMode() { return TriggerMode; } + int GetRunNumber() { return RunNumber; } + PXIEvent* GetEvent() { return CurrentEvent; } + int GetEventNumber() { return CurrentEventNumber;} + char* GetConfigFileName() { return ConfigFileName;} + char* GetInputFileName() { return InputFileName;} + char* GetSuffixFileName() { return SuffixFileName;} + char* GetPrefixFileName() { return PrefixFileName;} + void Close(); + void PrintStatistics(ostream &stream=cout); // JB 2010/08/26 // SS 2011/12/14 + + unsigned int SwapEndian( unsigned int data); + + ClassDef(PXIBoardReader,2); +}; + +# endif diff --git a/include/PXIeBoardReader.h b/include/PXIeBoardReader.h new file mode 100644 index 0000000..904b45d --- /dev/null +++ b/include/PXIeBoardReader.h @@ -0,0 +1,277 @@ +#ifndef _PXIeBoardReader_included_ +#define _PXIeBoardReader_included_ + + +#include "Riostream.h" +#include "TObject.h" +#include "TH1.h" +#include "TH1F.h" +//#include "TH2F.h" +#include "TTree.h" +#include "TFile.h" +//#include +#include +#include +#include "DGlobalTools.h" // to have fTool has a data member +using namespace std; + +// -------------------------------------------------------------------------------------- + +class PXIePixel : public TObject { + + // Container for a simple pixel + // JB, 2009/08/13 + + private: + + int Input; + int Value; + int LineNumber; + int ColumnNumber; + + public: + + PXIePixel() { Input = 0; Value = 0; LineNumber = 0; ColumnNumber = 0;} + PXIePixel( int input, int value, int line, int col) { Input = input; Value = value; LineNumber = line; ColumnNumber = col;} + virtual ~PXIePixel() {;} + int GetInput() { return Input; } + int GetValue() { return Value; } + int GetLineNumber() { return LineNumber; } + int GetColumnNumber() { return ColumnNumber; } + + ClassDef(PXIePixel,1) +}; + +// -------------------------------------------------------------------------------------- + +class PXIeEvent : public TObject { + + private: + + int EventNumber; + int BoardNumber; + int RunNumber; + std::vector *ListOfPixels; + std::vector *ListOfTriggerPos; //JB 2010/06/16 + std::vector *ListOfFrames; //JB 2010/06/16 + std::vector *ListOfLineOverflow; /// MG 2012/02/15 + std::vector *ListOfTimestamps; // JB 2012/05/04 + + public: + + PXIeEvent() {;} +/// PXIeEvent( int EventNumber, int boardNumber, int runNumber, vector *ListOfPixels, vector *ListOfTriggerPos, vector *ListOfFrames); + PXIeEvent( int EventNumber, int boardNumber, int runNumber, vector *ListOfPixels, vector *ListOfTriggerPos, vector *ListOfFrames, vector *ListOfTimestamps, vector *ListOfLineOverflow); //MG 2012/03/14, JB 2012/05/04 + ~PXIeEvent(); + + int GetEventNumber() { return EventNumber; } + int GetBoardNumber() { return BoardNumber; } + int GetRunNumber() { return RunNumber; } + int GetNumberOfPixels() { return ListOfPixels->size(); } + std::vector *GetPixels() { return ListOfPixels;} + PXIePixel *GetPixelAt( int index) { return &(ListOfPixels->at(index)); } + int GetNumberOfFrames() { return ListOfFrames->size(); } //JB 2010/06/16 + std::vector *GetFrames() { return ListOfFrames;} //JB 2010/06/16 + int GetNumberOfTriggers() { return ListOfTriggerPos->size(); } //JB 2010/06/16 + std::vector *GetTriggers() { return ListOfTriggerPos;} //JB 2010/06/16 + std::vector *GetLineOverflow() { return ListOfLineOverflow;} // MG 2012/02/15 + int GetNumberOfLineOverflow ( int module ) { return ListOfLineOverflow[module].size();} // MG 2012/02/15 + int GetNumberOfTimestamps() { return ListOfTimestamps->size(); }// JB 2012/05/04 + int GetTimestampAt( int index) { return ListOfTimestamps->at(index);} + std::vector *GetTimestamps() { return ListOfTimestamps;} + + ClassDef(PXIeEvent,2) +}; + +// -------------------------------------------------------------------------------------- + +class PXIeBoardReader : public TObject { + + private: + + int DebugLevel; + DGlobalTools fTool; // JB 2011/07/18 + + int BoardNumber; + int NSensors; + int TriggerMode; + int EventBuildingMode; + int FramesToSkipAtEndOfAcqForTrig; // JB 2011/06/30 + int TriggerLineOffset; + int FramesPostTrigger; + int NextFirstLineToKeep; + int NextFirstFrame; + int NextLastLineToKeep; // JB 2011/03/14 + int FirstLineToKeep; + int FirstFrame; + int LastLineToKeep; + int LastFrame; + int LastFrameDUT; + int NumberOfLines; + int RunNumber; + int EventsPerFile; + int FramesReadFromFile; + int AcqsReadFromFile; // JB 2011/03/14 + int NFramesPerAcq; // JB 2011/03/14 + int Nacquisitions; // JB 2011/03/14 + int PeriodsVetoOff; // JB 2012/02/23 + int OriginAcq; // JB 2012/05/04 + int RunTimeInSec; // JB 2012/05/12 + + int ASIC__SENSOR; // AP 2014/11/24 + + std::vector ListOfDUTSensors; // JB 2014/02/12 + + bool ReadingEvent; + bool ReadTwice; + bool Overflow; // JB 2009/09/08 + bool VetoOverflow; // JB 2010/07/06 + bool VetoEvent; // JB 2012/02/23 + bool EventReady; + bool StopIfRequiredFrameNotFound; // JB 2012/09/04 + bool AbortEvent; // JB 2015/03/16 + bool NoMoreData; // JB 2012/09/04 + PXIeEvent *CurrentEvent; + int CurrentEventNumber; + std::vector ListOfPixels; + std::vector ListOfTriggerPos; //JB 2010/06/16 + std::vector ListOfNextTriggerPos; //JB 2011/07/18 + std::vector ListOfFrames; //JB 2010/06/16 + std::vector *ListOfLineOverflow; // MG 2012/02/15 + std::vector ListOfTimestamps; // JB 2012/05/04 + std::vector ListOfNextTimestamps; // JB 2012/05/04 + + int EventsCount; // JB 2009/09/09 + int EventsOverflow; // JB 2009/09/09 + int EventsAbortedByTrig; // JB 2009/09/16, name modified on 2015/03/16 + int EventsAbortedByTag; // JB 2015/03/16 + int EventsMissed; // JB 2012/09/04 + int EventsWithBadTrigger; // JB 2012/09/05 + int FramesReadTwice; // JB 2009/10/14 + int TriggerCount; // JB 2011/06/18 + int TriggerInvalidCount; // JB 2012/09/25 + int NStatesInBlock[100]; // up to 100 blocks + int NStatesInLine; // up to 100 blocks + int *overflowSensor; // JB 2011/11/02 + TH1S *h1BlockOccupancy; // JB 2009/09/10 + TH1S *h1LineOccupancy; // JB 2009/09/10 + TH1F **hLineOverFlowDist; //AP 2014/06/03 + //TH2F **hHitMapInFrame; //AP 2014/10/21 + + ifstream RawFileStream; + char *InputFileName; + char* PrefixFileName; + char* SuffixFileName; + + FILE *ConfigFile; + char ConfigFileName[300]; + int CurrentFileNumber + int NumberOfFiles; + + + size_t SizeOfDaqEvent; + unsigned int *Data; + int Endianness; // 0= do not swap bytes, 1= swap bytes + int TypeFlag; //AP, 2014/10/09 + bool IsFSBBbis; //AP, 2015/06/11 + int NTriggersInEvent; //AP, 2014/10/09 + int FramesToReadInEvent; //AP, 2014/10/09 + int ZeroTriggersCounter; //AP, 2014/10/09 + std::vector ListOfEventTriggers_Frame; //AP, 2014/10/09 + std::vector ListOfEventTriggers_Line; //AP, 2014/10/09 + int FSBB_FirstFrame; //AP, 2014/10/09 + int FSBB_LastFrame; //AP, 2014/10/09 + int FSBB_AcqNo; //JB, 2015/03/17 + int Current_AcqNo; //JB, 2015/03/17 + int NumberOfColumns; //AP, 2014/10/09 + + struct header{ + int triggerNb; + int frameNb; + int acqId; + int frameId; + int triggersInFrame; + int triggerPos; + int timestamp; + }; + TTree *treeHeaders; + TFile *fileHeaders; + + void AddPixel( int input, int value, int aLine, int aColumn); + int ComputeTimestamp( int aAcqId, int aFrameId, int aLineNumber); + bool OpenFileHeaders(); + + public: + + int test( char *path, int runNumber,int MimosaType); + PXIeBoardReader() {;} + PXIeBoardReader( int boardNumber, char *configFileName, int runNumber, int triggerMode, int eventBuildingMode=0, bool vetoOverflow=true, int endian=0, int numberOfRows=576, + int MimosaType = 26); + ~PXIeBoardReader(); + + bool ReadConfiguration(); + void SetDebugLevel( int level) { DebugLevel = level; cout << "PXIeBoardReader " << BoardNumber << " debug updated to " << DebugLevel << endl;} + void SetEndiannes( int endian) { Endianness = endian; } + void AddFileList( char *prefixFileName, int firstIndex, int endIndex,const char *suffixFileName, int MimosaType = 26); + //bool OpenNextFile(); + void AddDUTSensor( int aSensorId); // JB 2014/02/12 + + void ResetReading(); // Restart reading from first event, JB 2015/03/02 + bool GetNextDaqEvent(); + bool ResetDaqEvent( int newAcqNo, int newFrNo); // JB 2012/07/10 + //bool DecodeFrame(int iSensor); // obsolete, replaced by the 5 following methods + bool ReadTriggersFromFrame(); // JB 2011/03/14 + bool CheckPixelToAdd( Int_t aSensorId, Int_t aFrame, Int_t aLine, Int_t aColumn); // JB 2014/02/11 + bool IsDUTSensor( int aSensorId); // JB 2014/02/12 + bool CheckTriggerValidity(); // JB 2012/07/10 + bool GetTriggerList(); // JB 2012/09/25 + void StartEventReading(); // JB 2011/03/14 + void DefineEventEnd(); // JB 2011/03/14 + void CheckSecondReading(); // JB 2011/03/14 + bool ReadPixelsFromFrame(); // JB 2011/03/14 + bool ReadPixelsFromFrame_Mi26(); // AP 2014/10/09 + bool ReadPixelsFromFrame_FSBB(); // AP 2014/10/09 + bool HasData(); + bool HasData( int acqNo, int frNo); // JB 2012/07/10 + bool HasData( int aTriggerNb); // JB 2012/07/10 + void SkipNextEvent(); + int GetBoardNumber() { return BoardNumber; } + int GetNSensors() { return NSensors; } + int GetTriggerMode() { return TriggerMode; } + int GetRunNumber() { return RunNumber; } + PXIeEvent* GetEvent() { return CurrentEvent; } + int GetEventNumber() { return CurrentEventNumber;} + char* GetConfigFileName() { return ConfigFileName;} + char* GetInputFileName() { return InputFileName;} + char* GetSuffixFileName() { return SuffixFileName;} + char* GetPrefixFileName() { return PrefixFileName;} + void Close(); + void PrintStatistics(ostream &stream=cout); // JB 2010/08/26 // SS 2011/12/14 + void SetVetoPixel( int noiseRun); // JB 2012/03/11 + void DumpEventHeaders( int nFrames); // JB 2012/05/03 + //AP, 2014/10/09: Added a couple of functions to get and set flag for choosing data-format readout + // TypeFlag == 0, previous M26 format + // TypeFlag > 0, other possible formats (e.g. FSBB) + int GetFlag() { return TypeFlag; } + void SetFlag(int sFlag) { + TypeFlag = sFlag; + if(TypeFlag == 2) { + //If flag is 3 then reading FSBB-bis + cout << "TypeFlag is 2. Setting it to 1 and setting IsFSBBbis to true" << endl; + TypeFlag = 1; + IsFSBBbis = true; //bool to apply the double line inversion in ReadPixelsFromFrame_FSBB fonction. Default value is false + }; + return; + } + //AP, 2014/10/21: Methods to get the colum number from the Setup + int GetNumberOfColumns() { return NumberOfColumns; } + void SetNumberOfColumns(int ColumnNum) { NumberOfColumns = ColumnNum; return;} + void SetASICType(int ASIC_type); //AP, 2014/11/24 + + + unsigned int SwapEndian( unsigned int data); + + ClassDef(PXIeBoardReader,3); +}; + +# endif diff --git a/include/TMimosa24_25Map.h b/include/TMimosa24_25Map.h new file mode 100755 index 0000000..de8e122 --- /dev/null +++ b/include/TMimosa24_25Map.h @@ -0,0 +1,201 @@ +#ifndef CLASS_TMimosa24_25Map +#define CLASS_TMimosa24_25Map + +// +//Example of usage: +// +// #include "TMimosa24_25Map.h" +//int main(int argc, char **argv) { +// TMimosa24_25Map *Mi = new TMimosa24_25Map("Mi25A_20um"); // or "Mi24", "Mi25B_20um","Mi25A_30um","Mi25B_30um","Mi25A_40um","Mi25B_40um" +// Mi->print_map(2); // print n sample and k channel of TNT board in a Mimosa matrix layout.. +// Mi->print_map(1); // print n sample of TNT board in a Mimosa matrix layout.. +// delete Mi; +//} + + + +#include +#include + +class TMimosa24_25Map { +public: + int mats; + + static const int buff_k_max=8; + static const int buff_n_max=4096; + + static const int buff_m_max=13; + static const int buff_c_max=64; + static const int buff_r_max=64; + + + int k_max; + int n_max; + int m_max; + int c_max; + int r_max; + + int cols[buff_m_max]; + int rows[buff_m_max]; + + short c[buff_k_max][buff_n_max]; + short r[buff_k_max][buff_n_max]; + short m[buff_k_max][buff_n_max]; + + short k[buff_m_max][buff_c_max][buff_r_max]; + short n[buff_m_max][buff_c_max][buff_r_max]; + + void inverse_map(void) { + for(int ki=0;ki=12) ind = ic-8; + for(int ir=0;ir +#include +#include +#include +#include "DGlobalTools.h" // to have fTool has a data member + + +using namespace std; + + +// -------------------------------------------------------------------------------------- + +class TNTPixel : public TObject { + + // Container for a simple pixel + // only 3 values + // JB, 2008/09/27 + + private: + + int Input; + int Value; + int Index; + + public: + + TNTPixel() { Input = 0; Value = 0; Index = 0; } + TNTPixel( int input, int value, int index) { Input = input; Value = value; Index = index; } + virtual ~TNTPixel() {;} + int GetInput() { return Input; } + int GetValue() { return Value; } + int GetIndex() { return Index; } + + ClassDef(TNTPixel,1) +}; + +// -------------------------------------------------------------------------------------- + +class TNTEvent : public TObject { + + private: + + int EventNumber; + int BoardNumber; + std::vector *ListOfTriggers; + std::vector *ListOfTimestamps; //RDM150509 + std::vector *ListOfFrames; + std::vector *ListOfPixels; + + public: + + TNTEvent() {;} + TNTEvent( int currentEventNumber, int boardNumber, vector *ListOfTriggers, vector *ListOfTimestamps, vector *ListOfFrames, vector *ListOfPixels); //RDM150509 + ~TNTEvent(); + + int GetEventNumber() { return EventNumber; } + int GetBoardNumber() { return BoardNumber; } + int GetNumberOfTriggers() { return ListOfTriggers->size(); } + int GetNumberOfTimestamps() { return ListOfTimestamps->size(); }//RDM150509 + std::vector *GetTriggers() { return ListOfTriggers;} + std::vector *GetTimestamps() { return ListOfTimestamps;} //RDM150509 + int GetTriggerAt( int index) { return ListOfTriggers->at(index);} + int GetTimestampAt( int index) { return ListOfTimestamps->at(index);}//RDM150509 + int GetNumberOfFrames() { return ListOfFrames->size(); } + std::vector *GetFrames() { return ListOfFrames;} //JB 2010/06/16 + int GetFrameAt( int index) { return ListOfFrames->at(index);} + int GetNumberOfPixels() { return ListOfPixels->size(); } + std::vector *GetPixels() { return ListOfPixels;} + TNTPixel *GetPixelAt( int index) { return &(ListOfPixels->at(index)); } + + ClassDef(TNTEvent,1) +}; + +// -------------------------------------------------------------------------------------- + +class TNTBoardReader : public TObject { + + private: + + int DebugLevel; + DGlobalTools fTool; // JB 2011/07/18 + + int BoardNumber; + bool ReadingEvent; + Int_t TriggerMode; // JB 2009/09/28 + TNTEvent *CurrentEvent; + int CurrentEventNumber; + int CurrentTriggerNumber; // Jb 2009/09/28 + int CurrentFrameNumber; + int CurrentTimestamp; //JB 2009/05/21 + int TimeLimitBetweenTwoTriggers; // JB 2009/05/21 + std::vector ListOfTriggers; + std::vector ListOfTimestamps;//RDM150509 + int maxNumberOfTriggersPerEvent; + std::vector ListOfFrames; + std::vector ListOfPixels; + + ifstream RawFileStream; + char *InputFileName; + char* PrefixFileName; + char* SuffixFileName; + int CurrentFileNumber; + int NumberOfFiles; + bool NoMoreFile; // JB 2010/10/13 + size_t SizeOfWord; + size_t SizeOfDataBuffer; + unsigned int *Data; + int CurrentWordIndex; + int Endianness; // 0= do not swap bytes, 1= swap bytes + int NumberOfBitsValue; // 13 by default + bool SignedValues; // JB 2010/08/26 + int NewFormat; // 30/10/09 NCS + + // Masks for binary decoding, JB 2010/09/26 + int MaskForValue; + int ShiftForValue; + int MaskForIndex; + int MaskForAddress; + int MaxSignedValue; + + // For statistics, JB 2010/09/26 + int TotalNEvents; // JB 2010/08/26 + int TotalNTriggers; // JB 2010/08/26 + int TotalNFaultyTriggers; // JB 2010/08/26 + int TotalNFrames; // JB 2010/08/26 + int TotalNPixels; // JB 2010/08/26 + int TotalNErrors; // JB 2010/08/26 + int TotalOverflows; // JB 2010/10/06 + + bool GetNextWord(); + void AddPixel( int input, int value, int index); + + int eventnumber; // NCS 19/11/2009 + + public: + + TNTBoardReader() {;} + TNTBoardReader( int boardNumber, int sizeOfWord=1024, int endian=0, int timelimit=0, int triggermode=0, int numberOfBits=12, int newformat=1); + ~TNTBoardReader(); + void SetDebugLevel( int level) { DebugLevel = level; cout << "TNTBoardReader " << BoardNumber << " debug updated to " << DebugLevel << endl;} + void SetEndiannes( int endian) { Endianness = endian; } + bool AddFile(char *inputFileName); + bool AddFileList(const char *prefixFileName, int startIndex, int endIndex, const char *suffixFileName); + bool HasData(); + void SkipNextEvent(); // JB 2009/05/26 + int GetBoardNumber() { return BoardNumber; } + TNTEvent* GetEvent() { return CurrentEvent; } + int GetEventNumber() { return CurrentEventNumber;} + char* GetInputFileName() { return InputFileName;} //RDM300509 + char* GetSuffixFileName() { return SuffixFileName;} //RDM300509 + char* GetPrefixFileName() { return PrefixFileName;} //RDM300509 + void Close(); + unsigned int SwapEndian( unsigned int data); + void PrintStatistics(ostream &stream=cout); // JB 2010/08/26 // SS 2011/12/06 + + ClassDef(TNTBoardReader,1); +}; + +# endif diff --git a/include/VMEBoardReader.h b/include/VMEBoardReader.h new file mode 100644 index 0000000..d217693 --- /dev/null +++ b/include/VMEBoardReader.h @@ -0,0 +1,137 @@ +#ifndef _VMEBoardReader_HXX +#define _VMEBoardReader_HXX +/*! + \file + \version $Id: VMEBoardReader.hxx,v 1.8 2003/07/08 18:54:19 mueller Exp $ + \brief Declaration of VMEBoardReader. +*/ +/*------------------------------------------+---------------------------------*/ + +#include "BoardReader.h" // withROOT is define therein +#include +#include +#include +#include "TString.h" +#include "TH1F.h" +#include "TH2F.h" +#include "DGlobalTools.h" // to have fTool has a data member +using namespace std; + +class TH2F; +class TH1F; + +#include "mi26types.h" + +#define withROOT + +//############################################################################## +class VMEBoardReader : public TObject { + +public: + + VMEBoardReader(int boardNumber, TString pathName, TString prefixName, TString suffixName, int runNumber, int numberOfSensors, int numberOfRows); + ~VMEBoardReader(); + + void SetDebugLevel( int aLevel) { fDebugLevel = aLevel; } + void SetVetoPixel( int noiseRun); + bool HasData(); + int GetDebugLevel() { return fDebugLevel; } + int GetBoardNumber() { return fBoardNumber; } + int GetEventNumber() { return fEventNumber; } + Int_t GetSensorsN() const { return fNumberOfSensors; } + BoardReaderEvent* GetEvent() { return fCurrentEvent; } + void PrintStatistics(ostream &stream); + + //! Histograms + // void SetDisplayOn() { fDisplay = true; CreateHistogram(); } + // bool ValidHistogram() { return fDisplay; } + // void CreateHistogram(); + + +private: + + int fDebugLevel; // debug level + DGlobalTools fTool; + Bool_t fDisplay; + int fBoardNumber; + Int_t fRunNumber; // run number + int fNumberOfSensors; // fNSensors + int fNumberOfRows; + int fNumberOfColumns; + int fVetoOverflow; + TString fPrefixName; // prefix folder name + TString fSuffixName; // suffix file name + TString fPathName; // base file name + ifstream fRawFileAscii[10]; // file streamm + + Int_t fIndex; // Index of what? + Int_t fEventSize; // ? + Int_t fDataSize; + vector fData; // data array to fill + UInt_t* fDataEvent; // data array to fill the whole eevent + + Int_t fEventNumber; // number of the event + Int_t fPrevEventNumber[8]; // previous number of the event + Int_t fTriggerNumber; // number of the trigger + Int_t fPrevTriggerNumber[8]; // previous number of the trigger + Int_t fTimeStamp; // time stamp per frame + Int_t fPrevTimeStamp[8]; // time stamp per frame + + Int_t fFrameCount; // number of frame + Int_t fTriggerNumberFrame; // number of the trigger + Int_t fTimeStampFrame; // time stamp per frame + Int_t fFirstFrame; // first frame flag + Bool_t fFrameOk; // first frame flag + UInt_t fCurrentTriggerCnt; + Bool_t fReadingEvent; + Bool_t fOverflow; + Int_t fEventsOverflow; + Int_t fNStatesInLine; + Int_t fFramesReadFromFile; + + BoardReaderEvent* fCurrentEvent; + std::vector ListOfPixels; + std::vector ListOfFrames; + std::vector ListOfLineOverflow; + std::vector ListOfTriggers; + + + // Markers used by the acquisition + static const UInt_t fgkKeyHeader[]; + static const Int_t fgkFrameHeaderSize; + static const UInt_t fgkKeyTail[]; + static const Int_t fgkLineWidth; + static const UInt_t fgkFrameHeader; + static const UInt_t fgkFrameTail; + + static UInt_t GetKeyHeader(Int_t idx) { return fgkKeyHeader[idx]; } + static Int_t GetHeaderSize() { return fgkFrameHeaderSize; } + static UInt_t GetKeyTail(Int_t idx) { return fgkKeyTail[idx]; } + static Int_t GetLineWidth() { return fgkLineWidth; } + static UInt_t GetFrameHeader() { return fgkFrameHeader; } + static UInt_t GetFrameTail() { return fgkFrameTail; } + + + //! File management + virtual Int_t Open(); + virtual void Close(); + + //! Processing + virtual Bool_t Process(); + Bool_t GetSensorEvent(Int_t iSensor); + Bool_t GetFrame(Int_t iSensor, MI26_FrameRaw* data); + Bool_t DecodeFrame(Int_t iSensor, MI26_FrameRaw *frame); + Bool_t IsPartEqual(UInt_t data, UInt_t key); + void ResetFrames(); + void AddPixel( Int_t input, Int_t value, Int_t aLine, Int_t aColumn); + Int_t GetSensor(UInt_t key); + + //! Fill histogram frame + // void FillHistoFrame(Int_t iSensor, MI26_FrameRaw* data); + // void FillHistoEvt(Int_t iSensor); + + + ClassDef(VMEBoardReader,1) +}; + +#endif diff --git a/include/img_daq_lib/das.h b/include/img_daq_lib/das.h new file mode 100755 index 0000000..2f03a47 --- /dev/null +++ b/include/img_daq_lib/das.h @@ -0,0 +1,31 @@ +// @(#)maf/maf:$Name: $:$Id das.h v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Gilles CLAUS 23/11/02 + +/////////////////////////////////////////////////////////////////////////////////////////////// +// das.h : // +// MIMOSA 9 : has a special feature. Matrices 64 x 64 and 32 x 32 recorded // +// in the same time. // +// So while one frame is read on the first submatrix, 4 frames are read on the // +// second submatrix. // +// This has to be taken into account mainly in DPlane.cxx, mi9_mat_a3.c, event_header.typ . // +// Put readout = 8 in the config file. // +/////////////////////////////////////////////////////////////////////////////////////////////// + +#undef TCD_COMPIL + +#define DAS_EVENT_MAX_SZ (5*1024*1024) + +#define DAS_HEADER_SZ 112 +#define DAS_REFDET_SZ 2048 +#define DAS_TRAILER_SZ 4 + + +typedef struct{ + + TPEventHeader PtHeader; + int* PtRef; + int* PtMimosa; + int* PtEOR; + +} +DAS_TEvent; diff --git a/include/img_daq_lib/event_header.typ b/include/img_daq_lib/event_header.typ new file mode 100755 index 0000000..8e0605b --- /dev/null +++ b/include/img_daq_lib/event_header.typ @@ -0,0 +1,108 @@ +// @(#)maf/maf:$Name: $:$Id event_header.typ v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Gilles CLAUS 23/11/02 +// Modification : JB 2014/10/15 S/UINT32 -> S/UINT32 to allow compilation with other libraries declaring also S/UINT32 + +#ifndef EVENT_HEADER_TYP +#define EVENT_HEADER_TYP + + +/////////////////////////////////////////////////////////////////////////////////////////////// +// event_header.typ : // +// MIMOSA 9 : has a special feature. Matrices 64 x 64 and 32 x 32 recorded // +// in the same time. // +// So while one frame is read on the first submatrix, 4 frames are read on the // +// second submatrix. // +// This has to be taken into account mainly in DPlane.cxx, mi9_mat_a3.c, event_header.typ . // +// Put readout = 8 in the config file. // +/////////////////////////////////////////////////////////////////////////////////////////////// + + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/das_fio/event_header.typ +Goal : Event header definition of DAS datafile format. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI +*******************************************************************************/ + + +typedef int SInt32img; +typedef unsigned int UInt32img; +typedef short SInt16; +typedef unsigned short UInt16; + +#define NB_MAX_VFAS 5 +#define EVENT_HEADER_RESERVED_ESZ 10 + + +/**************************/ +/* Event header structure */ +/**************************/ + + +/* One run is split in N file of each FileEvNb events ( or less for last file ) */ +/* for eg RUN 100 => RUN_100_0.rz, RUN_100_1.rz, RUN_100_2.rz ... RUN_rrr_fff.rz */ +/* RUN_rrr_fff.rz => rrr is the run number and fff is the file number */ + +/* Some fields seems to be useless */ +/* I wrote my own I/O routines, then i need some fields for this */ + +typedef struct { + + + UInt32img EvTrig; /* Event trigger : Increment from 0 at each trigger */ + UInt32img EvNo ; /* Event number : Increment from 0 at each event taken */ + UInt32img EvPos ; /* Event position in file : Increment from 0 after each event write */ + + /* Why EvNo & EvPos ? */ + + /* There are two types of datas files with the same header format */ + /* - Files with all events taken => for off-line analysis */ + /* - Files with on-line monitoring events => a percentage of all events */ + /* In data file for off-line analysis EvNo = EvPos */ + /* In data file from on-line monitoring EvNo != EvPos */ + /* For eg if we take 50 % the the sequence should be as follows */ + /* EvNo = 0, 2, 4, 6, 8, 10 */ + /* EvPos = 0, 1, 2, 3, 4, 5 */ + + + SInt32img EvTag; /* Event tag : for future use - should be 0 */ + SInt32img EvDate; /* Event date = 0 */ + SInt32img EvTime; /* Event time = SSSS ssss ( S = second s = mS - 10 ms resolution ) */ + + /* I am afraid TrigCnt isn't ok now */ + UInt32img TrigCnt; /* Total triggers received by acquisition system : accepted or not */ + + UInt32img EvVmeTime; /* Time to read VME boards in ms [10 ms res] */ + /* Set to 0 at first event, then increase */ + /* Vme time Ev 0 = EvVmeTime[1] - EvVmeTime[0] */ + /* Vme time Ev 1 = EvVmeTime[2] - EvVmeTime[1] */ + + SInt32img VFasCnt[NB_MAX_VFAS]; /* Hardware Adc strip counter */ + SInt32img VFasReg[NB_MAX_VFAS]; + + /* New fields => must decrement Reserved size when you add field ! */ + + SInt32img EvNetTime; /* Time to send one event by ethernet in ms [10 ms res] */ + /* Set to 0 at first event, then increase */ + /* Net time Ev 0 = EvNetTime[1] - EvNetTime[0] */ + /* Net time Ev 1 = EvNetTime[2] - EvNetTime[1] */ + + SInt16 MeasNo; /* Index of current measure */ + SInt16 EvInMeasNo; /* Index of event in current measure */ + + SInt32img Reserved[EVENT_HEADER_RESERVED_ESZ-2]; + + +} TEventHeader; + +typedef TEventHeader* TPEventHeader; + +#define EVENT_HEADER_SZ (sizeof (TEventHeader)) + + +#endif + diff --git a/include/mi26types.h b/include/mi26types.h new file mode 100755 index 0000000..1d00502 --- /dev/null +++ b/include/mi26types.h @@ -0,0 +1,47 @@ +#ifndef _mi26types_h +#define _mi26types_h + +typedef struct { + unsigned int Header; + unsigned int TriggerCnt; + unsigned int TriggerLine; // ? not sure + unsigned int FrameCnt; + unsigned int DataLength; + unsigned int ADataW16[140]; //data MI26 + unsigned int Trailer; + +} MI26_FrameRaw; + + +typedef union { + + unsigned int W16; + + struct { + + unsigned int StateNb : 4; + unsigned int LineAddr : 11; + unsigned int Ovf : 1; + + } F; + +} MI26__TStatesLine; + + +typedef union { + + unsigned int W16; + + struct { + + unsigned int HitNb : 2; + unsigned int ColAddr : 11; + unsigned int NotUsed : 3; + + } F; + +} MI26__TState; + + + +#endif diff --git a/include/mimo_daq_lib/.DS_Store b/include/mimo_daq_lib/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..970dcc98885a8230406f2141130ab45500f3cc3b GIT binary patch literal 10244 zcmeHMTTC5A827*z1UI@7d2>WQD`Z>ou11U*6!IoJ-g=s zr5Ix3CEDmyn`mqwe9$!22kYfYAGFccgO(hG3XZ0h%GXMe*?wJMF%& z&*EuAx1E-js~9LKEGjOMBt=q|D@Xc8SmqFW>Ww+WareI8vW%JgSbV>( zjYQRzU6$#@bW_W4u%6VY$>9OrOj;wIR@O|~yq`W%AxW|%N7b6~@ut?6@Ycpq(>>v~ ziN?^lc-q#oePTkEs_Mh-J;zdGr^ZiDJaL|gqJ-`m59Q){Cci*;i%#Ac3ilFoeZS66Q+UYs1n_3gJlJ&GV?dX>JUO&hTK&PH1LQH-`pt zx~<0zt>28Lw2G1fS>~wKRl(qaY+OH?)txc5PLih7vhw9hO>mv8zAGJ0(n$7LN!DYM z*92>V8zkuvEAPr^l#61eK6r<$#-x6m<|VqgQ)!e{TkbzWauCqFm9V5H<$Xpht{I|e zv$91}AC?DlVtS%*yRt*7z()B1y|on0#}>uAf)PpmR65Fh?~d8d-n3?tdp7sZnqY8{ zm3JhQT2hjvx=4fIiBDHnSu{}%8)#MA3B52#U-t-{fwOQ9UWH5W9=s2qz~}H4d<|FO z8hj5w!cXus`~uhE5BL-QLJ2Fd5?A1QY`{%;7dB!T@5LS1j=Qi6cjF%1i@mrXqj(JC zn7|Y0U=~Ml44=g3@eICzFX9D!9pA#s_%^NRVX+I^%nZFC{wt0hcR5^udeR9mYuF^R{G^|gwMq<5LuZmOr+fLqtpOmzh$ZBf_S zrqrrMq+)^Gx=m5kLXx?t-PumH#UyBHs=6w;TIp1}W%jM9;8o;;db|ji;X~5mx9}bO zKsx*tt|MSEmf~t$has%PjaZM(*n+LthMP%&_hAQiauq(pRXB);@CY6yEe_-3XkZFW z93dr+<7u40r}0^Qj%)HPp2L^$WqbwC<7;@yqsAVO8sAuo8dFwxxBELIbyQtW=q*<| zmWE6ID_nZ`=9l(dU&b^nbBM;pzPx4h+iO$YaKk7i@CCJ;9i_~V^8C&hw0lsc+?P)N z!fu4&P?V7u6BSl_a4asdDKhcm=80(vpIIW-fiXzWjVlU&_h8xTlkYc5k<=(fhk0>e z0n^ZImQ+HIfl1M1ltypTs>_g3iV8I<%bRym!h^3|1V7IlioW#pAyf26GbN8Ud7Ou_ z;`?rhn8!!)n;t|N`-rdYwC5y&e}tC9ixjS)^1W*4xx-SVdeZdo*vk7 sJl~U3nR|x8>mzQvNntsha2!rnoaW#1e+Kyb|66uY +#include +#include + + +// ----------------------------------------------------------------------- +// Compilation directives +// ----------------------------------------------------------------------- + +#define CC_MSIS1_BDF_LIGHT + + +// ----------------------------------------------------------------------- +// Macro definition +// ----------------------------------------------------------------------- + + + + +// ----------------------------------------------------------------------- +// Types definition +// ----------------------------------------------------------------------- + + +#ifndef UInt8 +typedef uint8_t UInt8; +#endif + +#ifndef UByte +typedef uint8_t UByte; +#endif + +#ifndef SInt8 +typedef int8_t SInt8; +#endif + +#ifndef SByte +typedef int8_t SByte; +#endif + +#ifndef UInt16 +typedef uint16_t UInt16; +#endif + +#ifndef UWord +typedef uint16_t UWord; +#endif + +#ifndef SInt16 +typedef int16_t SInt16; +#endif + +#ifndef SWord +typedef int16_t SWord; +#endif + +#ifndef UInt32 +typedef uint32_t UInt32; +#endif + +#ifndef ULong +typedef uint32_t ULong; +#endif + +#ifndef SInt32 +typedef int32_t SInt32; +#endif + +#ifndef SLong +typedef int32_t SLong; +#endif + + +#ifndef UInt64 +typedef uint64_t UInt64; +#endif + +#ifndef SInt64 +typedef int64_t SInt64; +#endif + + + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + +typedef UInt16 TW128As8W16[8]; // Endianness is function of CC_TW128_LITTLE_ENDIAN + +// +// If CC_TW128_LITTLE_ENDIAN IS defined +// => TW128As8W16, DECOM__TW128As8W16 are little endian +// => [0] = LS W16, [7] = MS W16 +// => W128 = 0000 1111 2222 3333 4444 5555 6666 7777 +// = > [7] = 0000, [6] = 1111, [5] = 2222, [4] = 3333, [3] = 4444, [2] = 5555, [1] = 6666, [0] = 7777 +// +// If CC_TW128_LITTLE_ENDIAN IS NOT defined +// => TW128As8W16, DECOM__TW128As8W16 are big endian +// => [0] = MS W16, [7] = LS W16 +// => W128 = 0000 1111 2222 3333 4444 5555 6666 7777 +// = > [0] = 0000, [1] = 1111, [2] = 2222, [3] = 3333, [4] = 4444, [5] = 5555, [6] = 6666, [7] = 7777 + + + + +#endif diff --git a/include/mimo_daq_lib/errors_light.c b/include/mimo_daq_lib/errors_light.c new file mode 100644 index 0000000..a02ea0d --- /dev/null +++ b/include/mimo_daq_lib/errors_light.c @@ -0,0 +1,1089 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\prj\win\mimosis_1\run_read_light_bt\com\errors_light.c +* \brief Goal : Errors messages library - Functions +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 12/05/2021 +* \date File date : 12/05/2021 +* \date Doc date : 12/05/2021 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IPHC 23 Rue du Loess 67037 STRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + +#ifndef ERR_L_C +#define ERR_L_C + + +#include +#include + + +#ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + + +SInt32 ERR_FEnableLog ( SInt8 Enable ) { +} + + +SInt32 ERR_EnableLog ( SInt8 Enable ) { + return (0); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetFileLogEnabled () { + return (0); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetUserLogEnabled () { + return (0); +} + + +SInt32 ERR_FSetLogFilePath ( char* LogFilePath ) { + return (0); +} + +char* ERR_FGetLogFilePath () { + return ( ERR_VGMsgNotAvailable ); +} + +SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath ) { + return (0); +} + + +SInt32 ERR_FEnd () { + return (0); +} + + +SInt32 ERR_FStopLog ( SInt8 Stop ) { + return (0); +} + +/* 11/06/2005 */ + +SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel ) { + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetFileLogLevel () { + return (0); +} + +/* 07/04/2007 */ + +char* ERR_FLogLevel2Str ( SInt8 Lvl ) { + + return ( ERR_VGMsgNotAvailable ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetFileLogLevelStr () { + + return ( ERR_VGMsgNotAvailable ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel ) { + + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetUserLogLevel () { + + return (0); +} + +/* 07/04/2007 */ + +char* ERR_FGetUserLogLevelStr () { + + return ( ERR_VGMsgNotAvailable ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetErrLogConfStr () { + + return ( ERR_VGMsgNotAvailable ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FUserStopLog ( SInt8 Stop ) { + + return (0); +} + +/* 10/06/2005 */ + +SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func ) { + + return (0); +} + +// 25 05 18 MS added counter to the message system for debugging for mimosis0 + +SInt32 ERR_FGenError ( char MsgType ) { + + return (0); +} + + + +char* ERR_FGetLastErrMsg () { + + return (ERR_OUT); + +} + + +// GC - 20/02/2020 + +char* ERR_FGetLastErrMsgLong () { + + return (ERR_OUT); + +} + + +// GC - 20/02/2020 + +char* ERR_FGetLastErrMsgShort () { + + return (ERR_OUT); + +} + +// Returns trace messages flag an reset it +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// GC 06/04/2021 + +SInt8 ERR_FIsTraceMsg () { + + return (0); +} + + +// Returns warning messages flag an reset it +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// GC 06/04/2021 + +SInt8 ERR_FIsWarnMsg () { + + return (0); +} + + +// Returns errors messages flag an reset it +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// GC 06/04/2021 + +SInt8 ERR_FIsErrMsg () { + + + return (0); +} + + +// Returns messages flag an reset it +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// +// ErrType +// - 0 => No error <=> Do nothing +// - 1 => Trace +// - 2 => Warnings +// - 3 => Errors +// - 4 => Warning + Errors +// - 5 => Any => Trace or Warning or Error +// + +// GC 06/04/2021 +// +// ErrType +// - 0 => No error <=> Do nothing +// - 1 => Trace +// - 2 => Warning +// - 3 => Error +// - 4 => Any => Trace or Warning or Error + +// GC 14/04/2021 +// WARNING List of ErrType modified +// + +SInt8 ERR_FIsMsg ( SInt8 ErrType ) { + + return (0); +} + + + + +// Emul error messaget +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// ErrType +// - 0 => No error <=> Do nothing +// - 1 => Trace +// - 2 => Warning +// - 3 => Error +// +// GC 06/04/2021 + + + +SInt8 ERR_FEmulErr ( UInt8 ErrType, char* Msg) { + + + return (0); +} + + + +void FPrint ( void ) +{ +} + + +// 01/03/2012 + +SInt32 ERR_FGetEnumSz () { + + + return (0); +} + + + +//========================================================================================= + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 ERR_FPrintLvErrMsg ( SInt8 LvIsError, SInt32 LvErrCode, char* LvMsg, char* UserErrMsg, char* UserOkMsg, SInt32 UserErrLvl ) +* : +* \brief : Prints an error message from LabVIEW (LV error cluster) to error log file +* : +* : +* \param : LvIsError - Connecter to LV boolean of error cluster via cat bool to int +* : 0 => No error, > 0 => error +* : +* \param : LvErrCode - Error code = LV SInt32 of error cluster +* : +* \param : LvMsg - Text message from LV (char*) = LV text of error cluster +* : +* \param : UserErrMsg - Optional error msg from user (char*), printed in case LvIsError > 0 +* : +* \param : UserErrOk - Optional ok message from user (char*), printed in case LvIsError = 0 +* : +* \param : UserErrLvl - Optional error level from user (SInt32), 0 = Not set / No error, 1 = Warning, 2 = Error +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : To give acces to this function in a DLL you MUST add its prototype in my_dll.cpp before error lib files inclusion +* \warning : add => extern "C" __declspec(dllexport) SInt32 ERR_FPrintLvErrMsg ( SInt8 LvIsError, SInt32 LvErrCode, char* LvMsg, char* UserMsg, SInt32 UserErrLvl ); +* \warning : +* \warning : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/04/2019 +* \date : Doc date : 26/04/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 ERR_FPrintLvErrMsg ( SInt8 LvIsError, SInt32 LvErrCode, char* LvMsg, char* UserErrMsg, char* UserOkMsg, SInt32 UserErrLvl ) { + + + return (0); +} + + + + +#else // Of #ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + +// ----------------------------------------------------------------------- +// Functions +// ----------------------------------------------------------------------- + + +#ifdef CC_APP_OS9 + +char* strerror ( SInt32 errno ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + sprintf ( VMsgStr, "Not avalibale under OS9" ); + + return (VMsgStr); +} + +#endif + +#ifndef CC_APP_WINDOWS + + +char *_strerror ( char* UsrStr ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + #ifdef APP_ROOT + sprintf ( VMsgStr, "%s : No errno str because not supported by ROOT", UsrStr ); + #else + strncpy ( VMsgStr, UsrStr, ERR_USR_MSG_SZ-10 ); + strcat ( VMsgStr, " : " ); + strncat ( VMsgStr, strerror ( errno ), ERR_SYS_MSG_SZ-10 ); + #endif + + + return (VMsgStr); +} + + +#endif + +SInt32 ERR_FEnableLog ( SInt8 Enable ) { + + ERR_VGFileLogEnable = Enable; + + ERR_VGUserLogEnable = Enable; + + if (Enable){ + + if ( ERR_VGLogClosed && (ERR_VGLogFile != stdout) && (ERR_VGLogFile != stderr) ) { + ERR_VGLogClosed = 0; + + // + // 29/10/10 => Don't open log file in append mode but overwrite it + // + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + + // 02/06/12 => Enable again open in append mode for strip analysis LIB / DLL debug + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + + + ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); + } + } + + // 11 04 2019 MS try to remove the closing of the file + +/* else{ + if (ERR_VGLogClosed == 0){ + fclose(ERR_VGLogFile); + ERR_VGLogClosed = 1; + ERR_VGLogFile = NULL; + } + + }*/ + + + return (0); +} + +SInt32 ERR_EnableLog ( SInt8 Enable ) { + return ( ERR_FEnableLog ( Enable) ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetFileLogEnabled () { + return ( ERR_VGFileLogEnable ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetUserLogEnabled () { + return ( ERR_VGUserLogEnable ); +} + + +SInt32 ERR_FSetLogFilePath ( char* LogFilePath ) { + sprintf ( ERR_VGLogPath, "%s", LogFilePath ); + return (0); +} + +char* ERR_FGetLogFilePath () { + return ( ERR_VGLogPath ); +} + +SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath ) { + + // 30/11/2019 begin : + // Upgrade in order to + // - get one couple of log files per DLL instance loaded by application ( a suffix 0, 1, is added to log files names) + // - keep one single couple of log files for the application itself, each time a library (compiled by src inclusion) + // defines a new log file, it is ignored if one is laready opened => the first log file name configured is used + // + // DLL compilation => DO NOT define APP_SAME_LOG_FILES_NAMES + // Application compilation => Define APP_SAME_LOG_FILES_NAMES + + + #ifndef APP_SAME_LOG_FILES_NAMES + + ERR_VGLogClosed = 1; + + if ( ERR_VGLogFile != NULL ) { + fflush (ERR_VGLogFile); + fclose (ERR_VGLogFile); + } + + #endif + + // 30/11/2019 end modif + + ERR_FSetLogFilePath ( FilePath ); + ERR_FEnableLog ( Enable ); + + return (0); +} + + +SInt32 ERR_FEnd () { + if (ERR_VGLogClosed == 0){ + fclose(ERR_VGLogFile); + ERR_VGLogClosed = 1; + } + return (0); +} + + +SInt32 ERR_FStopLog ( SInt8 Stop ) { + ERR_VGFileDontLog = Stop; + return (0); +} + +/* 11/06/2005 */ + +SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel ) { + ERR_VGFileLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetFileLogLevel () { + return ( ERR_VGFileLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FLogLevel2Str ( SInt8 Lvl ) { + + static char VStr[GLB_CMT_SZ+1]; + + switch ( Lvl ) { + + case ERR_LOG_LVL_NONE : { + sprintf ( VStr, "ERR_LOG_LVL_NONE" ); + break; } + + case ERR_LOG_LVL_ALL : { + sprintf ( VStr, "ERR_LOG_LVL_ALL" ); + break; } + + case ERR_LOG_LVL_WARINGS_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_WARINGS_ERRORS" ); + break; } + + case ERR_LOG_LVL_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_ERRORS" ); + break; } + + default : { + sprintf ( VStr, "Unknow error level = %d", Lvl ); + break; } + + } + + return ( VStr ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetFileLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGFileLogLevel ) ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel ) { + ERR_VGUserLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetUserLogLevel () { + return ( ERR_VGUserLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FGetUserLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGUserLogLevel ) ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetErrLogConfStr () { + + static char VStr[GLB_CMT_SZ+1]; + + sprintf ( VStr, "Error log configuration \n\n - File log enabled = %d \n - File log level = %s \n - File stop log =%d \n - Log file name = %s \n - User log enabled = %d \n - User log level = %s \n - User stop log =%d \n\n", ERR_VGFileLogEnable, ERR_FGetFileLogLevelStr (), ERR_VGFileDontLog, ERR_VGLogPath, ERR_VGUserLogEnable, ERR_FGetUserLogLevelStr (), ERR_VGUserDontLog ); + + return (VStr); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FUserStopLog ( SInt8 Stop ) { + ERR_VGUserDontLog = Stop; + return (0); +} + +/* 10/06/2005 */ + +SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func ) { + + ERR_VGUserErrorFunc = Func; + + return (0); +} + +// 25 05 18 MS added counter to the message system for debugging for mimosis0 + +SInt32 ERR_FGenError ( char MsgType ) { + + static char VErrMsg[ERR_TOT_MSG_SZ]; + static SInt32 VErrPrintCnt = 0;// + + + // 03/11/2020 - No log if called in class constructor + + #ifndef CC_FORCE_LOG_IN_CONSTRUCTORS + + if ( ERR_VGConstructorNoLog ) { + return (0); + } + + #endif + + ERR_VGLastErrMsg = VErrMsg; + + /* ERR_VGLogLevel */ + /* == ERR_LOG_LVL_NONE => No log */ + /* == ERR_LOG_LVL_ALL => Log 'T', 'W', 'E' */ + /* == ERR_LOG_LVL_WARINGS_ERRORS => Log 'W', 'E' */ + /* == ERR_LOG_LVL_ERRORS => Log 'E' */ + + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_NONE) && (ERR_VGUserLogLevel == ERR_LOG_LVL_NONE) ) { + return (0); + } + + + // 06/04/2021 + + switch ( MsgType ) { + + case 'T' : { + ERR_VGIsTraceMsg = 1; + break; } + + case 'W' : { + ERR_VGIsWarnMsg = 1; + break; } + + case 'E' : { + ERR_VGIsErrMsg = 1; + break; } + + + } + + + sprintf ( VErrMsg, "%d\\%s%s \n", VErrPrintCnt, ERR_VGStrLocationMsg , ERR_OUT ); + + VErrPrintCnt++; // + + /* File log handling */ + + while (1) { + + if ( ERR_VGFileLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Write error message to file */ + + // + // 09/04/2019 MS + // + // moved the opening of the log file to the ERR_FEnableLog function + // + // 10/04/2019 MS + // + // enabled again to ensure compatibility with old software + // + + if ( ERR_VGLogClosed && (ERR_VGLogFile != stdout) && (ERR_VGLogFile != stderr) ) { + + ERR_VGLogClosed = 0; + + // + // 29/10/10 => Don't open log file in append mode but overwrite it + // + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + + // 02/06/12 => Enable again open in append mode for strip analysis LIB / DLL debug + // + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + + + ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); + } + + if ( (ERR_VGFileDontLog == 0) && (ERR_VGLogFile != NULL) ) { + fprintf ( ERR_VGLogFile, VErrMsg ); + fflush ( ERR_VGLogFile ); + } + + break; + } + + /* User log handling */ + + while (1) { + + if ( ERR_VGUserLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Call user error function */ + + if ( (ERR_VGUserDontLog == 0) && (ERR_VGUserErrorFunc != NULL) ) { + ERR_VGUserErrorFunc ( MsgType, ERR_VGStrLocationMsg , ERR_OUT, VErrMsg ); + } + + break; + } + + + + + + + return (0); +} + + + +char* ERR_FGetLastErrMsg () { + + return (ERR_VGLastErrMsg); + +} + + +// GC - 20/02/2020 + +char* ERR_FGetLastErrMsgLong () { + + return (ERR_VGLastErrMsg); + +} + + +// GC - 20/02/2020 + +char* ERR_FGetLastErrMsgShort () { + + return (ERR_OUT); + +} + +// Returns trace messages flag an reset it +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// GC 06/04/2021 + +SInt8 ERR_FIsTraceMsg () { + + if ( ERR_VGIsTraceMsg ) { + ERR_VGIsTraceMsg = 0; + return (1); + } + + return (0); +} + + +// Returns warning messages flag an reset it +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// GC 06/04/2021 + +SInt8 ERR_FIsWarnMsg () { + + if ( ERR_VGIsWarnMsg ) { + ERR_VGIsWarnMsg = 0; + return (1); + } + + return (0); +} + + +// Returns errors messages flag an reset it +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// GC 06/04/2021 + +SInt8 ERR_FIsErrMsg () { + + if ( ERR_VGIsErrMsg ) { + ERR_VGIsErrMsg = 0; + return (1); + } + + return (0); +} + + +// Returns messages flag an reset it +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// +// ErrType +// - 0 => No error <=> Do nothing +// - 1 => Trace +// - 2 => Warnings +// - 3 => Errors +// - 4 => Warning + Errors +// - 5 => Any => Trace or Warning or Error +// + +// GC 06/04/2021 +// +// ErrType +// - 0 => No error <=> Do nothing +// - 1 => Trace +// - 2 => Warning +// - 3 => Error +// - 4 => Any => Trace or Warning or Error + +// GC 14/04/2021 +// WARNING List of ErrType modified +// + +SInt8 ERR_FIsMsg ( SInt8 ErrType ) { + + + switch ( ErrType ) { + + case 0 : { + // Nothing to do + return (0); + break; } + + + case 1 : { + return ( ERR_FIsTraceMsg () ); + break; } + + + case 2 : { + return ( ERR_FIsWarnMsg () ); + break; } + + + case 3 : { + return ( ERR_FIsErrMsg () ); + break; } + + + case 4 : { + + if ( ERR_VGIsWarnMsg || ERR_VGIsErrMsg ) { + ERR_VGIsWarnMsg = 0; + ERR_VGIsErrMsg = 0; + return (1); + } + + else { + return (0); + } + + break; } + + + case 5 : { + + if ( ERR_VGIsTraceMsg || ERR_VGIsWarnMsg || ERR_VGIsErrMsg ) { + ERR_VGIsTraceMsg = 0; + ERR_VGIsWarnMsg = 0; + ERR_VGIsErrMsg = 0; + return (1); + } + + else { + return (0); + } + + break; } + + + } + + + return (0); +} + + + + +// Emul error messaget +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// ErrType +// - 0 => No error <=> Do nothing +// - 1 => Trace +// - 2 => Warning +// - 3 => Error +// +// GC 06/04/2021 + + + +SInt8 ERR_FEmulErr ( UInt8 ErrType, char* Msg) { + + + // Check param + + err_retnull ( Msg, (ERR_OUT,"Abort => Msg == NULL") ); + + + // Emul message + + switch ( ErrType ) { + + case 0 : { + // Nothing to do + break; } + + + case 1 : { + err_trace (( ERR_OUT, "%s", Msg )); + break; } + + + case 2 : { + err_warning (( ERR_OUT, "%s", Msg )); + break; } + + + case 3 : { + err_error (( ERR_OUT, "%s", Msg )); + break; } + + } + + + return (0); +} + + + +void FPrint ( void ) +{ + printf ( "%s \n", VGOut ); +} + + +// 01/03/2012 + +SInt32 ERR_FGetEnumSz () { + + SInt32 VSz; + + typedef enum EEnumTest { FIRST, PREC, NEXT, LAST } TEnumTest; + + VSz = sizeof ( TEnumTest ); + + err_trace (( ERR_OUT, "Enum size = %d Bytes", VSz )); + + return (VSz); +} + + + +//========================================================================================= + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 ERR_FPrintLvErrMsg ( SInt8 LvIsError, SInt32 LvErrCode, char* LvMsg, char* UserErrMsg, char* UserOkMsg, SInt32 UserErrLvl ) +* : +* \brief : Prints an error message from LabVIEW (LV error cluster) to error log file +* : +* : +* \param : LvIsError - Connecter to LV boolean of error cluster via cat bool to int +* : 0 => No error, > 0 => error +* : +* \param : LvErrCode - Error code = LV SInt32 of error cluster +* : +* \param : LvMsg - Text message from LV (char*) = LV text of error cluster +* : +* \param : UserErrMsg - Optional error msg from user (char*), printed in case LvIsError > 0 +* : +* \param : UserErrOk - Optional ok message from user (char*), printed in case LvIsError = 0 +* : +* \param : UserErrLvl - Optional error level from user (SInt32), 0 = Not set / No error, 1 = Warning, 2 = Error +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : To give acces to this function in a DLL you MUST add its prototype in my_dll.cpp before error lib files inclusion +* \warning : add => extern "C" __declspec(dllexport) SInt32 ERR_FPrintLvErrMsg ( SInt8 LvIsError, SInt32 LvErrCode, char* LvMsg, char* UserMsg, SInt32 UserErrLvl ); +* \warning : +* \warning : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/04/2019 +* \date : Doc date : 26/04/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 ERR_FPrintLvErrMsg ( SInt8 LvIsError, SInt32 LvErrCode, char* LvMsg, char* UserErrMsg, char* UserOkMsg, SInt32 UserErrLvl ) { + + SInt32 VRetError; + + + VRetError = 0; + + + // If no error + + if ( LvIsError == 0 ) { + err_retok (( ERR_OUT, "$LV: %s", UserOkMsg )); + return (VRetError); + } + + // If error + + // Force UserErrLvl to "error", in case it has not been set, or set incorrectly + // 0 => Not set or No error + // 1 => Warning + // 2 => Error + + if ( UserErrLvl == 0 ) { + UserErrLvl = 2; + } + + switch ( UserErrLvl ) { + + // Should never happen here, but who knows ... + + case 0 : { + VRetError = 0; + err_retok (( ERR_OUT, "$LV: LvMsg = %s - UserMsg = %s", LvMsg, UserErrMsg )); + break; } + + case 1 : { + VRetError = -1; + err_warning (( ERR_OUT, "$LV: LvErrCode = %d - LvMsg = %s - UserMsg = %s", LvErrCode, LvMsg, UserErrMsg )); + break; } + + case 2 : { + VRetError = -1; + err_error (( ERR_OUT, "$LV: LvErrCode = %d - LvMsg = %s - UserMsg = %s", LvErrCode, LvMsg, UserErrMsg )); + break; } + + default : { + VRetError = -1; + err_warning (( ERR_OUT, "$LV: Unknown UserErrLvl = %d <> 0=No,1=Warning,2=Error - LvErrCode = %d - LvMsg = %s - UserMsg = %s", UserErrLvl, LvErrCode, LvMsg, UserErrMsg )); + break; } + + } + + return (VRetError); +} + + + + +#endif // End of #ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + + + +#endif diff --git a/include/mimo_daq_lib/errors_light.h b/include/mimo_daq_lib/errors_light.h new file mode 100644 index 0000000..0212907 --- /dev/null +++ b/include/mimo_daq_lib/errors_light.h @@ -0,0 +1,361 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\prj\win\mimosis_1\run_read_light_bt\com\errors_light.h +* \brief Goal : Errors messages library - Constants, types, functions proto, ... +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 12/05/2021 +* \date File date : 12/05/2021 +* \date Doc date : 12/05/2021 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IPHC 23 Rue du Loess 67037 STRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + +#ifndef ERR_L_H +#define ERR_L_H + + +#include +#include +#include // GC 19/05/2021 : + +#include "var_decl_def.h" + + +#ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + +// ----------------------------------------------------------------------- +// Constants for errors messages +// ----------------------------------------------------------------------- + + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + +// ----------------------------------------------------------------------- +// Errors messages "conversion" lowercase to uppercase +// ----------------------------------------------------------------------- + +#define err_trace(Msg) ERR_TRACE(Msg) +#define err_tracel(Lvl,Msg) ERR_TRACE(Msg) +#define err_warning(Msg) ERR_WARNING(Msg) +#define err_error(Msg) ERR_ERROR(Msg) + +#define err_ret(Code,MsgOk,MsgFail) ERR_RET(Code,MsgOk,MsgFail) +#define err_retok(MsgOk) ERR_RET_OK(MsgOk) +#define err_retval(Code,MsgOk) ERR_RET_VAL(Code,MsgOk) +#define err_retfail(Code,MsgFail) ERR_RET_FAIL(Code,MsgFail) +#define err_retfailnull(Code,MsgFail) ERR_RET_FAIL_NULL(Code,MsgFail) +#define err_retnull(Ptr,MsgFail) ERR_RET_NULL(Ptr,MsgFail) + + +// ----------------------------------------------------------------------- +// Macro for errors messages +// ----------------------------------------------------------------------- + +// Because __FUNCTION__ does not exists under C++ Builder (Windows) + +#ifdef CC_APP_GUI_CPP + #define __FUNCTION__ __FUNC__ +#endif + + +/* + +#define ERR_TRACE(Msg) { sprintf ( ERR_OUT, "T : file %s function ? line %.4d ", __FILE__, __LINE__ ) ; } + +#define ERR_WARNING(Msg) { sprintf ( ERR_OUT, "W : file %s function ? line %.4d ", __FILE__, __LINE__ ) ; } + +#define ERR_ERROR(Msg) { sprintf ( ERR_OUT, "E : file %s function ? line %.4d ", __FILE__, __LINE__ ) ; } + +*/ + + +#define ERR_TRACE(Msg) { sprintf ( ERR_OUT, "T : file %s function %s line %.4d ", __FILE__, __FUNCTION__, __LINE__ ) ; } + +#define ERR_WARNING(Msg) { sprintf ( ERR_OUT, "W : file %s function %s line %.4d ", __FILE__, __FUNCTION__, __LINE__ ) ; } + +#define ERR_ERROR(Msg) { sprintf ( ERR_OUT, "E : file %s function %s line %.4d ", __FILE__, __FUNCTION__, __LINE__ ) ; } + + + +#define ERR_RET(Code,MsgOk,MsgFail) { \ + if ((Code)<0) ERR_ERROR (MsgFail) \ + else ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_RET_FAIL(Code,MsgFail) { \ + if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (Code); } \ + } + + + +#define ERR_RET_FAIL_NULL(Code,MsgFail) { \ +if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (NULL); } \ + } + + + +#define ERR_RET_NULL(Ptr,MsgFail) { \ +if ((void*)(Ptr)==NULL) { ERR_ERROR (MsgFail) return (-1); } \ + } + + + + +#define ERR_RET_OK(MsgOk) { \ + if ( ERR_VGFastErrRetOkNoLog == 0 ) ERR_TRACE (MsgOk); \ + return (0); \ + } + + +#define ERR_RET_VAL(Code,MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (Code); \ + } + + + +// ----------------------------------------------------------------------- +// Types definition +// ----------------------------------------------------------------------- + + +typedef SInt32 (*ERR_TUserErrorFunc) ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ); + + +// ----------------------------------------------------------------------- +// Variables for errors messages +// ----------------------------------------------------------------------- + + + // VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[GLB_CMT_SZ] ); + + VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_OUT[GLB_CMT_SZ] , ""); + + VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFastErrRetOkNoLog, 0); + + VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_VGMsgNotAvailable[GLB_CMT_SZ] , "Errors loging not fully available"); + + + + + +#else + + + + + +// #include "..\..\com\var_decl_def.h" // For selection between variable creation / export via CC + // #undef CC_INTERFACE_FILE => Creates variables and initializes them + // #define CC_INTERFACE_FILE => Export variables only + + + + +// ----------------------------------------------------------------------- +// Compilation directives +// ----------------------------------------------------------------------- + + + +// ----------------------------------------------------------------------- +// Macro definition +// ----------------------------------------------------------------------- + + +// Because __FUNCTION__ does not exists under C++ Builder (Windows) + +#ifdef CC_APP_GUI_CPP + #define __FUNCTION__ __FUNC__ +#endif + + + +// ----------------------------------------------------------------------- +// Macro for errors messages +// ----------------------------------------------------------------------- + + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + + + +#define ERR_USR_MSG_SZ 256 +#define ERR_SYS_MSG_SZ 256 +#define ERR_TOT_MSG_SZ (ERR_USR_MSG_SZ + ERR_SYS_MSG_SZ) + + +/* 07/04/2007 ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ +/* #define ERR_OUT ERR_VGStrUserMsg */ + + +/* 07/04/2007 - Use a local variable in each function because __FUNCTION__ IS NOT handled by CNT ... */ +/* __LINE__ is replaced by 0 because __LINE__ because ... __LINE__ is not handled file by file ... */ + +#ifdef APP_ROOT + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,VFuncName, 0 /* __LINE__ */ );} +#else + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,__FUNCTION__,__LINE__ );} +#endif + + + +#define ERR_WARNING(Msg) { sprintf Msg; ERR_LOCATION ('W'); ERR_FGenError ('W'); } + +#define ERR_ERROR(Msg) { sprintf Msg; ERR_LOCATION ('E'); ERR_FGenError ('E'); } + +#define ERR_TRACE(Msg) { sprintf Msg; ERR_LOCATION ('T'); ERR_FGenError ('T'); } + + +#define ERR_RET(Code,MsgOk,MsgFail) { \ + if ((Code)<0) ERR_ERROR (MsgFail) \ + else ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_RET_FAIL(Code,MsgFail) { \ + if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (Code); } \ + } + + + +#define ERR_RET_FAIL_NULL(Code,MsgFail) { \ +if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (NULL); } \ + } + + + +#define ERR_RET_NULL(Ptr,MsgFail) { \ +if ((void*)(Ptr)==NULL) { ERR_ERROR (MsgFail) return (-1); } \ + } + + + + +#define ERR_RET_OK(MsgOk) { \ + if ( ERR_VGFastErrRetOkNoLog == 0 ) ERR_TRACE (MsgOk); \ + return (0); \ + } + + + +#define ERR_RET_VAL(Code,MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (Code); \ + } + + + +#define err_trace(Msg) ERR_TRACE(Msg) +#define err_tracel(Lvl,Msg) ERR_TRACE(Msg) +#define err_warning(Msg) ERR_WARNING(Msg) +#define err_error(Msg) ERR_ERROR(Msg) + +#define err_ret(Code,MsgOk,MsgFail) ERR_RET(Code,MsgOk,MsgFail) +#define err_retok(MsgOk) ERR_RET_OK(MsgOk) +#define err_retval(Code,MsgOk) ERR_RET_VAL(Code,MsgOk) +#define err_retfail(Code,MsgFail) ERR_RET_FAIL(Code,MsgFail) +#define err_retfailnull(Code,MsgFail) ERR_RET_FAIL_NULL(Code,MsgFail) +#define err_retnull(Ptr,MsgFail) ERR_RET_NULL(Ptr,MsgFail) + + + + +// ----------------------------------------------------------------------- +// Types definition +// ----------------------------------------------------------------------- + + +typedef SInt32 (*ERR_TUserErrorFunc) ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ); + + + + + +// ----------------------------------------------------------------------- +// Variables definition +// ----------------------------------------------------------------------- + + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 1); + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogEnable , 1); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogLevel , ERR_LOG_LVL_ALL); + + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGConstructorNoLog , 0); // 03/11/2020, used for error AND msg lib + + +// VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_VGLogPath[GLB_FILE_PATH_SZ] , "c:\\tmp\\errors.txt"); // Before 30/11/2019 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_VGLogPath[GLB_FILE_PATH_SZ] , "./default_err.txt"); // Since 30/11/2019 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGTmpLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt32 ERR_VGMsgCnt , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, ERR_TUserErrorFunc ERR_VGUserErrorFunc , NULL); +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ] ); + +/* 07/04/2007 - ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ + +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + +VAR_DCL ( EXTERN, VAR_STATIC, char VGOut[255] ); + +// 21/12/2010 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char *ERR_VGLastErrMsg, "NULL"); + +// 26/02/2020 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFastErrRetOkNoLog, 0); + + +// Flags to indicate that there is a trace, warnning, error message available +// mainly for interface / LabVIEW => Testing errors messages presence by polling +// +// 06/04/2021 + + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGIsTraceMsg, 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGIsWarnMsg, 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGIsErrMsg, 0); + + + +#endif // End of #ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + + +#endif diff --git a/include/mimo_daq_lib/globals_root.def b/include/mimo_daq_lib/globals_root.def new file mode 100644 index 0000000..225f9ad --- /dev/null +++ b/include/mimo_daq_lib/globals_root.def @@ -0,0 +1,43 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_ROOT_DEF +#define GLOBALS_ROOT_DEF + +/* CONDITIONNAL COMPILATION */ + +#define GLB_GC_CASCADE +#define GLB_FIRST_REC_FORMAT + +/* MACROS */ + +#define GLB_FILE_PATH_SZ 256 +#define GLB_CMT_SZ 256 +#define GLB_HOST_NAME_SZ 50 + +#define GLB_SEQ 0 + +#define GLB_RMP_FILE_PATH "/common/rmp/RMP" +#define GLB_RMPS_FILE_PATH "/common/rmp/RUN" + + +#define GLB_DEF_BYTE_SEX 0x3615ABCD + + +// #define GLB_DESY_VME_A32_BASE 0xd0000000 /* By default it's LEPSI config base address 0xd0000000*/ + +#define GLB_DLL_LOG_SUFFIX_FILE_DIR "c:/tmp/" + + +#endif diff --git a/include/mimo_daq_lib/mimo_daq_lib.c b/include/mimo_daq_lib/mimo_daq_lib.c new file mode 100644 index 0000000..3410167 --- /dev/null +++ b/include/mimo_daq_lib/mimo_daq_lib.c @@ -0,0 +1,65 @@ +#include "mimo_daq_lib.h" + +#include "errors_light.c" +#include "msg_light.c" + + + +/* ========================== */ +/* Application constants */ +/* ========================== */ + +//#define MIS1__TBtRunRead_DEF_ERR_LOG_FILE "./Results/err_MIS1__TBtRunRead.txt" +//#define MIS1__TBtRunRead_DEF_MSG_LOG_FILE "./Results/msg_MIS1__TBtRunRead.txt" + +/* ========================== */ +/* Application macros */ +/* ========================== */ + +#define APP__READ_CR { while ( getchar () != '\n' ); }; +#define ERR_LOG_LVL_ALL 1 + +/* ============================= */ +/* Application context type */ +/* ============================= */ + +typedef struct { + + // Parameters + + char ParRunDir[GLB_FILE_PATH_SZ]; // Run directory + char ParFileNamePrefix[20]; // Run file prefix, eg : RUN_666 => RUN_ is the prefix + SInt32 ParRunNo; + + SInt32 ParFrameNbPerAcq; // Nb of frame in the acquisition ( get from run file ) + SInt32 ParAcqNo; // Index of acquisition to select ( get from GUI ) + SInt32 ParFrameNo; // Index of frame to get + + // Intermediate variables + + char InfRunParFile[GLB_FILE_PATH_SZ]; // File which contains run parameters *.par + char InfRunDataFile[GLB_FILE_PATH_SZ]; // File which contains run data *.bin + SInt32 InfMaxFrameSz; // Maximal size of one frame = total size for N Mimosa 26 + + // Results + + SInt8 ResRunLoaded; // Flag indicates run state : -1 not loaded, +1 loaded + + //EFRIO__TRunCont ResRunCont; // Run context record = run parameter + additional info + // Loaded from file RUN*.par + + //EFRIO__TFrameList ResFramesList; // List of frames + +} APP__TContext; + + +SInt32 APP_VGErrFileLogLvl = ERR_LOG_LVL_ALL; // Log level for log file +SInt32 APP_VGErrUserLogLvl = ERR_LOG_LVL_ALL; // Log level for user print function => not used + +// General messages logging level ( file msg.txt ), 127 => log all messages + +SInt32 APP_VGMsgFileLogLvl = 127; // Log level for log file +SInt32 APP_VGMsgUserLogLvl = 127; // Log level for user print function => not used + + +APP__TContext APP__VGContext; // generic pointer to the DAQ information diff --git a/include/mimo_daq_lib/mimo_daq_lib.h b/include/mimo_daq_lib/mimo_daq_lib.h new file mode 100755 index 0000000..7510d5c --- /dev/null +++ b/include/mimo_daq_lib/mimo_daq_lib.h @@ -0,0 +1,106 @@ +// Creation date: 21/05/2021 +// Author: Ziad EL BITAR +// Author: ziad.elbitar@iphc.cnrs.fr +// Based on daq_lib.h in PXIeBoardReader + + +#ifndef MIMO_DAQ_LIB_VERSION_4_1 +#define MIMO_DAQ_LIB_VERSION_4_1 + +#define _FILE_OFFSET_BITS 64 // Mandatory for large files ( > 2 GB ) handling +// MUST be set before standard C header files + +#include +#include +#include // types +#include +#include + +/* ========================================= */ +/* Conditional compilation for DAQ sources */ +/* ========================================= */ + +#define ROOT_ROOT // Disable code parts which can't compile under ROOT +#define CC_UNIX // Specify operating system + +//--------------------------------------------------------------------------------- +// Conditionnal compilation switches +// --------------------------------------------------------------------------------- + + +#undef CC_APP_GUI_CPP // Disables C++ Builder GUI application => Memo for error and general messagess logging + +#define CC_MSIS1_BDF_LIGHT // Reduces functions, class integrated from library X:/lib/com/maps/msis1/Data + // in oder to minimize the risk of compilation warnings / errors + +#define CC_NOT_CPP_BUILDER // Removes items (cst, functions, etc ... ) only available under C++ Builder + + + +#undef CC_INTERFACE_FILE // To get variables created in this module + + +// #define APP_ERR_MSG_MACROS_NOT_SUPPORTED // To be defined in case of compilation errors on errors and general messages libs + // ..\..\com\errors_light.c, errors_light.h + // ..\..\com\msg_light.c, msg_light.h + + +#undef CC_APP_ERR_LOG_VIA_PRINTF // If enabled => Error log message are automatically printed in console via printf () function + // Rq : The sames messages are written in MIS1__TBtRunRead_DEF_ERR_LOG_FILE + +#define CC_APP_MSG_LOG_VIA_PRINTF // If enabled => General message log are automatically printed in console via printf () function + // Rq : The sames messages are written in MIS1__TBtRunRead_DEF_MSG_LOG_FILE + +// + +/* ========================== */ +/* Application constants */ +/* ========================== */ + +#define MIS1__TBtRunRead_DEF_ERR_LOG_FILE "./Results/err_MIS1__TBtRunRead.txt" +#define MIS1__TBtRunRead_DEF_MSG_LOG_FILE "./Results/msg_MIS1__TBtRunRead.txt" +/* ========================================= */ +/* Includes DAQ source files */ +/* ========================================= */ + +// C4Pi test team general lib interface + +#include "c4pi_test_team.h" +#include "globals_root.def" +#include "types.def" + +// C4Pi test team general errors and general messages lib interface + +#include "errors_light.h" +#include "msg_light.h" + +// C4Pi test team Mimosis 1 data lib interface + + +#include "msis1_data.def" +#include "msis1_data.typ" +#include "msis1_data_exp.h" + +// C4Pi test team general errors and general messages lib +// C code inclusion in application +// +// Remark : Ugly piggy way, but fast way and no time to do better ;-) +// anyway if someone wants to do better => please do + + +#include "errors_light.c" + +#include "msg_light.c" + + +// C4Pi test team general Mimossi 1 data lib +// C code inclusion in application +// +// Remark : Ugly piggy way, but fast way and no time to do better ;-) +// anyway if someone wants to do better => please do + + +#include "msis1_data.c" // From common source tree "X:/lib/com/maps/msis1/Data/msis1_data.c" + + +#endif diff --git a/include/mimo_daq_lib/msg_light.c b/include/mimo_daq_lib/msg_light.c new file mode 100644 index 0000000..bab5361 --- /dev/null +++ b/include/mimo_daq_lib/msg_light.c @@ -0,0 +1,559 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\prj\win\mimosis_1\run_read_light_bt\com\msg_light.c +* \brief Goal : Genral messages library - Functions +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 12/05/2021 +* \date File date : 12/05/2021 +* \date Doc date : 12/05/2021 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IPHC 23 Rue du Loess 67037 STRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + +#ifndef MSG_L_C +#define MSG_L_C + + +#include +#include + + +#ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + +SInt32 MSG_FGenEnableLog ( SInt8 Chan, SInt8 Enable ) { + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGenGetLogEnabled ( SInt8 Chan ) { + return (0); +} + + +SInt32 MSG_FGenSetLogFilePath ( SInt8 Chan, char* LogFilePath ) { + return (0); +} + +char* MSG_FGenGetLogFilePath ( SInt8 Chan ) { + return ( MSG_VGMsgNotAvailable ); +} + +SInt32 MSG_FGenStopLog ( SInt8 Chan, SInt8 Stop ) { + return (0); +} + + +SInt32 MSG_FGenBegin ( SInt8 Chan, SInt8 Enable, char* FilePath ) { + + return (0); +} + +SInt32 MSG_FBegin ( SInt8 Enable, char* FilePath ) { + + return (0); +} + + +SInt32 MSG_FEnd () { + + return (0); +} + + +SInt32 MSG_FEnableLog ( SInt8 Enable ) { + return (0 ); +} + +SInt32 MSG_EnableLog ( SInt8 Enable ) { + return (0); +} + +SInt8 MSG_FGetLogEnabled () { + return (0); +} + +SInt32 MSG_FSetLogFilePath ( char* LogFilePath ) { + return (0); +} + +/* 11/06/2005 */ + +SInt32 MSG_FSetFileLogLevel ( SInt8 Level ) { + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_GSetFileLogLevel () { + return (0); +} + + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserLogLevel ( SInt8 Level ) { + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGetUserLogLevel () { + return (0); +} + +char* MSG_FGetLogFilePath ( void ) { + return ( MSG_VGMsgNotAvailable ); +} + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserMsgFunc ( TUserMsgFunc Func ) { + + return (0); +} + + +/* 07/04/2007 */ + +char* MSG_FGenGetMsgLogConfStr ( SInt8 Chan ) { + + return ( MSG_VGMsgNotAvailable ); +} + +/* 07/04/2007 */ + +char* MSG_FGetMsgLogConfStr () { + + return ( MSG_VGMsgNotAvailable ); +} + +SInt32 MSG_FGenMsg ( SInt8 Chan, SInt8 Level ) { + + return (0); + +} + +// GC - 20/02/2020 + +char* MSG_FGetLastMsgLong ( UInt16 Chan ) { + + + return (MSG_OUT); +} + +// GC - 20/02/2020 + +char* MSG_FGetLastMsgShort ( UInt16 Chan ) { + + + return (MSG_OUT); + +} + + + +// Returns messages flag an reset it +// The message level must be <= Level +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// GC 08/04/2021 + +SInt8 MSG_FIsMsg ( UInt16 Chan, SInt8 Level ) { + + return (0); +} + + + + + +#else // Of #ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + +// ----------------------------------------------------------------------- +// Functions +// ----------------------------------------------------------------------- + + +SInt32 MSG_FGenEnableLog ( SInt8 Chan, SInt8 Enable ) { + +// MSG_VGALogClosed[Chan] = Enable; + MSG_VGALogEnabled[Chan] = Enable; + + if (Enable){ + + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + + // 29/10/2010 => Alway overwrite log file + + // if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + // MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + // } + + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + + } + } + + // 23/05/2019 - GC try to remove the closing of the file + +/* else{ + if ( MSG_VGALogClosed[Chan] == 0){ + fclose(MSG_VGALogFile[Chan]); + MSG_VGALogClosed[Chan] = 1; + MSG_VGALogFile[Chan] = NULL; + } + + } +*/ + + + + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGenGetLogEnabled ( SInt8 Chan ) { + return (MSG_VGALogEnabled[Chan]); +} + + +SInt32 MSG_FGenSetLogFilePath ( SInt8 Chan, char* LogFilePath ) { + sprintf ( MSG_VGALogPath[Chan], "%s", LogFilePath ); + return (0); +} + +char* MSG_FGenGetLogFilePath ( SInt8 Chan ) { + return ( MSG_VGALogPath[Chan] ); +} + +SInt32 MSG_FGenStopLog ( SInt8 Chan, SInt8 Stop ) { + MSG_VGADontLog[Chan] = Stop; + return (0); +} + + +SInt32 MSG_FGenBegin ( SInt8 Chan, SInt8 Enable, char* FilePath ) { + + MSG_FGenSetLogFilePath ( Chan, FilePath ); + MSG_FGenEnableLog ( Chan, Enable ); + + return (0); +} + +SInt32 MSG_FBegin ( SInt8 Enable, char* FilePath ) { + + SInt8 ViChan; + + // remove ( FilePath ); // 31/01/13 because file is not rewritten when lib used in LabVIEW via a DLL + // Don't know why, it should not be needed, but it's required + // 04 12 2017 MS removed because it seems that it makes prolblems + + // 30/11/2019 begin : + // Upgrade in order to + // - get one couple of log files per DLL instance loaded by application ( a suffix 0, 1, is added to log files names) + // - keep one single couple of log files for the application itself, each time a library (compiled by src inclusion) + // defines a new log file, it is ignored if one is laready opened => the first log file name configured is used + // + // DLL compilation => DO NOT define APP_SAME_LOG_FILES_NAMES + // Application compilation => Define APP_SAME_LOG_FILES_NAMES + + + + #ifndef APP_SAME_LOG_FILES_NAMES + + for ( ViChan = 0; ViChan < MSG_CHAN_NB; ViChan++ ) { + + MSG_VGALogClosed[ViChan] = 1; + + if ( MSG_VGALogFile[ViChan] != NULL ) { + fflush ( MSG_VGALogFile[ViChan] ); + fclose ( MSG_VGALogFile[ViChan] ); + } + + } + + #endif + + // 30/11/2019 end + + + // 23/05/2019 - GC : Code used since 23/05/2019 (functions calls swapped / before 23/05/2019) + // + // MS has fixed the bug of "multiple files opening" which requires to swap the call order of + // the following functions. It has been done for error log lib, it seems it has not been fully + // done for this lib, it is done for MSG_FGenBegin (...) but not here for MSG_FBegin (...),it is ok now. + + MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, FilePath ); + MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable ); + + // 23/05/2019 - GC : Code used before 23/05/2019 => Msg file never created + // + // MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable ); + // MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, FilePath ); + + return (0); +} + + +SInt32 MSG_FEnd () { + + SInt32 VIndex; + + for (VIndex = 0 ; VIndex < MSG_CHAN_NB ; VIndex++){ + + if (MSG_VGALogClosed[VIndex] == 0){ + fclose(MSG_VGALogFile[VIndex]); + MSG_VGALogClosed[VIndex] = 1; + } + + + + + } + return (0); +} + + +SInt32 MSG_FEnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt32 MSG_EnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt8 MSG_FGetLogEnabled () { + return ( MSG_FGenGetLogEnabled ( MSG_CHAN_MSG ) ); +} + +SInt32 MSG_FSetLogFilePath ( char* LogFilePath ) { + return ( MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, LogFilePath ) ); +} + +/* 11/06/2005 */ + +SInt32 MSG_FSetFileLogLevel ( SInt8 Level ) { + + MSG_VGFileLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_GSetFileLogLevel () { + return (MSG_VGFileLogLevel); +} + + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserLogLevel ( SInt8 Level ) { + + MSG_VGUserLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGetUserLogLevel () { + return (MSG_VGUserLogLevel); +} + +char* MSG_FGetLogFilePath ( void ) { + return ( MSG_FGenGetLogFilePath ( MSG_CHAN_MSG ) ); +} + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserMsgFunc ( TUserMsgFunc Func ) { + + MSG_VGUserMsgFunc = Func; + + return (0); +} + + +/* 07/04/2007 */ + +char* MSG_FGenGetMsgLogConfStr ( SInt8 Chan ) { + + static char VStr[MSG_CMT_SZ+1]; + + sprintf ( VStr, "Messages log configuration \n\n - Log enabled = %d \n - Stop log = %d \n - File log level = %d \n - Log file name = %s \n - User log level = %d \n\n ", MSG_VGALogEnabled[Chan], MSG_VGADontLog[Chan], MSG_VGFileLogLevel, MSG_VGALogPath[Chan], MSG_VGUserLogLevel ); + + return (VStr); +} + +/* 07/04/2007 */ + +char* MSG_FGetMsgLogConfStr () { + return ( MSG_FGenGetMsgLogConfStr (MSG_CHAN_MSG) ); +} + +SInt32 MSG_FGenMsg ( SInt8 Chan, SInt8 Level ) { + + static char VMsg[256 /* MSG_CMT_SZ include file not visble from ROOT => must be solved */]; + + + // 03/11/2020 - No log if called in class constructor + + #ifndef CC_FORCE_LOG_IN_CONSTRUCTORS + + if ( ERR_VGConstructorNoLog ) { + return (0); + } + + #endif + + + + if ( (MSG_VGFileLogLevel == 0) && (MSG_VGUserLogLevel == 0) ) { + return (0); + } + + sprintf ( VMsg, "MSG %.7d => %s \n", MSG_VGAMsgCnt[Chan]++, MSG_VGAStrMsg[Chan]); + + sprintf ( MSG_VGAStrMsgLong[Chan], "%s", VMsg ); + + if ( (MSG_VGFileLogLevel != 0) && (MSG_VGFileLogLevel >= Level) ) { + + + MSG_VGIsMsgAndLevel[Chan] = Level; // 08/04/2021 + + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + + // 29/10/2010 => Alway overwrite log file + + // if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + // MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + // } + + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "%s", VMsg ); + fflush ( MSG_VGALogFile[Chan] ); + } + + } /* End if ( Level >= MSG_VGFileLogLevel ) */ + + if ( (MSG_VGUserLogLevel != 0) && (MSG_VGUserLogLevel >= Level) ) { + + if ( MSG_VGUserMsgFunc != NULL ) { + MSG_VGUserMsgFunc ( VMsg ); + } + + } /* End if ( Level >= MSG_VGUserLogLevel ) */ + + + return (0); + +/* + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + } + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "MSG %.4d =>", MSG_VGAMsgCnt[Chan]++ ); + fprintf ( MSG_VGALogFile[Chan], MSG_VGAStrMsg[Chan] ); + fprintf ( MSG_VGALogFile[Chan], "\n" ); + fflush ( MSG_VGALogFile[Chan] ); + } + + return (0); + +*/ + +} + +// GC - 20/02/2020 + +char* MSG_FGetLastMsgLong ( UInt16 Chan ) { + + static char VStrErr[GLB_CMT_SZ]; + + if ( Chan >= MSG_CHAN_NB ) { + sprintf ( VStrErr, "Error => Chan = %d > Max = %d", Chan, MSG_CHAN_NB - 1 ); + return ( VStrErr ); + } + + return ( MSG_VGAStrMsgLong[Chan] ); +} + +// GC - 20/02/2020 + +char* MSG_FGetLastMsgShort ( UInt16 Chan ) { + + + static char VStrErr[GLB_CMT_SZ]; + + if ( Chan >= MSG_CHAN_NB ) { + sprintf ( VStrErr, "Error => Chan = %d > Max = %d", Chan, MSG_CHAN_NB - 1 ); + return ( VStrErr ); + } + + return ( MSG_VGAStrMsg[Chan] ); + +} + + + +// Returns messages flag an reset it +// The message level must be <= Level +// Mainly for interface / LabVIEW => Testing errors messages presence by polling +// GC 08/04/2021 + +SInt8 MSG_FIsMsg ( UInt16 Chan, SInt8 Level ) { + + + if ( Chan >= MSG_CHAN_NB ) { + return (-1); + } + + + if ( (MSG_VGIsMsgAndLevel[Chan] != 0) && (MSG_VGIsMsgAndLevel[Chan] <= Level) ) { + MSG_VGIsMsgAndLevel[Chan] = 0; + return (1); + } + + return (0); +} + + + + +#endif // Of #ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + + + +#endif diff --git a/include/mimo_daq_lib/msg_light.h b/include/mimo_daq_lib/msg_light.h new file mode 100644 index 0000000..ec6a0b3 --- /dev/null +++ b/include/mimo_daq_lib/msg_light.h @@ -0,0 +1,194 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\prj\win\mimosis_1\run_read_light_bt\com\msg_light.h +* \brief Goal : General messages library - Constants, types, functions proto, ... +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 12/05/2021 +* \date File date : 12/05/2021 +* \date Doc date : 12/05/2021 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IPHC 23 Rue du Loess 67037 STRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + +#ifndef MSG_L_H +#define MSG_L_H + + +#include +#include + + +// #include "..\..\com\var_decl_def.h" // For selection between variable creation / export via CC + // #undef CC_INTERFACE_FILE => Creates variables and initializes them + // #define CC_INTERFACE_FILE => Export variables only + + +#include "var_decl_def.h" + + +#ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + + +// ----------------------------------------------------------------------- +// Constants for genral messages +// ----------------------------------------------------------------------- + +#define MSG_CMT_SZ 10000 // 1024 until 23/05/2019 + +#define MSG_CHAN_NB 2 +#define MSG_CHAN_MSG 0 +#define MSG_CHAN_RMSG 1 + + +// ----------------------------------------------------------------------- +// General messages "conversion" lowercase to uppercase +// ----------------------------------------------------------------------- + + +#define MSG_PRINTF(Msg) { sprintf Msg;} + +#define msg(Msg) MSG_PRINTF(Msg) + +#define MSG_PRINTF_LVL(Msg,Lvl) { sprintf Msg; } + +#define msgl(Msg,Lvl) MSG_PRINTF_LVL(Msg,Lvl) + + +// ----------------------------------------------------------------------- +// Types definition +// ----------------------------------------------------------------------- + + +typedef SInt32 (*TUserMsgFunc) ( char* Msg ); + + +// ----------------------------------------------------------------------- +// Variables for errors messages +// ----------------------------------------------------------------------- + + +// VAR_DCL_INIT ( EXTERN, VAR_STATIC, char* MSG_OUT , MSG_VGAStrMsg[MSG_CHAN_MSG] ); + + VAR_DCL_INIT ( EXTERN, VAR_STATIC, char MSG_OUT[GLB_CMT_SZ] , ""); + + VAR_DCL_INIT ( EXTERN, VAR_STATIC, char MSG_VGMsgNotAvailable[GLB_CMT_SZ] , "General messages loging not fully available"); + +#else + +// ----------------------------------------------------------------------- +// Compilation directives +// ----------------------------------------------------------------------- + + + +// ----------------------------------------------------------------------- +// Macro definition +// ----------------------------------------------------------------------- + + + + + +// ----------------------------------------------------------------------- +// Macro for genral messages +// ----------------------------------------------------------------------- + +#define MSG_CMT_SZ 10000 // 1024 until 23/05/2019 + +#define MSG_CHAN_NB 2 +#define MSG_CHAN_MSG 0 +#define MSG_CHAN_RMSG 1 + + +/* Must be after variables definition, instead CINT will be unable to handle these macros */ + +#define MSG_VGLogFile MSG_VGALogFile[MSG_CHAN_MSG] +#define MSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_MSG] +#define MSG_VGDontLog MSG_VGADontLog[MSG_CHAN_MSG] +#define MSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_MSG] +#define MSG_VGLogPath MSG_VGALogPath[MSG_CHAN_MSG] + +#define RMSG_VGLogFile MSG_VGALogFile[MSG_CHAN_RMSG] +#define RMSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_RMSG] +#define RMSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_RMSG] +#define RMSG_VGLogPath MSG_VGALogPath[MSG_CHAN_RMSG] + +/* 07/04/2007 MSG_VGAStrMsg identifier replaced by MSG_OUT because of ROOT CINT macros limitations */ +/* #define MSG_OUT MSG_VGAStrMsg[MSG_CHAN_MSG] */ + +#define RMSG_OUT MSG_VGAStrMsg[MSG_CHAN_RMSG] + +#define MSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,127);} +#define msg(Msg) MSG_PRINTF(Msg) + +#define MSG_PRINTF_LVL(Msg,Lvl) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,Lvl); } +#define msgl(Msg,Lvl) MSG_PRINTF_LVL(Msg,Lvl) + + +#define RMSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_RMSG,127); } +#define msgr(Msg) RMSG_PRINTF(Msg) +#define rmsg(Msg) RMSG_PRINTF(Msg) + + + + + +// ----------------------------------------------------------------------- +// Types definition +// ----------------------------------------------------------------------- + +typedef SInt32 (*TUserMsgFunc) ( char* Msg ); + +// ----------------------------------------------------------------------- +// Variables definition +// ----------------------------------------------------------------------- + + + +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, FILE* MSG_VGALogFile[MSG_CHAN_NB] , NULL, NULL ); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogClosed[MSG_CHAN_NB] , 1, 1); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGADontLog[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] , 0, 0); + + +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ], "./default_msg.txt", "./default_rmsg" ); // Since 30/11/2019 + +VAR_DCL ( EXTERN, VAR_STATIC, char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ] ); + +VAR_DCL ( EXTERN, VAR_STATIC, char MSG_VGAStrMsgLong[MSG_CHAN_NB][MSG_CMT_SZ] ); // GC - 20/02/2020, full message with line No for ERR_FGetLastErrMsg (...) + +/* 07/04/2007 Replace macro MSG_OUT by a variable which points to MSG_VGAStrMsg[MSG_CHAN_MSG] because of ROOT CINT macros limitations */ + + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char* MSG_OUT , MSG_VGAStrMsg[MSG_CHAN_MSG] ); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGFileLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGUserLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, TUserMsgFunc MSG_VGUserMsgFunc , NULL); + + +// Flags to indicate that there is a message available +// mainly for interface / LabVIEW => Testing errors messages presence by polling +// +// 08/04/2021 + + +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGIsMsgAndLevel[MSG_CHAN_NB], 0, 0); // 0 => No msg, > 0 one msg and value indicates msg level (1 to 127) + + +#endif // End of #ifdef APP_ERR_MSG_MACROS_NOT_SUPPORTED + + +#endif diff --git a/include/mimo_daq_lib/msis1_data.c b/include/mimo_daq_lib/msis1_data.c new file mode 100644 index 0000000..b5520f8 --- /dev/null +++ b/include/mimo_daq_lib/msis1_data.c @@ -0,0 +1,22394 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\lib\com\maps\msis1\data\msis1_data.c +* \brief Goal : Functions of Mimosis 1 lib +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 03/05/2019 +* \date File date : 03/05/2019 +* \date Doc date : 03/05/2019 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IHC 23 Rue du Loess 67037 STRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + + +#ifndef MIMOSIS1_DATA_C +#define MIMOSIS1_DATA_C + + + + +#ifndef CC_MSIS1_BDF_LIGHT + + + + + +// =================================================================================== +// * Functions (comment not processed by DOXYGEN) +// * +// =================================================================================== + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FVersionGet ( char* VerStr, UInt32* PtVerMajor, UInt32* PtVerMinor, UInt32* PtVerDate ) +* +* \brief : Template / demonstration function for documentation generation +* extra info on function DISPLAYED IN THE FIRST LINE +* +* \brief : Extra info on the function if long explanation is needed, it +* will NOT be displayed in the FIRST LINE, it will be a new +* bloc of info displayed before the parameters list +* +* \param : InNumber - Input number \n +* : Range of values allowed is 0 to 45000 +* \param : InStr - Input string (char* type) +* : +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : MUST not use err and msg macro because this function can be called before libs init +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FVersionGet ( char* VerStr, UInt32* PtVerMajor, UInt32* PtVerMinor, UInt32* PtVerDate ) { + + + sprintf ( MIS1__VGVerStr, "Lib Mimosis data : Ver %d.%d date %x", MIS1__VGVerMajor, MIS1__VGVerMinor, MIS1__VGVerDate ); + + + if ( VerStr != NULL ) { + strcpy ( VerStr, MIS1__VGVerStr ); + } + + + if ( PtVerMajor != NULL ) { + *PtVerMajor = MIS1__VGVerMajor; + } + + + if ( PtVerMinor != NULL ) { + *PtVerMinor = MIS1__VGVerMinor; + } + + + if ( PtVerDate != NULL ) { + *PtVerDate = MIS1__VGVerDate; + } + + return (0); + +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FTemplateForDoc ( SInt32 InNumber, char* InStr ) +* +* \brief : Template / demonstration function for documentation generation +* extra info on function DISPLAYED IN THE FIRST LINE +* +* \brief : Extra info on the function if long explanation is needed, it +* will NOT be displayed in the FIRST LINE, it will be a new +* bloc of info displayed before the parameters list +* +* \param : InNumber - Input number \n +* : Range of values allowed is 0 to 45000 +* \param : InStr - Input string (char* type) +* : +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 11/04/2019 +* \date : Doc date : 11/04/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FTemplateForDoc ( SInt32 InNumber, char* InStr ) { + + const SInt32 IN_NUMBER_MIN = 0; + const SInt32 IN_NUMBER_MAX = 45000; + + + if ( MIS1__VGBeginDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FBegin (...) has not been called !") ); + } + + if ( (InNumber < IN_NUMBER_MIN) || (InNumber > IN_NUMBER_MAX) ) { + err_retfail ( -1, (ERR_OUT,"Abort => InNumber = %d is ouf range %d..%d", InNumber, IN_NUMBER_MIN, IN_NUMBER_MAX ) ); + } + + + return (0); + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FBegin ( SInt8 ErrLogLvl, char* ErrFile, SInt8 MsgLogLvl, char* MsgFile ) +* : +* \brief : Init error and info messages handling, variables initialization, etc ... +* : +* \param : ErrLogLvl - Eror logging level, can be ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, +* : ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS +* \param : ErrFile - Error log text file name + path +* \param : MsgLogLvl - Info messages logging level, 0 = no print, 127 = prints all messages +* \param : MsgFile - Info messages log text file name + path +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Now 08/04/2019 the function returns always 0 +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 11/04/2019 +* \date : Doc date : 11/04/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FBegin ( SInt8 ErrLogLvl, char* ErrFile, SInt8 MsgLogLvl, char* MsgFile ) { + + MIS1__VGBeginDone = 0; + + ERR_FBegin ( ( ErrLogLvl != 0 ) /* Enable */, ErrFile ); + ERR_FSetFileLogLevel ( ErrLogLvl ); + + MSG_FBegin ( (MsgLogLvl != 0) /* Enable */, MsgFile ); + MSG_FSetFileLogLevel ( MsgLogLvl ); + + + MIS1__VGBeginDone = 1; + + err_retok (( ERR_OUT, "" )); + +} + +// 888 + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FAcqProcInitPtrFields ( MIS1__TAcqProc* Pt, MIS1__TRunPar* PtRunPar, MIS1__TRunInf* PtRunInf, MIS1__TRunStatus PtRunStatus, FIL__TCBinFile* PtOStepFile, FIL__TCBinFile* PtOSubStepsFile ) +: +* \brief : Init external records pointers fields of MIS1__TAcqProc variable \n +* +* \param : Pt - Pointer on the record +: +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/06/2020 +* \date : Doc date : 26/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FAcqProcInitPtrFields ( MIS1__TAcqProc* Pt, MIS1__TRunPar* PtRunPar, MIS1__TRunInf* PtRunInf, MIS1__TRunStatus* PtRunStatus, FIL__TCBinFile* PtOStepFile, FIL__TCBinFile* PtOSubStepsFile ) { + + + + // Check param + + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + err_retnull ( PtRunPar, (ERR_OUT,"Abort => PtRunPar == NULL") ); + err_retnull ( PtRunInf, (ERR_OUT,"Abort => PtRunInf == NULL") ); + err_retnull ( PtRunStatus, (ERR_OUT,"Abort => PtRunStatus == NULL") ); + err_retnull ( PtOStepFile, (ERR_OUT,"Abort => PtOStepFile == NULL") ); + err_retnull ( PtOSubStepsFile, (ERR_OUT,"Abort => PtOSubStepsFile == NULL") ); + + // Set fields + + Pt->PtRunPar = PtRunPar; + Pt->PtRunInf = PtRunInf; + Pt->PtRunStatus = PtRunStatus; + Pt->PtOStepFile = PtOStepFile; + Pt->PtOSubStepsFile = PtOSubStepsFile; + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FAcqProcFieldsFree ( MIS1__TAcqProc* Pt ) +: +* \brief : Free all the arrays field of a MIS1__TAcqProc variable \n +* +* \param : Pt - Pointer on the record +: +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 08/06/2020 +* \date : Doc date : 08/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FAcqProcFieldsFree ( MIS1__TAcqProc* Pt ) { + + SInt16 Vi; + + // Check param + + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + // Free mem + + if ( Pt->AAcqFrListRaw != NULL ) { + free ( Pt->AAcqFrListRaw ); + Pt->AAcqFrListRaw = NULL; + } + + if ( Pt->AAcqFrMapRaw != NULL ) { + free ( Pt->AAcqFrMapRaw ); + Pt->AAcqFrMapRaw = NULL; + } + + if ( Pt->AFrListDec != NULL ) { + free ( Pt->AFrListDec ); + Pt->AFrListDec = NULL; + } + + if ( Pt->AFrMapDec != NULL ) { + free ( Pt->AFrMapDec ); + Pt->AFrMapDec = NULL; + } + + if ( Pt->PtSubStepPixCnt != NULL ) { + free ( Pt->PtSubStepPixCnt ); + Pt->PtSubStepPixCnt = NULL; + } + + if ( Pt->PtStepPixCnt != NULL ) { + free ( Pt->PtStepPixCnt ); + Pt->PtStepPixCnt = NULL; + } + + if ( Pt->ADecFrPix != NULL ) { + free ( Pt->ADecFrPix ); + Pt->ADecFrPix = NULL; + } + + + // Remark + + // void* AAcqFrDecBuff[MIS1__MAX_BUFFERED_ACQ_NB] is NOT freed HERE + +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FAcqProcFieldsAlloc ( MIS1__TAcqProc* Pt ) +* +* \brief : Allocate all the arrays field of a MIS1__TAcqProc variable \n +* because size is too big to get them in the record (C++ B crash) +* +* \param : Pt - Pointer on the record +* +* \param : ProcMode - Processing mode, defines fields to alloc +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 08/06/2020 +* \date : Doc date : 08/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FAcqProcFieldsAlloc ( MIS1__TAcqProc* Pt, MIS1__TProcMode ProcMode, SInt32* PtBuffNb, UInt32* PtBuffSzW8, UInt32* PtBuffTotSzW8, float* PtBuffTotSzMB ) { + + SInt16 Vi; + UInt32 VBuffTotSzW8; + UInt32 VAllBuffTotSzW8; + float VAllBuffTotSzMB; + + // ================================================================ + // Check param + // ================================================================ + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + // Free all fled (if not already done) and set ptr to NULL + + MIS1__FAcqProcFieldsFree ( Pt ); + + // ================================================================ + // Alloc mem + // ================================================================ + + VBuffTotSzW8 = 0; + + // ---------------------------------------------------------------- + // Fr list and fr map raw always allocated + // ---------------------------------------------------------------- + + Pt->AAcqFrListRaw = (MIS1__TAcqFrList*) malloc ( MIS1__MAX_BUFFERED_ACQ_NB * sizeof (MIS1__TAcqFrList) ); + + err_retnull ( Pt->AAcqFrListRaw, (ERR_OUT,"Abort => Allocate AAcqFrListRaw failed !") ); + + VBuffTotSzW8 += sizeof (MIS1__TAcqFrList); + + Pt->AAcqFrMapRaw = (MIS1__TAcqFrMap*) malloc ( MIS1__MAX_BUFFERED_ACQ_NB * sizeof (MIS1__TAcqFrMap) ); + + err_retnull ( Pt->AAcqFrMapRaw, (ERR_OUT,"Abort => Allocate AAcqFrMapRaw failed !") ); + + VBuffTotSzW8 += sizeof (MIS1__TAcqFrMap); + + // ---------------------------------------------------------------- + // Decoded pixels buffers + // ---------------------------------------------------------------- + + if ( ProcMode >= PM_DECODE_FR ) { + + Pt->AFrListDec = (MIS1__TDecFrList*) malloc ( MIS1__MAX_BUFFERED_ACQ_NB * MIS1__MAX_FR_NB_PER_ACQ * sizeof (MIS1__TDecFrList) ); + + err_retnull ( Pt->AFrListDec, (ERR_OUT,"Abort => Allocate AFrListDec failed !") ); + + VBuffTotSzW8 += MIS1__MAX_FR_NB_PER_ACQ * sizeof (MIS1__TDecFrList); + + Pt->AFrMapDec = (MIS1__TDecFrMap*) malloc ( MIS1__MAX_BUFFERED_ACQ_NB * MIS1__MAX_FR_NB_PER_ACQ * sizeof (MIS1__TDecFrMap) ); + + err_retnull ( Pt->AFrMapDec, (ERR_OUT,"Abort => Allocate AAcqFrMapDec failed !") ); + + VBuffTotSzW8 += MIS1__MAX_FR_NB_PER_ACQ * sizeof (MIS1__TDecFrMap); + + Pt->ADecFrPix = (MIS1__TDecFrPix*) malloc ( MIS1__MAX_BUFFERED_ACQ_NB * MIS1__MAX_FR_NB_PER_ACQ * sizeof (MIS1__TDecFrPix) ); + + err_retnull ( Pt->ADecFrPix, (ERR_OUT,"Abort => Allocate AFrPix failed !") ); + + VBuffTotSzW8 += MIS1__MAX_FR_NB_PER_ACQ * sizeof (MIS1__TDecFrPix) ; + + } // End if ( ProcMode >= PM_DECODE_FR ) + + + // ---------------------------------------------------------------- + // Fired pixels counting buffers + // ---------------------------------------------------------------- + + if ( ProcMode >= PM_DECODE_FR_CNT_PIX ) { + + Pt->PtSubStepPixCnt = (MIS1__TMatPixCntU16*) malloc ( sizeof (MIS1__TMatPixCntU16) ); + + err_retnull ( Pt->PtSubStepPixCnt, (ERR_OUT,"Abort => Allocate PtSubStepPixCnt failed !") ); + + VBuffTotSzW8 += sizeof (MIS1__TMatPixCntU16); + + Pt->PtStepPixCnt = (MIS1__TMatPixCntU16*) malloc ( sizeof (MIS1__TMatPixCntU16) ); + + err_retnull ( Pt->PtStepPixCnt, (ERR_OUT,"Abort => Allocate PtStepPixCnt failed !") ); + + VBuffTotSzW8 += sizeof (MIS1__TMatPixCntU16); + + } // End if ( ProcMode >= PM_DECODE_FR_CNT_PIX ) + + + // Remark + + // void* AAcqFrDecBuff[MIS1__MAX_BUFFERED_ACQ_NB] is NOT allocated HERE + + // Caclulate buffers sz + + VAllBuffTotSzW8 = (VBuffTotSzW8 * MIS1__MAX_BUFFERED_ACQ_NB) + sizeof (MIS1__TMatPixCntU16); + + VAllBuffTotSzMB = VAllBuffTotSzW8/ 1024 / 1024; + + + // Update buffers size info + + if ( PtBuffNb != NULL ) { + *PtBuffNb = MIS1__MAX_BUFFERED_ACQ_NB; + } + + if ( PtBuffSzW8 != NULL ) { + *PtBuffSzW8 = VBuffTotSzW8; + } + + + if ( PtBuffTotSzW8 != NULL ) { + *PtBuffTotSzW8 = VAllBuffTotSzW8; + } + + + if ( PtBuffTotSzMB != NULL ) { + *PtBuffTotSzMB = VAllBuffTotSzMB; + } + +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FEnd () +: +* \brief : Terminates library operation => To be called at end of program +: +* \param : None +: +* \return : Error code ( On 11/04/2019 it returns always 0 ) +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 11/04/2019 +* \date : Doc date : 11/04/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FEnd () { + + MIS1__VGBeginDone = 0; + + + err_retok (( ERR_OUT, "" )); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintPar, SInt32 ParS32, float ParFloat, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) +* : +* \brief : Print messages in msg or error log file from LabView. +* : If PrintPar = 1 => Print ParS32 and ParFloat in log file specified by PrintAs ... +* : If PrintPar = 0 => Print Msg in log file specified by PrintAs ... +* : +* \param : DummyS32In - Dummy value used under Labview to easily " chain " function execution. +* : +* : To execute it after a Vi call, connect any output of this Vi to the +* : DummyS32In pin and it will be automatically called after Vi end. +* : To execute it before a Vi call, if this Vi has an integer parameter +* : cut the wire and insert DummyS32In input and function output on it. +* : +* \param : PrintPar - 1 = print parameters / 0 = print message +* : +* \param : ParS32 - S32 parameter to print +* \param : ParFloat - Float parameter to print +* : +* \param : Printing mode flags +* : +* \param : PrintAsMsg - If 1 -> Print in messages log file +* \param : PrintAsTrace - If 1 -> Print in errors log file as a trace message +* \param : PrintAsWarning - If 1 -> Print in errors log file as a warning message +* \param : PrintAsError - If 1 -> Print in errors log file as an error message +* : +* \param : Msg - Message to print ( string ) +* : +* \return : The function always returns the input parameter DummyS32In. +* : +* \warning : Globals : +* \warning : Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) +* It can be used to insert this function call on an integer datapath under LabView +* : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 11/04/2019 +* \date : Doc date : 11/04/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintPar, SInt32 ParS32, float ParFloat, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + if ( PrintPar == 1 ) { + if ( PrintAsMsg ) msg (( MSG_OUT, "ParS32=%d - ParFloat=%.3f", Msg )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "ParS32=%d - ParFloat=%.3f", Msg )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "ParS32=%d - ParFloat=%.3f", Msg )); + if ( PrintAsError ) err_error (( ERR_OUT, "ParS32=%d - ParFloat=%.3f", Msg )); + } + + else { + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", Msg )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", Msg )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", Msg )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", Msg )); + } + + + return (DummyS32In); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPrintStr ( char* Str, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* : +* \brief : Prints str to log file, memo, both in function of PrintDest param value +* : +* \param : Str - String to print +* : +* \param : PrintDest - Print destination, +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3, NULL if not used +* : +* \param : PtFile - Pointer to text file +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 23/05/2019 +* \date : Doc date : 23/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FPrintStr ( char* Str, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + // Check param + + // PrintDest, Memo, PtFile MUST already have been tested => No test to reduce execution time + + // Str tested because string NULL pointer may always happen ... + + err_retnull ( Str, (ERR_OUT,"Abort => Str = NULL") ); + + // Prints + + switch ( PrintDest ) { + + // Nothing to print + + case 0 : { + break; } + + // Msg file + + case 1 : { + msg (( MSG_OUT, "%s", Str )); + break; } + + // Memo + + case 2 : { + Memo->Lines->Add ( Str ); + break; } + + // Msg file + Memo + + case 3 : { + msg (( MSG_OUT, "%s", Str )); + Memo->Lines->Add ( Str ); + break; } + + // Text file + + case 4 : { + fprintf ( PtFile, "%s \n", Str ); + break; } + + // Text file + Memo + + case 5 : { + Memo->Lines->Add ( Str ); + fprintf ( PtFile, "%s \n", Str ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => Unknown PrintDest = %d", PrintDest) ); + break; } + + } // End switch ( PrintMth ) + + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FGenPRBS16Fib ( UInt16* PtDest, SInt32 DestSzW16, UInt16 StartVal, SInt32 W16Nb ) +* : +* \brief : Generates a 16 bits Fibonacci LFSR / PRBS, stores values in PtDest[0 to W16Nb-1] +* : +* \param : PtDest - Pointer to destination array +* : +* \param : DestSzW16 - Destination array max size in W16 +* : +* \param : StartVal - Firdt value of PRBS, MUST NOT be 0 +* : +* \param : W16Nb - Number of W16 to generate +* : +* \return : = 0 if OK +* : < 0 in case of error +* : +* \warning : Globals : +* \warning : Remark : Code from https://en.wikipedia.org/wiki/Linear-feedback_shift_register +* : : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 15/11/2019 +* \date : Doc date : 12/11/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FGenPRBS16Fib ( UInt16* PtDest, SInt32 DestSzW16, UInt16 StartVal, SInt32 W16Nb ) + +{ + UInt16 start_state = 0xACE1u; /* Any nonzero start state will work. */ + UInt16 lfsr = start_state; + UInt16 bit; /* Must be 16-bit to allow bit<<15 later in the code */ + unsigned period = 0; + char VStr[GLB_CMT_SZ]; + + + // Check param + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL !") ); + + err_retnull ( StartVal, (ERR_OUT,"Abort => StartVal == 0, it is NOT allowed !") ); + + + // Generats PRBS + + do + { /* taps: 16 14 13 11; feedback polynomial: x^16 + x^14 + x^13 + x^11 + 1 */ + bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5)) /* & 1u */; + lfsr = (lfsr >> 1) | (bit << 15); + + PtDest[period] = lfsr; + + // sprintf ( VStr, "PRBS[%.4d] = %x", period, lfsr ); + + ++period; + + if ( period >= W16Nb ) { + break; + } + + } + while (lfsr != start_state); + + + + return period; +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FDxErrCntReset ( MIS1__TDxErrCnt* PtDest ) +* : +* \brief : Resets the Dx errors counters +* : +* \param : PtDest - Pointer to counters record +* : +* \return : = 0 if OK +* : < 0 in case of error +* : +* \warning : Globals : +* \warning : Remark : +* : : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 14/11/2019 +* \date : Doc date : 14/11/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FDxErrCntReset ( MIS1__TDxErrCnt* PtDest ) { + + SInt8 ViDx; + + // Check destination header pointer + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + // Reset errors counters + + for ( ViDx = 0; ViDx < MIS1__MAX_OUT_NB; ViDx++ ) { + PtDest->AErrCnt[ViDx] = 0; + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FDxErrCntCumul ( MIS1__TDxErrCnt* PtDestCumul, MIS1__TDxErrCnt* PtSrc) +* : +* \brief : Cumul Dx errors counters, add content of PtSrc to PtDestCumul +* : +* \param : PtDestCumul - Pointer to cumul destination +* : +* \param : PtSrc - Pointer to dx counter to add to cumul +* : +* \return : = 0 if OK +* : < 0 in case of error +* : +* \warning : Globals : +* \warning : Remark : +* : : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 14/11/2019 +* \date : Doc date : 14/11/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FDxErrCntCumul ( MIS1__TDxErrCnt* PtDestCumul, MIS1__TDxErrCnt* PtSrc) { + + SInt8 ViDx; + + // Check destination header pointer + + err_retnull ( PtDestCumul, (ERR_OUT,"Abort => PtDestCumul == NULL") ); + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + // Cumul errors counters + + for ( ViDx = 0; ViDx < MIS1__MAX_OUT_NB; ViDx++ ) { + PtDestCumul->AErrCnt[ViDx] += PtSrc->AErrCnt[ViDx]; + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FFrHeaderSetDefTags ( MIS1__TDsFrHeader* PtDest ) +* : +* \brief : Sets the default values (MIS1__DS_TAG_HEADER) of frame header tags +* : +* \param : PtDest - A pointer to the header +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 13/05/2019 +* \date : Doc date : 13/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FFrHeaderSetDefTags ( MIS1__TDsFrHeader* PtDest ) { + + SInt32 VStrLen; + UInt32 VFrCnt; + + // Check destination header pointer + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + // Sets frame counter fields + + PtDest->F.W7 = MIS1__DS_TAG_HEADER; + PtDest->F.W6 = MIS1__DS_TAG_HEADER; + PtDest->F.W5 = MIS1__DS_TAG_HEADER; + PtDest->F.W4 = MIS1__DS_TAG_HEADER; + PtDest->F.W3H = MIS1__DS_TAG_HEADER >> 8; + PtDest->F.W2H = MIS1__DS_TAG_HEADER >> 8; + PtDest->F.W1H = MIS1__DS_TAG_HEADER >> 8; + PtDest->F.W0H = MIS1__DS_TAG_HEADER >> 8; + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FFrHeaderSetFrCnt ( UInt32 FrCnt, MIS1__TDsFrHeader* PtDest ) +* : +* \brief : Sets the frame counter fields of header from a frame count value +* : +* \param : FrCnt - The frame counter value +* : +* \param : PtDest - A pointer to the header +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 07/05/2019 +* \date : Doc date : 07/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FFrHeaderSetFrCnt ( UInt32 FrCnt, MIS1__TDsFrHeader* PtDest ) { + + SInt32 VStrLen; + UInt32 VFrCnt; + + // Check destination header pointer + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + // Sets frame counter fields + + PtDest->F.FC0 = (FrCnt & 0x000000FF); + PtDest->F.FC1 = (FrCnt & 0x0000FF00) >> 8; + PtDest->F.FC2 = (FrCnt & 0x00FF0000) >> 16; + PtDest->F.FC3 = (FrCnt & 0xFF000000) >> 24; + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FFrHeaderGetFrCnt ( MIS1__TDsFrHeader* Pt ) +* : +* \brief : Gets the frame counter fields of header +* : +* \param : FrCnt - The frame counter value +* : +* \param : Pt - A pointer to the header +* : +* \return : The frame counter or error +* : Frame counter >= 0 is OK +* : < 0 in case of error +* : +* \warning : Globals : +* \warning : Remark : Returned value is SInt32 for error handling \n +* : : => Cast on UInt32 to get full fame counter dynamic +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 13/05/2019 +* \date : Doc date : 13/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FFrHeaderGetFrCnt ( MIS1__TDsFrHeader* Pt ) { + + UInt32 VFrCnt; + + // Check destination header pointer + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + // Builts frame counter + + VFrCnt = Pt->F.FC0 + (Pt->F.FC1 << 8) + (Pt->F.FC2 << 16) + (Pt->F.FC3 << 24); + + return ( VFrCnt ); +} + + + +// 9999 + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FFrHeaderCheck8Out ( MIS1__TDsFrHeader* Pt, UInt32 AcqNoForPrint, UInt32 FrNoForPrint, UInt16 W7, UInt16 W6, UInt16 W5, UInt16 W4, UInt8 W3H, UInt8 W2H, UInt8 W1H, UInt8 W0H, UInt32 FrCnt, MIS1__TDxErrCnt* PtResDxErrCnt, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* : +* \brief : Checks the header fields / expected values, for MSIS1 in 8 outputs mode +* : +* \param : Pt - A pointer to the header +* : +* \param : AcqNoForPrint- No of the acquisition for error message text +* : +* \param : FrNoForPrint - No of the frame for error message text +* : +* \param : W7 - Expected value for W7 field (16 bits) +* : +* \param : W6 - Expected value for W6 field (16 bits) +* : +* \param : W5 - Expected value for W5 field (16 bits) +* : +* \param : W4 - Expected value for W4 field (16 bits) +* : +* \param : W3H - Expected value for high byte of W3 field (16 bits) +* : +* \param : W2H - Expected value for high byte of W2 field (16 bits) +* : +* \param : W1H - Expected value for high byte of W1 field (16 bits) +* : +* \param : W0H - Expected value for high byte of W0 field (16 bits) +* : +* \param : FrCnt - Expected value for frames counter (32 bits), FrCnt : B0B7 = W0L, B8B15 = W1L, B16B23 = W2L, B24B31 = W3L +* : +* \param : PtResDxErrCnt - Stores errors count on each Dx, set it to NULL if not used. Warning, it adds errors to current count, no reset at beginning of function. +* : +* \param : PrintDest - Print destination for errors +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3, NULL if not used +* : +* \param : PtFile - Pointer to text file if PrintDest = 4 or 5, NULL if not used +* : +* \return : < 0 in case of sw error, example Pt == NULL +* : = 0 if no error on header fields +* : > 0 = number of errors on header fields +* : +* \warning : Globals : +* \warning : Remark : +* : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 13/11/2019 +* \date : Doc date : 13/11/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FFrHeaderCheck8Out ( MIS1__TDsFrHeader* Pt, UInt32 AcqNoForPrint, UInt32 FrNoForPrint, UInt16 W7, UInt16 W6, UInt16 W5, UInt16 W4, UInt8 W3H, UInt8 W2H, UInt8 W1H, UInt8 W0H, UInt32 FrCnt, MIS1__TDxErrCnt* PtResDxErrCnt, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + SInt32 VErrCnt; + char VStrErr[GLB_CMT_SZ]; + UInt32 VFrCnt; + + // Check destination header pointer + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + // Builts frame counter + + VFrCnt = Pt->F.FC0 + (Pt->F.FC1 << 8) + (Pt->F.FC2 << 16) + (Pt->F.FC3 << 24); + + // Resets errors cnt + + VErrCnt = 0; + + // Check W7 to W4 16 bits fields + + if ( Pt->F.W7 != W7 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[7]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W7 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.W7, W7 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->F.W6 != W6 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[6]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W6 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.W6, W6 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->F.W5 != W5 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[5]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W5 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.W5, W5 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->F.W4 != W4 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[4]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W4 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.W4, W4 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + // Check high byte of W3 to W0 fields + + if ( Pt->F.W3H != W3H ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[3]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W3H = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.W3H, W3H ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->F.W2H != W2H ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[2]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W2H = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.W2H, W2H ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->F.W1H != W1H ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[1]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W1H = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.W1H, W1H ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->F.W0H != W0H ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[0]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W0H = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.W0H, W0H ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + // Check frame counter + + + if ( VFrCnt != FrCnt ) { + + ++VErrCnt; + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : FrCnt = %.6d <> expected = %.6d", AcqNoForPrint, FrNoForPrint, VFrCnt, FrCnt ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + // Search Dx source of errors + + if ( PtResDxErrCnt != NULL ) { + + if ( (VFrCnt & 0x000000FF) != (FrCnt & 0x000000FF) ) { + ++PtResDxErrCnt->AErrCnt[0]; + } + + if ( (VFrCnt & 0x0000FF00) != (FrCnt & 0x0000FF00) ) { + ++PtResDxErrCnt->AErrCnt[1]; + } + + if ( (VFrCnt & 0x00FF0000) != (FrCnt & 0x00FF0000) ) { + ++PtResDxErrCnt->AErrCnt[2]; + } + + if ( (VFrCnt & 0xFF000000) != (FrCnt & 0xFF000000) ) { + ++PtResDxErrCnt->AErrCnt[3]; + } + + } // End if ( PtResDxErrCnt != NULL ) + + } // End if ( VFrCnt != FrCnt ) + + + // If errors have been printed => Add a line "======" at end of text + + if ( (PrintDest != 0) && (VErrCnt > 0) ) { + MIS1__FPrintStr ( "============================================================", PrintDest, Memo, PtFile ); + } + + + + return ( VErrCnt ); +} + + + +// 88888 + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : char* MIS1__FFrEwChkSumTrailer2Str ( MIS1__TDsFrEwChkSumTrailer* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) +* : +* \brief : Converts the data stream frame trailer field in a string +* : +* \param : PtSrc - A pointer to the trailer +* : +* \param : DestStr - Destination string +* : +* \param : DestStrSz - Size of destination string +* : +* \param : Mode - Print mode, reserved for future use +* : +* \return : A string which contains the frame trailer +* : - DestStr if provided as non NULL pointer and if size > required +* : - A static local string in case DestStr can't be used +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/07/2019 +* \date : Doc date : 02/07/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +char* MIS1__FFrEwChkSumTrailer2Str ( MIS1__TDsFrEwChkSumTrailer* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) { + + static char VStrEw[GLB_CMT_SZ]; + static char VStrChkSum[GLB_CMT_SZ]; + static char VStrTrailer[GLB_CMT_SZ]; + + static char VRetStr[GLB_CMT_SZ]; + SInt32 VStrLen; + UInt32 VFrCnt; + + // Check header pointer + + if ( PtSrc == NULL ) { + sprintf ( VRetStr, "Abort => PtSrc == NULL" ); + err_error (( ERR_OUT, "%s", VRetStr )); + return (VRetStr); + } + + // Convert empty words + + sprintf ( VStrEw, "#T : [W7]=%x [W6]=%x [W5]=%x [W4]=%x [W3 ]=%x [W2 ]=%x [H]", PtSrc->AW16[7], PtSrc->AW16[6], PtSrc->AW16[5], PtSrc->AW16[4], PtSrc->AW16[3], PtSrc->AW16[2] ); + + + // Convert Check sum to string + + sprintf ( VStrChkSum, "Check sum = %x [H]", PtSrc->F.CheckSum.W16 ); + + // Convert Trailer to string + + MIS1__FFrTrailer2Str ( &(PtSrc->F.Trailer), VStrTrailer, GLB_CMT_SZ, 0 /* Mode */ ); + + // Builts result string + + sprintf ( VRetStr, "%s %s %s", VStrEw, VStrChkSum, VStrTrailer ); + + VStrLen = strlen ( VRetStr ); + + // Copy result to DestStr if possible + errors messages + + if ( DestStr == NULL ) { + err_error (( ERR_OUT, "DestStr == NULL => Returns local variable, DestStr not updated" )); + } + + if ( DestStrSz <= VStrLen ) { + err_error (( ERR_OUT, "DestStrSz=%d <= VStrLen=%d => Returns local variable, DestStrSz is too small", DestStrSz, VStrLen )); + } + + if ( (DestStr != NULL) && (DestStrSz > VStrLen) ) { + strcpy ( DestStr, VRetStr ); + return (DestStr); + } + + else { + return (VRetStr); + } + +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FFrEwChkSumTrailerCheck8Out ( MIS1__TDsFrEwChkSumTrailer* Pt, UInt32 AcqNoForPrint, UInt32 FrNoForPrint, UInt16 W7, UInt16 W6, UInt16 W5, UInt16 W4, UInt16 W3, UInt16 W2, UInt16 CheckSum, MIS1__TDsFrTrailer Trailer, MIS1__TDxErrCnt* PtResDxErrCnt, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* : +* \brief : Checks the Empty Words, check sum, trailer fields / expected values, , for MSIS1 in 8 outputs mode +* : +* \param : Pt - A pointer to the empty words, check sum and trailer record +* : +* \param : AcqNoForPrint- No of the acquisition for error message text +* : +* \param : FrNoForPrint - No of the frame for error message text +* : +* \param : W7 - Expected value for W7 field (16 bits) +* : +* \param : W6 - Expected value for W6 field (16 bits) +* : +* \param : W5 - Expected value for W5 field (16 bits) +* : +* \param : W4 - Expected value for W4 field (16 bits) +* : +* \param : W3 - Expected value for W3 field (16 bits) +* : +* \param : W2 - Expected value for W2 field (16 bits) +* : +* \param : CheckSum - Expected value for the checksum field +* : +* \param : Flags - Expected value for the flags field +* : +* \param : PtResDxErrCnt - Stores errors count on each Dx, set it to NULL if not used. Warning, it adds errors to current count, no reset at beginning of function. +* : +* \param : PrintDest - Print destination for errors +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3, set it to NULL if not used +* : +* \param : PtFile - Pointer to text file if PrintDest = 4 or 5, set it to NULL if not used +* : +* \return : < 0 in case of sw error, example Pt == NULL +* : = 0 if no error on header fields +* : > 0 = number of errors on header fields +* : +* \warning : Globals : +* \warning : Remark : +* : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 13/11/2019 +* \date : Doc date : 13/11/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FFrEwChkSumTrailerCheck8Out ( MIS1__TDsFrEwChkSumTrailer* Pt, UInt32 AcqNoForPrint, UInt32 FrNoForPrint, UInt16 W7, UInt16 W6, UInt16 W5, UInt16 W4, UInt16 W3, UInt16 W2, UInt16 CheckSum, MIS1__TDsFrTrailer Trailer, MIS1__TDxErrCnt* PtResDxErrCnt, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + SInt32 VErrCnt; + char VStrErr[GLB_CMT_SZ]; + + // Check destination header pointer + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + + // Resets errors cnt + + VErrCnt = 0; + + // Check W7 to W4 16 bits fields + + if ( Pt->AW16[7] != W7 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[7]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W7 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->AW16[7], W7 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->AW16[6] != W6 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[6]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W6 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->AW16[6], W6 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->AW16[5] != W5 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[5]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W5 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->AW16[5], W5 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->AW16[4] != W4 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[4]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W4 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->AW16[4], W4 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->AW16[3] != W3 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[3]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W3 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->AW16[3], W3 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->AW16[2] != W2 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[2]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : W2 = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->AW16[2], W2 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->F.CheckSum.W16 != CheckSum ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[1]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : CheckSum = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.CheckSum, CheckSum ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + if ( Pt->F.Trailer.W16 != Trailer.W16 ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[0]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Header error Acq %.6d - Fr %.6d : Flags = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, Pt->F.Trailer.W16, Trailer.W16 ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } + + + + // If errors have been printed => Add a line "======" at end of text + + if ( (PrintDest != 0) && (VErrCnt > 0) ) { + MIS1__FPrintStr ( "============================================================", PrintDest, Memo, PtFile ); + } + + + + return ( VErrCnt ); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FFrDataAsW16Check8Out ( UInt16* PtSrc, SInt32 W16Nb, UInt32 AcqNoForPrint, UInt32 FrNoForPrint, UInt16* PtExpVal, MIS1__TDxErrCnt* PtResDxErrCnt, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* : +* \brief : Checks the data fields / expected values, for MSIS1 in 8 outputs mode +* : +* \param : PtSrc - A pointer to the source data (as a W16 array)) +* : +* \param : W16Nb - W16 number to check = size of PtSrc array +* : +* \param : AcqNoForPrint- No of the acquisition for error message text +* : +* \param : FrNoForPrint - No of the frame for error message text +* : +* \param : PtExpVal - Array of expected values, its size must be W16Nb +* : +* \param : PtResDxErrCnt - Stores errors count on each Dx, set it to NULL if not used. Warning, it adds errors to current count, no reset at beginning of function. +* : +* \param : PrintDest - Print destination for errors +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3, set it to NULL if not used +* : +* \param : PtFile - Pointer to text file if PrintDest = 4 or 5, set it to NULL if not used +* : +* \return : < 0 in case of sw error, example Pt == NULL +* : = 0 if no error on data fields +* : > 0 = number of errors on data fields +* : +* \warning : Globals : +* \warning : Remark : +* : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : MIS1__FFrHeader2Str ( MIS1__TDsFrHeader* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) +* : +* \date : Date : 14/11/2019 +* \date : Doc date : 13/11/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FFrDataAsW16Check8Out ( UInt16* PtSrc, SInt32 W16Nb, UInt32 AcqNoForPrint, UInt32 FrNoForPrint, UInt16* PtExpVal, MIS1__TDxErrCnt* PtResDxErrCnt, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + SInt32 VErrCnt; + char VStrErr[GLB_CMT_SZ]; + SInt8 ViOut; + SInt32 ViW16; + SInt32 ViW128; + + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + err_retnull ( PtExpVal, (ERR_OUT,"Abort => PtExpVal == NULL") ); + + if ( (W16Nb < 0) || (W16Nb == 0) ) { + err_retfail ( -1, (ERR_OUT,"Abort => W16Nb = %d <= 0", W16Nb) ); + } + + // Resets errors cnt + + VErrCnt = 0; + + // ---------------------- + // Check data fields + // ---------------------- + + ViW16 = 0; + + while (1) { + + // Outputs D0..D7 loop + + for ( ViOut = 0 ; ViOut < 8; ViOut++ ) { + + if ( PtSrc[ViW16] != PtExpVal[ViW16] ) { + + ++VErrCnt; + + if ( PtResDxErrCnt != NULL ) { + ++PtResDxErrCnt->AErrCnt[ViOut]; + } + + if ( PrintDest != 0 ) { + sprintf ( VStrErr, "Data error Acq %.6d - Fr %.6d W16[%.6d] : W%d = D0%d = %x H <> expected = %x H", AcqNoForPrint, FrNoForPrint, ViW16, ViOut, ViOut, PtSrc[ViW16], PtExpVal[ViW16] ); + MIS1__FPrintStr ( VStrErr, PrintDest, Memo, PtFile ); + } + + } // End if ( PtSrc[ViW16] != PtExpVal[ViW16] ) + + ++ViW16; + + } // End for ( ViOut ) + + + // End of src buffer reached + + if ( ViW16 >= W16Nb ) { + break; + } + + } // End while (1) + + + // VDataW16NbChecked = ViW16; + + // ++VDataW16NbChecked; + + // If errors have been printed => Add a line "======" at end of text + + if ( (PrintDest != 0) && (VErrCnt > 0) ) { + MIS1__FPrintStr ( "============================================================", PrintDest, Memo, PtFile ); + } + + + + return ( VErrCnt ); +} + + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRegHeaderSetDefTags ( MIS1__TDsRegHeader* PtDest ) +* : +* \brief : Sets the default values (MIS1__DS_TAG_REGION) of region header tags +* : +* \param : PtDest - A pointer to the region header +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 13/05/2019 +* \date : Doc date : 13/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRegHeaderSetDefTags ( MIS1__TDsRegHeader* PtDest ) { + + + // Check destination header pointer + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + // Sets tag field + + PtDest->F.Tag = MIS1__DS_TAG_REGION; + PtDest->F.Zero = 0; + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRegHeaderSetReg ( MIS1__TDsRegHeader* PtDest, UInt8 Reg ) +* : +* \brief : Sets the region value of region header +* : +* \param : PtDest - A pointer to the region header field +* : +* \param : Reg - The region +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 13/05/2019 +* \date : Doc date : 13/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRegHeaderSetReg ( MIS1__TDsRegHeader* PtDest, UInt8 Reg ) { + + + // Check destination header pointer + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + // Check the region value + + if ( Reg >= MIS1__DS_MAX_REGION_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => Reg=%d >= MIS1__DS_MAX_REGION_NB=%d", Reg, MIS1__DS_MAX_REGION_NB ) ); + } + + // Sets region field + + PtDest->F.Reg = Reg; + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 SInt32 MIS1__FRegHeaderGetReg ( MIS1__TDsRegHeader* Pt ) +* : +* \brief : Gets region value of region header field +* : +* \param : PtDest - A pointer to the region header +* : +* \return : The region value of an error code +* : >= 0 - Region value +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 13/05/2019 +* \date : Doc date : 13/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRegHeaderGetReg ( MIS1__TDsRegHeader* Pt ) { + + + // Check destination header pointer + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + return (Pt->F.Reg); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : char* MIS1__FRegHeader2Str ( MIS1__TDsRegHeader* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) +* : +* \brief : Converts the data stream region field in a string +* : +* \param : PtSrc - A pointer to the region header +* : +* \param : DestStr - Destination string +* : +* \param : DestStrSz - Size of destination string +* : +* \param : Mode - Print mode, reserved for future use +* : +* \return : A string which contains the region header +* : - DestStr if provided as non NULL pointer and if size > required +* : - A static local string in case DestStr can't be used +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 07/05/2019 +* \date : Doc date : 07/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +char* MIS1__FRegHeader2Str ( MIS1__TDsRegHeader* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) { + + static char VRetStr[GLB_CMT_SZ]; + SInt32 VStrLen; + + // Check header pointer + + if ( PtSrc == NULL ) { + sprintf ( VRetStr, "Abort => PtSrc == NULL" ); + err_error (( ERR_OUT, "%s", VRetStr )); + return (VRetStr); + } + + + // Builts result string + + sprintf ( VRetStr, "Tag = %x (H) - Zero = %d - Region = %d", PtSrc->F.Tag, PtSrc->F.Zero, PtSrc->F.Reg ); + + VStrLen = strlen ( VRetStr ); + + // Copy result to DestStr if possible + errors messages + + if ( DestStr == NULL ) { + err_error (( ERR_OUT, "DestStr == NULL => Returns local variable, DestStr not updated" )); + } + + if ( DestStrSz <= VStrLen ) { + err_error (( ERR_OUT, "DestStrSz=%d <= VStrLen=%d => Returns local variable, DestStrSz is too small", DestStrSz, VStrLen )); + } + + if ( (DestStr != NULL) && (DestStrSz > VStrLen) ) { + strcpy ( DestStr, VRetStr ); + return (DestStr); + } + + else { + return (VRetStr); + } + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32Save ( MIS1__TMatPixS32* PtSrc, char* FileName ) +* +* \brief : Save MIS1__TMatPixS32* to file +* +* \param : PtSrc - Pointer to source matrix +* +* \param : FileName - File name +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 13/08/2020 +* \date : Doc date : 13/08/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixS32Save ( MIS1__TMatPixS32* PtSrc, char* FileName ) { + + SInt32 VRet; + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + + // Save + + VRet = FIL_FWriteRecord ( FileName, PtSrc, sizeof (MIS1__TMatPixS32) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => FIL_FWriteRecord (PtSrc, File=%s) Ret = %d", FileName, VRet) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32Load ( MIS1__TMatPixS32* PtDest, char* FileName ) +* +* \brief : Load MIS1__TMatPixS32* from file +* +* \param : PtDest - Pointer to destination matrix +* +* \param : FileName - File name +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 13/08/2020 +* \date : Doc date : 13/08/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixS32Load ( MIS1__TMatPixS32* PtDest, char* FileName ) { + + SInt32 VRet; + SInt32 VExpectedFileSz; + + + // Check param + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + + // Check file format via file size + + VRet = FIL_FFileSize ( FileName ); + + err_retfail ( VRet, (ERR_OUT,"Abort => FIL_FFileSize (File=%s) failed Ret = %d", FileName, VRet) ); + + // Check size + + VExpectedFileSz = sizeof (MIS1__TMatPixS32); + + if ( VRet != VExpectedFileSz ) { + err_retfail ( -1, (ERR_OUT,"Abort => File size = %d <> MIS1__TMatPixS32 size = %d => Bad file format, U16 instead of S32 ?", VRet, VExpectedFileSz ) ); + } + + // Load + + VRet = FIL_FReadRecord ( FileName, PtDest, sizeof (MIS1__TMatPixS32) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => FIL_FReadRecord (PtDest, File=%s) Ret = %d", FileName, VRet) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FRstAllCnt ( SInt8 MSisId ) +* : +* \brief : Reset the Acq OVF counters, to be called at scan beginning \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FRstAllCnt ( SInt8 MSisId ) { + + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + memset ( AWarnErrCnt[MSisId], 0, sizeof(AWarnErrCnt[0][0]) * MIS1__WE_NB ); + + return (0); +} + + + + +// 999 + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixCntU16FreeAlloc ( MIS1__TMatPixCntU16** PtPtMat, SInt8 FreeAlloc ) +* : +* \brief : Free or allocate pixels matrix +* : +* \param : PtPtMat - Address of a pointer on matrix seen as 2D array MIS1__TMatPixS32 +* : +* \param : FreeAlloc - 0 => Free, 1 = Allocate +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/09/2020 +* \date : Doc date : 17/09/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +SInt32 MIS1__FMatPixCntU16FreeAlloc ( MIS1__TMatPixCntU16** PtPtMat, SInt8 FreeAlloc ) { + + // Check param + + err_retnull ( PtPtMat, (ERR_OUT,"Abort => PtPtMat == NULL") ); + + // Free + + if ( FreeAlloc == 0 ) { + free ( *PtPtMat ); + *PtPtMat = NULL; + err_retok (( ERR_OUT, "" )); + } + + // Alloc + + *PtPtMat = (MIS1__TMatPixCntU16*) malloc ( sizeof (MIS1__TMatPixCntU16) ); + + err_retnull ( *PtPtMat, (ERR_OUT,"Abort => Allocation has failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32FreeAlloc ( MIS1__TMatPixS32** PtPtMat, SInt8 FreeAlloc ) +* : +* \brief : Free or allocate pixels matrix +* : +* \param : PtPtMat - Address of a pointer on matrix seen as 2D array MIS1__TMatPixS32 +* : +* \param : FreeAlloc - 0 => Free, 1 = Allocate +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/09/2020 +* \date : Doc date : 17/09/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixS32FreeAlloc ( MIS1__TMatPixS32** PtPtMat, SInt8 FreeAlloc ) { + + // Check param + + err_retnull ( PtPtMat, (ERR_OUT,"Abort => PtPtMat == NULL") ); + + // Free + + if ( FreeAlloc == 0 ) { + free ( *PtPtMat ); + *PtPtMat = NULL; + err_retok (( ERR_OUT, "" )); + } + + // Alloc + + *PtPtMat = (MIS1__TMatPixS32*) malloc ( sizeof (MIS1__TMatPixS32) ); + + err_retnull ( *PtPtMat, (ERR_OUT,"Abort => Allocation has failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixFloatFreeAlloc ( MIS1__TMatPixFloat** PtPtMat, SInt8 FreeAlloc ) +* : +* \brief : Free or allocate pixels matrix +* : +* \param : PtPtMat - Address of a pointer on matrix seen as 2D array MIS1__TMatPixFloat +* : +* \param : FreeAlloc - 0 => Free, 1 = Allocate +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/09/2020 +* \date : Doc date : 17/09/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixFloatFreeAlloc ( MIS1__TMatPixFloat** PtPtMat, SInt8 FreeAlloc ) { + + // Check param + + err_retnull ( PtPtMat, (ERR_OUT,"Abort => PtPtMat == NULL") ); + + // Free + + if ( FreeAlloc == 0 ) { + free ( *PtPtMat ); + *PtPtMat = NULL; + err_retok (( ERR_OUT, "" )); + } + + // Alloc + + *PtPtMat = (MIS1__TMatPixFloat*) malloc ( sizeof (MIS1__TMatPixFloat) ); + + err_retnull ( *PtPtMat, (ERR_OUT,"Abort => Allocation has failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32ResetAll ( MIS1__TMatPixS32* PtMat ) +* : +* \brief : Clears or fires all pixels of matrix, for tests purpose +* : +* \param : PtMat - Pointer on matrix seen as "bit" 2D array MIS1__TMatPixS32 +* : +* \param : ClearFireAll - 0 => Clears all pixels, 1 = Fires all pixels +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 15/10/2020 +* \date : Doc date : 15/10/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixS32ResetAll ( MIS1__TMatPixS32* PtMat ) { + + SInt32 VRet; + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + // Clears + + memset ( PtMat, 0, sizeof (MIS1__TMatPixS32) ); + + + return (0); + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32ResetSetAll ( MIS1__TMatPixS32* PtMat, SInt8 ResetSetAll ) +* : +* \brief : Clears or fires all pixels of matrix, for tests purpose +* : +* \param : PtMat - Pointer on matrix seen as "bit" 2D array MIS1__TMatPixS32 +* : +* \param : ClearFireAll - 0 => Clears all pixels, 1 = Fires all pixels +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2019 +* \date : Doc date : 22/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixS32ResetSetAll ( MIS1__TMatPixS32* PtMat, SInt8 ResetSetAll ) { + + SInt32 VRet; + SInt16 ViRow; + SInt16 ViCol; + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + // Clears / Fires + + for ( ViRow=0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + for ( ViCol=0; ViCol < MIS1__COL_NB; ViCol++ ) { + + if ( ResetSetAll == 0 ) { + (*PtMat)[ViCol][ViRow] = 0; + } + + else { + (*PtMat)[ViCol][ViRow] = 1; + } + + } + + } + + return (0); + +} + + + + +#define MIS1_NEW_RST_FUNC +#ifdef MIS1_NEW_RST_FUNC + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixFloatResetSetAll ( MIS1__TMatPixFloat* PtMat, SInt8 ResetSetAll ) +* : +* \brief : Clears or fires all pixels of matrix, for tests purpose +* : +* \param : PtMat - Pointer on matrix seen as "bit" 2D array MIS1__TMatPixS32 +* : +* \param : ClearFireAll - 0 => Clears all pixels, 1 = Fires all pixels +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/09/2020 +* \date : Doc date : 17/09/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixFloatResetSetAll ( MIS1__TMatPixFloat* PtMat, SInt8 ResetSetAll ) { + + SInt32 VRet; + SInt16 ViRow; + SInt16 ViCol; + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + // Clears / Fires + + for ( ViRow=0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + for ( ViCol=0; ViCol < MIS1__COL_NB; ViCol++ ) { + + if ( ResetSetAll == 0 ) { + (*PtMat)[ViCol][ViRow] = 0; + } + + else { + (*PtMat)[ViCol][ViRow] = 1; + } + + } + + } + + return (0); + +} + + +#endif + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32ResetSetPix ( MIS1__TMatPixS32* PtMat, SInt8 PixState, UInt16 PixX, UInt16 PixY ) +* : +* \brief : Clears or fires all pixels of matrix, for tests purpose +* : +* \param : PtMat - Pointer on matrix seen as "bit" 2D array MIS1__TMatPixS32 +* : +* \param : PixState - Pixel state 0 / 1 +* : +* \param : PixX - Pixel X coordinate = column +* : +* \param : PixY - Pixel Y coordinate = row +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2019 +* \date : Doc date : 22/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixS32ResetSetPix ( MIS1__TMatPixS32* PtMat, SInt8 PixState, UInt16 PixX, UInt16 PixY ) { + + SInt32 VRet; + SInt16 ViRow; + SInt16 ViCol; + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + if ( PixX >= MIS1__COL_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => PixX = %d > %d", PixX, MIS1__COL_NB - 1 ) ); + } + + if ( PixY >= MIS1__ROW_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => PixY = %d > %d", PixY, MIS1__ROW_NB - 1 ) ); + } + + // Clears / Fires pixel + + (*PtMat)[PixX][PixY] = PixState; + + return (0); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32ResetSetFromPixList ( MIS1__TMatPixS32* PtMat, SInt8 ResetSet, MIS1__TPixXY* APixList, SInt32 PixNb ) +* : +* \brief : resets / Sets pixels from list APixList in matrix PtMat, for tests purpose +* : +* \param : PtMat - Pointer on matrix seen as "bit" 2D array MIS1__TMatPixS32 +* : +* \param : ResetSet - 0 => reset pixels / 1 => sets pixels +* : +* \param : APixList - Pixel list (X, Y) of typz MIS1__TPixXY, used to setr pixels +* : +* \param : PixNb - Number of pixels in list APixList +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2019 +* \date : Doc date : 22/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixS32ResetSetFromPixList ( MIS1__TMatPixS32* PtMat, SInt8 ResetSet, MIS1__TPixXY* APixList, SInt32 PixNb ) { + + SInt32 VRet; + SInt32 ViPix; + SInt16 VRow; + SInt16 VCol; + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + err_retnull ( APixList, (ERR_OUT,"Abort => APixList == NULL") ); + + + if ( PixNb > MIS1__PIX_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => PixNb = %d > MIS1__PIX_NB = %d", PixNb, MIS1__PIX_NB ) ); + } + + + // reset / Fires pixels from list in matrix + + for ( ViPix=0; ViPix < PixNb; ViPix++ ) { + VRow = APixList[ViPix].C.y; + VCol = APixList[ViPix].C.x; + (*PtMat)[VCol][VRow] = ResetSet; + } + + return (0); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32Print ( MIS1__TMatPixS32* PtMat, UInt8 EncodeMth, UInt8 PrintDest, UInt8 PrintFormat, SInt32 CountThL, SInt32 CountThH, TMemo* Memo, char* FileName ) +* : +* \brief : Prints pixels states of Mimosis 1 matrix MIS1__TMatPixS32 +* : +* \param : PtMat - Pointer on Mimosis 1 matrix +* : +* \param : EncodeMth - Encoding method (for future use) => is used now +* : +* \param : PrintDest - Print destination, +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \param : PrintFormat - Print format ... +* : 0 = No print +* : 1 = fired pixels list, +* : 2 = all pixels 2D matrix, with column no print in first line +* : 3 = all pixels 2D matrix, with column no print in each line +* : +* \param : CountThL - If PrintFormat == 1, print pixel if CountThL <= value <= CountThH +* +* \param : CountThH - If PrintFormat == 1, print pixel if CountThL <= value <= CountThH +: +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3 +* : +* \param : FileName - Pointer to destination text file name if PrintDest = 4 or 5 +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2019 +* \date : Rev : 12/08/2020 +* : - Add param CountTh +* \date : Doc date : 22/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixS32Print ( MIS1__TMatPixS32* PtMat, UInt8 EncodeMth, UInt8 PrintDest, UInt8 PrintFormat, SInt32 CountThL, SInt32 CountThH, TMemo* Memo, char* FileName, char* CsvFileName, char* HistoFileName ) { + + SInt32 VRet; + SInt32 VMatCol; // Source matrix column = X + SInt32 VMatRow; // Source matrix row = Y + SInt32 VPixCol; // Pixel column = X calculated via EncodeMth + SInt32 VPixRow; // Pixel row = Y calculated via EncodeMth + + SInt32 VPixVal; + + static char VStrColPixList[MIS1__STR_COL_LIST_MAX_SZ]; + static char VStrColPix[GLB_CMT_SZ]; + static char VStrInfo[GLB_CMT_SZ]; + + FILE* VPtFile; + FILE* VPtFileCSV; + FILE* VPtFileHisto; + + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + // Rq : EncodeMth param is checked in printing loops + + if ( PrintDest > 5 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintDest=%d > 5", PrintDest) ); + } + + if ( PrintFormat > 3 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintFormat=%d > 3", PrintFormat) ); + } + + if ( ((PrintDest == 2) || (PrintDest == 3)) && (Memo == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to memo requested BUT Memo = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (FileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to texte file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (CsvFileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to CSV file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (HistoFileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to histo file requested BUT FileName = NULL !") ); + } + + + + // Create text file if PrintDest = 1, 4 or 5 + + if ( (PrintDest == 1) ||(PrintDest == 4) || (PrintDest == 5) ) { + + VPtFile = fopen ( FileName, "wt" ); + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create file %s failed !", FileName) ); + + VPtFileCSV = fopen ( CsvFileName, "wt" ); + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create file %s failed !", FileName) ); + + + VPtFileHisto = fopen ( HistoFileName, "wt" ); + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create file %s failed !", FileName) ); + + } + + + // Print info header + + MIS1__FPrintStr ( "-------------------------------------------------", PrintDest, Memo, VPtFile ); + sprintf ( VStrInfo, "List pixels with fired count in range %d to %d", CountThL, CountThH ); + MIS1__FPrintStr ( VStrInfo, PrintDest, Memo, VPtFile ); + MIS1__FPrintStr ( "-------------------------------------------------", PrintDest, Memo, VPtFile ); + MIS1__FPrintStr ( "", PrintDest, Memo, VPtFile ); + + + + // Extracts pixels info & Prints + + for ( VMatRow=0; VMatRow < MIS1__ROW_NB; VMatRow++ ) { + + // PrintFormat = 2 => Prints pixels as 2D matrix + // - Print colmuns list at top of matrix + + if ( (PrintFormat == 2) && (VMatRow == 0) ) { + + sprintf ( VStrColPixList, "Col : " ); + + for ( VMatCol=0; VMatCol < MIS1__COL_NB; VMatCol++ ) { + sprintf ( VStrColPix, "%.4d ", VMatCol ); + strcat ( VStrColPixList, VStrColPix ); + } + + MIS1__FPrintStr ( VStrColPixList, PrintDest, Memo, VPtFile ); + + } // End if ( PrintFormat == 2 ) + + + if ( (PrintFormat == 2) || (PrintFormat == 3) ) { + + sprintf ( VStrColPixList, "%4d : ", VMatRow ); + + } // End if ( PrintFormat == 2 ) + + + for ( VMatCol=0; VMatCol < MIS1__COL_NB; VMatCol++ ) { + + // Extracts pixels info + + switch ( EncodeMth ) { + + case 0 : { + VPixRow = VMatRow; + VPixCol = VMatCol; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => Unknown EncodeMth = %d", EncodeMth) ); + break; } + } + + // PrintFormat = 1 => Prints pixels list + + // Before 30/07/2020 + // + // if ( (PrintFormat == 1) && ((*PtMat)[VPixCol][VPixRow] == 1) ) { + // + // sprintf ( VStrColPix, "Pixel[x=%.4d,y=%.4d] = 1", VPixCol, VPixRow); + + //Since 30/07/2020 + + VPixVal = (*PtMat)[VPixCol][VPixRow]; + + if ( (PrintFormat == 1) && (VPixVal >= CountThL) && (VPixVal <= CountThH) ) { + + + sprintf ( VStrColPix, "Pixel[x=%.4d,y=%.4d] = %.4d", VPixCol, VPixRow, VPixVal ); + + + // Prints + + MIS1__FPrintStr ( VStrColPix, PrintDest, Memo, VPtFile ); + + // Print to CSV file + + fprintf ( VPtFileCSV, "%d,%d,%d \n", VPixCol, VPixRow, VPixVal ); + + // Print to histo file + + fprintf ( VPtFileHisto, "%d \n", VPixVal ); + + + + } // End if (PrintFormat == 1) + + + // PrintFormat = 2 => Prints pixels as 2D matrix => Builds line + + if ( PrintFormat == 2 ) { + sprintf ( VStrColPix, "%.4d ", (*PtMat)[VPixCol][VPixRow] ); + strcat ( VStrColPixList, VStrColPix ); + } // End if ( PrintFormat == 2 ) + + // PrintFormat = 3 => Prints pixels as 2D matrix => Builds line + + if ( PrintFormat == 3 ) { + sprintf ( VStrColPix, "%.4d,%.4d ", VPixCol, (*PtMat)[VPixCol][VPixRow] ); + strcat ( VStrColPixList, VStrColPix ); + } // End if ( PrintFormat == 2 ) + + } // End for (VMatCol) + + + // PrintFormat = 2 => Prints pixels as 2D matrix => Prints line + + if ( (PrintFormat == 2) ||(PrintFormat == 3) ) { + MIS1__FPrintStr ( VStrColPixList, PrintDest, Memo, VPtFile ); + } // End if ( PrintFormat == 2 ) + + + } // Enf for ( VMatRow ) + + + if ( (PrintDest == 1) || (PrintDest == 4) || (PrintDest == 5) ) { + + if ( fclose ( VPtFile ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", FileName) ); + } + + if ( fclose ( VPtFileCSV ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", CsvFileName) ); + } + + + if ( fclose ( VPtFileHisto ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", HistoFileName) ); + } + + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32ListFPCInCntRange ( MIS1__TMatPixS32* PtMat, UInt8 EncodeMth, UInt8 PrintDest, UInt8 PrintFormat, SInt32 CountThL, SInt32 CountThH, SInt32* PtResCountMin, SInt32* PtResCountMax, float* PtResCountMean, TMemo* Memo, char* FileName )* : +* +* \brief : Counts, and prints pixels with CountThL <= value ()fired count) <= CountThH of Mimosis 1 matrix MIS1__TMatPixS32 +* +* \param : PtMat - Pointer on Mimosis 1 matrix +* +* \param : EncodeMth - Encoding method (for future use) => is used now +* +* \param : PrintDest - Print destination, +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* +* \param : PrintFormat - Print format ... +* : 0 = No print (count only) +* : 1 = fired pixels list +* +* \param : CountThL - Low count threshold +* +* \param : CountThH - High count threshold +* +* \param : PtResCountMin - Ptr to count min, set it to NULL if not used. Min for calculated for count > 0 +* +* \param : PtResCountMax - Ptr to count max, set it to NULL if not used. Max for calculated for count >= 0 +* +* \param : PtResCountMean - Ptr to count mean, set it to NULL if not used. Mean calculated for CountThL <= Count <= CountThH +* +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3 +* +* \param : FileName - Pointer to destination text file name if PrintDest = 4 or 5 +* +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 12/08/2020 +* \date : Doc date : 12/08/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixS32ListFPCInCntRange ( MIS1__TMatPixS32* PtMat, UInt8 EncodeMth, UInt8 PrintDest, UInt8 PrintFormat, SInt32 CountThL, SInt32 CountThH, SInt32* PtResCountMin, SInt32* PtResCountMax, float* PtResCountMean, TMemo* Memo, char* FileName ) { + + SInt32 VRet; + SInt32 VMatCol; // Source matrix column = X + SInt32 VMatRow; // Source matrix row = Y + SInt32 VPixCol; // Pixel column = X calculated via EncodeMth + SInt32 VPixRow; // Pixel row = Y calculated via EncodeMth + + SInt32 VPixVal; + SInt32 VPixNbInRange; + SInt8 VPixIsInRange; + + static char VStrColPixList[MIS1__STR_COL_LIST_MAX_SZ]; + static char VStrColPix[GLB_CMT_SZ]; + + SInt32 VResCountMin; + SInt32 VResCountMax; + SInt64 VResCountSum; + SInt8 VCountSumOvf; + + float VResCountMean; + SInt32 VVResPixNbFPCNot0; // Calculated but not returen as result + + SInt8 VMinFound; + SInt8 VMaxFound; + + + FILE* VPtFile; + + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + // Rq : EncodeMth param is checked in printing loops + + if ( PrintDest > 5 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintDest=%d > 5", PrintDest) ); + } + + if ( PrintFormat > 1 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintFormat=%d > 1", PrintFormat) ); + } + + if ( ((PrintDest == 2) || (PrintDest == 3)) && (Memo == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to memo requested BUT Memo = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (FileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to texte file requested BUT FileName = NULL !") ); + } + + + // Create text file if PrintDest = 1, 4 or 5 + + if ( (PrintDest == 1) ||(PrintDest == 4) || (PrintDest == 5) ) { + VPtFile = fopen ( FileName, "wt" ); + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create file %s failed !", FileName) ); + } + + + // Extracts pixels info & Prints + + VPixNbInRange = 0; + + VResCountMin = 0x7FFFFFFF; + VResCountMax = 0; + VResCountSum = 0; + + VVResPixNbFPCNot0 = 0; + + VMinFound = 0; + VMaxFound = 0; + + VCountSumOvf = 0; + + + for ( VMatRow=0; VMatRow < MIS1__ROW_NB; VMatRow++ ) { + + for ( VMatCol=0; VMatCol < MIS1__COL_NB; VMatCol++ ) { + + // Extracts pixels info + + switch ( EncodeMth ) { + + case 0 : { + VPixRow = VMatRow; + VPixCol = VMatCol; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => Unknown EncodeMth = %d", EncodeMth) ); + break; } + } + + VPixVal = (*PtMat)[VPixCol][VPixRow]; + + + // Check pix cnt range + + if ( (VPixVal >= CountThL) && (VPixVal <= CountThH) ) { + VPixIsInRange = 1; + VPixNbInRange++; + } + + else { + VPixIsInRange = 0; + } + + + // Update counter of pixels with FPC N > 0 + + if ( VPixVal > 0 ) { + ++VVResPixNbFPCNot0; + } + + + // Update count max, for % = 0 to 100 % + + if ( VPixVal > VResCountMax ) { + VResCountMax = VPixVal; + VMaxFound = 1; + } + + // Update count min, for % > 0 to 100 % + // > 0 because otherwiase min always = 0 as there are always pixels % = 0 + + if ( (VPixVal > 0) && (VPixVal < VResCountMin) ) { + VResCountMin = VPixVal; + VMinFound = 1; + } + + // Stop summing if OVF + + if ( VResCountSum < 0 ) { + VCountSumOvf = 1; + } + + else { + + if ( VPixIsInRange == 1 ) { + VResCountSum += VPixVal; + } + + } + + + // PrintFormat = 1 => Prints pixels list + + if ( (PrintFormat == 1) && (VPixIsInRange == 1) ) { + + sprintf ( VStrColPix, "Pixel[x=%.4d,y=%.4d] = %.4d", VPixCol, VPixRow, (*PtMat)[VPixCol][VPixRow] ); + + // Prints + + MIS1__FPrintStr ( VStrColPix, PrintDest, Memo, VPtFile ); + + } // End if (PrintFormat == 1) + + + } // End for (VMatCol) + + + } // End for ( VMatRow ) + + + if ( VMinFound == 0 ) { + VResCountMin = -1; + } + + if ( VMaxFound == 0 ) { + VResCountMax = -1; + } + + + + if ((VCountSumOvf == 1) || ( VPixNbInRange > MIS1__PIX_NB) ) { + VResCountMean = -1; + } + + else { + VResCountMean = (float) VResCountSum / (float) VPixNbInRange; + } + + + if ( (PrintDest == 1) || (PrintDest == 4) || (PrintDest == 5) ) { + + if ( fclose ( VPtFile ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", FileName) ); + } + + } + + + if ( PtResCountMin != NULL ) { + *PtResCountMin = VResCountMin; + } + + if ( PtResCountMax != NULL ) { + *PtResCountMax = VResCountMax; + } + + if ( PtResCountMean != NULL ) { + *PtResCountMean = VResCountMean; + } + + return (VPixNbInRange); +} + + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixFloatListFPCInPCentRange ( MIS1__TMatPixFloat* PtMat, UInt8 EncodeMth, UInt8 PrintDest, UInt8 PrintFormat, float PCentThL, float PCentThH, float* PtResPCentMin, float* PtResPCentMax, TMemo* Memo, char* FileName ) +* : +* \brief : Counts, and prints pixels with PCentThL <= value ()fired count) <= PCentThH of Mimosis 1 matrix MIS1__TMatPixFloat +* : +* \param : PtMat - Pointer on Mimosis 1 matrix +* : +* \param : EncodeMth - Encoding method (for future use) => is used now +* : +* \param : PrintDest - Print destination, +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \param : PrintFormat - Print format ... +* : 0 = No print (count only) +* : 1 = fired pixels list +* : +* \param : PCentThL - Low % threshold +* +* \param : PCentThH - High % threshold +* : +* \param : PtResPCentMin - Ptr to % min, set it to NULL if not used. Min for calculated for % > 0 +* +* \param : PtResPCentMax - Ptr to % max, set it to NULL if not used. Max for calculated for % >= 0 +* +* \param : PtResPCentMean - Ptr to % mean, set it to NULL if not used. Mean calculated for PCentThL <= % <= PCentThH +* +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3 +* : +* \param : FileName - Pointer to destination text file name if PrintDest = 4 or 5 +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/09/2020 +* \date : Doc date : 17/09/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixFloatListFPCInPCentRange ( MIS1__TMatPixFloat* PtMat, UInt8 EncodeMth, UInt8 PrintDest, UInt8 PrintFormat, float PCentThL, float PCentThH, float* PtResPCentMin, float* PtResPCentMax, float* PtResPCentMean, TMemo* Memo, char* FileName, char* CsvFileName, char* HistoFileName ) { + + SInt32 VRet; + SInt32 VMatCol; // Source matrix column = X + SInt32 VMatRow; // Source matrix row = Y + SInt32 VPixCol; // Pixel column = X calculated via EncodeMth + SInt32 VPixRow; // Pixel row = Y calculated via EncodeMth + + float VPixVal; + SInt32 VPixNbInRange; + SInt8 VPixIsInRange; + + static char VStrColPixList[MIS1__STR_COL_LIST_MAX_SZ]; + static char VStrColPix[GLB_CMT_SZ]; + + float VResPCentMin; + float VResPCentMax; + SInt64 VResPCentSum; + float VResPCentMean; + SInt8 VPCentSumOvf; + + + SInt8 VMinFound; + SInt8 VMaxFound; + + + SInt32 VResPixNbSupMinPCent; // Nb of pxiel with % >= VMinPCent, Calculated but not returned + float VMinPCent = 1; // Minimum % used to calculate VResPixNbSupMinPCent + + FILE* VPtFile; + FILE* VPtFileCSV; + FILE* VPtFileHisto; + + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + // Rq : EncodeMth param is checked in printing loops + + if ( PrintDest > 5 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintDest=%d > 5", PrintDest) ); + } + + if ( PrintFormat > 1 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintFormat=%d > 1", PrintFormat) ); + } + + if ( ((PrintDest == 2) || (PrintDest == 3)) && (Memo == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to memo requested BUT Memo = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (FileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to texte file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (CsvFileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to CSV file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (HistoFileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to histo file requested BUT FileName = NULL !") ); + } + + + + // Create text file if PrintDest = 1, 4 or 5 + + if ( (PrintDest == 1) ||(PrintDest == 4) || (PrintDest == 5) ) { + + VPtFile = fopen ( FileName, "wt" ); + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create file %s failed !", FileName) ); + + VPtFileCSV = fopen ( CsvFileName, "wt" ); + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create file %s failed !", FileName) ); + + VPtFileHisto = fopen ( HistoFileName, "wt" ); + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create file %s failed !", FileName) ); + + } + + + // Extracts pixels info & Prints + + VPixNbInRange = 0; + + VResPCentMin = 100; + VResPCentMax = 0; + VResPCentSum = 0; + + VMinFound = 0; + VMaxFound = 0; + + VResPixNbSupMinPCent = 0; + + + for ( VMatRow=0; VMatRow < MIS1__ROW_NB; VMatRow++ ) { + + for ( VMatCol=0; VMatCol < MIS1__COL_NB; VMatCol++ ) { + + // Extracts pixels info + + switch ( EncodeMth ) { + + case 0 : { + VPixRow = VMatRow; + VPixCol = VMatCol; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => Unknown EncodeMth = %d", EncodeMth) ); + break; } + } + + VPixVal = (*PtMat)[VPixCol][VPixRow]; + + + // Check pix cnt range + + if ( (VPixVal >= PCentThL) && (VPixVal <= PCentThH) ) { + VPixIsInRange = 1; + VPixNbInRange++; + } + + else { + VPixIsInRange =0; + } + + + // Update counter of pixels with FPC % >= VMinPCent + + if ( VPixVal >= VMinPCent ) { + ++VResPixNbSupMinPCent; + } + + // Update % count max, for % = 0 to 100 % + + if ( VPixVal > VResPCentMax ) { + VResPCentMax = VPixVal; + VMaxFound = 1; + } + + // Update % count min, for % > 0 to 100 % + // > 0 because otherwiase min always = 0 as there are always pixels % = 0 + + if ( (VPixVal > 0) && (VPixVal < VResPCentMin) ) { + VResPCentMin = VPixVal; + VMinFound = 1; + } + + + // Stop summing if OVF or pixel value is out of thresholds range + + if ( VResPCentSum < 0 ) { + VPCentSumOvf = 1; + } + + else { + + if ( VPixIsInRange == 1 ) { + VResPCentSum += VPixVal; + } + + } + + + + // PrintFormat = 1 => Prints pixels list + + if ( (PrintFormat == 1) && (VPixIsInRange == 1) ) { + + sprintf ( VStrColPix, "Pixel[x=%.4d,y=%.4d] = %.1f", VPixCol, VPixRow, VPixVal ); + + // Prints + + MIS1__FPrintStr ( VStrColPix, PrintDest, Memo, VPtFile ); + + // Print to CSV file + + fprintf ( VPtFileCSV, "%d,%d,%.1f \n", VPixCol, VPixRow, VPixVal ); + + // Print to histo file + + fprintf ( VPtFileHisto, "%.1f \n", VPixVal ); + + + + } // End if (PrintFormat == 1) + + + } // End for (VMatCol) + + + } // End for ( VMatRow ) + + + if ( VMinFound == 0 ) { + VResPCentMin = -1; + } + + if ( VMaxFound == 0 ) { + VResPCentMax = -1; + } + + + if ( (VPCentSumOvf == 1) || (VPixNbInRange > MIS1__PIX_NB) ) { + VResPCentMean = -1; + } + + + else { + VResPCentMean = (float) VResPCentSum / (float) ( VPixNbInRange ); + } + + + if ( (PrintDest == 1) || (PrintDest == 4) || (PrintDest == 5) ) { + + if ( fclose ( VPtFile ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", FileName) ); + } + + if ( fclose ( VPtFileCSV ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", CsvFileName) ); + } + + + if ( fclose ( VPtFileHisto ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", HistoFileName) ); + } + + + } + + + if ( PtResPCentMin != NULL ) { + *PtResPCentMin = VResPCentMin; + } + + if ( PtResPCentMax != NULL ) { + *PtResPCentMax = VResPCentMax; + } + + if ( PtResPCentMean != NULL ) { + *PtResPCentMean = VResPCentMean; + } + + return (VPixNbInRange); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixFloatListFPCInPCentRangeExt ( MIS1__TMatPixFloat* PtMat, UInt16 FirstLine, UInt16 LastLine, UInt16 FirstCol, UInt16 LastCol, UInt8 EncodeMth, UInt8 PrintDest, UInt8 PrintFormat, float PCentThL, float PCentThH, float* PtResPCentMin, float* PtResPCentMax, TMemo* Memo, char* FileName ) +* : +* \brief : Counts, and prints pixels with PCentThL < value ()fired count) <= PCentThH of Mimosis 1 matrix MIS1__TMatPixFloat +* : +* \param : PtMat - Pointer on Mimosis 1 matrix +* : +* \param : FirstLine - +* : +* \param : LastLine - +* : +* \param : FirstCol - +* : +* \param : FirstCol - +* : +* \param : EncodeMth - Encoding method (for future use) => is used now +* : +* \param : PrintDest - Print destination, +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \param : PrintFormat - Print format ... +* : 0 = No print (count only) +* : 1 = fired pixels list +* : +* \param : PCentThL - Low % threshold +* +* \param : PCentThH - High % threshold +* +* \param : PtResPCentMin - Ptr to % min, set it to NULL if not used. Min for calculated for % > 0 +* +* \param : PtResPCentMax - Ptr to % max, set it to NULL if not used. Max for calculated for % >= 0 +* +* \param : PtResPCentMean - Ptr to % mean, set it to NULL if not used. Mean calculated for PCentThL <= % <= PCentThH +* +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3 +* : +* \param : FileName - Pointer to destination text file name if PrintDest = 4 or 5 +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/09/2020 +* \date : Doc date : 17/09/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixFloatListFPCInPCentRangeExt ( MIS1__TMatPixFloat* PtMat, UInt16 FirstLine, UInt16 LastLine, UInt16 FirstCol, UInt16 LastCol, UInt8 EncodeMth, UInt8 PrintDest, UInt8 PrintFormat, float PCentThL, float PCentThH, float* PtResPCentMin, float* PtResPCentMax, float* PtResPCentMean, TMemo* Memo, char* FileName, char* CsvFileName, char* HistoFileName ) { + + SInt32 VRet; + SInt32 VMatCol; // Source matrix column = X + SInt32 VMatRow; // Source matrix row = Y + SInt32 VPixCol; // Pixel column = X calculated via EncodeMth + SInt32 VPixRow; // Pixel row = Y calculated via EncodeMth + + float VPixVal; + SInt32 VPixNbInRange; + SInt8 VPixIsInRange; + + static char VStrColPixList[MIS1__STR_COL_LIST_MAX_SZ]; + static char VStrColPix[GLB_CMT_SZ]; + + float VResPCentMin; + float VResPCentMax; + SInt64 VResPCentSum; + float VResPCentMean; + SInt8 VPCentSumOvf; + + + SInt32 VResPixNbSupMinPCent; // Nb of pxiel with % >= VMinPCent, Calculated but not returned + float VMinPCent = 1; // Minimum % used to calculate VResPixNbSupMinPCent + + SInt8 VMinFound; + SInt8 VMaxFound; + + + FILE* VPtFile; + FILE* VPtFileCSV; + FILE* VPtFileHisto; + + + // Check param + + err_retnull ( PtMat, (ERR_OUT,"Abort => PtMat == NULL") ); + + if ( (FirstLine >= MIS1__ROW_NB) || (LastLine >= MIS1__ROW_NB) || (FirstLine > LastLine) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Bad lines range %d to %d MUST be in 0 to %d", FirstLine, LastLine, MIS1__ROW_NB - 1 ) ); + } + + if ( (FirstCol >= MIS1__COL_NB) || (LastCol >= MIS1__COL_NB) || (FirstCol > LastCol) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Bad columns range %d to %d MUST be in 0 to %d", FirstCol, LastCol, MIS1__COL_NB - 1 ) ); + } + + + // Rq : EncodeMth param is checked in printing loops + + if ( PrintDest > 5 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintDest=%d > 5", PrintDest) ); + } + + if ( PrintFormat > 1 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintFormat=%d > 1", PrintFormat) ); + } + + if ( ((PrintDest == 2) || (PrintDest == 3)) && (Memo == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to memo requested BUT Memo = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (FileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to texte file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (CsvFileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to CSV file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (HistoFileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to histo file requested BUT FileName = NULL !") ); + } + + + + // Create text file if PrintDest = 1, 4 or 5 + + if ( (PrintDest == 1) ||(PrintDest == 4) || (PrintDest == 5) ) { + + VPtFile = fopen ( FileName, "wt" ); + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create file %s failed !", FileName) ); + + VPtFileCSV = fopen ( CsvFileName, "wt" ); + err_retnull ( VPtFileCSV, (ERR_OUT,"Abort => Create file %s failed !", CsvFileName) ); + + + VPtFileHisto = fopen ( HistoFileName, "wt" ); + err_retnull ( VPtFileHisto, (ERR_OUT,"Abort => Create file %s failed !", HistoFileName) ); + + + } + + + // Extracts pixels info & Prints + + VPixNbInRange = 0; + + VResPCentMin = 100; + VResPCentMax = 0; + VResPCentSum = 0; + + VPCentSumOvf = 0; + + VResPixNbSupMinPCent = 0; // Calculated but not returned + + VMinFound = 0; + VMaxFound = 0; + + + for ( VMatRow=FirstLine; VMatRow <= LastLine; VMatRow++ ) { + + for ( VMatCol=FirstCol; VMatCol <= LastCol; VMatCol++ ) { + + // Extracts pixels info + + switch ( EncodeMth ) { + + case 0 : { + VPixRow = VMatRow; + VPixCol = VMatCol; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => Unknown EncodeMth = %d", EncodeMth) ); + break; } + } + + VPixVal = (*PtMat)[VPixCol][VPixRow]; + + + // Check pix cnt range + + if ( (VPixVal > PCentThL) && (VPixVal <= PCentThH) ) { + VPixIsInRange = 1; + VPixNbInRange++; + } + + else { + VPixIsInRange =0; + } + + + // Update counter of pixels with FPC % >= VMinPCent + + if ( VPixVal >= VMinPCent ) { + ++VResPixNbSupMinPCent; + } + + // Update % count max, for % = 0 to 100 % + + if ( VPixVal > VResPCentMax ) { + VResPCentMax = VPixVal; + VMaxFound = 1; + } + + // Update % count min, for % > 0 to 100 % + // > 0 because otherwiase min always = 0 as there are always pixels % = 0 + + if ( (VPixVal > 0) && (VPixVal < VResPCentMin) ) { + VResPCentMin = VPixVal; + VMinFound = 1; + } + + // Stop summing if OVF or pixel value is out of thresholds range + + if ( VResPCentSum < 0 ) { + VPCentSumOvf = 1; + } + + else { + + if ( VPixIsInRange == 1 ) { + VResPCentSum += VPixVal; + } + + } + + + // PrintFormat = 1 => Prints pixels list + + if ( (PrintFormat == 1) && (VPixIsInRange == 1) ) { + + sprintf ( VStrColPix, "Pixel[x=%.4d,y=%.4d] = %3.9f", VPixCol, VPixRow, VPixVal ); + + // Prints + + MIS1__FPrintStr ( VStrColPix, PrintDest, Memo, VPtFile ); + + + // Print to CSV file + + fprintf ( VPtFileCSV, "%d,%d,%3.9f \n", VPixCol, VPixRow, VPixVal ); + + // Print to histo file + + fprintf ( VPtFileHisto, "%3.9f \n", VPixVal ); + + + + } // End if (PrintFormat == 1) + + + } // End for (VMatCol) + + + } // End for ( VMatRow ) + + + + if ( VMinFound == 0 ) { + VResPCentMin = -1; + } + + if ( VMaxFound == 0 ) { + VResPCentMax = -1; + } + + + + if ( (VPCentSumOvf == 1) || (VPixNbInRange > MIS1__PIX_NB) ) { + VResPCentMean = -1; + } + + + else { + + if ( VPixNbInRange == 0 ) { + VResPCentMean = -1; + } + + else { + VResPCentMean = (float) VResPCentSum / (float) ( VPixNbInRange ); + } + + + } + + + + if ( (PrintDest == 1) || (PrintDest == 4) || (PrintDest == 5) ) { + + if ( fclose ( VPtFile ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", FileName) ); + } + + if ( fclose ( VPtFileCSV ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", CsvFileName) ); + } + + + if ( fclose ( VPtFileHisto ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", HistoFileName) ); + } + + + + } + + + if ( PtResPCentMin != NULL ) { + *PtResPCentMin = VResPCentMin; + } + + if ( PtResPCentMax != NULL ) { + *PtResPCentMax = VResPCentMax; + } + + if ( PtResPCentMean != NULL ) { + *PtResPCentMean = VResPCentMean; + } + + return (VPixNbInRange); +} + + + + + +// 1664 + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1_FMatCumToMatPCent ( MIS1__TMatPixS32* PtMatSrc, MIS1__TMatPixFloat* PtMatDest, SInt32 FrNb ) +* : +* \brief : This function convert cumul matrix to % / S curve data mattrix \n +* : +* \param : PtMatSrc - Source matrix +* : +* \param : PtMatDest - Destination matrix +* : +* \param : FrNb - Frames number +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : The user should not modify this function +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/09/2020 +* \date : Doc date : +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1_FMatCumToMatPCent ( MIS1__TMatPixS32* PtMatSrc, MIS1__TMatPixFloat* PtMatDest, SInt32 FrNb ) { + + SInt32 Vx, Vy; + float VPixVal; + + // Check param + + err_retnull ( PtMatSrc, (ERR_OUT,"Abort => PtMatSrc == NULL") ); + + err_retnull ( PtMatDest, (ERR_OUT,"Abort => PtMatDest == NULL") ); + + // Scan matrix + // [MIS1__COL_NB][MIS1__ROW_NB] + + for ( Vx=0; Vx < MIS1__COL_NB; Vx++ ) { + + + for ( Vy=0; Vy < MIS1__ROW_NB; Vy++ ) { + + VPixVal = (*PtMatSrc)[Vx][Vy]; + + if ( VPixVal == 0 ) { + (*PtMatDest)[Vx][Vy] = 0; + } + + else { + (*PtMatDest)[Vx][Vy] = ( (float) VPixVal / (float) FrNb ) * 100; + } + + + } // End for ( Vy ) + + } // End for ( Vx ) + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanAlloc ( ) +* : +* \brief : +* : +* \param : +* : +* \param : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanAlloc ( ) { + + + MIS1__VGPtRecResScan = (MIS1__TRecResScan*) malloc ( sizeof (MIS1__TRecResScan) ); + + err_retnull ( MIS1__VGPtRecResScan, (ERR_OUT,"Abort => Alloc MIS1__VGPtRecResScan failed !") ); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanFree ( ) +* : +* \brief : +* : +* \param : +* : +* \param : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanFree ( ) { + + + err_retnull ( MIS1__VGPtRecResScan, (ERR_OUT,"Abort => MIS1__VGPtRecResScan already == NULL") ); + + free ( MIS1__VGPtRecResScan ); + + MIS1__VGPtRecResScan = NULL; + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanResetAll ( MIS1__TRecResScan* PtRec ) +* : +* \brief : Fill record with 0 +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanResetAll ( MIS1__TRecResScan* PtRec ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + // Reset + + memset ( PtRec, 0, sizeof (MIS1__TRecResScan) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanResetAll () +* : +* \brief : Fill record with 0 +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanResetAll ( ) { + + return ( MIS1__FRecResScanResetAll ( MIS1__VGPtRecResScan ) ); + +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanReset ( MIS1__TRecResScan* PtRec ) +* : +* \brief : Fill record with 0 +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/10/2020 +* \date : Doc date : 01/10/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanResetRes ( MIS1__TRecResScan* PtRec ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + + // Reset + + memset ( &(PtRec->R.ResMat), 0, sizeof (MIS1__TMatScanFloat) ); + + memset ( PtRec->R.APCentMin , -1, MIS1__COL_NB * MIS1__ROW_NB * sizeof (PtRec->R.APCentMin[0][0]) ); + memset ( PtRec->R.APCentMax , -1, MIS1__COL_NB * MIS1__ROW_NB * sizeof (PtRec->R.APCentMax[0][0]) ); + memset ( PtRec->R.AResScanRegValForLowPCent , -1, MIS1__COL_NB * MIS1__ROW_NB * sizeof (PtRec->R.AResScanRegValForLowPCent[0][0]) ); + memset ( PtRec->R.AResScanRegValForHighPCent, -1, MIS1__COL_NB * MIS1__ROW_NB * sizeof (PtRec->R.AResScanRegValForHighPCent[0][0]) ); + memset ( PtRec->R.AResScanRegValForMidPCent , -1, MIS1__COL_NB * MIS1__ROW_NB * sizeof (PtRec->R.AResScanRegValForMidPCent[0][0]) ); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanReset () +* : +* \brief : Fill record with 0 +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanResetRes () { + + return ( MIS1__FRecResScanResetRes (MIS1__VGPtRecResScan) ); + +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSaveBin ( MIS1__TRecResScan* PtRec, char* FileName ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/10/2020 +* \date : Doc date : 01/10/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSaveBin ( MIS1__TRecResScan* PtRec, char* FileName ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL" ) ); + + // Save file + + VRet = FIL_FWriteRecord ( FileName, PtRec, sizeof ( MIS1__TRecResScan) ); + + err_retfail ( VRet, (ERR_OUT,"Saving record to file %s failed !", FileName ) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSaveBin ( char* FileName ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSaveBin ( char* FileName ) { + + return ( MIS1__FRecResScanSaveBin ( MIS1__VGPtRecResScan, FileName ) ); + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanParSaveBin ( MIS1__TRecResScanPar* PtRec, char* FileName ) +* : +* \brief : Save scan record PARAMETERS part in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/11/2020 +* \date : Doc date : 24/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanParSaveBin ( MIS1__TRecResScanPar* PtRec, char* FileName ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL" ) ); + + // Save file + + VRet = FIL_FWriteRecord ( FileName, PtRec, sizeof (MIS1__TRecResScanPar) ); + + err_retfail ( VRet, (ERR_OUT,"Saving record to file %s failed !", FileName ) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanParSaveBin ( char* FileName ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/11/2020 +* \date : Doc date : 24/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanParSaveBin ( char* FileName ) { + + return ( MIS1__FRecResScanParSaveBin ( &(MIS1__VGPtRecResScan->P), FileName ) ); + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanLoadBin ( MIS1__TRecResScan* PtRec, char* FileName ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/10/2020 +* \date : Doc date : 01/10/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanLoadBin ( MIS1__TRecResScan* PtRec, char* FileName ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL" ) ); + + + // Read file + + VRet = FIL_FReadRecord ( FileName, PtRec, sizeof ( MIS1__TRecResScan) ); + + err_retfail ( VRet, (ERR_OUT,"Loading record from file %s failed !", FileName ) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanLoadBin ( char* FileName ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanLoadBin ( char* FileName ) { + + return ( MIS1__FRecResScanLoadBin ( MIS1__VGPtRecResScan, FileName) ); + +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanParLoadBin ( MIS1__TRecResScanPar* PtRec, char* FileName ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/11/2020 +* \date : Doc date : 24/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanParLoadBin ( MIS1__TRecResScanPar* PtRec, char* FileName ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL" ) ); + + + // Read file + + VRet = FIL_FReadRecord ( FileName, PtRec, sizeof (MIS1__TRecResScanPar) ); + + err_retfail ( VRet, (ERR_OUT,"Loading record from file %s failed !", FileName ) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanParLoadBin ( char* FileName ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanParLoadBin ( char* FileName ) { + + return ( MIS1__FRecResScanParLoadBin ( &(MIS1__VGPtRecResScan->P), FileName) ); + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSetDac ( MIS1__TRecResScan* PtRec, UInt32* ASrcDac, UInt32 SrcDacMaxESz ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSetDac ( MIS1__TRecResScan* PtRec, UInt32* ASrcDac, UInt32 SrcDacMaxESz ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( ASrcDac, (ERR_OUT,"Abort => ASrcDac == NULL") ); + + if ( SrcDacMaxESz < MIS1__DAC_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort source array size = %d < MIS1__DAC_NB = %d", SrcDacMaxESz, MIS1__DAC_NB ) ); + } + + // Set DAC + + memcpy ( PtRec->P.ParADac, ASrcDac, MIS1__DAC_NB * sizeof (PtRec->P.ParADac[0]) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSetDac ( UInt32* ASrcDac, UInt32 SrcDacMaxESz ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSetDac ( UInt32* ASrcDac, UInt32 SrcDacMaxESz ) { + + return ( MIS1__FRecResScanSetDac ( MIS1__VGPtRecResScan, ASrcDac, SrcDacMaxESz ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetDac ( MIS1__TRecResScan* PtRec, UInt32* ADestDac, UInt32 DestDacMaxESz, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetDac ( MIS1__TRecResScan* PtRec, UInt32* ADestDac, UInt32 DestDacMaxESz, UInt32 Print ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( ADestDac, (ERR_OUT,"Abort => ADestDac == NULL") ); + + if ( DestDacMaxESz < MIS1__DAC_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort destination array size = %d < MIS1__DAC_NB = %d", DestDacMaxESz, MIS1__DAC_NB ) ); + } + + // Return DAC + + memcpy ( ADestDac, PtRec->P.ParADac, MIS1__DAC_NB * sizeof (PtRec->P.ParADac[0]) ); + + // Print + + if ( Print ) { + msg (( MSG_OUT, "DAC regsiters print is not yet implemented => TBD" )); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetDac ( UInt32* ADestDac, UInt32 DestDacMaxESz, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetDac ( UInt32* ADestDac, UInt32 DestDacMaxESz, UInt32 Print ) { + + return ( MIS1__FRecResScanGetDac ( MIS1__VGPtRecResScan, ADestDac, DestDacMaxESz, Print ) ); + +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSetScCnfFile ( MIS1__TRecResScan* PtRec, char* SrcScCnfFile ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSetScCnfFile ( MIS1__TRecResScan* PtRec, char* SrcScCnfFile ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( SrcScCnfFile, (ERR_OUT,"Abort => SrcScCnfFile == NULL") ); + + // Set sc cnf file + + strcpy ( PtRec->P.ParScConfFile, SrcScCnfFile ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSetScCnfFile ( char* SrcScCnfFile ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSetScCnfFile ( char* SrcScCnfFile ) { + + return ( MIS1__FRecResScanSetScCnfFile ( MIS1__VGPtRecResScan, SrcScCnfFile ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetScCnfFile ( MIS1__TRecResScan* PtRec, char* DestScCnfFile, UInt32 DestScCnfFileMaxSz, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetScCnfFile ( MIS1__TRecResScan* PtRec, char* DestScCnfFile, UInt32 DestScCnfFileMaxSz, UInt32 Print ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( DestScCnfFile, (ERR_OUT,"Abort => SrcScCnfFile == NULL") ); + + if ( DestScCnfFileMaxSz < GLB_FILE_PATH_SZ ) { + err_retfail ( -1, (ERR_OUT,"Abort => Destination string size = %d < Max src size = %d", DestScCnfFileMaxSz, GLB_FILE_PATH_SZ) ); + } + + // Set sc cnf file + + strcpy ( DestScCnfFile, PtRec->P.ParScConfFile ); + + // Print + + if ( Print ) { + msg (( MSG_OUT, "SC conf file = %s", PtRec->P.ParScConfFile )); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetScCnfFile ( MIS1__TRecResScan* PtRec, char* DestScCnfFile, UInt32 DestScCnfFileMaxSz, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetScCnfFile ( char* DestScCnfFile, UInt32 DestScCnfFileMaxSz, UInt32 Print ) { + + return ( MIS1__FRecResScanGetScCnfFile ( MIS1__VGPtRecResScan, DestScCnfFile, DestScCnfFileMaxSz, Print ) ); + +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSetScanReg ( MIS1__TRecResScan* PtRec, UInt32* ASrcScanReg, UInt32 SrcScanRegMaxESz ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSetScanReg ( MIS1__TRecResScan* PtRec, UInt32* ASrcScanReg, UInt32 SrcScanRegMaxESz ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( ASrcScanReg, (ERR_OUT,"Abort => ASrcScanReg == NULL") ); + + if ( SrcScanRegMaxESz < MIS1__CAR_MAX_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort source array size = %d < MIS1__CAR_MAX_STEP_NB = %d", SrcScanRegMaxESz, MIS1__CAR_MAX_STEP_NB ) ); + } + + // Set scan reg + + memcpy ( PtRec->P.AParScanRegVal, ASrcScanReg, MIS1__CAR_MAX_STEP_NB * sizeof (PtRec->P.AParScanRegVal[0]) ); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSetScanReg ( UInt32* ASrcScanReg, UInt32 SrcScanRegMaxESz ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSetScanReg ( UInt32* ASrcScanReg, UInt32 SrcScanRegMaxESz ) { + + return ( MIS1__FRecResScanSetScanReg ( MIS1__VGPtRecResScan, ASrcScanReg, SrcScanRegMaxESz ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetScanReg ( MIS1__TRecResScan* PtRec, UInt32* ADestScanReg, UInt32 DestScanRegMaxESz, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetScanReg ( MIS1__TRecResScan* PtRec, UInt32* ADestScanReg, UInt32 DestScanRegMaxESz, UInt32 Print ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( ADestScanReg, (ERR_OUT,"Abort => ADestScanReg == NULL") ); + + if ( DestScanRegMaxESz < MIS1__CAR_MAX_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort destination array size = %d < MIS1__CAR_MAX_STEP_NB = %d", DestScanRegMaxESz, MIS1__CAR_MAX_STEP_NB ) ); + } + + // Return DAC + + memcpy ( ADestScanReg, PtRec->P.AParScanRegVal, MIS1__CAR_MAX_STEP_NB * sizeof (PtRec->P.AParScanRegVal[0]) ); + + + // Print + + if ( Print ) { + + VRet = MIS1__FRecResScanPrintScanRegVal ( PtRec, 1 /* All */ ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Print scan reg failed ! Ret = %d", VRet) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetScanReg ( UInt32* ADestScanReg, UInt32 DestScanRegMaxESz, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetScanReg ( UInt32* ADestScanReg, UInt32 DestScanRegMaxESz, UInt32 Print ) { + + return ( MIS1__FRecResScanGetScanReg ( MIS1__VGPtRecResScan, ADestScanReg, DestScanRegMaxESz, Print ) ); + +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetStepFrNb ( MIS1__TRecResScan* PtRec, UInt32* PtFirstStep, UInt32* PtLastStep, UInt32* PtStepNb, UInt322* PtFrNb, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetStepFrNb ( MIS1__TRecResScan* PtRec, UInt32* PtFirstStep, UInt32* PtLastStep, UInt32* PtStepNb, UInt32* PtFrNb, UInt32 Print ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( PtFirstStep, (ERR_OUT,"Abort => PtFirstStep == NULL") ); + err_retnull ( PtLastStep , (ERR_OUT,"Abort => PtLastStep == NULL") ); + err_retnull ( PtStepNb , (ERR_OUT,"Abort => PtStepNb == NULL") ); + err_retnull ( PtFrNb , (ERR_OUT,"Abort => PtFrNb == NULL") ); + + + // Return steps info + + *PtFirstStep = PtRec->P.ParFirstStep; + *PtLastStep = PtRec->P.ParLastStep; + *PtStepNb = PtRec->P.ParStepNb; + *PtFrNb = PtRec->P.ParFrNb; + + if ( Print ) { + msg (( MSG_OUT, "First step = %d, last step = %d, steps nb = %d, fr nb = %d", PtRec->P.ParFirstStep, PtRec->P.ParLastStep, PtRec->P.ParStepNb, PtRec->P.ParFrNb )); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetStepFrNb ( UInt32* PtFirstStep, UInt32* PtLastStep, UInt32* PtStepNb, UInt32* PtFrNb, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetStepFrNb ( UInt32* PtFirstStep, UInt32* PtLastStep, UInt32* PtStepNb, UInt32* PtFrNb, UInt32 Print ) { + + return ( MIS1__FRecResScanGetStepFrNb ( MIS1__VGPtRecResScan, PtFirstStep, PtLastStep, PtStepNb, PtFrNb, Print ) ); + +} + + +// 9999 + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSetPulsePar ( MIS1__TRecResScan* PtRec, char* Mat, UInt32 FirstCol, UInt32 LastCol, UInt32 FirstRow, UInt32 LastRow, UInt32 PixPulseAA, UInt32 PixPulseAB ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 19/11/2020 +* \date : Doc date : 19/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSetPulsePar ( MIS1__TRecResScan* PtRec, char* Mat, UInt32 FirstCol, UInt32 LastCol, UInt32 FirstRow, UInt32 LastRow, UInt32 PixPulseAA, UInt32 PixPulseAB ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + + // Set pulse param + + PtRec->P.ParMatrixPulsed = toupper (Mat[0]); // A, B, C, D + + PtRec->P.ParFirstColPulsed = FirstCol; + PtRec->P.ParLastColPulsed = LastCol; + PtRec->P.ParFirstRowPulsed = FirstRow; + PtRec->P.ParLastRowPulsed = LastRow; + + PtRec->P.ParPixPulseAA = PixPulseAA; + PtRec->P.ParPixPulseAB = PixPulseAB; + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanSetPulsePar ( char* Mat, UInt16 FirstCol, UInt32 LastCol, UInt32 FirstRow, UInt32 LastRow, UInt32 PixPulseAA, UInt32 PixPulseAB ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 19/11/2020 +* \date : Doc date : 19/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanSetPulsePar ( char* Mat, UInt32 FirstCol, UInt32 LastCol, UInt32 FirstRow, UInt32 LastRow, UInt32 PixPulseAA, UInt32 PixPulseAB ) { + + return ( MIS1__FRecResScanSetPulsePar ( MIS1__VGPtRecResScan, Mat, FirstCol, LastCol, FirstRow, LastRow, PixPulseAA, PixPulseAB ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetPulsePar ( MIS1__TRecResScan* PtRec, char* Mat, UInt32* PtFirstCol, UInt32* PtLastCol, UInt32* PtFirstRow, UInt32* PtLastRow, UInt32* PtPixPulseAA, UInt32* PtPixPulseAB, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetPulsePar ( MIS1__TRecResScan* PtRec, char* Mat, UInt32* PtFirstCol, UInt32* PtLastCol, UInt32* PtFirstRow, UInt32* PtLastRow, UInt32* PtPixPulseAA, UInt32* PtPixPulseAB, UInt32 Print ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( PtFirstCol , (ERR_OUT,"Abort => PtFirstCol == NULL") ); + err_retnull ( PtLastCol , (ERR_OUT,"Abort => PtLastCol == NULL") ); + err_retnull ( PtFirstRow , (ERR_OUT,"Abort => PtFirstRow == NULL") ); + err_retnull ( PtLastRow , (ERR_OUT,"Abort => PtLastRow == NULL") ); + err_retnull ( PtPixPulseAA, (ERR_OUT,"Abort => PtPixPulseAA == NULL") ); + err_retnull ( PtPixPulseAB, (ERR_OUT,"Abort => PtPixPulseAB == NULL") ); + + + // Get pulse param + + Mat[0] = PtRec->P.ParMatrixPulsed; + Mat[1] = 0; + + + *PtFirstCol = PtRec->P.ParFirstColPulsed; + *PtLastCol = PtRec->P.ParLastColPulsed; + *PtFirstRow = PtRec->P.ParFirstRowPulsed; + *PtLastRow = PtRec->P.ParLastRowPulsed; + + *PtPixPulseAA = PtRec->P.ParPixPulseAA; + *PtPixPulseAB = PtRec->P.ParPixPulseAB; + + // Print + + if ( Print ) { + msg (( MSG_OUT, "FirstCol = %d, LastCol = %d, FirstRow = %d, LasrRow = %d, PixPulseAA = %d, PixPulseAB = %d", *PtFirstCol, *PtLastCol, *PtFirstRow, *PtLastRow, *PtPixPulseAA, *PtPixPulseAB )); + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetPulsePar ( char* Mat, UInt32* PtFirstCol, UInt32* PtLastCol, UInt32* PtFirstRow, UInt32* PtLastRow, UInt32* PtPixPulseAA, UInt32* PtPixPulseAB, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetPulsePar ( char* Mat, UInt32* PtFirstCol, UInt32* PtLastCol, UInt32* PtFirstRow, UInt32* PtLastRow, UInt32* PtPixPulseAA, UInt32* PtPixPulseAB, UInt32 Print ) { + + return ( MIS1__FRecResScanGetPulsePar ( MIS1__VGPtRecResScan, Mat, PtFirstCol, PtLastCol, PtFirstRow, PtLastRow, PtPixPulseAA, PtPixPulseAB, Print ) ); + +} + + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetPixelSteps ( MIS1__TRecResScan* PtRec, UInt32 PixX, UInt32 PixY, float* ADestPixSteps, UInt32 DestPixStepsMaxESz, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetPixelSteps ( MIS1__TRecResScan* PtRec, UInt32 PixX, UInt32 PixY, float* ADestPixSteps, UInt32 DestPixStepsMaxESz, UInt32 Print ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( ADestPixSteps, (ERR_OUT,"Abort => ADestPixSteps == NULL") ); + + if ( PixX >= MIS1__COL_NB ) { + err_retfail ( 1, (ERR_OUT,"Abort => PixX = %d > Max = %d", PixX, MIS1__COL_NB - 1) ); + } + + if ( PixY >= MIS1__ROW_NB ) { + err_retfail ( 1, (ERR_OUT,"Abort => PixY = %d > Max = %d", PixY, MIS1__ROW_NB - 1) ); + } + + if ( DestPixStepsMaxESz < MIS1__CAR_MAX_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => DestPixStepsMaxESz = %d < MIS1__CAR_MAX_STEP_NB = %d", DestPixStepsMaxESz, MIS1__CAR_MAX_STEP_NB) ); + } + + + // Return pixels steps % + + memcpy ( ADestPixSteps, &(PtRec->R.ResMat[PixX][PixY][PtRec->P.ParFirstStep]), PtRec->P.ParStepNb * sizeof (float) ); + + + if ( Print ) { + MIS1__FRecResScanPrintPixSteps ( PtRec, PixX, PixY, 1 /* All */ ); + } + + + // err_retok (( ERR_OUT, "" )); // No err_retok (...) in order to save execution time + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanGetPixelSteps ( UInt32 PixX, UInt32 PixY, float* ADestPixSteps, UInt32 DestPixStepsMaxESz, UInt32 Print ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanGetPixelSteps ( UInt32 PixX, UInt32 PixY, float* ADestPixSteps, UInt32 DestPixStepsMaxESz, UInt32 Print ) { + + return ( MIS1__FRecResScanGetPixelSteps ( MIS1__VGPtRecResScan, PixX, PixY, ADestPixSteps, DestPixStepsMaxESz, Print ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanPrintScanRegVal ( MIS1__TRecResScan* PtRec, UInt32 All ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanPrintScanRegVal ( MIS1__TRecResScan* PtRec, UInt32 All ) { + + SInt32 VRet; + SInt16 ViReg; + SInt16 ViRegFirst; + SInt16 ViRegLast; + + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + if ( All > 1 ) { + err_retfail ( -1, (ERR_OUT,"Abort => All = %d <> 0, 1", All) ); + } + + // Print + + if ( All ) { + ViRegFirst = 0; + ViRegLast = MIS1__CAR_MAX_STEP_NB - 1; + } + + else { + ViRegFirst = PtRec->P.ParFirstStep; + ViRegLast = PtRec->P.ParLastStep; + } + + + msg (( MSG_OUT, "==========================================================" )); + msg (( MSG_OUT, " Scan reg step values" )); + + if ( All ) { + msg (( MSG_OUT, " - Print ALL" )) + } + + else { + msg (( MSG_OUT, " - Print only first to last steps" )); + } + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, " First step = %d, last step = %d, step nb = %d", PtRec->P.ParFirstStep, PtRec->P.ParLastStep, PtRec->P.ParStepNb )); + msg (( MSG_OUT, "==========================================================" )); + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "" )); + + for ( ViReg = ViRegFirst; ViReg <= ViRegLast; ViReg++ ) { + msg (( MSG_OUT, "Scan reg [Step = %.2d] = %.3d", ViReg, PtRec->P.AParScanRegVal[ViReg] )); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanPrintScanRegVal ( UInt32 All ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanPrintScanRegVal ( UInt32 All ) { + + return ( MIS1__FRecResScanPrintScanRegVal ( MIS1__VGPtRecResScan, All ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanPrintPixSteps ( MIS1__TRecResScan* PtRec, UInt32 PixX, UInt32 PixY, UInt32 All ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanPrintPixSteps ( MIS1__TRecResScan* PtRec, UInt32 PixX, UInt32 PixY, UInt32 All ) { + + SInt32 VRet; + SInt16 ViStep; + SInt16 ViStepFirst; + SInt16 ViStepLast; + + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + if ( All > 1 ) { + err_retfail ( -1, (ERR_OUT,"Abort => All = %d <> 0, 1", All) ); + } + + if ( PixX >= MIS1__COL_NB ) { + err_retfail ( 1, (ERR_OUT,"Abort => PixX = %d > Max = %d", PixX, MIS1__COL_NB - 1) ); + } + + if ( PixY >= MIS1__ROW_NB ) { + err_retfail ( 1, (ERR_OUT,"Abort => PixY = %d > Max = %d", PixY, MIS1__ROW_NB - 1) ); + } + + + + // Print + + if ( All ) { + ViStepFirst = 0; + ViStepLast = MIS1__CAR_MAX_STEP_NB - 1; + } + + else { + ViStepFirst = PtRec->P.ParFirstStep; + ViStepLast = PtRec->P.ParLastStep; + } + + + msg (( MSG_OUT, "==========================================================" )); + msg (( MSG_OUT, " Pixel X = %.4d, Y = %.4d steps %% results", PixX, PixY )); + + if ( All ) { + msg (( MSG_OUT, " - Print ALL" )) + } + + else { + msg (( MSG_OUT, " - Print only first to last steps" )); + } + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, " First step = %d, last step = %d, step nb = %d", PtRec->P.ParFirstStep, PtRec->P.ParLastStep, PtRec->P.ParStepNb )); + msg (( MSG_OUT, "==========================================================" )); + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "" )); + + for ( ViStep = ViStepFirst; ViStep <= ViStepLast; ViStep++ ) { + msg (( MSG_OUT, "Pix [X = %.4d, Y = %.4d, Step = %.2d] = %.1f %%", PixX, PixY, ViStep, PtRec->R.ResMat[PixX][PixY][ViStep] )); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanPrintPixSteps ( UInt32 PixX, UInt32 PixY, UInt32 All ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/11/2020 +* \date : Doc date : 18/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanPrintPixSteps ( UInt32 PixX, UInt32 PixY, UInt32 All ) { + + return ( MIS1__FRecResScanPrintPixSteps ( MIS1__VGPtRecResScan, PixX, PixY, All )); + +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanBuild ( MIS1__TRecResScan* PtRec, char* RunRootDir, UInt32 RunNo, UInt32 FirstStep, UInt32 LastStep, UInt32 FrNb, UInt32 FileFormatU16S32 ) +* : +* \brief : Save scan record in a binary file +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : FileName - The file : +* : +* \return : Error code +* : >= 0 - Number of pixels in the threshold range +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/11/2020 +* \date : Doc date : 17/11/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanBuild ( MIS1__TRecResScan* PtRec, char* RunRootDir, UInt32 RunNo, UInt32 FileFormatU16S32, UInt32 FirstStep, UInt32 LastStep, UInt32* AScanRegVal, UInt32 ScanRegValESz, UInt32 FrNb ) { + + SInt32 VRet; + SInt16 ViStep; + char VStepSrcFile[GLB_FILE_PATH_SZ]; + SInt16 VPixX; + SInt16 VPixY; + float VPixPCent; + + MIS1__TMatPixS32* VPtMatStepS32; + MIS1__TMatPixCntU16* VPtMatStepU16; + MIS1__TMatPixFloat* VPtMatPCent; + + + err_error (( ERR_OUT, "PtRec = %X, RunRootDir = %s, RunNo = %d, FileFormatU16S32 = %d, FirstStep = %d, LastStep = %d, AScanRegVal = %X, ScanRegValESz = %d, FrNb = %d", PtRec, RunRootDir, RunNo, FileFormatU16S32, FirstStep, LastStep, AScanRegVal, ScanRegValESz, FrNb )); + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( RunRootDir, (ERR_OUT,"Abort => RunRootDir == NULL" ) ); + + if ( LastStep < FirstStep ) { + err_retfail ( -1, (ERR_OUT,"Abort : LastStep = %d < FirstStep = %d", LastStep, FirstStep ) ); + } + + if ( (LastStep - FirstStep + 1) > MIS1__CAR_MAX_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort : Total step nb = %d > Max = %d", LastStep - FirstStep + 1, MIS1__CAR_MAX_STEP_NB ) ); + } + + + if ( LastStep >= ScanRegValESz ) { + err_retfail ( -1, (ERR_OUT,"Abort : Scan reg array too small = %d items > last step index = %d ", ScanRegValESz, LastStep ) ); + } + + if ( (FileFormatU16S32 < 0) || (FileFormatU16S32 > 1 ) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Bad file format = %d <> 0 = U16, 1 = S32", FileFormatU16S32) ); + } + + + // Check if run exists + + if ( ! DirectoryExists ( RunRootDir ) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Run directory = %s does not exists", RunRootDir ) ); + } + + // Set param to record + + PtRec->P.ParFirstStep = FirstStep; + PtRec->P.ParLastStep = LastStep; + PtRec->P.ParStepNb = LastStep - FirstStep + 1; + + PtRec->P.ParFrNb = FrNb; + + + if ( AScanRegVal != NULL ) { + + for ( ViStep = 0; ViStep < MIS1__CAR_MAX_STEP_NB; ViStep++ ) { + PtRec->P.AParScanRegVal[ViStep] = 0; + } + + for ( ViStep = PtRec->P.ParFirstStep; ViStep <= PtRec->P.ParLastStep; ViStep++ ) { + PtRec->P.AParScanRegVal[ViStep] = AScanRegVal[ViStep]; + } + + } // End if ( AScanRegVal != NULL ) + + + // Alloc buffers + + if ( FileFormatU16S32 == 0 ) { + + VPtMatStepU16 = (MIS1__TMatPixCntU16*) malloc ( sizeof (MIS1__TMatPixCntU16) ); + + err_retnull ( VPtMatStepU16, (ERR_OUT,"Abort => Alloc step file buffer U16 failed") ); + + } + + VPtMatStepS32 = (MIS1__TMatPixS32*) malloc ( sizeof (MIS1__TMatPixS32) ); + + err_retnull ( VPtMatStepS32, (ERR_OUT,"Abort => Alloc step file buffer S32 failed") ); + + VPtMatPCent = (MIS1__TMatPixFloat*) malloc ( sizeof (MIS1__TMatPixFloat) ); + + err_retnull ( VPtMatPCent, (ERR_OUT,"Abort => Alloc step mat pcent failed") ); + + + + // Reset results + + MIS1__FRecResScanResetRes ( PtRec ); + + + + // Process the run files + + for ( ViStep = FirstStep; ViStep <= LastStep; ViStep++ ) { + + // Build step source file name + + sprintf ( VStepSrcFile, "%s/run_%d/data/run_%d_%d_step.bin", RunRootDir, RunNo, RunNo, ViStep ); + + msg (( MSG_OUT, "File = %s", VStepSrcFile )); + + // Load src step file + + if ( FileFormatU16S32 == 0 ) { + + // Load U16 files + + VRet = MIS1__FMatPixCntU16Load ( VPtMatStepU16, VStepSrcFile ); + + err_retfail ( VRet, (ERR_OUT, "Error loading cumul matrix U16 from %s file - May be no file or bad format U16/S32 ?", VStepSrcFile ) ); + + // Convert U16 to S32 file + + VRet = MIS1__FMatPixCntU16ToMatPixS32 ( VPtMatStepU16, VPtMatStepS32 ); + + err_retfail ( VRet, (ERR_OUT, "Abort => Matrix U16 to S32 conversion" ) ); + + } // End if ( FileFormatU16S32 == 0 ) + + // Load a S32 file + + else { + + VRet = MIS1__FMatPixS32Load ( VPtMatStepS32, VStepSrcFile ); + + err_retfail ( VRet, (ERR_OUT, "Error loading cumul matrix S32 from %s file - May be no file or bad format U16/S32 ?", VStepSrcFile) ); + + } // End else + +if (1) { + + // Calc ResMat % + + VRet = MIS1_FMatCumToMatPCent ( VPtMatStepS32, VPtMatPCent, FrNb ); + + err_retfail ( VRet, (ERR_OUT, "Abort => Calculate APP__VGPtMatPCent failed !" ) ); + + + for ( VPixX = 0; VPixX < MIS1__COL_NB; VPixX++ ) { + + for ( VPixY = 0; VPixY < MIS1__ROW_NB; VPixY++ ) { + + VPixPCent = (*VPtMatPCent)[VPixX][VPixY]; + + PtRec->R.ResMat[VPixX][VPixY][ViStep] = VPixPCent; + + } // End for ( VPixY ) + + } // End for ( VPixX ) + + + } // End for ( ViStep ) + + +} + + + // Free buffers + + + if ( FileFormatU16S32 == 0 ) { + free ( VPtMatStepU16 ); + } + + free ( VPtMatStepS32 ); + + free ( VPtMatPCent ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecResScanExtractPixel ( MIS1__TRecResScan* PtRec, UInt16 PixX, UInt16 PixY, UInt16* AScanPar, SInt16 ScanParNb, UInt8 PrintDest, UInt8 PrintFormat, TMemo* Memo, char* LogFileName, char* CsvFileName, char* PlotFileNameX, char* PlotFileNameY ) : +* : +* \brief : Extract one pixel and save it as text files +* : +* \param : PtRec - Pointer on Mimosis 1 scan record +* : +* \param : PixX - Pixel X +* : +* \param : PixY - Pixel Y +* : +* \param : AScanPar - Array which contains scan parameter value for each step +* : +* \param : ScanParNb - Items nb = steps nb in AScanPar +* : +* \param : PrintDest - Print destination, +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \param : PrintFormat - Print format ... for future use +* : +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3 +* : +* \param : LogFileName - Pointer to destination text log file name if PrintDest = 4 or 5 +* : +* \param : CsvFileName - Pointer to destination text CSV file name if PrintDest = 4 or 5 +* : +* \param : PlotFileNameX - Pointer to destination text X data file for S curve plot +* : +* \param : PlotFileNameY - Pointer to destination text U data file for S curve plot +* : +* \return : Error code +* : > 0 - Error, returns nb of times the pixel is out of range 0 .. 100 % +* : = 0 - ok +* : < 0 - SW Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 30/09/2020 +* \date : Doc date : 30/09/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRecResScanExtractPixel ( MIS1__TRecResScan* PtRec, UInt16 PixX, UInt16 PixY, UInt16* AScanPar, SInt16 ScanParNb, UInt8 PrintDest, UInt8 PrintFormat, TMemo* Memo, char* LogFileName, char* CsvFileName, char* PlotFileNameX, char* PlotFileNameY ) { + + SInt32 VRet; + + FILE* VPtFileLog; + FILE* VPtFileCSV; + FILE* VPtFilePlotX; + FILE* VPtFilePlotY; + + SInt32 ViStep; + float VPixPCent; + + char VStrPixXYPCent[GLB_CMT_SZ]; + + SInt32 VPixBadPCentCnt; + + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + err_retnull ( AScanPar, (ERR_OUT,"Abort => AScanPar == NULL") ); + + if ( ScanParNb > MIS1__CAR_MAX_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => ScanParNb = %d > MIS1__CAR_MAX_STEP_NB = %d", ScanParNb, MIS1__CAR_MAX_STEP_NB ) ); + } + + if ( ScanParNb != PtRec->P.ParStepNb ) { + err_retfail ( -1, (ERR_OUT,"Abort => ScanParNb = %d != Scan par nb for scan record = %d", ScanParNb, PtRec->P.ParStepNb ) ); + } + + if ( PixX >= MIS1__COL_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => Bad column = %d MUST be in 0 to %d", PixX, MIS1__COL_NB - 1 ) ); + } + + + if ( PixY >= MIS1__ROW_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => Bad line = %d MUST be in 0 to %d", PixY, MIS1__ROW_NB - 1 ) ); + } + + + + if ( PrintDest > 5 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PrintDest=%d > 5", PrintDest) ); + } + + + if ( ((PrintDest == 2) || (PrintDest == 3)) && (Memo == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to memo requested BUT Memo = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (LogFileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to log text file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (CsvFileName == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to CSV file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (PlotFileNameX == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to plot X file requested BUT FileName = NULL !") ); + } + + if ( ((PrintDest == 4) || (PrintDest == 5)) && (PlotFileNameY == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to plot Y file requested BUT FileName = NULL !") ); + } + + + // Create text file if PrintDest = 1, 4 or 5 + + if ( (PrintDest == 1) ||(PrintDest == 4) || (PrintDest == 5) ) { + + VPtFileLog = fopen ( LogFileName, "wt" ); + err_retnull ( VPtFileLog, (ERR_OUT,"Abort => Create file %s failed !", LogFileName) ); + + VPtFileCSV = fopen ( CsvFileName, "wt" ); + err_retnull ( VPtFileCSV, (ERR_OUT,"Abort => Create file %s failed !", CsvFileName) ); + + + VPtFilePlotX = fopen ( PlotFileNameX, "wt" ); + err_retnull ( VPtFilePlotX, (ERR_OUT,"Abort => Create file %s failed !", PlotFileNameX) ); + + + VPtFilePlotY = fopen ( PlotFileNameY, "wt" ); + err_retnull ( VPtFilePlotY, (ERR_OUT,"Abort => Create file %s failed !", PlotFileNameY) ); + + } + + + // Extracts pixel info & Prints + + VPixBadPCentCnt = 0; + + + for ( ViStep = 0; ViStep < PtRec->P.ParStepNb; ViStep++ ) { + + // typedef float MIS1__TTMatScanFloat[MIS1__COL_NB][MIS1__ROW_NB][MIS1__CAR_MAX_STEP_NB]; + + VPixPCent = PtRec->R.ResMat[PixX][PixY][ViStep]; + + // Check + + if ( (VPixPCent < 0) || (VPixPCent > 100) ) { + ++VPixBadPCentCnt; + err_warning (( ERR_OUT, "Pix %% = %.1f not in range 0..100%% : Step = %.2d, ScanPar = %.3d, x = %.3d, y = %.3d ", VPixPCent, ViStep, AScanPar[ViStep], PixX, PixY )); + } + + + if ( PrintDest != 0) { + + // Prints + + sprintf ( VStrPixXYPCent, "Pixel[x=%.4d,y=%.4d,step=%.4d] = %.1f", PixX, PixY, ViStep, VPixPCent ); + + MIS1__FPrintStr ( VStrPixXYPCent, PrintDest, Memo, VPtFileLog ); + + + // Print to CSV file + + fprintf ( VPtFileCSV, "%d,%d,%.1f \n", PixX, PixY, VPixPCent ); + + // Print to plot files + + fprintf ( VPtFilePlotX, "%d \n", AScanPar[ViStep] ); + + fprintf ( VPtFilePlotY, "%.1f \n", VPixPCent ); + + } // End if ( PrintDest != 0) + + + } + + + + if ( (PrintDest == 1) || (PrintDest == 4) || (PrintDest == 5) ) { + + if ( fclose ( VPtFileLog ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", LogFileName) ); + } + + if ( fclose ( VPtFileCSV ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", CsvFileName) ); + } + + + if ( fclose ( VPtFilePlotX ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", PlotFileNameX) ); + } + + if ( fclose ( VPtFilePlotY ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => fclose file %s failed !", PlotFileNameY) ); + } + + + } + + + return (VPixBadPCentCnt); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32ToMatPixXYSP ( MIS1__TMatPixS32* PtMatSrc, MIS1__TMatPixXYSP* PtMatDest, UInt8 EncodeMth ) +* : +* \brief : Convert a matrix view as MIS1__TMatPixS32 to MIS1__TMatPixXYSP view +* : +* \param : PtMatSrc - Pointer on source matrix MIS1__TMatPixS32 +* : +* \param : PtMatDest - Pointer on destination matrix MIS1__TMatPixXYSP +* : +* \param : EncodeMth - Encode method (Only 0 is handled on 29/05/2019) +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 29/05/2019 +* \date : Doc date : 29/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FMatPixS32ToMatPixXYSP ( MIS1__TMatPixS32* PtMatSrc, MIS1__TMatPixXYSP* PtMatDest, UInt8 EncodeMth ) { + + SInt32 VRet; + SInt16 VSrcIRow; + SInt16 VSrcICol; + SInt16 VDestIRow; + SInt16 VDestICol; + SInt32 VPixS32Val; + MIS1__TPixXYSP* VPtPixXYSP; + + SInt16 VDestCol; + SInt16 VDestRow; + SInt16 VDestRegion; + SInt16 VDestSRegion; + SInt16 VDestPeNoInMatrix; + SInt16 VDestPeNoInRegion; + SInt16 VDestPeNoInSRegion; + SInt16 VDestPeRow; + SInt16 VDestPeAddr; + + // Check param + + err_retnull ( PtMatSrc, (ERR_OUT,"Abort => PtMatSrc == NULL") ); + + err_retnull ( PtMatDest, (ERR_OUT,"Abort => PtMatDest == NULL") ); + + if ( EncodeMth != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => EncodeMth = %d <> 0", EncodeMth ) ); + } + + // Convert matrix + + for ( VSrcIRow=0; VSrcIRow < MIS1__ROW_NB; VSrcIRow++ ) { + + for ( VSrcICol=0; VSrcICol < MIS1__COL_NB; VSrcICol++ ) { + + switch ( EncodeMth ) { + + case 0 : { + VDestICol = VSrcICol; + VDestIRow = VSrcIRow; + + VPixS32Val = (*PtMatSrc)[VSrcICol][VSrcIRow]; + VDestCol = VSrcICol; + VDestRow = VSrcIRow; + VPtPixXYSP = &((*PtMatDest)[VDestICol][VDestIRow]); + VDestRegion = VDestCol / MIS1__COL_PER_REG; + VDestSRegion = VDestCol / MIS1__COL_PER_SREG; + + VDestPeNoInMatrix = VDestCol / MIS1__COL_PER_PE; + VDestPeNoInRegion = VDestCol % MIS1__PE_PER_REG; + VDestPeNoInSRegion = VDestCol % MIS1__PE_PER_SREG; + VDestPeRow = VSrcIRow; + VDestPeAddr = 0; + + break; } + + // No default case because EncodeMth is checked at function beginning + + } + + VPtPixXYSP->PixXYS.PixState = VPixS32Val; + VPtPixXYSP->PixXYS.PixXY.C.x = VDestCol; + VPtPixXYSP->PixXYS.PixXY.C.y = VDestRow; + VPtPixXYSP->Region = VDestRegion; + VPtPixXYSP->SRegion = VDestSRegion; + + VPtPixXYSP->PeNoInMatrix = VDestPeNoInMatrix; + VPtPixXYSP->PeNoInRegion = VDestPeNoInRegion; + VPtPixXYSP->PeNoInSRegion = VDestPeNoInSRegion; + VPtPixXYSP->PeRow = VDestPeRow; + VPtPixXYSP->PeAddr = VDestPeAddr; + + } // End for ( VSrcICol ) + + } // End for ( VSrcIRow ) + + + return (0); + +} + +#ifdef CPY_TYPES_ + +typedef struct { + + MIS1__TPixXYS PixXYS; /*!< Pixel coordinates + state MIS1__TPixXYS */ + + SInt16 PeNoInMatrix; /*!< Priority encoder No in matrix => 0..MIS1__PE_NB-1 = 511 */ + SInt16 PeNoInRegion; /*!< Priority encoder No in region => 0..MIS1__PE_PER_REG-1 = 7 */ + SInt16 PeNoInSRegion; /*!< Priority encoder No in super region => 0..MIS1__PE_PER_SREG-1 = 31 */ + SInt16 PeRow; /*!< Priority encoder row => 0..MIS1__ROW_NB-1 = 503 */ + +} MIS1__TPixXYSP; + + +typedef struct { + + MIS1__TPixXY PixXY; /*!< Pixel coordinates MIS1__TPixXY */ + + SInt8 PixState; /*!< Pixel state 0 / 1 */ + +} MIS1__TPixXYS; + + +typedef union { + + SInt16 Axy[2]; /*!< Pixel coordinates array [0] = x, [1] = y */ + + struct { + SInt16 x; /*!< Pixel coordinates structure C.x, C.y */ + SInt16 y; + } C; + +} MIS1__TPixXY; + +#endif + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPeResetSetAll ( MIS1__TPe* PtPe, SInt8 ResetSetAll ) +* : +* \brief : Clears or fireds all pixels of a PE, for tests purpose +* : +* \param : PtPe - Pointer on PE +* : +* \param : ClearFireAll - 0 => Clears all pixels, 1 = Fires all pixels +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 14/05/2019 +* \date : Doc date : 14/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FPeResetSetAll ( MIS1__TPe* PtPe, SInt8 ResetSetAll ) { + + SInt32 VRet; + SInt16 ViRow; + + // Check param + + err_retnull ( PtPe, (ERR_OUT,"Abort => PtPe == NULL") ); + + // Clears / Fires + + for ( ViRow=0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + if ( ResetSetAll == 0 ) { + PtPe->AColLeft[ViRow] = 0; + PtPe->AColRight[ViRow] = 0; + } + + else { + PtPe->AColLeft[ViRow] = 1; + PtPe->AColRight[ViRow] = 1; + } + + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPeResetSetPix ( MIS1__TPe* PtPe, SInt8 PixState, UInt16 PixX, UInt16 PixY ) +* : +* \brief : Clears or fireds all pixels of a PE, for tests purpose +* : +* \param : PtPe - Pointer on PE +* : +* \param : PixState - Pixel state 0 / 1 +* +* \param : PixX - Pixel X coordinate = PE column = 0 (left) / 1 (right) +* : +* \param : PixY - Pixel Y coordinate = row +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 14/05/2019 +* \date : Doc date : 14/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FPeResetSetPix ( MIS1__TPe* PtPe, SInt8 PixState, UInt16 PixX, UInt16 PixY ) { + + SInt32 VRet; + SInt16 ViRow; + + // Check param + + err_retnull ( PtPe, (ERR_OUT,"Abort => PtPe == NULL") ); + + if ( PixX > 1 ) { + err_retfail ( -1, (ERR_OUT,"Abort => PixX = %d > 1", PixX ) ); + } + + if ( PixY >= MIS1__ROW_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => PixY = %d > %d", PixY, MIS1__ROW_NB - 1 ) ); + } + + // Clears / Fires pixel + + if ( PixX == 0 ) { + PtPe->AColLeft[PixY] = PixState; + } + + else { + PtPe->AColRight[PixY] = PixState; + } + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPePrint ( MIS1__TPe* PtPe, SInt16 PeReg, SInt8 PeNoInReg, UInt8 EncodeMth, UInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* : +* \brief : Prints PE states of MIS1__TPe structure +* : +* \param : PtPe - Pointer on PE +* : +* \param : PeReg - Region of PE (0..63) +* : +* \param : PeNoInReg - No of PE in region (0..7) +* : +* \param : EncodeMth - Encoding method (for future use) +* : +* \param : PrintDest - Print to ... 0 = No print, 1 = Msg file, 2 = Memo, 3 = Msg file + Memo +* : +* \param : Memo - Pointer to destination Memo if PrintDest = 2 or 3 +* : +* \param : PtFile - Pointer to destination text file if PrintDest = 4 or 5 +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 14/05/2019 +* \date : Doc date : 14/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FPePrint ( MIS1__TPe* PtPe, SInt16 PeReg, SInt8 PeNoInReg, UInt8 EncodeMth, UInt8 PrintMth, TMemo* Memo, FILE* PtFile ) { + + SInt32 VRet; + SInt16 ViRow; + SInt16 VPixRow; + SInt16 VPixColLeft; + SInt16 VPixColRight; + SInt16 VPixAddr; + SInt8 VPixColLeftState; + SInt8 VPixColRightState; + char VMsg[GLB_CMT_SZ]; + + + // Check param + + err_retnull ( PtPe, (ERR_OUT,"Abort => PtPe == NULL") ); + + if ( (EncodeMth >= 2) && (Memo == NULL) ) { + err_retfail ( -1, (ERR_OUT,"Abort => Print to memo requested BUT Memo = NULL !") ); + } + + + // Encodes PE, Pixels info + + + for ( ViRow=0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + switch ( EncodeMth ) { + + case 0 : { + VPixRow = ViRow; + VPixColLeft = (PeReg * MIS1__COL_PER_REG) + (PeNoInReg * 2); + VPixColRight = VPixColLeft + 1; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => Unknown EncodeMth = %d", EncodeMth) ); + break; } + } + + // Converts PE, Pixelsinfo to string + + if ( (PtPe->AColLeft[ViRow] == 1) || (PtPe->AColRight[ViRow] == 1) ) { + VPixColLeftState = PtPe->AColLeft[ViRow]; + VPixColRightState = PtPe->AColRight[ViRow]; + sprintf ( VMsg, "Region %.2d PE[%.1d,%.3d] = %d, %d = Pix [%.4d,%.3d]=%d, [%.4d,%.3d]=%d", PeReg, PeNoInReg, ViRow, VPixColLeftState, VPixColRightState, VPixColLeft, VPixRow, VPixColLeftState, VPixColRight, VPixRow, VPixColRightState ); + } + + // Prints + + MIS1__FPrintStr ( VMsg, PrintMth, Memo, PtFile ); + } + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPeConvRowCol2Addr ( UInt16 PeRow, UInt16 PeRegionCol, UInt8 Mode, UInt8 EncodeMth ) +* : +* \brief : Converts priority encoder Row, Col (in region) to address +* : +* \param : PeRow - PE row => 0..MIS1__ROW_NB-1 => 0..503 +* : +* \param : PeRegionCol - PE column in region => 0..MIS1__COL_PER_REG-1 => 0..15 +* +* \param : Mode - 0 = returns PE address corresponding to PeRow, PeRegionCol +* : - 1 = Initialize the lookup table +* : +* \param : EncodeMth - Encoding method, only 0 is used now +* : +* \return : Address or Error code +* : >= 0 - Address +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Before beeing used to convert (Mode = 0), it must be called one time with param Mode = 1 +* \warning : Level : +* : +* \warning : Item not filled now : +* \todo : Code is not finished (in fact not written) => Functions always returns -1 +* : +* bug : +* : +* \date : Date : 04/06/2019 +* \date : Doc date : 04/06/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FPeConvRowCol2Addr ( UInt16 PeRow, UInt16 PeRegionCol, UInt8 Mode, UInt8 EncodeMth ) { + + static SInt16 VAPeAdd[MIS1__PE_NB][MIS1__COL_PER_PE]; + UInt8 VPeCol; + + // ==================================================================== + // WARNING => Code not finsihed !!!!!!!!!!!!!!!!! + // ==================================================================== + + err_retfail ( -1, (ERR_OUT,"Code is not finished (in fact not written) => Functions always returns -1" ) ); + + // VPeCol = PeRegionCol % // Code not finished on 02/07/2019 + + // Convert + + if ( Mode == 0 ) { + // return ( VAPeAdd); + } + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPrintRawAcqFrMapTable ( MIS1__TAcqFrMap* SrcPtFrMap, UInt32 AcqId, SInt16 FirstFr, SInt16 LastFr, SInt8 PrintDecHex ) +* : +* \brief : Prints RAW frames map table info (fields data offset) of one acq for debug purpose +* +* \param : SrcPtFrMap - Pointer to the map table +* : +* \param : AcqId - Id of the acquisition, only for printing, not used to find info +* : +* \param : FirstFr - First frame to print +* : +* \param : LastFr - Last frame to print, \n +* set LastFr = -1 to display all frames starting at FirstFr \n +* set LastFr = FirstFr = -1 to disable frames list printing +* : +* \param : PrintDecHex - 0 => Print in decimal, 1 => Print in hex +* : +* \return : Error code +* : < 0 - Error +* : 0 - Not frames in this Acq => ??? +* : > 0 - Frames number in this Acq +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 09/04/2020 +* \date : Doc date : 09/04/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FPrintRawAcqFrMapTable ( MIS1__TAcqFrMap* SrcPtFrMap, UInt32 AcqId, SInt16 FirstFr, SInt16 LastFr, SInt8 PrintDecHex ) { + + UInt16 ViFr; + UInt16 VTotFrNb; + + // Check param + + err_retnull ( SrcPtFrMap, (ERR_OUT,"Abort => SrcPtFrMap == NULL") ); + + VTotFrNb = SrcPtFrMap->ResFrNb; + + if ( VTotFrNb == 0 ) { + msg (( MSG_OUT, "============================" )); + msg (( MSG_OUT, " No RAW frames in Acq No %d ", AcqId )); + msg (( MSG_OUT, "============================" )); + return (0); + } + + if ( FirstFr >= VTotFrNb ) { + err_retfail ( -1, (ERR_OUT,"Abort => FirstFr = %d > LastFr in table = %d", FirstFr, VTotFrNb - 1 ) ); + } + + if ( LastFr >= VTotFrNb ) { + err_retfail ( -1, (ERR_OUT,"Abort => LastFr = %d > LastFr in table = %d", LastFr, VTotFrNb - 1 ) ); + } + + // User wants to display all frames + + if ( LastFr == -1 ) { + LastFr = VTotFrNb - 1; + } + + // msg (( MSG_OUT, "Frames map : Par Acq No %.4d, Rec Acq No %d, Rec FrNb %d, Rec Acq sz %d W8, Acq pos %d W8", AcqId, SrcPtFrMap->ResAcqId, SrcPtFrMap->ResAcqSz, SrcPtFrMap->ResFrNb, SrcPtFrMap->ResAcqPos )); + + msg (( MSG_OUT, "=================================" )); + msg (( MSG_OUT, "RAW Frames map : Par Acq No %.4d, Rec Acq No %d, Rec FrNb %d", AcqId, SrcPtFrMap->ResAcqId, SrcPtFrMap->ResFrNb )); + msg (( MSG_OUT, "RAW Frames map : Rec Acq sz %d W8, Acq pos %d W8", SrcPtFrMap->ResAcqSz, SrcPtFrMap->ResAcqPos )); + msg (( MSG_OUT, "=================================" )); + msg (( MSG_OUT, "" )); + + + // User wants to display only acq info not fames list + + if ( (FirstFr == -1) && (LastFr == -1) ) { + return ( VTotFrNb ); + } + + + // Print offsets in decimal + + if ( PrintDecHex == 0 ) { + + for ( ViFr = FirstFr; ViFr <= LastFr; ViFr++ ) { + msg (( MSG_OUT, "==================================" )); + msg (( MSG_OUT, "RAW Fr No %.4d", ViFr )); + msg (( MSG_OUT, "----------------------------------" )); + msg (( MSG_OUT, "RAW Header = %.6d", SrcPtFrMap->ResAPosFrHead[ViFr] )); + msg (( MSG_OUT, "RAW Data = %.6d", SrcPtFrMap->ResAPosFrData[ViFr] )); + msg (( MSG_OUT, "RAW Trailer = %.6d", SrcPtFrMap->ResAPosFrTrail[ViFr] )); + msg (( MSG_OUT, "==================================" )); + } + + } + + // Print offsets in hexadecimal + + else { + + for ( ViFr = FirstFr; ViFr <= LastFr; ViFr++ ) { + msg (( MSG_OUT, "==================================" )); + msg (( MSG_OUT, "RAW Fr No %.4d", ViFr )); + msg (( MSG_OUT, "----------------------------------" )); + msg (( MSG_OUT, "RAW Header = %.6X", SrcPtFrMap->ResAPosFrHead[ViFr] )); + msg (( MSG_OUT, "RAW Data = %.6X", SrcPtFrMap->ResAPosFrData[ViFr] )); + msg (( MSG_OUT, "RAW Trailer = %.6X", SrcPtFrMap->ResAPosFrTrail[ViFr] )); + msg (( MSG_OUT, "==================================" )); + } + + + } + + return ( VTotFrNb ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPrintDecAcqFrMapTable ( MIS1__TDecFrMap* SrcPtFrMap, UInt32 AcqId, SInt16 FirstFr, SInt16 LastFr, SInt16 FrNbInAcq ) +* : +* \brief : Prints DEC frames map table info (fields data offset) of one acq for debug purpose +* +* \param : SrcPtFrMap - Pointer to the FIRST frame map table of the acq \n +* It is not like RAW acq map table, it is not one table listing all frames \n +* of the acq, there is one table for each frame, we provide pointer on the \n +* first table of the acq. +* : +* \param : AcqId - Id of the acquisition, only for printing, not used to find info +* : +* \param : FirstFr - First frame to print +* : +* \param : LastFr - Last frame to print, \n +* set LastFr = -1 to display all frames starting at FirstFr \n +* +* \param : FrNbInAcq - Frames n b in the acq, to check param FirstFr, LastFr +* : +* \return : Error code +* : < 0 - Error +* : 0 - No frames in this Acq => ??? +* : > 0 - Frames number in this Acq +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 11/06/2020 +* \date : Doc date : 11/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FPrintDecAcqFrMapTable ( MIS1__TDecFrMap* SrcPtFrMap, UInt32 AcqId, SInt16 FirstFr, SInt16 LastFr, SInt16 FrNbInAcq ) { + + UInt16 ViFr; + MIS1__TDecFrMap* VSrcPtFrMap; + + // Check param + + err_retnull ( SrcPtFrMap, (ERR_OUT,"Abort => SrcPtFrMap == NULL") ); + + + if ( FrNbInAcq == 0 ) { + msg (( MSG_OUT, "============================" )); + msg (( MSG_OUT, " No DEC frames in Acq No %d ", AcqId )); + msg (( MSG_OUT, "============================" )); + return (0); + } + + if ( FirstFr >= FrNbInAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort => FirstFr = %d > LastFr in table = %d", FirstFr, FrNbInAcq - 1 ) ); + } + + if ( LastFr >= FrNbInAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort => LastFr = %d > LastFr in table = %d", LastFr, FrNbInAcq - 1 ) ); + } + + // User wants to display all frames + + if ( LastFr == -1 ) { + LastFr = FrNbInAcq - 1; + } + + + // Print + + for ( ViFr = FirstFr; ViFr <= LastFr; ViFr++ ) { + + VSrcPtFrMap = &SrcPtFrMap[ViFr]; + + // Check ptr + + if ( VSrcPtFrMap == NULL ) { + msg (( MSG_OUT, "============================" )); + msg (( MSG_OUT, "DEC frame map listing stops on FR = %d not available (FrMap ptr == NULL) ", ViFr )); + msg (( MSG_OUT, "============================" )); + break; + } + + // Display + + msg (( MSG_OUT, "==================================" )); + msg (( MSG_OUT, "DEC Fr No = %.4d info", ViFr )); + msg (( MSG_OUT, "----------------------------------" )); + msg (( MSG_OUT, "DEC Acq id in run = %.4d", VSrcPtFrMap->ResAcqIdInRun )); // Id of acquisition + msg (( MSG_OUT, "DEC Fr nb in acq = %.4d", VSrcPtFrMap->ResFrNbInAcq )); + msg (( MSG_OUT, "DEC Fr id in acq = %.4d", VSrcPtFrMap->ResFrIdInAcq )); // Id frame in its acquisition 0 to max fr nb per acq - 1 + msg (( MSG_OUT, "DEC Pixels data size = %.4d", VSrcPtFrMap->ResFrSz )); // Size of frame in W8 + msg (( MSG_OUT, "DEC ResPtFrBeg = %.8X", VSrcPtFrMap->ResPtFrBeg )); + msg (( MSG_OUT, "==================================" )); + + + } + + + return (FrNbInAcq); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FAcqFrMapToAcqFrList ( UInt8* PtU8AcqBeg, MIS1__TAcqFrMap* SrcPtFrMap, MIS1__TAcqFrList* DestPtFrList, UInt32 AcqId ) +* +* \brief : Prints frames map table info (fields data offset) of one acq for debug purpose +* +* \param : SrcPtFrMap - Pointer to the source map table +* : +* \param : DestPtFrList - Pointer to the destination frames list +* : +* \param : AcqId - Id of the acquisition, only for debug printing, not used for processing +* : +* \return : Error code +* : < 0 - Error. Rq : No frame in this Acq is ans error. +* : > 0 - Frames number in this Acq +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 09/04/2020 +* \date : Doc date : 09/04/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FAcqFrMapToAcqFrList ( UInt8* PtU8AcqBeg, MIS1__TAcqFrMap* SrcPtFrMap, MIS1__TAcqFrList* DestPtFrList, UInt32 AcqId ) { + + UInt16 ViFr; + UInt16 VTotFrNb; + + // Check param + + err_retnull ( PtU8AcqBeg, (ERR_OUT,"Abort => PtU8AcqBeg == NULL") ); + + err_retnull ( SrcPtFrMap, (ERR_OUT,"Abort => SrcPtFrMap == NULL") ); + + err_retnull ( DestPtFrList, (ERR_OUT,"Abort => DestPtFrList == NULL") ); + + + VTotFrNb = SrcPtFrMap->ResFrNb; + + if ( VTotFrNb == 0 ) { + err_retfail ( -1, (ERR_OUT,"No frame in Acq No %d", AcqId) ); + } + + // Reset frames list + + memset ( DestPtFrList, 0, sizeof (MIS1__TAcqFrList) ); + + // Build the list + + for ( ViFr = 0; ViFr < VTotFrNb; ViFr++ ) { + + DestPtFrList->ResAPtFrHead[ViFr] = (void*) ( (UInt32) PtU8AcqBeg + SrcPtFrMap->ResAPosFrHead[ViFr]); + DestPtFrList->ResAPtFrData[ViFr] = (void*) ( (UInt32) PtU8AcqBeg + SrcPtFrMap->ResAPosFrData[ViFr]); + DestPtFrList->ResAPtFrTrail[ViFr] = (void*) ( (UInt32) PtU8AcqBeg + SrcPtFrMap->ResAPosFrTrail[ViFr]); + } + + DestPtFrList->ResFrNb = VTotFrNb; + + return ( VTotFrNb ); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunInfBuild ( MIS1__TRunPar* PtPar, MIS1__TRunInf* PtInf ) +* +* \brief : Get run parameters from GUI. +* +* \param : PtPar - Pointer on run param record +* +* \param : PtInf - Pointer on run info record +* : +* \return : Error code +* : < 0 - Error +* : 0 - OK +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 11/05/2020 +* \date : Doc date : 11/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunInfBuild ( MIS1__TRunPar* PtPar, MIS1__TRunInf* PtInf ) { + + // Check param + + err_retnull ( PtPar, (ERR_OUT,"Abort => PtPar == NULL") ); + err_retnull ( PtInf, (ERR_OUT,"Abort => PtInf == NULL") ); + + // Build info + + PtInf->InfSave = PtPar->ParSaveRaw || PtPar->ParSaveDec || PtPar->ParSaveFPC; + + sprintf ( PtInf->InfRunDir, "%s\\%d", PtPar->ParRunRootDir, PtPar->ParRunNo ); + + sprintf ( PtInf->InfSCFileName, "%s\\%s_%d_slow_ctrl.bin", PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + sprintf ( PtInf->InfRunConfFileName, "%s\\%s_%d_run_conf.bin", PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + sprintf ( PtInf->InfRunStatusFileName, "%s\\%s_%d_run_status.bin", PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + + sprintf ( PtInf->InfRawIndexFileName, "%s\\%s_%d_raw_index.bin", PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + sprintf ( PtInf->InfRawDataFileName , "%s\\%s_%d_raw_data.bin", PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + + sprintf ( PtInf->InfDecIndexFileName, "%s\\%s_%d_dec_index.bin", PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + sprintf ( PtInf->InfDecDataFileName, "%s\\%s_%d_dec_data.bin", PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + + sprintf ( PtInf->InfFPCSubStepsFileName, "%s\\%s_%d_fpc_substeps.bin" , PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + sprintf ( PtInf->InfFPCStepFileName , "%s\\%s_%d_fpc_step.bin" , PtInf->InfRunDir, PtPar->ParRunPrefix, PtPar->ParRunNo ); + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunParamPrint ( MIS1__TRunPar* PtPar, MIS1__TRunInf* PtInf ) +* : +* \brief : Print run parameters in log file. +* +* \param : PtPar - Pointer on run param record +* : +* \param : PtInf - Pointer on run info record +* : +* \return : Error code +* : < 0 - Error +* : 0 - OK +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 11/05/2020 +* \date : Doc date : 11/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunParamInfPrint ( MIS1__TRunPar* PtPar, MIS1__TRunInf* PtInf ) { + + // Check param + + err_retnull ( PtPar, (ERR_OUT,"Abort => PtPar == NULL") ); + err_retnull ( PtInf, (ERR_OUT,"Abort => PtInf == NULL") ); + + // Print + + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, " Run parameters" )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "File format : %X", PtPar->FileFormat )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, " General parameters" )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "Allow RC : %d", PtPar->ParAllowRc )); + msg (( MSG_OUT, "Run prefix : %s", PtPar->ParRunPrefix )); + msg (( MSG_OUT, "Run No : %d", PtPar->ParRunNo )); + msg (( MSG_OUT, "Tot fr nb : %d", PtPar->ParTotFrNb )); + msg (( MSG_OUT, "Run forever : %d", PtPar->ParRunForever )); + msg (( MSG_OUT, "Fr nb / Acq : %d", PtPar->ParFrNbPerAcq )); + msg (( MSG_OUT, "Buff Acq nb : %d", PtPar->ParBufferedAcqNb )); + msg (( MSG_OUT, "Acq nb / file : %d", PtPar->ParAcqNbPerFile )); + msg (( MSG_OUT, "Fr nb / file (not used): %d", PtPar->ParFrNbPerFile )); + msg (( MSG_OUT, "Proc mode : %d", (UInt32) PtPar->ParProcMode )); + msg (( MSG_OUT, "Proc print level : %d", PtPar->ParProcPrintLvl )); + msg (( MSG_OUT, "Root dir : %s", PtPar->ParRunRootDir )); + msg (( MSG_OUT, "Save raw : %d", PtPar->ParSaveRaw )); + msg (( MSG_OUT, "Save decoded : %d", PtPar->ParSaveDec )); + msg (( MSG_OUT, "Decoded format : %d", PtPar->ParDecFormat )); + msg (( MSG_OUT, "Save fired pix count : %d", PtPar->ParSaveFPC )); + msg (( MSG_OUT, "Processing enabled : %d", PtPar->ParProc )); + msg (( MSG_OUT, "----------------------------------------------" )); + + if ( PtPar->ParCarMode > 0 ) { + + msg (( MSG_OUT, " Characterization parameters" )); + msg (( MSG_OUT, "Characterisation mode : %d", PtPar->ParCarMode )); + msg (( MSG_OUT, "Thresholds steps nb : %d", PtPar->ParCarStepNb )); + msg (( MSG_OUT, "Sub steps nb : %d", PtPar->ParCarSubStepNb )); + msg (( MSG_OUT, "Fr nb / sub step : %d", PtPar->ParCarSubStepFrNb )); + msg (( MSG_OUT, "Acq nb / sub step : %d", PtPar->ParCarSubStepAcqNb )); + msg (( MSG_OUT, "Fr nb / Acq : %d", PtPar->ParCarFrNbPerAcq )); + msg (( MSG_OUT, "Fields not printed" )); + msg (( MSG_OUT, " - ParCarAAStepTh [][]")); + msg (( MSG_OUT, " - ParCarSubStepConfId[]" )); + + } + + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, " Info built from run parameters" )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "Save data : %d", PtInf->InfSave )); + msg (( MSG_OUT, "Run dir : %s", PtInf->InfRunDir )); + msg (( MSG_OUT, "SC file : %s", PtInf->InfSCFileName )); + msg (( MSG_OUT, "File raw index : %s", PtInf->InfRawIndexFileName )); + msg (( MSG_OUT, "File raw data : %s", PtInf->InfRawDataFileName )); + msg (( MSG_OUT, "File decoded index : %s", PtInf->InfDecIndexFileName )); + msg (( MSG_OUT, "File decoded data : %s", PtInf->InfDecDataFileName )); + msg (( MSG_OUT, "File FPC sub steps : %s", PtInf->InfFPCSubStepsFileName )); + msg (( MSG_OUT, "File FPC step : %s", PtInf->InfFPCStepFileName )); + msg (( MSG_OUT, "==============================================" )); + + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunConfFileSave ( char* FilePath, MIS1__TRunConf* PtConf ) +* +* \brief : Save the run configuration in a binary file +* +* \param : FilePath - Name of file, full path +* +* \param : PtConf - Pointer to the record to save +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2020 +* \date : Doc date : 25/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FRunConfFileSave ( char* FilePath, MIS1__TRunConf* PtConf ) { + + SInt32 VRet; + + // Check param + + err_retnull ( FilePath, (ERR_OUT,"Abort => FilePath == NULL") ); + + err_retnull ( PtConf, (ERR_OUT,"Abort => PtConf == NULL") ); + + // Set file format tag + + PtConf->RunPar.FileFormat = MIS1__RUN_CONF_FFORMAT_TAG; + + // Save record + + VRet = FIL_FWriteRecord ( FilePath, PtConf, sizeof (MIS1__TRunConf) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Save run conf file = %s failed !", FilePath) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunConfFileLoad ( char* FilePath, MIS1__TRunConf* PtConf ) +* +* \brief : Load the run configuration from a binary file +* +* \param : FilePath - Name of file, full path +* +* \param : PtConf - Pointer to the destination record +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2020 +* \date : Doc date : 25/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FRunConfFileLoad ( char* FilePath, MIS1__TRunConf* PtConf ) { + + SInt32 VRet; + + // Check param + + err_retnull ( FilePath, (ERR_OUT,"Abort => FilePath == NULL") ); + + err_retnull ( PtConf, (ERR_OUT,"Abort => PtConf == NULL") ); + + // Load record + + VRet = FIL_FReadRecord ( FilePath, PtConf, sizeof (MIS1__TRunConf) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load run conf file = %s failed !", FilePath) ); + + // Check file format tag + + + if ( PtConf->RunPar.FileFormat != MIS1__RUN_CONF_FFORMAT_TAG ) { + err_retfail ( -1, (ERR_OUT,"Abort => Bad file format = %X <> Expected = %X", PtConf->RunPar.FileFormat, MIS1__RUN_CONF_FFORMAT_TAG) ) + } + + + err_retok (( ERR_OUT, "" )); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunStatusPrint ( MIS1__TRunStatus* PtStatus ) +* +* \brief : Print run parameters in log file. +* +* \param : PtPar - Pointer on run param record +* +* \param : PtInf - Pointer on run info record +* +* \return : Error code \n +* : < 0 - Error \n +* : 0 - OK \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2020 +* \date : Doc date : 25/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunStatusPrint ( MIS1__TRunStatus* PtStatus ) { + + // Check param + + err_retnull ( PtStatus, (ERR_OUT,"Abort => PtStatus == NULL") ); + + + // Print + + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, " Run status" )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "File format : %X", PtStatus->FileFormat )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "ParGuiUpdRate : %d", PtStatus->ParGuiUpdRate )); + msg (( MSG_OUT, "ParUpdOnlyAcqErrCnt : %d", PtStatus->ParUpdOnlyAcqErrCnt )); + msg (( MSG_OUT, "ParOptDaqSpeed : %d", PtStatus->ParOptDaqSpeed )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "ResRunInProgress : %d", PtStatus->ResRunInProgress )); + msg (( MSG_OUT, "ResAcqCnt : %d", PtStatus->ResAcqCnt )); + msg (( MSG_OUT, "ResFrCnt : %d", PtStatus->ResFrCnt )); + msg (( MSG_OUT, "ResAcqRateHz : %.1f", PtStatus->ResAcqRateHz )); + msg (( MSG_OUT, "ResFrRateHz : %.1f", PtStatus->ResFrRateHz )); + msg (( MSG_OUT, "ResMSis1FrRateHz : %.1f", PtStatus->ResMSis1FrRateHz )); + msg (( MSG_OUT, "ResDaqEffPCent : %.1f", PtStatus->ResDaqEffPCent )); + msg (( MSG_OUT, "ResFrNbInCurAcq : %d", PtStatus->ResFrNbInCurAcq )); + msg (( MSG_OUT, "==============================================" )); + + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunStatusFileSave ( char* FilePath, MIS1__TRunStatus* PtStatus ) +* +* \brief : Save the run configuration in a binary file +* +* \param : FilePath - Name of file, full path +* +* \param : PtStatus - Pointer to the record to save +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2020 +* \date : Doc date : 25/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FRunStatusFileSave ( char* FilePath, MIS1__TRunStatus* PtStatus ) { + + SInt32 VRet; + + // Check param + + err_retnull ( FilePath, (ERR_OUT,"Abort => FilePath == NULL") ); + + err_retnull ( PtStatus, (ERR_OUT,"Abort => PtStatus == NULL") ); + + // Set file format tag + + PtStatus->FileFormat = MIS1__RUN_STATUS_FFORMAT_TAG; + + // Save record + + VRet = FIL_FWriteRecord ( FilePath, PtStatus, sizeof (MIS1__TRunStatus) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Save run status file = %s failed !", FilePath) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunStatusFileLoad ( char* FilePath, MIS1__TRunStatus* PtStatus ) +* +* \brief : Load the run configuration from a binary file +* +* \param : FilePath - Name of file, full path +* +* \param : PtStatus - Pointer to the destination record +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2020 +* \date : Doc date : 25/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FRunStatusFileLoad ( char* FilePath, MIS1__TRunStatus* PtStatus ) { + + SInt32 VRet; + + // Check param + + err_retnull ( FilePath, (ERR_OUT,"Abort => FilePath == NULL") ); + + err_retnull ( PtStatus, (ERR_OUT,"Abort => PtStatus == NULL") ); + + // Load record + + VRet = FIL_FReadRecord ( FilePath, PtStatus, sizeof (MIS1__TRunStatus) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load run status file = %s failed !", FilePath) ); + + // Check file format tag + + if ( PtStatus->FileFormat != MIS1__RUN_STATUS_FFORMAT_TAG ) { + err_retfail ( -1, (ERR_OUT,"Abort => Bad file format = %X <> Expected = %X", PtStatus->FileFormat, MIS1__RUN_STATUS_FFORMAT_TAG) ) + } + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesBegin ( UInt8 ObjId = 0 ) +* +* \brief : Initialize run files records, objects, needed to access to run files +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2020 +* \date : Doc date : 25/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + + +#ifdef MIS1__CC_DATA_FORMAT_SINCE_V211 + +SInt32 MIS1__FRunFilesBegin ( char* ErrLogFile, SInt8 ErrLogLvl, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + + // Check param + + if ( ObjId >= MIS1__MAX_RUN_FILES ) { + err_retfail ( -1, (ERR_OUT,"Abort => ObjId = %d out of range [0..%d]", ObjId, MIS1__MAX_RUN_FILES - 1) ); + } + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Reset record + + memset ( VPtRF, 0, sizeof (MIS1__TRunFiles) ); + + // Init fields + + VPtRF->RawLoadedFileSuffix = -1; + VPtRF->DecLoadedFileSuffix = -1; + VPtRF->FpcStepLoadedFileSuffix = -1; + VPtRF->FpcSubStepLoadedFileSuffix = -1; + + VPtRF->RawCurAcqId = -1; + VPtRF->RawCurFrId = -1; + + VPtRF->DecCurAcqId = -1; + VPtRF->DecCurFrId = -1; + + VPtRF->FpcCurStepId = -1; + VPtRF->FpcCurSubStepId = -1; + + + VPtRF->RawCurAcqFileSuffix = -1; + + VPtRF->DecCurAcqFileSuffix = -1; + + VPtRF->FpcCurStepFileSuffix = -1; + + VPtRF->FpcCurSubStepFileSuffix = -1; + + + // Init OBuff objects IDs + + VPtRF->RawFBuffIndexId = ObjId * MIS1__MAX_OBUFF_PER_RUN_FILES; + VPtRF->RawFBuffDataId = VPtRF->RawFBuffIndexId + 1; + + + VPtRF->DecFBuffIndexId = VPtRF->RawFBuffIndexId + 2; + VPtRF->FBuffDecDataId = VPtRF->RawFBuffIndexId + 3; + + + + // Create RAW data files objects + // - Index file + + VRet = BF__FOBuffInit ( VPtRF->RawFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create OBuff for raw index file, ObjId = %d failed !", ObjId) ); + + // Create RAW data files objects + // - Data file + + VRet = BF__FOBuffInit ( VPtRF->RawFBuffDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create OBuff for raw data file, ObjId = %d failed !", ObjId) ); + + + + // Create DEC data files objects + // - Index file + + VRet = BF__FOBuffInit ( VPtRF->DecFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create OBuff for Dec index file, ObjId = %d failed !", ObjId) ); + + // Create DEC data files objects + // - Data file + + VRet = BF__FOBuffInit ( VPtRF->FBuffDecDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create OBuff for Dec data file, ObjId = %d failed !", ObjId) ); + + // ----------------------------------- + // Create FPC data files objects + // ----------------------------------- + + // Init ptr + + VPtRF->PtFPCSubStepsBinFile = &MIS1__VGFPCSubStepsBinFile; + VPtRF->PtFPCStepBinFile = &MIS1__VGFPCStepBinFile; + + // Init objects + + VRet = VPtRF->PtFPCSubStepsBinFile->PubFBegin ( ErrLogFile, 1 /* EnableErrLog */, ErrLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create TCBinFile for sub steps data file, ObjId = %d failed !", ObjId) ); + + VRet = VPtRF->PtFPCStepBinFile->PubFBegin ( ErrLogFile, 1 /* EnableErrLog */, ErrLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create TCBinFile for steps data file, ObjId = %d failed !", ObjId) ); + + // Configure objects + + VRet = VPtRF->PtFPCSubStepsBinFile->PubFConf ( "" /* DataFile */, FIL__TCBinFile_RWB_MODE_READ, sizeof (MIS1__TMatPixCntU16) /* MaxBlocSz */, sizeof (MIS1__TMatPixCntU16) /* BlocSz */, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Conf TCBinFile for steps data file, ObjId = %d failed !", ObjId) ); + + VRet = VPtRF->PtFPCStepBinFile->PubFConf ( "" /* DataFile */, FIL__TCBinFile_RWB_MODE_READ, sizeof (MIS1__TMatPixCntU16) /* MaxBlocSz */, sizeof (MIS1__TMatPixCntU16) /* BlocSz */, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Conf TCBinFile for sub steps data file, ObjId = %d failed !", ObjId) ); + + + // Init done + + VPtRF->FBeginDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + +#else + + +SInt32 MIS1__FRunFilesBegin ( UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + + // Check param + + if ( ObjId >= MIS1__MAX_RUN_FILES ) { + err_retfail ( -1, (ERR_OUT,"Abort => ObjId = %d out of range [0..%d]", ObjId, MIS1__MAX_RUN_FILES - 1) ); + } + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Reset record + + memset ( VPtRF, 0, sizeof (MIS1__TRunFiles) ); + + // Init fields + + VPtRF->RawLoadedFileSuffix = -1; + VPtRF->DecLoadedFileSuffix = -1; + + VPtRF->RawCurAcqId = -1; + VPtRF->RawCurFrId = -1; + + VPtRF->DecCurAcqId = -1; + VPtRF->DecCurFrId = -1; + + + VPtRF->RawCurAcqFileSuffix = -1; + + + VPtRF->DecCurAcqFileSuffix = -1; + + // Init OBuff objects IDs + + VPtRF->RawFBuffIndexId = ObjId * MIS1__MAX_OBUFF_PER_RUN_FILES; + VPtRF->RawFBuffDataId = VPtRF->RawFBuffIndexId + 1; + + + VPtRF->DecFBuffIndexId = VPtRF->RawFBuffIndexId + 2; + VPtRF->FBuffDecDataId = VPtRF->RawFBuffIndexId + 3; + + + + // Create RAW data files objects + // - Index file + + VRet = DAMIS1__FOBuffInit ( VPtRF->RawFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create OBuff for raw index file, ObjId = %d failed !", ObjId) ); + + // Create RAW data files objects + // - Data file + + VRet = DAMIS1__FOBuffInit ( VPtRF->RawFBuffDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create OBuff for raw data file, ObjId = %d failed !", ObjId) ); + + + + // Create DEC data files objects + // - Index file + + VRet = DAMIS1__FOBuffInit ( VPtRF->DecFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create OBuff for Dec index file, ObjId = %d failed !", ObjId) ); + + // Create DEC data files objects + // - Data file + + VRet = DAMIS1__FOBuffInit ( VPtRF->FBuffDecDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create OBuff for Dec data file, ObjId = %d failed !", ObjId) ); + + + + VPtRF->FBeginDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + +#endif + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesOpen ( char* RunConfFile, SInt8 ReadRaw, SInt8 ReadDec, SInt8 ReadFP, UInt8 ObjId = 0 ) +* +* \brief : Open a raw data run file = load conf, status files, allocate buffers +* +* \param : RunConfFile - Run config file, ex : MSIS1_777_run_conf.bin +* +* \param : ReadRaw - The run raw data files will be loaded, please read remark +* +* \param : ReadDec - The run decoded data files will be loaded, please read remark +* +* \param : ReadFP - The run fired pixels data files will be loaded, please read remark +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : One or all modes ReadRaw, ReadDec, ReadFP can be enabled \n +* but each mode requires memory => don't enable unsed modes +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2020 +* \date : Doc date : 25/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +#ifdef MIS1__CC_DATA_FORMAT_SINCE_V211 + +SInt32 MIS1__FRunFilesOpen ( char* RunConfFile, SInt8 ReadRaw, SInt8 ReadDec, SInt8 ReadFP, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + // Check param + + if ( ObjId >= MIS1__MAX_RUN_FILES ) { + err_retfail ( -1, (ERR_OUT,"Abort => ObjId = %d out of range [0..%d]", ObjId, MIS1__MAX_RUN_FILES - 1) ); + } + + err_retnull ( RunConfFile, (ERR_OUT,"Abort => RunRootDir == NULL") ); + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesBegin () has been called + + if ( VPtRF->FBeginDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesBegin () has not been called !") ); + } + + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Load run conf file + + VRet = MIS1__FRunConfFileLoad ( RunConfFile, VPtRConf ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load run conf file = %s failed !", RunConfFile) ); + + // Load run status + + VRet = MIS1__FRunStatusFileLoad ( VPtRInf->InfRunStatusFileName, VPtRStatus ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load run status file = %s failed !", VPtRInf->InfRunStatusFileName) ); + + // Calculate Acq max sz + + VPtRF->AcqMaxSzW64 = MIS1__DS_TOT_FRAME_SZ_W64 * VPtRPar->ParFrNbPerAcq; + + VPtRF->AcqMaxSzW8 = MIS1__DS_TOT_FRAME_SZ_W8 * VPtRPar->ParFrNbPerAcq; + + + // Alloc RAW data files objects + + if ( ReadRaw == 1 ) { + + // - Index file + + // 600 VRet = DAMIS1__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParBufferedAcqNb * sizeof (MIS1__TAcqFrMap) / 8 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffIndexId ); + + VRet = BF__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParAcqNbPerFile * sizeof (MIS1__TAcqFrMap) /* BuffW8Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffIndexId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Alloc OBuff for raw index file, ObjId = %d failed !", ObjId) ); + + // Alloc RAW data files objects + // - Data file + + // 600 VRet = DAMIS1__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParBufferedAcqNb * VPtRF->AcqMaxSzW64 / 8 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffDataId ); + + VRet = BF__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParAcqNbPerFile * VPtRF->AcqMaxSzW64 /* BuffW8Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffDataId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Alloc OBuff for raw file, ObjId = %d failed !", ObjId) ); + + } // End if ( ReadRaw == 1 ) + + + + + + // Alloc DEC data files objects + + if ( ReadDec == 1 ) { + + // - Index file + + // 600 VRet = DAMIS1__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParBufferedAcqNb * VPtRPar->ParFrNbPerAcq * sizeof (MIS1__TDecFrMap) / 8 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->DecFBuffIndexId ); + + VRet = BF__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParAcqNbPerFile * VPtRPar->ParFrNbPerAcq * sizeof (MIS1__TDecFrMap) /* BuffW8Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->DecFBuffIndexId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Alloc OBuff for dec index file, ObjId = %d failed !", ObjId) ); + + // Alloc DEC data files objects + // - Data file + + // 600 VRet = DAMIS1__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParBufferedAcqNb * VPtRPar->ParFrNbPerAcq * sizeof (MIS1__TDecFrPix) / 8 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->FBuffDecDataId ); + + VRet = BF__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParAcqNbPerFile * VPtRPar->ParFrNbPerAcq * sizeof (MIS1__TDecFrPix) /* BuffW8Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->FBuffDecDataId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Alloc OBuff for dec file, ObjId = %d failed !", ObjId) ); + + } // End if ( ReadRaw == 1 ) + + + + VPtRF->FOpenDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + +#else + +SInt32 MIS1__FRunFilesOpen ( char* RunConfFile, SInt8 ReadRaw, SInt8 ReadDec, SInt8 ReadFP, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + // Check param + + if ( ObjId >= MIS1__MAX_RUN_FILES ) { + err_retfail ( -1, (ERR_OUT,"Abort => ObjId = %d out of range [0..%d]", ObjId, MIS1__MAX_RUN_FILES - 1) ); + } + + err_retnull ( RunConfFile, (ERR_OUT,"Abort => RunRootDir == NULL") ); + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesBegin () has been called + + if ( VPtRF->FBeginDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesBegin () has not been called !") ); + } + + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Load run conf file + + VRet = MIS1__FRunConfFileLoad ( RunConfFile, VPtRConf ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load run conf file = %s failed !", RunConfFile) ); + + // Load run status + + VRet = MIS1__FRunStatusFileLoad ( VPtRInf->InfRunStatusFileName, VPtRStatus ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load run status file = %s failed !", VPtRInf->InfRunStatusFileName) ); + + // Calculate Acq max sz + + VPtRF->AcqMaxSzW64 = MIS1__DS_TOT_FRAME_SZ_W64 * VPtRPar->ParFrNbPerAcq; + + VPtRF->AcqMaxSzW8 = MIS1__DS_TOT_FRAME_SZ_W8 * VPtRPar->ParFrNbPerAcq; + + + // Alloc RAW data files objects + + if ( ReadRaw == 1 ) { + + // - Index file + + VRet = DAMIS1__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParAcqNbPerFile * sizeof (MIS1__TAcqFrMap) / 8 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Alloc OBuff for raw index file, ObjId = %d failed !", ObjId) ); + + // Alloc RAW data files objects + // - Data file + + VRet = DAMIS1__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParAcqNbPerFile * VPtRF->AcqMaxSzW64 / 8 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Alloc OBuff for raw file, ObjId = %d failed !", ObjId) ); + + } // End if ( ReadRaw == 1 ) + + + + + + // Alloc DEC data files objects + + if ( ReadDec == 1 ) { + + // - Index file + + VRet = DAMIS1__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParAcqNbPerFile * VPtRPar->ParFrNbPerAcq * sizeof (MIS1__TDecFrMap) / 8 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->DecFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Alloc OBuff for dec index file, ObjId = %d failed !", ObjId) ); + + // Alloc DEC data files objects + // - Data file + + VRet = DAMIS1__FOBuffAllocFree ( 1 /* FreeAlloc */, VPtRPar->ParAcqNbPerFile * VPtRPar->ParFrNbPerAcq * sizeof (MIS1__TDecFrPix) / 8 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->FBuffDecDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Alloc OBuff for dec file, ObjId = %d failed !", ObjId) ); + + } // End if ( ReadRaw == 1 ) + + + + VPtRF->FOpenDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + +#endif + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesPrintConf ( UInt8 ObjId = 0 ) +* +* \brief : Print run config file +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 26/05/2020 +* \date : Doc date : 26/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesPrintConf ( UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + VRet = MIS1__FRunParamInfPrint ( VPtRPar, VPtRInf ); + + err_retfail ( VRet, (ERR_OUT,"Abort => MIS1__FRunParamInfPrint (...) failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesPrintStatus ( UInt8 ObjId = 0 ) +* +* \brief : Print run status file +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 26/05/2020 +* \date : Doc date : 26/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesPrintStatus ( UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + VRet = MIS1__FRunStatusPrint ( VPtRStatus ); + + err_retfail ( VRet, (ERR_OUT,"Abort => MIS1__FRunStatusPrint (...) failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesGetAcqFrNb ( UInt32* PtAcqNb, UInt32* PtFrNb, UInt8 ObjId = 0 ) +* +* \brief : Print run status file +* +* \param : PtAcqNb - Pointer to acq number +* +* \param : PtFrNb - Pointer to frames number +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 30/05/2020 +* \date : Doc date : 30/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesGetAcqFrNb ( UInt32* PtAcqNb, UInt32* PtFrNb, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunStatus* VPtRStatus; + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Update results + + if ( PtAcqNb != NULL ) { + *PtAcqNb = VPtRStatus->ResAcqCnt; + } + + + if ( PtFrNb != NULL ) { + *PtFrNb = VPtRStatus->ResFrCnt; + } + + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesRawPrivFindAcq ( SInt32 AcqId, UInt8 ObjId = 0 ) +* +* \brief : Private function, calculate info needed to access to AcqId, file No, etc ... +* +* \param : AcqId - The no, id of the aquisition +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 27/05/2020 +* \date : Doc date : 27/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesRawPrivFindAcq ( SInt32 AcqId, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + // Check AcqId + + err_retfail ( AcqId, (ERR_OUT,"Abort => AcqId = %d < 0 !", AcqId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Set AcqId, FrId + + VPtRF->RawCurAcqId = AcqId; + VPtRF->RawCurFrId = 0; // Set first frame by default + + // Check if AcqId is in run files + + if ( AcqId >= VPtRStatus->ResAcqCnt ) { + VPtRF->RawCurAcqFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => AcqId = %d > Run acq nb = %d", AcqId, VPtRStatus->ResAcqCnt ) ); + } + + + // Calculate info + + VPtRF->RawCurAcqFileSuffix = AcqId / VPtRPar->ParAcqNbPerFile; + VPtRF->RawCurAcqIdInFile = AcqId % VPtRPar->ParAcqNbPerFile; + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesDecPrivFindAcq ( SInt32 AcqId, UInt8 ObjId = 0 ) +* +* \brief : Private function, calculate info needed to access to AcqId, file No, etc ... +* +* \param : AcqId - The no, id of the aquisition +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 10/06/2020 +* \date : Doc date : 10/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesDecPrivFindAcq ( SInt32 AcqId, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + // Check AcqId + + err_retfail ( AcqId, (ERR_OUT,"Abort => AcqId = %d < 0 !", AcqId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Set AcqId, FrId + + VPtRF->DecCurAcqId = AcqId; + VPtRF->DecCurFrId = 0; // Set first frame by default + + // Check if AcqId is in run files + + if ( AcqId >= VPtRStatus->ResAcqCnt ) { + VPtRF->DecCurAcqFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => AcqId = %d > Run acq nb = %d", AcqId, VPtRStatus->ResAcqCnt ) ); + } + + + // Calculate info + + VPtRF->DecCurAcqFileSuffix = AcqId / VPtRPar->ParAcqNbPerFile; + VPtRF->DecCurAcqIdInFile = AcqId % VPtRPar->ParAcqNbPerFile; + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesPrivFindFr ( SInt32 FrId, UInt8 ObjId = 0 ) +* +* \brief : Private function, calculate info needed to access to AcqId, file No, etc ... +* +* \param : FrId - The no of the frame +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 27/05/2020 +* \date : Doc date : 27/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesRawPrivFindFr ( SInt32 FrId, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + err_retfail ( FrId, (ERR_OUT,"Abort => This function has not been checked !") ); + + + // Check AcqId + + err_retfail ( FrId, (ERR_OUT,"Abort => FrId = %d < 0 !", FrId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + + // Set AcqId, FrId + + VPtRF->RawCurAcqId = FrId / VPtRPar->ParFrNbPerAcq; + VPtRF->RawCurFrId = FrId; + + // Check if FrId is in run files + + if ( FrId >= VPtRStatus->ResFrCnt ) { + VPtRF->RawCurAcqFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => FrId = %d > Run fr nb = %d", FrId, VPtRStatus->ResFrCnt ) ); + } + + // Calculate info + + VPtRF->RawCurAcqFileSuffix = VPtRF->RawCurAcqId / VPtRPar->ParAcqNbPerFile; + VPtRF->RawCurAcqIdInFile = VPtRF->RawCurAcqId % VPtRPar->ParAcqNbPerFile; + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesDecPrivFindFr ( SInt32 FrId, UInt8 ObjId = 0 ) +* +* \brief : Private function, calculate info needed to access to AcqId, file No, etc ... +* +* \param : FrId - The no of the frame +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 10/06/2020 +* \date : Doc date : 10/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesDecPrivFindFr ( SInt32 FrId, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + err_retfail ( FrId, (ERR_OUT,"Abort => This function has not been checked !") ); + + + // Check AcqId + + err_retfail ( FrId, (ERR_OUT,"Abort => FrId = %d < 0 !", FrId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + + // Set AcqId, FrId + + VPtRF->DecCurAcqId = FrId / VPtRPar->ParFrNbPerAcq; + VPtRF->DecCurFrId = FrId; + + // Check if FrId is in run files + + if ( FrId >= VPtRStatus->ResFrCnt ) { + VPtRF->DecCurAcqFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => FrId = %d > Run fr nb = %d", FrId, VPtRStatus->ResFrCnt ) ); + } + + // Calculate info + + VPtRF->DecCurAcqFileSuffix = VPtRF->DecCurAcqId / VPtRPar->ParAcqNbPerFile; + VPtRF->DecCurAcqIdInFile = VPtRF->DecCurAcqId % VPtRPar->ParAcqNbPerFile; + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesFpcPrivFindStep ( SInt32 StepId, UInt8 ObjId = 0 ) +* +* \brief : Private function, calculate info needed to access to StepId, file No, etc ... +* +* \param : StepId - The no, id of the step +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 03/07/2020 +* \date : Doc date : 03/07/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesFpcPrivFindStep ( SInt32 StepId, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + SInt32 VLastAcqOfStep; + + + // Check StepId + + err_retfail ( StepId, (ERR_OUT,"Abort => StepId = %d < 0 !", StepId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Set AcqId, FrId => Not used + + VPtRF->RawCurAcqId = -1; + VPtRF->RawCurFrId = -1; + + // Set FpcCurStepId, + + VPtRF->FpcCurStepId = StepId; + + // Check if StepId is in run files + + + if ( StepId >= VPtRPar->ParCarStepNb ) { + VPtRF->FpcCurStepFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => StepId = %d > Run step nb = %d", StepId, VPtRPar->ParCarStepNb ) ); + } + + + VLastAcqOfStep = ((StepId + 1) * VPtRPar->ParCarSubStepNb * VPtRPar->ParCarSubStepAcqNb) - 1; + + if ( VLastAcqOfStep >= VPtRStatus->ResAcqCnt ) { + VPtRF->FpcCurStepFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => StepId = %d requires %d Acq in run, there are only %d acq", StepId, VLastAcqOfStep + 1, VPtRStatus->ResAcqCnt ) ); + } + + + // Calculate info + + VPtRF->FpcCurStepFileSuffix = StepId; + + + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesFpcPrivFindSubStep ( SInt32 StepId, SInt32 SubStepId, UInt8 ObjId = 0 ) +* +* \brief : Private function, calculate info needed to access to StepId, SubStepId file No, etc ... +* +* \param : StepId - The no, id of the step +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 06/07/2020 +* \date : Doc date : 06/07/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesFpcPrivFindSubStep ( SInt32 StepId, SInt32 SubStepId, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + SInt32 VLastAcqOfStep; + + + // Check StepId, SubStepId + + err_retfail ( StepId, (ERR_OUT,"Abort => StepId = %d < 0 !", StepId) ); + + err_retfail ( SubStepId, (ERR_OUT,"Abort => SubStepId = %d < 0 !", SubStepId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Set AcqId, FrId => Not used + + VPtRF->RawCurAcqId = -1; + VPtRF->RawCurFrId = -1; + + // Set FpcCurStepId, + + + VPtRF->FpcCurSubStepId = SubStepId; + + // Check if StepId is in run files + + if ( StepId >= VPtRPar->ParCarStepNb ) { + VPtRF->FpcCurStepFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => StepId = %d > Run step nb = %d", StepId, VPtRPar->ParCarStepNb ) ); + } + + + VLastAcqOfStep = ((StepId + 1) * VPtRPar->ParCarSubStepNb * VPtRPar->ParCarSubStepAcqNb) - 1; + + if ( VLastAcqOfStep >= VPtRStatus->ResAcqCnt ) { + VPtRF->FpcCurStepFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => StepId = %d requires %d Acq in run, there are only %d acq", StepId, VLastAcqOfStep + 1, VPtRStatus->ResAcqCnt ) ); + } + + + // Check sub step id + + if ( SubStepId > VPtRPar->ParCarSubStepNb ) { + VPtRF->FpcCurSubStepFileSuffix = -1; + err_retfail ( -1, (ERR_OUT,"Abort => SubStepId = %d out of range [0..%d]", SubStepId, VPtRPar->ParCarSubStepNb ) ); + } + + + // Calculate info + + + VPtRF->FpcCurSubStepFileSuffix = StepId; // Only one file for all sub steps => same suffix as step file + + + err_retok (( ERR_OUT, "" )); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesRawPrintCurAcqInf ( UInt8 ObjId = 0 ) +* +* \brief : Print current acq information field, for test / debug +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 27/05/2020 +* \date : Rev : 11/06/2020 \n +* - Three functions Raw, Dec, Fpc +* \date : Doc date : 27/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesRawPrintCurAcqInf ( UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Print + + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, " Current acq info" )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "RawCurAcqId : %d", VPtRF->RawCurAcqId )); + msg (( MSG_OUT, "RawCurFrId : %d", VPtRF->RawCurFrId )); + msg (( MSG_OUT, "RawCurAcqFileSuffix : %d", VPtRF->RawCurAcqFileSuffix )); + msg (( MSG_OUT, "RawCurAcqIdInFile : %d", VPtRF->RawCurAcqIdInFile )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "RawLoadedFileSuffix : %d", VPtRF->RawLoadedFileSuffix )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "----------------------------------------------" )); + + + if ( VPtRF->RawCurAcqId >= 0 ) { + MIS1__FPrintRawAcqFrMapTable ( &(VPtRF->PtFileRawFrMap[VPtRF->RawCurAcqIdInFile]), VPtRF->RawCurAcqId, -1 /* FirstFr */, -1 /* LastFr */, 0 /* PrintDecHex */ ); + } + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesDecPrintCurAcqInf ( UInt8 ObjId = 0 ) +* +* \brief : Print current acq information field, for test / debug +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 11/06/2020 +* \date : Doc date : 11/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunFilesDecPrintCurAcqInf ( UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Print + + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, " Current acq info" )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "DecCurAcqId : %d", VPtRF->DecCurAcqId )); + msg (( MSG_OUT, "DecCurFrId : %d", VPtRF->DecCurFrId )); + msg (( MSG_OUT, "DecCurAcqFileSuffix : %d", VPtRF->DecCurAcqFileSuffix )); + msg (( MSG_OUT, "DecCurAcqIdInFile : %d", VPtRF->DecCurAcqIdInFile )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "DecLoadedFileSuffix : %d", VPtRF->DecLoadedFileSuffix )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "----------------------------------------------" )); + + // Displays only first and last frame of acq + + if ( VPtRF->DecCurAcqId >= 0 ) { + MIS1__FPrintDecAcqFrMapTable ( &(VPtRF->PtFileDecFrMap[VPtRF->DecCurAcqIdInFile * VPtRPar->ParFrNbPerAcq]), VPtRF->RawCurAcqId, 0 /* FirstFr */, 0 /* LastFr */, VPtRPar->ParFrNbPerAcq /* FrNbInAcq */ ); + MIS1__FPrintDecAcqFrMapTable ( &(VPtRF->PtFileDecFrMap[VPtRF->DecCurAcqIdInFile * VPtRPar->ParFrNbPerAcq]), VPtRF->RawCurAcqId, VPtRPar->ParFrNbPerAcq-1 /* FirstFr */, VPtRPar->ParFrNbPerAcq-1 /* LastFr */, VPtRPar->ParFrNbPerAcq /* FrNbInAcq */ ); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesRawGotoAcq ( SInt32 AcqId, UInt8 ObjId = 0 ) +* +* \brief : Print current acq information field, for test / debug +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 27/05/2020 +* \date : Doc date : 27/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +#ifdef MIS1__CC_DATA_FORMAT_SINCE_V211 + +SInt32 MIS1__FRunFilesRawGotoAcq ( SInt32 AcqId, MIS1__TAcqFrList** PtPtAcqFrList, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + MIS1__TAcqFrMap* VPtCurAcqFrMap; + + + // Check AcqId + + err_retfail ( AcqId, (ERR_OUT,"Abort => AcqId = %d < 0 !", AcqId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Calc acq info + + VRet = MIS1__FRunFilesRawPrivFindAcq ( AcqId, ObjId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => MIS1__FRunFilesPrivFindAcq ( AcqId = %d, ObjId = %d ) failed !", AcqId, ObjId ) ); + + // Load the raw run files if not already in memory + + if ( VPtRF->RawCurAcqFileSuffix != VPtRF->RawLoadedFileSuffix ) { + + // + + // 600 VRet = DAMIS1__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfRawIndexFileName /* FileName */, VPtRF->RawCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->RawFBuffIndexId ); + + VRet = BF__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfRawIndexFileName /* FileName */, VPtRF->RawCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->RawFBuffIndexId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Load raw index file = %s, suffix = %d failed !", VPtRInf->InfRawIndexFileName, VPtRF->RawCurAcqFileSuffix ) ); + + // 600 VPtRF->PtFileRawFrMap = (MIS1__TAcqFrMap*) DAMIS1__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->RawFBuffIndexId ); + + VPtRF->PtFileRawFrMap = (MIS1__TAcqFrMap*) BF__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->RawFBuffIndexId ); // 600 + + // 600 VRet = DAMIS1__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfRawDataFileName /* FileName */, VPtRF->RawCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->RawFBuffDataId ); + + VRet = BF__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfRawDataFileName /* FileName */, VPtRF->RawCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->RawFBuffDataId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Load raw data file = %s, suffix = %d failed !", VPtRInf->InfRawDataFileName, VPtRF->RawCurAcqFileSuffix ) ); + + // 600 VPtRF->PtAcqRawMem = (UInt8*) DAMIS1__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->RawFBuffDataId ); + + VPtRF->PtAcqRawMem = (UInt8*) BF__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->RawFBuffDataId ); + + + // InfRawIndexFileName + // InfRawDataFileName + // + // RawFBuffIndexId + // RawFBuffDataId + + VPtRF->RawLoadedFileSuffix = VPtRF->RawCurAcqFileSuffix; + + } + + + VPtCurAcqFrMap = &(VPtRF->PtFileRawFrMap[VPtRF->RawCurAcqIdInFile]); + + // MIS1__FAcqFrMapToAcqFrList ( UInt8* PtU8AcqBeg, MIS1__TAcqFrMap* SrcPtFrMap, MIS1__TAcqFrList* DestPtFrList, UInt32 AcqId ) + + VRet = MIS1__FAcqFrMapToAcqFrList ( &(VPtRF->PtAcqRawMem[VPtCurAcqFrMap->ResAcqPos]) /* PtU8AcqBeg */, VPtCurAcqFrMap /* SrcPtFrMap */, &(VPtRF->CurAcqRawFrList) /* DestPtFrList */, AcqId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Building acq frames list has failed !") ); + + + if ( PtPtAcqFrList != NULL ) { + *PtPtAcqFrList = &(VPtRF->CurAcqRawFrList); + } + + + err_retok (( ERR_OUT, "" )); +} + +#else + +SInt32 MIS1__FRunFilesRawGotoAcq ( SInt32 AcqId, MIS1__TAcqFrList** PtPtAcqFrList, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + MIS1__TAcqFrMap* VPtCurAcqFrMap; + + + // Check AcqId + + err_retfail ( AcqId, (ERR_OUT,"Abort => AcqId = %d < 0 !", AcqId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Calc acq info + + VRet = MIS1__FRunFilesRawPrivFindAcq ( AcqId, ObjId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => MIS1__FRunFilesPrivFindAcq ( AcqId = %d, ObjId = %d ) failed !", AcqId, ObjId ) ); + + // Load the raw run files if not already in memory + + if ( VPtRF->RawCurAcqFileSuffix != VPtRF->RawLoadedFileSuffix ) { + + // + + VRet = DAMIS1__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfRawIndexFileName /* FileName */, VPtRF->RawCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->RawFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load raw index file = %s, suffix = %d failed !", VPtRInf->InfRawIndexFileName, VPtRF->RawCurAcqFileSuffix ) ); + + VPtRF->PtFileRawFrMap = (MIS1__TAcqFrMap*) DAMIS1__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->RawFBuffIndexId ); + + VRet = DAMIS1__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfRawDataFileName /* FileName */, VPtRF->RawCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->RawFBuffDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load raw data file = %s, suffix = %d failed !", VPtRInf->InfRawDataFileName, VPtRF->RawCurAcqFileSuffix ) ); + + VPtRF->PtAcqRawMem = (UInt8*) DAMIS1__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->RawFBuffDataId ); + + // InfRawIndexFileName + // InfRawDataFileName + // + // RawFBuffIndexId + // RawFBuffDataId + + VPtRF->RawLoadedFileSuffix = VPtRF->RawCurAcqFileSuffix; + + } + + + VPtCurAcqFrMap = &(VPtRF->PtFileRawFrMap[VPtRF->RawCurAcqIdInFile]); + + // MIS1__FAcqFrMapToAcqFrList ( UInt8* PtU8AcqBeg, MIS1__TAcqFrMap* SrcPtFrMap, MIS1__TAcqFrList* DestPtFrList, UInt32 AcqId ) + + VRet = MIS1__FAcqFrMapToAcqFrList ( &(VPtRF->PtAcqRawMem[VPtCurAcqFrMap->ResAcqPos]) /* PtU8AcqBeg */, VPtCurAcqFrMap /* SrcPtFrMap */, &(VPtRF->CurAcqRawFrList) /* DestPtFrList */, AcqId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Building acq frames list has failed !") ); + + + if ( PtPtAcqFrList != NULL ) { + *PtPtAcqFrList = &(VPtRF->CurAcqRawFrList); + } + + + err_retok (( ERR_OUT, "" )); +} + + +#endif + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesDecGotoAcq ( SInt32 AcqId, UInt8 ObjId = 0 ) +* +* \brief : Print current acq information field, for test / debug +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 10/06/2020 +* \date : Doc date : 10/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +#ifdef MIS1__CC_DATA_FORMAT_SINCE_V211 + +SInt32 MIS1__FRunFilesDecGotoAcq ( SInt32 AcqId, MIS1__TDecFrList** PtPtFrList, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + SInt32 VIdInMapTableOfFirstFrOfAcq; + SInt32 ViFrInAcq; + + MIS1__TDecFrMap* VPtDecFrMap; + MIS1__TDecFrList* VPtAcqDecFrList; + + + + // Check AcqId + + err_retfail ( AcqId, (ERR_OUT,"Abort => AcqId = %d < 0 !", AcqId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + VPtDecFrMap = &MIS1__VGARunFile[ObjId].PtFileDecFrMap[0]; + + // Calc acq info + + VRet = MIS1__FRunFilesDecPrivFindAcq ( AcqId, ObjId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => MIS1__FRunFilesPrivFindAcq ( AcqId = %d, ObjId = %d ) failed !", AcqId, ObjId ) ); + + // Load the raw run files if not already in memory + + if ( VPtRF->DecCurAcqFileSuffix != VPtRF->DecLoadedFileSuffix ) { + + // + + // 600 VRet = DAMIS1__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfDecIndexFileName /* FileName */, VPtRF->DecCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->DecFBuffIndexId ); + + VRet = BF__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfDecIndexFileName /* FileName */, VPtRF->DecCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->DecFBuffIndexId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Load dec index file = %s, suffix = %d failed !", VPtRInf->InfDecIndexFileName, VPtRF->DecCurAcqFileSuffix ) ); + + // 600 VPtRF->PtFileDecFrMap = (MIS1__TDecFrMap*) DAMIS1__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->DecFBuffIndexId ); + + VPtRF->PtFileDecFrMap = (MIS1__TDecFrMap*) BF__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->DecFBuffIndexId ); // 600 + + // 600 VRet = DAMIS1__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfDecDataFileName /* FileName */, VPtRF->DecCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->FBuffDecDataId ); + + VRet = BF__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfDecDataFileName /* FileName */, VPtRF->DecCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->FBuffDecDataId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Load dec data file = %s, suffix = %d failed !", VPtRInf->InfDecDataFileName, VPtRF->DecCurAcqFileSuffix ) ); + + // 600 VPtRF->PtAcqDecMem = (UInt8*) DAMIS1__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->FBuffDecDataId ); + + VPtRF->PtAcqDecMem = (UInt8*) BF__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->FBuffDecDataId ); // 600 + + + // InfRawIndexFileName + // InfRawDataFileName + // + // RawFBuffIndexId + // RawFBuffDataId + + VPtRF->DecLoadedFileSuffix = VPtRF->DecCurAcqFileSuffix; + + // msg (( MSG_OUT, "Dec MAP : AcqInRun = %d, FrInAcq = %d, DataSz = %d, DataPos = %d", VPtRF->PtDecFrMap->ResAcqIdInRun, VPtRF->PtDecFrMap->ResFrIdInAcq, VPtRF->PtDecFrMap->ResFrSz, VPtRF->PtDecFrMap->ResFrPos )); + } + + // ------------------------------------ + // Building frame list of acq + // ------------------------------------ + + // We assume that acq nb / file and fr nb / acq are constant + // we check, if it is not the case => exit => upgrade of lib is needed to handle this case + + VIdInMapTableOfFirstFrOfAcq = (AcqId % VPtRPar->ParAcqNbPerFile) * VPtRPar->ParFrNbPerAcq; + + VPtDecFrMap = &MIS1__VGARunFile[ObjId].PtFileDecFrMap[VIdInMapTableOfFirstFrOfAcq]; + + // Check + + if ( VPtDecFrMap->ResAcqIdInRun != AcqId ) { + err_retfail ( -1, (ERR_OUT,"Abort => Map table AcqIdInRun = %d <> AcqId = %d => Not constant acq/file or fr/acq => Lib upgrade neeeded, if not constant fr/acq processing can be done with VPtDecFrMap->ResFrNbInAcq ", VPtDecFrMap->ResAcqIdInRun, AcqId) ); + } + + if ( VPtDecFrMap->ResFrIdInAcq != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => Map table FrIdInAcq of first frame of acq = %d <> 0 => Not constant acq/file or fr/acq => Lib upgrade neeeded", VPtDecFrMap->ResAcqIdInRun, AcqId) ); + } + + // Build list + + for ( ViFrInAcq = 0; ViFrInAcq < VPtRPar->ParFrNbPerAcq; ViFrInAcq++ ) { + + VPtDecFrMap = &MIS1__VGARunFile[ObjId].PtFileDecFrMap[VIdInMapTableOfFirstFrOfAcq + ViFrInAcq]; + VPtAcqDecFrList = &MIS1__VGARunFile[ObjId].ACurAcqDecFrList[ViFrInAcq]; + + + VPtAcqDecFrList->ResAcqIdInRun = VPtDecFrMap->ResAcqIdInRun; + VPtAcqDecFrList->ResFrNbInAcq = VPtDecFrMap->ResFrNbInAcq; + VPtAcqDecFrList->ResFrIdInAcq = VPtDecFrMap->ResFrIdInAcq; + VPtAcqDecFrList->ResFrSz = VPtDecFrMap->ResFrSz; + + VPtAcqDecFrList->ResPtFrBeg = (void*) ( (UInt32) VPtRF->PtAcqDecMem + VPtDecFrMap->ResFrPos ); + + } // End for + + + if ( PtPtFrList != NULL ) { + *PtPtFrList = &MIS1__VGARunFile[ObjId].ACurAcqDecFrList[0]; + } + + + err_retok (( ERR_OUT, "" )); +} + + +#else + +SInt32 MIS1__FRunFilesDecGotoAcq ( SInt32 AcqId, MIS1__TDecFrList** PtPtFrList, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + SInt32 VIdInMapTableOfFirstFrOfAcq; + SInt32 ViFrInAcq; + + MIS1__TDecFrMap* VPtDecFrMap; + MIS1__TDecFrList* VPtAcqDecFrList; + + + + // Check AcqId + + err_retfail ( AcqId, (ERR_OUT,"Abort => AcqId = %d < 0 !", AcqId) ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + VPtDecFrMap = &MIS1__VGARunFile[ObjId].PtFileDecFrMap[0]; + + // Calc acq info + + VRet = MIS1__FRunFilesDecPrivFindAcq ( AcqId, ObjId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => MIS1__FRunFilesPrivFindAcq ( AcqId = %d, ObjId = %d ) failed !", AcqId, ObjId ) ); + + // Load the raw run files if not already in memory + + if ( VPtRF->DecCurAcqFileSuffix != VPtRF->DecLoadedFileSuffix ) { + + // + + VRet = DAMIS1__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfDecIndexFileName /* FileName */, VPtRF->DecCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->DecFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load dec index file = %s, suffix = %d failed !", VPtRInf->InfDecIndexFileName, VPtRF->DecCurAcqFileSuffix ) ); + + VPtRF->PtFileDecFrMap = (MIS1__TDecFrMap*) DAMIS1__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->DecFBuffIndexId ); + + VRet = DAMIS1__FOBuffLoadBuffFromBinFile ( 0 /* BuffId */, VPtRInf->InfDecDataFileName /* FileName */, VPtRF->DecCurAcqFileSuffix, 0 /* Action */, 0 /* Mode */, VPtRF->FBuffDecDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Load dec data file = %s, suffix = %d failed !", VPtRInf->InfDecDataFileName, VPtRF->DecCurAcqFileSuffix ) ); + + VPtRF->PtAcqDecMem = (UInt8*) DAMIS1__FOBuffGetBuffPtrVoid ( 0 /* BuffId */, VPtRF->FBuffDecDataId ); + + + // InfRawIndexFileName + // InfRawDataFileName + // + // RawFBuffIndexId + // RawFBuffDataId + + VPtRF->DecLoadedFileSuffix = VPtRF->DecCurAcqFileSuffix; + + // msg (( MSG_OUT, "Dec MAP : AcqInRun = %d, FrInAcq = %d, DataSz = %d, DataPos = %d", VPtRF->PtDecFrMap->ResAcqIdInRun, VPtRF->PtDecFrMap->ResFrIdInAcq, VPtRF->PtDecFrMap->ResFrSz, VPtRF->PtDecFrMap->ResFrPos )); + } + + // ------------------------------------ + // Building frame list of acq + // ------------------------------------ + + // We assume that acq nb / file and fr nb / acq are constant + // we check, if it is not the case => exit => upgrade of lib is needed to handle this case + + VIdInMapTableOfFirstFrOfAcq = (AcqId % VPtRPar->ParAcqNbPerFile) * VPtRPar->ParFrNbPerAcq; + + VPtDecFrMap = &MIS1__VGARunFile[ObjId].PtFileDecFrMap[VIdInMapTableOfFirstFrOfAcq]; + + // Check + + if ( VPtDecFrMap->ResAcqIdInRun != AcqId ) { + err_retfail ( -1, (ERR_OUT,"Abort => Map table AcqIdInRun = %d <> AcqId = %d => Not constant acq/file or fr/acq => Lib upgrade neeeded, if not constant fr/acq processing can be done with VPtDecFrMap->ResFrNbInAcq ", VPtDecFrMap->ResAcqIdInRun, AcqId) ); + } + + if ( VPtDecFrMap->ResFrIdInAcq != 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => Map table FrIdInAcq of first frame of acq = %d <> 0 => Not constant acq/file or fr/acq => Lib upgrade neeeded", VPtDecFrMap->ResAcqIdInRun, AcqId) ); + } + + // Build list + + for ( ViFrInAcq = 0; ViFrInAcq < VPtRPar->ParFrNbPerAcq; ViFrInAcq++ ) { + + VPtDecFrMap = &MIS1__VGARunFile[ObjId].PtFileDecFrMap[VIdInMapTableOfFirstFrOfAcq + ViFrInAcq]; + VPtAcqDecFrList = &MIS1__VGARunFile[ObjId].ACurAcqDecFrList[ViFrInAcq]; + + + VPtAcqDecFrList->ResAcqIdInRun = VPtDecFrMap->ResAcqIdInRun; + VPtAcqDecFrList->ResFrNbInAcq = VPtDecFrMap->ResFrNbInAcq; + VPtAcqDecFrList->ResFrIdInAcq = VPtDecFrMap->ResFrIdInAcq; + VPtAcqDecFrList->ResFrSz = VPtDecFrMap->ResFrSz; + + VPtAcqDecFrList->ResPtFrBeg = (void*) ( (UInt32) VPtRF->PtAcqDecMem + VPtDecFrMap->ResFrPos ); + + } // End for + + + if ( PtPtFrList != NULL ) { + *PtPtFrList = &MIS1__VGARunFile[ObjId].ACurAcqDecFrList[0]; + } + + + err_retok (( ERR_OUT, "" )); +} + + + + +#endif + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesFpcGotoStep ( SInt32 StepId, MIS1__TMatPixCntU16** PtPtMatPixCnt, UInt8 ObjId = 0 ) +* +* \brief : +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 03/07/2020 +* \date : Doc date : 03/07/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FRunFilesFpcGotoStep ( SInt32 StepId, MIS1__TMatPixCntU16** PtPtMatPixCnt, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + + // Check param + + err_retfail ( StepId, (ERR_OUT,"Abort => StepId = %d < 0 !", StepId) ); + + err_retnull ( PtPtMatPixCnt, (ERR_OUT,"Abort => PtPtMatPixCnt == NULL") ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Step info + + VRet = MIS1__FRunFilesFpcPrivFindStep ( StepId, ObjId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => MIS1__FRunFilesFpcPrivFindStep ( StepId = %d, ObjId = %d ) failed !", StepId, ObjId ) ); + + // Load the fpc run files if not already in memory + + if ( VPtRF->FpcCurStepFileSuffix != VPtRF->FpcStepLoadedFileSuffix ) { + + // Build file name + + VRet = MIS1__FBuildFileNameSuffix ( VPtRInf->InfFPCStepFileName, VPtRInf->InfCurFPCStepFileName, GLB_FILE_PATH_SZ, VPtRF->FpcCurStepFileSuffix ); + + err_retfail ( VRet, (ERR_OUT, "Building FPC file name base = %s, prefix = %d failed", VPtRInf->InfFPCStepFileName, VPtRF->FpcCurStepFileSuffix ) ); + + // Open file + + VRet = VPtRF->PtFPCStepBinFile->PubFSetFileName ( VPtRInf->InfCurFPCStepFileName ); + + err_retfail ( VRet, (ERR_OUT,"Set FPC step file name = %s to TCBinFile failed !", VPtRInf->InfCurFPCStepFileName) ); + + VRet = VPtRF->PtFPCStepBinFile->PubFOpen (); + + err_retfail ( VRet, (ERR_OUT,"Open FPC step file name = %s to TCBinFile failed !", VPtRInf->InfCurFPCStepFileName) ); + + // Read + + VRet = VPtRF->PtFPCStepBinFile->PubFBlocRead ( 0 /* BlocNo */, &VPtRF->StepMatPixCnt, sizeof (MIS1__TMatPixCntU16) ); + + err_retfail ( VRet, (ERR_OUT,"Read FPC step file name = %s to TCBinFile failed !", VPtRInf->InfCurFPCStepFileName) ); + + + VPtRF->FpcStepLoadedFileSuffix = VPtRF->FpcCurStepFileSuffix; + + } + + + *PtPtMatPixCnt = &VPtRF->StepMatPixCnt; + + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesFpcGotoSubStep ( SInt32 StepId, SInt32 SubStepId, MIS1__TMatPixCntU16** PtPtMatPixCnt, UInt8 ObjId = 0 ) +* +* \brief : +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 06/07/2020 +* \date : Doc date : 06/07/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__FRunFilesFpcGotoSubStep ( SInt32 StepId, SInt32 SubStepId, MIS1__TMatPixCntU16** PtPtMatPixCnt, UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + MIS1__TRunConf* VPtRConf; + MIS1__TRunPar* VPtRPar; + MIS1__TRunInf* VPtRInf; + MIS1__TRunStatus* VPtRStatus; + + + + // Check param + + err_retfail ( StepId, (ERR_OUT,"Abort => StepId = %d < 0 !", StepId) ); + + err_retfail ( SubStepId, (ERR_OUT,"Abort => SubStepId = %d < 0 !", SubStepId) ); + + err_retnull ( PtPtMatPixCnt, (ERR_OUT,"Abort => PtPtMatPixCnt == NULL") ); + + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + // Check if MIS1__FRunFilesOpen () has been called + + if ( VPtRF->FOpenDone == 0) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FRunFilesOpen () has not been called !") ); + } + + VPtRConf = &MIS1__VGARunFile[ObjId].RunConf; + VPtRPar = &MIS1__VGARunFile[ObjId].RunConf.RunPar; + VPtRInf = &MIS1__VGARunFile[ObjId].RunConf.RunInf; + VPtRStatus = &MIS1__VGARunFile[ObjId].RunStatus; + + // Step, sub step info + + VRet = MIS1__FRunFilesFpcPrivFindSubStep ( StepId, SubStepId, ObjId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => MIS1__FRunFilesFpcPrivFindSubStep ( StepId = %d, SubStepId = %d, ObjId = %d ) failed !", StepId, SubStepId, ObjId ) ); + + // Load the fpc run files if not already in memory + + if ( VPtRF->FpcCurSubStepFileSuffix != VPtRF->FpcSubStepLoadedFileSuffix ) { + + // Build file name + + VRet = MIS1__FBuildFileNameSuffix ( VPtRInf->InfFPCSubStepsFileName, VPtRInf->InfCurFPCSubStepsFileName, GLB_FILE_PATH_SZ, VPtRF->FpcCurSubStepFileSuffix ); + + err_retfail ( VRet, (ERR_OUT, "Building FPC sub step file name base = %s, prefix = %d failed", VPtRInf->InfFPCSubStepsFileName, VPtRF->FpcCurSubStepFileSuffix ) ); + + // Open file + + VRet = VPtRF->PtFPCSubStepsBinFile->PubFSetFileName ( VPtRInf->InfCurFPCSubStepsFileName ); + + err_retfail ( VRet, (ERR_OUT,"Set FPC sub step file name = %s to TCBinFile failed !", VPtRInf->InfCurFPCSubStepsFileName) ); + + VRet = VPtRF->PtFPCSubStepsBinFile->PubFOpen (); + + err_retfail ( VRet, (ERR_OUT,"Open FPC sub step file name = %s to TCBinFile failed !", VPtRInf->InfCurFPCSubStepsFileName) ); + + VPtRF->FpcSubStepLoadedFileSuffix = VPtRF->FpcCurSubStepFileSuffix; + + } + + + // Read + + VRet = VPtRF->PtFPCSubStepsBinFile->PubFBlocRead ( SubStepId /* BlocNo */, &VPtRF->SubStepMatPixCnt, sizeof (MIS1__TMatPixCntU16) ); + + err_retfail ( VRet, (ERR_OUT,"Read FPC sub step = %d of step = %d, file name = %s to TCBinFile failed !", SubStepId, StepId, VPtRInf->InfCurFPCSubStepsFileName) ); + + + *PtPtMatPixCnt = &VPtRF->SubStepMatPixCnt; + + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunFilesEnd ( UInt8 ObjId = 0 ) +* +* \brief : Close run files records, objects, needed to access to run files +* +* \param : ObjId - Id of the RunFiles instance, up to MIS1__MAX_RUN_FILES - 1 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2020 +* \date : Doc date : 25/05/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +#ifdef MIS1__CC_DATA_FORMAT_SINCE_V211 + +SInt32 MIS1__FRunFilesEnd ( UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + + // Check param + + if ( ObjId >= MIS1__MAX_RUN_FILES ) { + err_retfail ( -1, (ERR_OUT,"Abort => ObjId = %d out of range [0..%d]", ObjId, MIS1__MAX_RUN_FILES - 1) ); + } + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + + VPtRF->FBeginDone = 0; + + + // Free RAW data files objects + // - Index file + + // 600 VRet = DAMIS1__FOBuffAllocFree ( 0 /* FreeAlloc */, 0 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffIndexId ); + + VRet = BF__FOBuffAllocFree ( 0 /* FreeAlloc */, 0 /* BuffW8Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffIndexId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Free OBuff for raw index file, ObjId = %d failed !", ObjId) ); + + // Free RAW data files objects + // - Data file + + // 600 VRet = DAMIS1__FOBuffAllocFree ( 0 /* FreeAlloc */, 0 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffDataId ); + + VRet = BF__FOBuffAllocFree ( 0 /* FreeAlloc */, 0 /* BuffW8Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffDataId ); // 600 + + err_retfail ( VRet, (ERR_OUT,"Abort => Free OBuff for raw index file, ObjId = %d failed !", ObjId) ); + + + // Free FPC TCBinFiles + + VPtRF->PtFPCSubStepsBinFile->~FIL__TCBinFile (); + + VPtRF->PtFPCStepBinFile->~FIL__TCBinFile (); + + // Reset record + + memset ( VPtRF, 0, sizeof (MIS1__TRunFiles) ); + + + err_retok (( ERR_OUT, "" )); +} + + +#else + +SInt32 MIS1__FRunFilesEnd ( UInt8 ObjId = 0 ) { + + SInt32 VRet; + MIS1__TRunFiles* VPtRF; + + // Check param + + if ( ObjId >= MIS1__MAX_RUN_FILES ) { + err_retfail ( -1, (ERR_OUT,"Abort => ObjId = %d out of range [0..%d]", ObjId, MIS1__MAX_RUN_FILES - 1) ); + } + + // Set ptr to record + + VPtRF = &MIS1__VGARunFile[ObjId]; + + + VPtRF->FBeginDone = 0; + + + // Free RAW data files objects + // - Index file + + VRet = DAMIS1__FOBuffAllocFree ( 0 /* FreeAlloc */, 0 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffIndexId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Free OBuff for raw index file, ObjId = %d failed !", ObjId) ); + + // Free RAW data files objects + // - Data file + + VRet = DAMIS1__FOBuffAllocFree ( 0 /* FreeAlloc */, 0 /* BuffW64Sz */, 0 /* BuffIdToAlloc */, 0 /* BuffIdToFree */, VPtRF->RawFBuffDataId ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Free OBuff for raw index file, ObjId = %d failed !", ObjId) ); + + // Reset record + + memset ( VPtRF, 0, sizeof (MIS1__TRunFiles) ); + + + err_retok (( ERR_OUT, "" )); +} + + +#endif + + +/** +=================================================================================== +* \fn : SInt32 MIS1__FProcDec ( SInt8 FirstAcqOfRun, MIS1__TAcqProc* PtAcqProc, MIS1__TProcMode ProcMode, SInt32 AcqIdInRun, SInt32 AcqIdInFile, SInt32 AcqIdInBuff, SInt8 PrintLvl ) +* +* \brief : Executes decode pixels processing +* +* \param : FirstAcqOfRun - Flag, 1 => It is the first acq of the run +* +* \param : PtAcqProc - Pointer to acq processing record +* +* \param : ProcMode - Processing mode +* +* \param : AcqIdInRun - Id of acq in run 0 to acq nb in run - 1 +* +* \param : AcqIdInFile - Id of acq in one file of the run, if characterization mode => acq id in current step +* +* \param : AcqIdInBuff - Id of acq in the bloc of acq bufferiezd in mem = for step file +* +* \param : PrintLvl - Print level +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 08/06/2020 +* \date : Rev : 30/06/2020 \n +* - Reduced paramters list, moved to MIS1__TAcqProc +* \date : Doc date : 08/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FProcDec ( SInt8 FirstAcqOfRun, MIS1__TAcqProc* PtAcqProc, MIS1__TProcMode ProcMode, SInt32 AcqIdInRun, SInt32 AcqIdInFile, SInt32 AcqIdInBuff, SInt8 PrintLvl ) { + + MIS1__TRunPar* VPtRunPar; + MIS1__TRunInf* VPtRunInf; + MIS1__TRunStatus* VPtRunStatus; + + // Variables for parameters removed on 30/06/2020, acces is now done via MIS1__TAcqProc + + SInt32 VAcqNbPerFile; + SInt32 VAcqNbPerSubStep; + SInt32 VAcqNbPerBuff; + FIL__TCBinFile* VPtStepBinFile; + FIL__TCBinFile* VPtSubStepBinFile; + + + + + // Check param + + err_retnull ( PtAcqProc, (ERR_OUT,"Abort => PtAcqProc == NULL") ); + + + // Get some parameters + + VPtRunPar = PtAcqProc->PtRunPar; + VPtRunInf = PtAcqProc->PtRunInf; + VPtRunStatus = PtAcqProc->PtRunStatus; + + VAcqNbPerFile = PtAcqProc->PtRunPar->ParAcqNbPerFile; + VAcqNbPerSubStep = PtAcqProc->PtRunPar->ParCarSubStepAcqNb; + VAcqNbPerBuff = PtAcqProc->PtRunPar->ParBufferedAcqNb; + VPtStepBinFile = PtAcqProc->PtOStepFile; + VPtSubStepBinFile = PtAcqProc->PtOSubStepsFile; + + + // Check + + if ( AcqIdInBuff >= VAcqNbPerBuff ) { + err_retfail ( -1, (ERR_OUT,"Abort => AcqIdInBuff >= VAcqNbPerBuff", AcqIdInBuff, VAcqNbPerBuff) ); + } + + + + + // Processing + + if ( PrintLvl > 0 ) { + msg (( MSG_OUT, "Proc Dec : AcqIdInRun = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d ", AcqIdInRun, AcqIdInBuff, VAcqNbPerBuff )); + } + + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FEmulDecFrPix ( MIS1__TDecFrPix* PtDest, SInt32 PixelsNb ) +* +* \brief : Emulate PixelsNb pixels, header fields are not modified +* +* \param : PtSrc - Pointer to the header +* +\param : PixelsNb - Number of pixels to emulate +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 11/06/2020 +* \date : Doc date : 11/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FEmulDecFrPixPatt0 ( MIS1__TDecFrPix* PtDest, SInt32 PixelsNb ) { + + SInt32 ViPix; + + + // Check param + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtSrc == NULL") ); + + + // Set pixels + + + for ( ViPix=0; ViPix < PixelsNb; ViPix++ ) { + + PtDest->APix[ViPix].C.y = ViPix / 1024; // MSis 1 = 1024 col + + PtDest->APix[ViPix].C.x = ViPix % 1024; // MSis 1 = 504 lines + + } + + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixCntU16ToMatPixS32 ( MIS1__TMatPixCntU16* PtSrcMatPixCntU16, MIS1__TMatPixS32* PtDestMatPixS32 ) +* +* \brief : Copy a MIS1__TMatPixCntU16 to a MIS1__TMatPixS32 +* +* \param : PtSrcMatPixCntU16 - Pointer to source +* +* \param : PtDestMatPixS32 - Pointer to destination +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 13/08/2020 +* \date : Doc date : 13/08/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixCntU16ToMatPixS32 ( MIS1__TMatPixCntU16* PtSrcMatPixCntU16, MIS1__TMatPixS32* PtDestMatPixS32 ) { + + SInt32 VRow; + SInt32 VCol; + + + // Check param + + err_retnull ( PtSrcMatPixCntU16, (ERR_OUT,"Abort => PtSrcMatPixCntU16 == NULL") ); + + err_retnull ( PtDestMatPixS32, (ERR_OUT,"Abort => PtDestMatPixS32 == NULL") ); + + + // Copy + // + // For info, types definition + // + // typedef UInt16 MIS1__TTMatPixCntU16[MIS1__COL_NB][MIS1__ROW_NB]; + // typedef MIS1__TTMatPixCntU16 MIS1__TMatPixCntU16; + // + // typedef SInt32 MIS1__TTMatPixS32[MIS1__COL_NB][MIS1__ROW_NB] ; + // typedef MIS1__TTMatPixS32 MIS1__TMatPixS32; + + + for ( VRow = 0; VRow < MIS1__ROW_NB; VRow++ ) { + + for ( VCol = 0; VCol < MIS1__COL_NB; VCol++ ) { + + (*PtDestMatPixS32)[VCol][VRow] = (*PtSrcMatPixCntU16)[VCol][VRow]; + + } // End for ( VCol ) + + } // End for ( VRow ) + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32ToMatPixCntU16 ( MIS1__TMatPixS32* PtSrcMatPixS32, MIS1__TMatPixCntU16* PtDestMatPixCntU16, SInt8 ListOvf ) +* +* \brief : Copy a MIS1__TMatPixS32 to MIS1__TMatPixCntU16 \n +* It checks for source pixel value overflow, if < 0 or > 65535 \n +* sets destination pixel value to 65535 +* +* \param : PtSrcMatPixS32 - Pointer to source +* +* \param : PtDestMatPixCntU16 - Pointer to destination +* +* \param : ListOvf - 1 => Generate an error message for pixel value overflow +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - SW Error \n +* : > 0 - SW pixels value overflow => Warning / Error ? \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 13/08/2020 +* \date : Doc date : 13/08/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixS32ToMatPixCntU16 ( MIS1__TMatPixS32* PtSrcMatPixS32, MIS1__TMatPixCntU16* PtDestMatPixCntU16, SInt8 ListOvf ) { + + SInt32 VRow; + SInt32 VCol; + SInt32 VSrcPixVal; + UInt16 VDestPixVal; + SInt32 VOvfCnt; + + + // Check param + + err_retnull ( PtSrcMatPixS32, (ERR_OUT,"Abort => PtSrcMatPixS32 == NULL") ); + + err_retnull ( PtDestMatPixCntU16, (ERR_OUT,"Abort => PtDestMatPixCntU16 == NULL") ); + + + // Copy + // + // For info, types definition + // + // typedef UInt16 MIS1__TTMatPixCntU16[MIS1__COL_NB][MIS1__ROW_NB]; + // typedef MIS1__TTMatPixCntU16 MIS1__TMatPixCntU16; + // + // typedef SInt32 MIS1__TTMatPixS32[MIS1__COL_NB][MIS1__ROW_NB] ; + // typedef MIS1__TTMatPixS32 MIS1__TMatPixS32; + + + VOvfCnt = 0; + + for ( VRow = 0; VRow < MIS1__ROW_NB; VRow++ ) { + + for ( VCol = 0; VCol < MIS1__COL_NB; VCol++ ) { + + VSrcPixVal = (*PtSrcMatPixS32)[VCol][VRow]; + + while (1) { + + if ( VSrcPixVal < 0 ) { + + VDestPixVal = 65535; + ++VOvfCnt; + + if ( ListOvf ) { + err_error (( ERR_OUT, "Overflox Pix[x=%.4d,y=%.4d] = %d not in range 0..65535", VCol, VRow, VSrcPixVal )); + } + + break; + } + + + if ( VSrcPixVal > 65535 ) { + + VDestPixVal = 65535; + ++VOvfCnt; + + if ( ListOvf ) { + err_error (( ERR_OUT, "Overflox Pix[x=%.4d,y=%.4d] = %d not in range 0..65535", VCol, VRow, VSrcPixVal )); + } + + break; + } + + VDestPixVal = VSrcPixVal; + break; + + } // End while (1) + + (*PtDestMatPixCntU16)[VCol][VRow] = VDestPixVal; + + } // End for ( VCol ) + + } // End for ( VRow ) + + + if ( VOvfCnt > 0 ) { + err_error (( ERR_OUT, "Copy done, but %d pixels with ovf on source value ( < 0 or > 65535 ) => set to 65535 in destination", VOvfCnt )); + return (VOvfCnt); + } + + err_retok (( ERR_OUT, "" )); +} + + +// 88888 + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32AddV1 ( MIS1__TMatPixS32* PtSrc, MIS1__TMatPixS32* PtDest ) +* +* \brief : Add content of matrix PtSrc to matrix PtDest \n +* This version No 1 of function add all items of source matrix \n +* +* \param : PtSrc - Pointer to source +* +* \param : PtDest - Pointer to destination +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - SW Error \n +* : > 0 - SW pixels value overflow => Warning / Error ? \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 15/108/2020 +* \date : Doc date : 15/108/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixS32AddV1 ( MIS1__TMatPixS32* PtSrc, MIS1__TMatPixS32* PtDest ) { + + SInt32 VRow; + SInt32 VCol; + SInt32 VSrcPixVal; + SInt32 VDestPixVal; + + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + + // Add + // + // For info, types definition + // + // typedef SInt32 MIS1__TTMatPixS32[MIS1__COL_NB][MIS1__ROW_NB] ; + // typedef MIS1__TTMatPixS32 MIS1__TMatPixS32; + + + + for ( VRow = 0; VRow < MIS1__ROW_NB; VRow++ ) { + + for ( VCol = 0; VCol < MIS1__COL_NB; VCol++ ) { + + VSrcPixVal = (*PtSrc)[VCol][VRow]; + + VDestPixVal = (*PtDest)[VCol][VRow]; + + (*PtDest)[VCol][VRow] = VDestPixVal + VSrcPixVal; + + } // End for ( VCol ) + + } // End for ( VRow ) + + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixS32AddV2 ( MIS1__TMatPixS32* PtSrc, MIS1__TMatPixS32* PtDest ) +* +* \brief : Add content of matrix PtSrc to matrix PtDest \n +* This version No 2 of function add only items of source matrix != 0 \n +* with the hope that it will save execution time => TBC +* +* \param : PtSrc - Pointer to source +* +* \param : PtDest - Pointer to destination +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - SW Error \n +* : > 0 - SW pixels value overflow => Warning / Error ? \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 15/108/2020 +* \date : Doc date : 15/108/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixS32AddV2 ( MIS1__TMatPixS32* PtSrc, MIS1__TMatPixS32* PtDest ) { + + SInt32 VRow; + SInt32 VCol; + SInt32 VSrcPixVal; + SInt32 VDestPixVal; + + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + + // Add + // + // For info, types definition + // + // typedef SInt32 MIS1__TTMatPixS32[MIS1__COL_NB][MIS1__ROW_NB] ; + // typedef MIS1__TTMatPixS32 MIS1__TMatPixS32; + + + + for ( VRow = 0; VRow < MIS1__ROW_NB; VRow++ ) { + + for ( VCol = 0; VCol < MIS1__COL_NB; VCol++ ) { + + VSrcPixVal = (*PtSrc)[VCol][VRow]; + + if ( VSrcPixVal != 0 ) { + VDestPixVal = (*PtDest)[VCol][VRow]; + (*PtDest)[VCol][VRow] = VDestPixVal + VSrcPixVal; + } + + + } // End for ( VCol ) + + } // End for ( VRow ) + + + err_retok (( ERR_OUT, "" )); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixCntU16Save ( MIS1__TMatPixCntU16* PtSrc, char* FileName ) +* +* \brief : Save MIS1__TMatPixCntU16 to file +* +* \param : PtSrc - Pointer to source matrix +* +* \param : FileName - File name +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 13/08/2020 +* \date : Doc date : 13/08/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixCntU16Save ( MIS1__TMatPixCntU16* PtSrc, char* FileName ) { + + SInt32 VRet; + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + + // Save + + VRet = FIL_FWriteRecord ( FileName, PtSrc, sizeof (MIS1__TMatPixCntU16) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => FIL_FWriteRecord (PtSrc, File=%s) Ret = %d", FileName, VRet) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixCntU16Load ( MIS1__TMatPixCntU16* PtDest, char* FileName ) +* +* \brief : Load MIS1__TMatPixCntU16 from file +* +* \param : PtDest - Pointer to destination matrix +* +* \param : FileName - File name +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 13/08/2020 +* \date : Doc date : 13/08/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixCntU16Load ( MIS1__TMatPixCntU16* PtDest, char* FileName ) { + + SInt32 VRet; + SInt32 VExpectedFileSz; + + + // Check param + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + + // Check file format via file size + + VRet = FIL_FFileSize ( FileName ); + + err_retfail ( VRet, (ERR_OUT,"Abort => FIL_FFileSize (File=%s) failed Ret = %d", FileName, VRet) ); + + // Check size + + VExpectedFileSz = sizeof (MIS1__TMatPixCntU16); + + if ( VRet != VExpectedFileSz ) { + err_retfail ( -1, (ERR_OUT,"Abort => File size = %d <> MIS1__TMatPixCntU16 = %d => Bad file format, S32 instead of U16 ?", VRet, VExpectedFileSz ) ); + } + + + // Load + + VRet = FIL_FReadRecord ( FileName, PtDest, sizeof (MIS1__TMatPixCntU16) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => FIL_FReadRecord (PtDest, File=%s) Ret = %d", FileName, VRet) ); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixCntU16Rst ( MIS1__TMatPixCntU16* PtDestFpc ) +* +* \brief : Reset mat pix count +* +* \param : PtSrc - Pointer to the header +* +\param : PixelsNb - Number of pixels to emulate +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 23/06/2020 +* \date : Doc date : 23/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FMatPixCntU16Rst ( MIS1__TMatPixCntU16* PtDestFpc ) { + + SInt32 VPixX; + SInt32 VPixY; + + // Check param + + err_retnull ( PtDestFpc, (ERR_OUT,"Abort => PtDestFpc == NULL") ); + + // MIS1__TTMatPixCntU16[MIS1__COL_NB][MIS1__ROW_NB]; + + for ( VPixY = 0; VPixY < MIS1__ROW_NB; VPixY++ ) { + + for ( VPixX = 0; VPixX < MIS1__COL_NB; VPixX++ ) { + (*PtDestFpc)[VPixX][VPixY] = 0; + } + + } // End for ( VPixY ) + + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FMatPixCntU16Print ( MIS1__TMatPixCntU16* PtSrc, SInt32 CountTh, char* Title, SInt8 Print, SInt32 ExitAFterNPrints, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* +* \brief : Count pixels from MIS1__TMatPixCntU16 with count > CountTh, print them if Print == 1 +* +* \param : PtSrc - Pointer to the header +* +* \param : CountTh - List pixels with hit count > PrintTh, print only if Print == 1 +* +* \param : Print - 0 => No print, 1 => Print +* +* \param : ExitAFterNPrints - Exit function after N pixels print in order to not lock the system \n +* n <= 0 => Not used, print all pixels \n +* n > 0 => Exit after printing n pixels +* +* \param : PrintDest - Print destination, \n +* : 0 => No print, \n +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo \n +* : 4 => text file, 5 => Text file + Memo \n +* +* \return : Error code \n +* : >= 0 - Number of pixel with counter > PrintTh \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 11/06/2020 +* \date : Doc date : 11/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +SInt32 MIS1__FMatPixCntU16Print ( MIS1__TMatPixCntU16* PtSrc, SInt32 CountTh, char* Title, SInt8 Print, SInt32 ExitAFterNPrints, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + SInt32 VxPix; + SInt32 VyPix; + SInt32 VPixNb; + UInt16 VValPix; + char VMsg[GLB_CMT_SZ]; + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + + // Print all pixels detected at 0 / 1 + + if ( ExitAFterNPrints <= 0 ) { + ExitAFterNPrints = MIS1__COL_NB * MIS1__ROW_NB; + } + + + + sprintf ( VMsg, "Print pixels with counter > %d - Cmt : %s", CountTh, Title ); + + MIS1__FPrintStr ( "================================================", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "================================================", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "", PrintDest, Memo, PtFile ); + + // MIS1__TMatPixCntU16[MIS1__COL_NB][MIS1__ROW_NB] + + VPixNb = 0; + + for ( VyPix = 0; VyPix < MIS1__ROW_NB; VyPix++ ) { + + for ( VxPix = 0; VxPix < MIS1__COL_NB; VxPix++ ) { + + VValPix = (*PtSrc)[VxPix][VyPix]; + + if ( VValPix > CountTh ) { + + if ( Print == 1 ) { + sprintf ( VMsg, "Pixel [%.4d] = X=%.4d, Y=%.4d => %.4d", VPixNb, VxPix, VyPix, VValPix ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + } + + VPixNb++; + + if ( VPixNb > ExitAFterNPrints ) { + msg (( MSG_OUT, "Abort before end => Max pix nb to print = %d reached", ExitAFterNPrints )); + MIS1__FPrintStr ( MSG_OUT, PrintDest, Memo, PtFile ); + err_retfail ( -1, (ERR_OUT,"%s", MSG_OUT) ); + } + + + } // End if ( VValPix > PrintTh ) + + } // End for ( VxPix = 0; VxPix < MIS1__COL_NB; VxPix++ ) + + + } // End for ( VyPix = 0; VyPix < ; VyPix++ ) + + + + return (VPixNb); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FEmulDecFrPixFPC ( MIS1__TDecFrPix* PtDest, SInt32 PixelsNb ) +* +* \brief : Emulate PixelsNb pixels, header fields are not modified +* +* \param : PtSrc - Pointer to the header +* +\param : PixelsNb - Number of pixels to emulate +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 23/06/2020 +* \date : Doc date : 23/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +SInt32 MIS1__FEmulDecFpcFrPixPatt0 ( MIS1__TDecFrPix* PtDestDec, MIS1__TMatPixCntU16* PtDestFpcSubStep, MIS1__TMatPixCntU16* PtDestFpcStep, SInt32 PixelsNb ) { + + SInt32 ViPix; + SInt32 VPixX; + SInt32 VPixY; + + + // Check param + + err_retnull ( PtDestDec, (ERR_OUT,"Abort => PtDestDec == NULL") ); + + err_retnull ( PtDestFpcSubStep, (ERR_OUT,"Abort => PtDestFpcSubStep == NULL") ); + + err_retnull ( PtDestFpcStep, (ERR_OUT,"Abort => PtDestFpcStep == NULL") ); + + // Set pixels + + + for ( ViPix=0; ViPix < PixelsNb; ViPix++ ) { + + VPixY = ViPix / 1024; // MSis 1 = 1024 col + VPixX = ViPix % 1024; // MSis 1 = 504 lines + + PtDestDec->APix[ViPix].C.y = VPixY; + PtDestDec->APix[ViPix].C.x = VPixX; + + // MIS1__TTMatPixCntU16[MIS1__COL_NB][MIS1__ROW_NB]; + + (*PtDestFpcSubStep)[VPixX][VPixY]++; + (*PtDestFpcStep)[VPixX][VPixY]++; + + } + + + return (0); +} + + + + +/** +=================================================================================== +* \fn : SInt32 MIS1__FProcEmulDec ( SInt8 FirstAcqOfRun, MIS1__TAcqProc* PtAcqProc, MIS1__TProcMode ProcMode, SInt32 AcqIdInRun, SInt32 AcqIdInFile, SInt32 AcqIdInBuff, SInt8 PrintLvl ) +* +* \brief : Execute emul decode pixels processing fro DAQ tests +* +* \param : FirstAcqOfRun - Flag, 1 => It is the first acq of the run +* +* \param : PtAcqProc - Pointer to acq processing record +* +* \param : ProcMode - Processing mode +* +* \param : AcqIdInRun - Id of acq in run 0 to acq nb in run - 1 +* +* \param : AcqIdInFile - Id of acq in one file of the run, if characterization mode => acq id in current step +* +* \param : AcqIdInBuff - Id of acq in the bloc of acq bufferiezd in mem = for step file +* +* \param : PrintLvl - Print level +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 09/06/2020 +* \date : Rev : 30/06/2020 \n +* - Reduced paramters list, moved to MIS1__TAcqProc +* \date : Doc date : 09/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FProcEmulDec ( SInt8 FirstAcqOfRun, MIS1__TAcqProc* PtAcqProc, MIS1__TProcMode ProcMode, SInt32 AcqIdInRun, SInt32 AcqIdInFile, SInt32 AcqIdInBuff, SInt8 PrintLvl ) { + + + // ======================================================================================================= + // Info on processinf method, data source, destination and buffers + // ======================================================================================================= + // - A number of acq are stored in a memory buffer, this number is defined via the GUI param "Buffered acq nb" + // - The processing can be done acquisition by acquisition or only when this memory buffer is fulled. + // + // - This function is called for each acquisition in the DAQ loop, it knows + // + // -- When the run starts by testing FirstAcqOfRun == 1 + // -- The processing mode via ProcMode, you can use it to check if this function is not called by error ;-) + // -- The id of the acq in the Run via AcqIdInRun, starting at 0 + // -- The id of the acq in the current file via AcqIdInFile, starting at 0 + // -- The id of the acq in the memory buffer via AcqIdInBuff, starting at 0 + // -- When filling of the memory buffer starts by testing AcqIdInBuff == 0 + // -- The maximum number of acq in the memory buffer via VAcqNbPerBuff + // -- The acq number per file via VAcqNbPerFile + // -- The acq number per sub step VAcqNbPerSubStep + // + // Some of the above info avec function parameters ( FirstAcqOfRun, AcqIdInRun, ...) they contain updated + // values since the beginning of the functiuon, others are variables (VAcqNbPerBuff, VAcqNbPerFile ... identifier + // starting by V) their value is only updated after their intialization block. + // + // - Any other run param, info, status can be accessed via four pointers + // -- PtAcqProc, available since beginning of function + // -- VPtRunPar, available after initialzation block + // -- VPtRunInf, available after initialzation block + // -- VPtRunStatus, available after initialzation block + // + // - The source data are organized as an array of Acq, because the FlexRIo returns data acq by acq, + // the destination data are function of the processing goal => different for each processing function + // + // - The source data for the processing and destination results buffers are already allocated and + // access is done via pointers fields in the MIS1__TAcqProc record, local variables are set here for this + // + // -- VPtAcqFrList = Source acq, VPtAcqFrList[n] = acq n in memory buffer, subfields give access to frames + // n = 0 to AcqNbInBuff - 1 + // + // -- VPtDecFrPix = Destination result, per frame, VPtDecFrPix[m] = pixels list for frame m + // m = 0 to ( MIS1__MAX_BUFFERED_ACQ_NB * MIS1__MAX_FR_NB_PER_ACQ ) - 1, buffer should be big enough + // but it is better to check that no access out of buffer space is done. + // As the pixels number can vary each VPtDecFrPix record has a fixed size header MIS1__TDecFrPixHeader + // and a variable pixels list field APix, size information MUST be set at two places via header field + // VPtFrMapDec and the records VPtFrListDec, VPtFrMapDec corresponding to the frame. + // + // -- Records VPtFrListDec, VPtFrMapDec contains information needed to access to the result records of + // processing function, because results records have a variable length. VPtFrListDec, VPtFrMapDec + // MUST be updated by THIS FUNCTION after processing of each frame. The record VPtFrListDec gives + // pointers to results record + some info, the VPtFrMapDec gives same info by pointer are converted + // to offset needed to create the index file. + // + // - The results of the processing, stored in buffer VPtDecFrPix are saved (if enabled) in a file at the + // end of the processing (after processing of AcqNbInBuff - 1) + + + MIS1__TRunPar* VPtRunPar; + MIS1__TRunInf* VPtRunInf; + MIS1__TRunStatus* VPtRunStatus; + + // Variables for parameters removed on 30/06/2020, acces is now done via MIS1__TAcqProc + + SInt32 VAcqNbPerFile; + SInt32 VAcqNbPerSubStep; + SInt32 VAcqNbPerBuff; + FIL__TCBinFile* VPtStepBinFile; + FIL__TCBinFile* VPtSubStepBinFile; + + + + SInt32 VCurAcqFrNb; // Fr nb in the current acq processed by this function + SInt32 VCurAcqFrId; // Fr id fro scanning frame of the current acq processed by this function + static SInt32 VDestFrId; // Result, destination Fr id for indexing destination array + static SInt32 VFrIdInBuff; // Fr id in the memory buffer of size "Buffered acq nb" in GUI + static SInt32 VFrIdInRun; // Fr id since beginning of the run + static UInt32 VFrPos; // Position in W8 / beginning of memory buffer = / beginning of file + // One memory buffer = "Buffered acq nb" = One file, One Run = Many files + + SInt32 VPixNbInFr; + + + MIS1__TAcqProc* VPtAcqProc; // Acquisition processing record, pointers fields to data buffers + MIS1__TAcqFrList* VPtAcqFrList; // List of acq, frames in the source acq to processed + MIS1__TAcqFrMap* VPtAcqFrMap; // Mapping of acq, frames (positions for index file) in the source acq to processed + MIS1__TDecFrList* VPtFrListDec; // List of frames in the destination buffer (already allocated) + MIS1__TDecFrMap* VPtFrMapDec; // Mapping of frames (positions for index file) in the destination buffer (already allocated) + MIS1__TDecFrPix* VPtDecFrPix; // Destination decoded pixels list for each frame, (already allocated) + + + + // Check param + + err_retnull ( PtAcqProc, (ERR_OUT,"Abort => PtAcqProc == NULL") ); + + // Get some parameters + + VPtRunPar = PtAcqProc->PtRunPar; + VPtRunInf = PtAcqProc->PtRunInf; + VPtRunStatus = PtAcqProc->PtRunStatus; + + VAcqNbPerFile = PtAcqProc->PtRunPar->ParAcqNbPerFile; + VAcqNbPerSubStep = PtAcqProc->PtRunPar->ParCarSubStepAcqNb; + VAcqNbPerBuff = PtAcqProc->PtRunPar->ParBufferedAcqNb; + VPtStepBinFile = PtAcqProc->PtOStepFile; + VPtSubStepBinFile = PtAcqProc->PtOSubStepsFile; + + + + if ( AcqIdInBuff >= VAcqNbPerBuff ) { + err_retfail ( -1, (ERR_OUT,"Abort => AcqIdInBuff >= VAcqNbPerBuff", AcqIdInBuff, VAcqNbPerBuff) ); + } + + // Set ptr + + VPtAcqProc = PtAcqProc; // Acquisition processing : scan to find frames list, count fired pixels, etc + VPtAcqFrList = &PtAcqProc->AAcqFrListRaw[AcqIdInBuff]; // List of frames in one acq - Now ONLY ONE acq used + VPtAcqFrMap = &PtAcqProc->AAcqFrMapRaw[AcqIdInBuff]; // List of frames in one acq - Now ONLY ONE acq used + + // Processing + + if ( PrintLvl == 2 ) { + msg (( MSG_OUT, "Proc Dec : AcqIdInRun = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d ", AcqIdInRun, AcqIdInBuff, VAcqNbPerBuff )); + } + + // Detect beginning of the run = First acq of the run + + if ( FirstAcqOfRun == 1 ) { + VFrIdInRun = 0; + } + + // Detect beginnig of processing = First acq stored in memory buffer <=> First acq of test step file + + if ( AcqIdInBuff == 0 ) { + VDestFrId = 0; + VFrIdInBuff = 0; + VFrPos = 0; + } + + VCurAcqFrNb = VPtAcqFrList->ResFrNb; + + + if ( PrintLvl == 1 ) { + msg (( MSG_OUT, "Proc Dec : AcqIdInRun = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d, FrNb = %d", AcqIdInRun, AcqIdInBuff, VAcqNbPerBuff, VCurAcqFrNb )); + } + + + randomize (); + + + // Process all frames of current acq + + for ( VCurAcqFrId = 0; VCurAcqFrId < VCurAcqFrNb; VCurAcqFrId++ ) { + + VPtDecFrPix = &PtAcqProc->ADecFrPix[VDestFrId]; + VPtFrListDec = &PtAcqProc->AFrListDec[VDestFrId]; + VPtFrMapDec = &PtAcqProc->AFrMapDec[VDestFrId]; + + + // msg (( MSG_OUT, "Proc Dec : AcqIdInRun = %d, AcqIdInBuff = %d, AcqNbInBuff = %d, FrNb = %d, VCurAcqFrId = %d", AcqIdInRun, AcqIdInBuff, AcqNbInBuff, VCurAcqFrNb, VCurAcqFrId )); + + + // Decode pixels here => Pixels loop + + // VPixNbInFr = random (100); + + // VPixNbInFr = 0; // VCurAcqFrId; + + VPixNbInFr = VCurAcqFrId; + + MIS1__FEmulDecFrPixPatt0 ( VPtDecFrPix, VPixNbInFr ); + + // Update MIS1__TDecFrPix header + + VPtDecFrPix->H.AcqIdInBuff = AcqIdInBuff; /*!< AcqId <= 65535 */ + VPtDecFrPix->H.FrIdInBuff = VFrIdInBuff; /*!< FrId <= 65535 */ + VPtDecFrPix->H.PixNb = VPixNbInFr; /*!< Number of pixels */ + VPtDecFrPix->H.MSis1FrCnt = 0; /*!< Frame counter from MSis 1 */ + VPtDecFrPix->H.MSis1ChkSum = 0; /*!< Check sum from MSis 1 */ + VPtDecFrPix->H.MSis1Flags = 0; /*!< Flags from MSis 1 */ + + + // Update AFrListDec + + VPtFrListDec->ResAcqIdInRun = AcqIdInRun; // Id of acquisition + VPtFrListDec->ResFrNbInAcq = VCurAcqFrNb; // Frames nb in the acq which contains this frame + VPtFrListDec->ResFrIdInAcq = VCurAcqFrId; // Id frame in its acquisition 0 to max fr nb per acq - 1 + VPtFrListDec->ResFrSz = sizeof ( MIS1__TDecFrPixHeader ) + (VPixNbInFr * sizeof (MIS1__TPixXY) ); // Size of frame in W8 + VPtFrListDec->ResPtFrBeg = VPtDecFrPix; + + + // Update AFrMapDec + + VPtFrMapDec->ResAcqIdInRun = AcqIdInRun; // Id of acquisition + VPtFrMapDec->ResFrNbInAcq = VCurAcqFrNb; // Frames nb in the acq which contains this frame + VPtFrMapDec->ResFrIdInAcq = VCurAcqFrId; // Id frame in its acquisition 0 to max fr nb per acq - 1 + VPtFrMapDec->ResFrSz = VPtFrListDec->ResFrSz; // Size of frame in W8 + + VPtFrMapDec->ResPtFrBeg = VPtDecFrPix; + + VPtFrMapDec->ResFrPos = VFrPos; // Position of fr / Beginning of file in W8 + + + VFrPos += VPtFrMapDec->ResFrSz; + + VFrIdInBuff++; + VFrIdInRun++; + VDestFrId++; + } + + + + + return (0); +} + + + + +/** +=================================================================================== +* \fn : SInt32 MIS1__FProcEmulDecFpc ( SInt8 FirstAcqOfRun, MIS1__TAcqProc* PtAcqProc, MIS1__TProcMode ProcMode, SInt32 AcqIdInRun, SInt32 AcqIdInFile, SInt32 AcqIdInBuff, SInt8 PrintLvl ) +* +* \brief : Execute emul decode pixels + FPC processing for DAQ tests +* +* \param : FirstAcqOfRun - Flag, 1 => It is the first acq of the run +* +* \param : PtAcqProc - Pointer to acq processing record +* +* \param : ProcMode - Processing mode +* +* \param : AcqIdInRun - Id of acq in run 0 to acq nb in run - 1 +* +* \param : AcqIdInFile - Id of acq in one file of the run, if characterization mode => acq id in current step +* +* \param : AcqIdInBuff - Id of acq in the bloc of acq bufferiezd in mem = for step file +* +* \param : PrintLvl - Print level +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 23/06/2020 +* \date : Rev : 30/06/2020 \n +* - Reduced paramters list, moved to MIS1__TAcqProc +* \date : Doc date : 23/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FProcEmulDecFpc ( SInt8 FirstAcqOfRun, MIS1__TAcqProc* PtAcqProc, MIS1__TProcMode ProcMode, SInt32 AcqIdInRun, SInt32 AcqIdInFile, SInt32 AcqIdInBuff, SInt8 PrintLvl ) { + + + // ======================================================================================================= + // Info on processinf method, data source, destination and buffers + // ======================================================================================================= + // - A number of acq are stored in a memory buffer, this number is defined via the GUI param "Buffered acq nb" + // - The processing can be done acquisition by acquisition or only when this memory buffer is fulled. + // + // - This function is called for each acquisition in the DAQ loop, it knows + // + // -- When the run starts by testing FirstAcqOfRun == 1 + // -- The processing mode via ProcMode, you can use it to check if this function is not called by error ;-) + // -- The id of the acq in the Run via AcqIdInRun, starting at 0 + // -- The id of the acq in the current file via AcqIdInFile, starting at 0 + // -- The id of the acq in the memory buffer via AcqIdInBuff, starting at 0 + // -- When filling of the memory buffer starts by testing AcqIdInBuff == 0 + // -- The maximum number of acq in the memory buffer via VAcqNbPerBuff + // -- The acq number per file via VAcqNbPerFile + // -- The acq number per sub step VAcqNbPerSubStep + // + // Some of the above info avec function parameters ( FirstAcqOfRun, AcqIdInRun, ...) they contain updated + // values since the beginning of the function, others are variables (VAcqNbPerBuff, VAcqNbPerFile ... identifier + // starting by V) their value is only updated after their intialization block. + // + // - Any other run param, info, status can be accessed via four pointers + // -- PtAcqProc, available since beginning of function + // -- VPtRunPar, available after initialzation block + // -- VPtRunInf, available after initialzation block + // -- VPtRunStatus, available after initialzation block + // + // - The source data are organized as an array of Acq, because the FlexRIo returns data acq by acq, + // the destination data are function of the processing goal => different for each processing function + // + // - The source data for the processing and destination results buffers are already allocated and + // access is done via pointers fields in the MIS1__TAcqProc record, local variables are set here for this + // + // -- VPtAcqFrList = Source acq, VPtAcqFrList[n] = acq n in memory buffer, subfields give access to frames + // n = 0 to AcqNbInBuff - 1 + // + // -- VPtDecFrPix = Destination result, per frame, VPtDecFrPix[m] = pixels list for frame m + // m = 0 to ( MIS1__MAX_BUFFERED_ACQ_NB * MIS1__MAX_FR_NB_PER_ACQ ) - 1, buffer should be big enough + // but it is better to check that no access out of buffer space is done. + // As the pixels number can vary each VPtDecFrPix record has a fixed size header MIS1__TDecFrPixHeader + // and a variable pixels list field APix, size information MUST be set at two places via header field + // VPtFrMapDec and the records VPtFrListDec, VPtFrMapDec corresponding to the frame. + // + // -- Records VPtFrListDec, VPtFrMapDec contains information needed to access to the result records of + // processing function, because results records have a variable length. VPtFrListDec, VPtFrMapDec + // MUST be updated by THIS FUNCTION after processing of each frame. The record VPtFrListDec gives + // pointers to results record + some info, the VPtFrMapDec gives same info by pointer are converted + // to offset needed to create the index file. + // + // - The results of the processing, stored in buffer VPtDecFrPix are saved (if enabled) in a file at the + // end of the processing (after processing of AcqNbInBuff - 1) + + + MIS1__TRunPar* VPtRunPar; + MIS1__TRunInf* VPtRunInf; + MIS1__TRunStatus* VPtRunStatus; + + // Variables for parameters removed on 30/06/2020, acces is now done via MIS1__TAcqProc + + SInt32 VAcqNbPerFile; + SInt32 VAcqNbPerSubStep; + SInt32 VAcqNbPerBuff; + FIL__TCBinFile* VPtStepBinFile; + FIL__TCBinFile* VPtSubStepBinFile; + + + SInt32 VRet; + + SInt32 VCurAcqFrNb; // Fr nb in the current acq processed by this function + SInt32 VCurAcqFrId; // Fr id fro scanning frame of the current acq processed by this function + static SInt32 VDestFrId; // Result, destination Fr id for indexing destination array + static SInt32 VFrIdInBuff; // Fr id in the memory buffer of size "Buffered acq nb" in GUI + static SInt32 VFrIdInRun; // Fr id since beginning of the run + static UInt32 VFrPos; // Position in W8 / beginning of memory buffer = / beginning of file + // One memory buffer = "Buffered acq nb" = One file, One Run = Many files + + static SInt32 ViSubStep; + static SInt32 ViStep; + + SInt32 VPixNbInFr; + + + MIS1__TAcqProc* VPtAcqProc; // Acquisition processing record, pointers fields to data buffers + MIS1__TAcqFrList* VPtAcqFrList; // List of acq, frames in the source acq to processed + MIS1__TAcqFrMap* VPtAcqFrMap; // Mapping of acq, frames (positions for index file) in the source acq to processed + MIS1__TDecFrList* VPtFrListDec; // List of frames in the destination buffer (already allocated) + MIS1__TDecFrMap* VPtFrMapDec; // Mapping of frames (positions for index file) in the destination buffer (already allocated) + MIS1__TDecFrPix* VPtDecFrPix; // Destination decoded pixels list for each frame, (already allocated) + MIS1__TMatPixCntU16* VPtSubStepPixCnt; // Destination for sub step fired pixels count matrix + MIS1__TMatPixCntU16* VPtStepPixCnt; // Destination for step fired pixels count matrix + + + + // Check param + + err_retnull ( PtAcqProc, (ERR_OUT,"Abort => PtAcqProc == NULL") ); + + // Get some parameters + + VPtRunPar = PtAcqProc->PtRunPar; + VPtRunInf = PtAcqProc->PtRunInf; + VPtRunStatus = PtAcqProc->PtRunStatus; + + VAcqNbPerFile = PtAcqProc->PtRunPar->ParAcqNbPerFile; + VAcqNbPerSubStep = PtAcqProc->PtRunPar->ParCarSubStepAcqNb; + VAcqNbPerBuff = PtAcqProc->PtRunPar->ParBufferedAcqNb; + VPtStepBinFile = PtAcqProc->PtOStepFile; + VPtSubStepBinFile = PtAcqProc->PtOSubStepsFile; + + + if ( AcqIdInBuff >= VAcqNbPerBuff ) { + err_retfail ( -1, (ERR_OUT,"Abort => AcqIdInBuff >= VAcqNbPerBuff", AcqIdInBuff, VAcqNbPerBuff) ); + } + + // Set ptr + + VPtAcqProc = PtAcqProc; // Acquisition processing : scan to find frames list, count fired pixels, etc + VPtAcqFrList = &PtAcqProc->AAcqFrListRaw[AcqIdInBuff]; // List of frames in one acq - Now ONLY ONE acq used + VPtAcqFrMap = &PtAcqProc->AAcqFrMapRaw[AcqIdInBuff]; // List of frames in one acq - Now ONLY ONE acq used + + VPtSubStepPixCnt = PtAcqProc->PtSubStepPixCnt; + VPtStepPixCnt = PtAcqProc->PtStepPixCnt; + + // Processing + + if ( PrintLvl == 2 ) { + msg (( MSG_OUT, "Proc Dec : AcqIdInRun = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d ", AcqIdInRun, AcqIdInBuff, VAcqNbPerBuff )); + } + + // Detect beginning of the run = First acq of the run + + if ( FirstAcqOfRun == 1 ) { + VFrIdInRun = 0; + ViStep = 0; + + + if ( PrintLvl == 3 ) { + msg (( MSG_OUT, "Proc FPC : Beginning of run : AcqIdInRun = %d, AcqIdInFile = %d, VAcqNbPerFile = %d, VAcqNbPerSubStep = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d", AcqIdInRun, AcqIdInFile, VAcqNbPerFile, VAcqNbPerSubStep, AcqIdInBuff, VAcqNbPerBuff )); + } + + } + + // Detect beginning of a new file, if characterization mode => beginning of new step + + if ( AcqIdInFile == 0 ) { + + if ( PrintLvl == 3 ) { + msg (( MSG_OUT, "Proc FPC : Beginning of file : AcqIdInRun = %d, AcqIdInFile = %d, VAcqNbPerFile = %d, VAcqNbPerSubStep = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d", AcqIdInRun, AcqIdInFile, VAcqNbPerFile, VAcqNbPerSubStep, AcqIdInBuff, VAcqNbPerBuff )); + } + + + ViSubStep = 0; + + // Count pixels + + MIS1__FMatPixCntU16Rst ( VPtSubStepPixCnt ); + MIS1__FMatPixCntU16Rst ( VPtStepPixCnt ); + + + if ( (VPtRunPar->ParSaveFPC == MIS1__SFPC_SUB_STEPS) || (VPtRunPar->ParSaveFPC == MIS1__SFPC_ALL) ) { + + // Create a sub step file + + VRet = MIS1__FBuildFileNameSuffix ( VPtRunInf->InfFPCSubStepsFileName, VPtRunInf->InfCurFPCSubStepsFileName, GLB_FILE_PATH_SZ, VPtRunInf->InfSaveFileNo ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Build file name with prefix for step = %d, sub step = %d failed !", ViStep, ViSubStep ) ); + + VRet = VPtSubStepBinFile->PubFSetFileName ( VPtRunInf->InfCurFPCSubStepsFileName ); + + VRet = VPtSubStepBinFile->PubFCreate (); + + err_retfail ( VRet, (ERR_OUT,"Abort => Create file for step = %d, sub step = %d failed !", ViStep, ViSubStep ) ); + + } // End if ( (VPtRunPar->ParSaveFPC == MIS1__SFPC_SUB_STEPS) || (VPtRunPar->ParSaveFPC == MIS1__SFPC_ALL) ) + + + } + + + // Detect beginnig of processing = First acq stored in memory buffer <=> First acq of test step file + + if ( AcqIdInBuff == 0 ) { + VDestFrId = 0; + VFrIdInBuff = 0; + VFrPos = 0; + } + + VCurAcqFrNb = VPtAcqFrList->ResFrNb; + + + if ( PrintLvl == 1 ) { + msg (( MSG_OUT, "Proc FPC : AcqIdInRun = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d, FrNb = %d", AcqIdInRun, AcqIdInBuff, VAcqNbPerBuff, VCurAcqFrNb )); + } + + + randomize (); + + + // Process all frames of current acq + + for ( VCurAcqFrId = 0; VCurAcqFrId < VCurAcqFrNb; VCurAcqFrId++ ) { + + VPtDecFrPix = &PtAcqProc->ADecFrPix[VDestFrId]; + VPtFrListDec = &PtAcqProc->AFrListDec[VDestFrId]; + VPtFrMapDec = &PtAcqProc->AFrMapDec[VDestFrId]; + + + // msg (( MSG_OUT, "Proc Dec : AcqIdInRun = %d, AcqIdInBuff = %d, AcqNbInBuff = %d, FrNb = %d, VCurAcqFrId = %d", AcqIdInRun, AcqIdInBuff, AcqNbInBuff, VCurAcqFrNb, VCurAcqFrId )); + + + // Decode pixels here => Pixels loop + + // VPixNbInFr = random (100); + + VPixNbInFr = VCurAcqFrId; + + + MIS1__FEmulDecFpcFrPixPatt0 ( VPtDecFrPix, VPtSubStepPixCnt, VPtStepPixCnt, VPixNbInFr ); + + + // Update MIS1__TDecFrPix header + + VPtDecFrPix->H.AcqIdInBuff = AcqIdInBuff; /*!< AcqId <= 65535 */ + VPtDecFrPix->H.FrIdInBuff = VFrIdInBuff; /*!< FrId <= 65535 */ + VPtDecFrPix->H.PixNb = VPixNbInFr; /*!< Number of pixels */ + VPtDecFrPix->H.MSis1FrCnt = 0; /*!< Frame counter from MSis 1 */ + VPtDecFrPix->H.MSis1ChkSum = 0; /*!< Check sum from MSis 1 */ + VPtDecFrPix->H.MSis1Flags = 0; /*!< Flags from MSis 1 */ + + + // Update AFrListDec + + VPtFrListDec->ResAcqIdInRun = AcqIdInRun; // Id of acquisition + VPtFrListDec->ResFrNbInAcq = VCurAcqFrNb; // Frames nb in the acq which contains this frame + VPtFrListDec->ResFrIdInAcq = VCurAcqFrId; // Id frame in its acquisition 0 to max fr nb per acq - 1 + VPtFrListDec->ResFrSz = sizeof ( MIS1__TDecFrPixHeader ) + (VPixNbInFr * sizeof (MIS1__TPixXY) ); // Size of frame in W8 + VPtFrListDec->ResPtFrBeg = VPtDecFrPix; + + + // Update AFrMapDec + + VPtFrMapDec->ResAcqIdInRun = AcqIdInRun; // Id of acquisition + VPtFrMapDec->ResFrNbInAcq = VCurAcqFrNb; // Frames nb in the acq which contains this frame + VPtFrMapDec->ResFrIdInAcq = VCurAcqFrId; // Id frame in its acquisition 0 to max fr nb per acq - 1 + VPtFrMapDec->ResFrSz = VPtFrListDec->ResFrSz; // Size of frame in W8 + + VPtFrMapDec->ResPtFrBeg = VPtDecFrPix; + + VPtFrMapDec->ResFrPos = VFrPos; // Position of fr / Beginning of file in W8 + + + VFrPos += VPtFrMapDec->ResFrSz; + + VFrIdInBuff++; + VFrIdInRun++; + VDestFrId++; + } + + // Detect end of sub step => save to file + + if ( (AcqIdInFile + 1) % VAcqNbPerSubStep == 0 ) { + + if ( PrintLvl == 3 ) { + msg (( MSG_OUT, "Proc FPC : End of sub step No %.4d : AcqIdInRun = %d, AcqIdInFile = %d, VAcqNbPerFile = %d, VAcqNbPerSubStep = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d", ViSubStep, AcqIdInRun, AcqIdInFile, VAcqNbPerFile, VAcqNbPerSubStep, AcqIdInBuff, VAcqNbPerBuff )); + } + + + if ( (VPtRunPar->ParSaveFPC == MIS1__SFPC_SUB_STEPS) || (VPtRunPar->ParSaveFPC == MIS1__SFPC_ALL) ) { + + // Save sub step record to sub step file file + + VRet = VPtSubStepBinFile->PubFSeqWrite ( VPtAcqProc->PtSubStepPixCnt, sizeof (MIS1__TMatPixCntU16) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Saving sub step file = %s failed !", VPtSubStepBinFile->PubFGetFileName () )); + + } // End if ( (VPtRunPar->ParSaveFPC == MIS1__SFPC_SUB_STEPS) || (VPtRunPar->ParSaveFPC == MIS1__SFPC_ALL) ) + + + ViSubStep++; + } + + // Detect end of step + + if ( (AcqIdInFile + 1) == VAcqNbPerFile ) { + + if ( PrintLvl == 3 ) { + msg (( MSG_OUT, "Proc FPC : End of step No %.4d : AcqIdInRun = %d, AcqIdInFile = %d, VAcqNbPerFile = %d, VAcqNbPerSubStep = %d, AcqIdInBuff = %d, VAcqNbPerBuff = %d", ViStep, AcqIdInRun, AcqIdInFile, VAcqNbPerFile, VAcqNbPerSubStep, AcqIdInBuff, VAcqNbPerBuff )); + } + + + if ( VPtRunPar->ParSaveFPC == MIS1__SFPC_ALL ) { + + // Save STEP record to SUB STEP file file + + VRet = VPtSubStepBinFile->PubFSeqWrite ( VPtAcqProc->PtStepPixCnt, sizeof (MIS1__TMatPixCntU16) ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Saving sub step file = %s failed !", VPtSubStepBinFile->PubFGetFileName () )); + + } // End if ( VPtRunPar->ParSaveFPC == MIS1__SFPC_ALL ) + + + if ( (VPtRunPar->ParSaveFPC == MIS1__SFPC_SUB_STEPS) || (VPtRunPar->ParSaveFPC == MIS1__SFPC_ALL) ) { + + // Close sub step file + + VRet = VPtSubStepBinFile->PubFClose (); + + err_retfail ( VRet, (ERR_OUT,"Abort => Close sub step file = %s failed !", VPtSubStepBinFile->PubFGetFileName () )); + + } // End if ( (VPtRunPar->ParSaveFPC == MIS1__SFPC_SUB_STEPS) || (VPtRunPar->ParSaveFPC == MIS1__SFPC_ALL) ) + + + + ViStep++; + } + + return (0); +} + + + + +/** +=================================================================================== +* \fn : SInt32 MIS1__FProc ( SInt8 FirstAcqOfRun, MIS1__TAcqProc* PtAcqProc, MIS1__TProcMode ProcMode, SInt32 AcqIdInRun, SInt32 AcqIdInFile, SInt32 AcqNbInFile, SInt32 AcqNbPerSubStep, SInt32 AcqIdInBuff, SInt32 AcqNbInBuff, SInt8 PrintLvl ) +* +* \brief : Execute acq processing, call processing function selected by ProcMode param +* +* \param : FirstAcqOfRun - Flag, 1 => It is the first acq of the run +* +* \param : PtAcqProc - Pointer to acq processing record +* +* \param : ProcMode - Processing mode +* +* \param : AcqIdInRun - Id of acq in run 0 to acq nb in run - 1 +* +* \param : AcqIdInFile - Id of acq in one file of the run, if characterization mode => acq id in current step +* +* \param : AcqNbInFile - Number of acq in one file of the run, if characterization mode => acq nb per step +* +* \param : AcqNbPerSubStep - If characterization mode => number of acq in current sub step +* +* \param : AcqIdInBuff - Id of acq in the bloc of acq bufferiezd in mem = for step file +* +* \param : AcqNbInBuff - Number of acq in the bloc of acq bufferiezd in mem = for step file +* +* \param : PrintLvl - Print level +* +* \param : PtStepBinFile - Step file TCBinFile object pointer +* +* \param : PtSubStepBinFile - Sub step file TCBinFile object pointer +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 08/06/2020 +* \date : Doc date : 08/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FProc ( SInt8 FirstAcqOfRun, MIS1__TAcqProc* PtAcqProc, MIS1__TProcMode ProcMode, SInt32 AcqIdInRun, SInt32 AcqIdInFile, SInt32 AcqIdInBuff, SInt8 PrintLvl ) { + + SInt32 VRet; + + switch ( ProcMode ) { + + case PM_NONE : { + break; } + + case PM_DECODE_FR : { + VRet = MIS1__FProcDec ( FirstAcqOfRun, PtAcqProc, ProcMode, AcqIdInRun, AcqIdInFile, AcqIdInBuff, PrintLvl ); + break; } + + case PM_DECODE_FR_CNT_PIX : { + break; } + + case PM_EMUL_DECODE_FR_DAQ_TEST : { + VRet = MIS1__FProcEmulDec ( FirstAcqOfRun, PtAcqProc, ProcMode, AcqIdInRun, AcqIdInFile, AcqIdInBuff, PrintLvl ); + break; } + + + case PM_EMUL_DECODE_FR_FPC_DAQ_TEST : { + VRet = MIS1__FProcEmulDecFpc ( FirstAcqOfRun, PtAcqProc, ProcMode, AcqIdInRun, AcqIdInFile, AcqIdInBuff, PrintLvl ); + break; } + + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => Unknown ProcMode = %d ", ProcMode ) ); + break; } + } + + err_retfail ( VRet, (ERR_OUT,"Abort => Prcoessing function failed") ); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPrintDecFrPixHeader ( MIS1__TDecFrPixHeader* PtSrc, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* +* \brief : Print the header of MIS1__TDecFrPix record +* +* \param : PtSrc - Pointer to the header +* +* \param : PrintDest - Print destination, \n +* 0 => No print, \n +* 1 => msg file , 2 => Memo, 3 => Msg file + Memo \n +* 4 => text file, 5 => Text file + Memo \n +* \n +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 11/06/2020 +* \date : Doc date : 11/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FPrintDecFrPixHeader ( MIS1__TDecFrPixHeader* PtSrc, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + char VMsg[GLB_CMT_SZ]; + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + // Print + + MIS1__FPrintStr ( "==================================", PrintDest, Memo, PtFile ); + sprintf ( VMsg, "Acq id in buffer / file = %.4d", PtSrc->AcqIdInBuff ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + sprintf ( VMsg, "Fr id in buffer / file = %.4d", PtSrc->FrIdInBuff ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + sprintf ( VMsg, "Pixel number in frame = %.4d", PtSrc->PixNb ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + sprintf ( VMsg, "MSis 1 frame cnt = %.4d",PtSrc->MSis1FrCnt ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + sprintf ( VMsg, "MSis 1 check sum = %.4X [H]", PtSrc->MSis1ChkSum ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + sprintf ( VMsg, "MSis 1 trailer + flags = %.4X [H]", PtSrc->MSis1Flags); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "==================================", PrintDest, Memo, PtFile ); + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPrintDecFrPix ( MIS1__TDecFrPix* PtSrc, SInt8 PrintHeader, SInt32 FirstPix, SInt32 LastPix, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* +* \brief : Print MIS1__TDecFrPix record header and / or pixels list +* +* \param : PtSrc - Pointer to the header +* +\param : PrintHeader - 1 => Print header, 0 => No +* +* \param : FirstPix - First pixel to print +* +* \param : LastPix - Last pixel to print, or -1 to print ALL pixel starting at FirstPix +* +* \param : PrintDest - Print destination, \n +* : 0 => No print, \n +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo \n +* : 4 => text file, 5 => Text file + Memo \n +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : To print ONLY the header set PrintHeader= 1 and FirstPix = LastPix= -1 +* \warning : Level : +* +* Items not filled now : \n +* todo : +* : +* bug : +* : +* \date : Date : 11/06/2020 +* \date : Doc date : 11/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +SInt32 MIS1__FPrintDecFrPix ( MIS1__TDecFrPix* PtSrc, SInt8 PrintHeader, SInt32 FirstPix, SInt32 LastPix, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + SInt32 ViPix; + SInt32 VPixNb; + char VMsg[GLB_CMT_SZ]; + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + // Print header + + if ( PrintHeader ) { + MIS1__FPrintDecFrPixHeader ( &(PtSrc->H), PrintDest, Memo, PtFile ); + } + + // No print of pixels list + + if ( (FirstPix== -1 ) && (LastPix== -1 ) ) { + return (0); + } + + // Print all pixels + + VPixNb = PtSrc->H.PixNb; + + if ( VPixNb == 0 ) { + + sprintf ( VMsg, "Acq in buff / file = %.4d, Fr = %.4d => No pixel ", PtSrc->H.AcqIdInBuff, PtSrc->H.FrIdInBuff ); + + MIS1__FPrintStr ( "================================================", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "================================================", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "", PrintDest, Memo, PtFile ); + + return (0); + } + + + sprintf ( VMsg, "Acq in buff / file = %.4d, Fr = %.4d => %d pixels ", PtSrc->H.AcqIdInBuff, PtSrc->H.FrIdInBuff, VPixNb ); + + MIS1__FPrintStr ( "================================================", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "================================================", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "", PrintDest, Memo, PtFile ); + + + + for ( ViPix=0; ViPix < VPixNb; ViPix++ ) { + sprintf ( VMsg, "Pixel [%.4d] = X=%.4d, Y=%.4d", ViPix, PtSrc->APix[ViPix].C.x , PtSrc->APix[ViPix].C.y ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + } + + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FSelPixMatResetSet ( MIS1__TMatPixSelPix* PtDestMat, SInt8 ResetSet ) +* +* \brief : Reset or set all pixels of p�xels select matrix +* +* \param : PtDestMat - Pointer to destination matrix +* +* \param : ResetSet - 0 => Reset, 1 => Set +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 18/06/2020 +* \date : Doc date : 18/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FSelPixMatResetSet ( MIS1__TMatPixSelPix* PtDestMat, SInt8 ResetSet ) { + + UInt16 ViCol; + UInt16 ViRow; + + + // Check param + + err_retnull ( PtDestMat, (ERR_OUT,"Abort => PtDestMat == NULL") ); + + + // Fill matrix + + // MIS1__TMatPixSelPix[MIS1__COL_NB][MIS1__ROW_NB] + + for ( ViCol = 0; ViCol < MIS1__COL_NB; ViCol++ ) { + + for ( ViRow = 0; ViRow < MIS1__ROW_NB; ViRow++ ) { + (*PtDestMat)[ViCol][ViRow] = ResetSet; + } + + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FSelPixMatPrint ( MIS1__TMatPixSelPix* PtSrcMat, SInt8 PrintZeroOne, SInt32 ExitAFterNPrints, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* +* \brief : +* +* \param : PtSrcMat - Pointer to source matrix +* +* \param : PrintZeroOne - 0 => Print pixels at 0, 1 => Print pixel at 1 +* +* \param : ExitAFterNPrints - Exit function after N pixels print in order to not lock the system \n +* n <= 0 => Not used, print all pixels \n +* n > 0 => Exit after printing n pixels +* +* \param : PrintDest - Print destination, \n +* : 0 => No print, \n +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo \n +* : 4 => text file, 5 => Text file + Memo \n +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 18/06/2020 +* \date : Doc date : 18/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FSelPixMatPrint ( MIS1__TMatPixSelPix* PtSrcMat, SInt8 PrintZeroOne, SInt32 ExitAFterNPrints, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + UInt16 ViCol; + UInt16 ViRow; + SInt32 ViPix; + char VMsg[GLB_CMT_SZ]; + + // Check param + + err_retnull ( PtSrcMat, (ERR_OUT,"Abort => PtSrcMat == NULL") ); + + // Print matrix + + + if ( PrintZeroOne == 0 ) { + MIS1__FPrintStr ( "---------------------------------", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( " List pixels at 0 ", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "---------------------------------", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "", PrintDest, Memo, PtFile ); + } + + else { + MIS1__FPrintStr ( "---------------------------------", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( " List pixels at 1 ", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "---------------------------------", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "", PrintDest, Memo, PtFile ); + } + + + // MIS1__TMatPixSelPix[MIS1__COL_NB][MIS1__ROW_NB] + + // Print all pixels detected at 0 / 1 + + if ( ExitAFterNPrints <= 0 ) { + ExitAFterNPrints = MIS1__COL_NB * MIS1__ROW_NB; + } + + + ViPix = 0; + + // Print 0 + + if ( PrintZeroOne == 0 ) { + + for ( ViCol = 0; ViCol < MIS1__COL_NB; ViCol++ ) { + + for ( ViRow = 0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + if ( (*PtSrcMat)[ViCol][ViRow] == 0 ) { + sprintf ( VMsg, "Pix [%.04d,%.04d] = 0", ViCol, ViRow ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + ViPix++; + } + + + if ( ViPix >= ExitAFterNPrints ) { + msg (( MSG_OUT, "Abort before end => Max pix nb to print = %d reached", ExitAFterNPrints )); + MIS1__FPrintStr ( MSG_OUT, PrintDest, Memo, PtFile ); + err_retfail ( -1, (ERR_OUT,"%s", MSG_OUT) ); + } + + + } // End for ( ViCol ) + + } // End for ( ViRow ) + + } + + // Print 1 + + else { + + for ( ViCol = 0; ViCol < MIS1__COL_NB; ViCol++ ) { + + for ( ViRow = 0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + if ( (*PtSrcMat)[ViCol][ViRow] == 1 ) { + sprintf ( VMsg, "Pix [%.04d,%.04d] = 1", ViCol, ViRow ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + ViPix++; + } + + + if ( ViPix >= ExitAFterNPrints ) { + msg (( MSG_OUT, "Abort before end => Max pix nb to print = %d reached", ExitAFterNPrints )); + MIS1__FPrintStr ( MSG_OUT, PrintDest, Memo, PtFile ); + err_retfail ( -1, (ERR_OUT,"%s", MSG_OUT) ); + } + + } // End for ( ViCol ) + + } // End for ( ViRow ) + + + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__FSelPixMatToList ( MIS1__TMatPixSelPix* PtSrcMat, MIS1__TPixXY* PtDest, UInt32 MaxDestESz, SInt8 ListZeroOne ) +* +* \brief : Build a list from the matrix +* +* \param : None +* +* \param : ListZeroOneAll - 0 => List only pixels at 0 \n +* - 1 => List only pixels at 1 \n +* - 2 => List all pixels, regardless of their state \n +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : >= 0 - Nb of pixels at 0 or 1 detected and filled in destination list \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 22/06/2020 +* \date : Doc date : 22/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FSelPixMatToList ( MIS1__TMatPixSelPix* PtSrcMat, MIS1__TPixXY* PtDest, UInt32 MaxDestESz, SInt8 ListZeroOne ) { + + UInt16 ViCol; + UInt16 ViRow; + SInt32 ViPix; + + + // Check param + + err_retnull ( PtSrcMat, (ERR_OUT,"Abort => PtSrcMat == NULL") ); + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + // Fill list + + ViPix = 0; + + // Print 0 + + if ( ListZeroOne == 0 ) { + + for ( ViCol = 0; ViCol < MIS1__COL_NB; ViCol++ ) { + + for ( ViRow = 0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + if ( (*PtSrcMat)[ViCol][ViRow] == 0 ) { + + PtDest[ViPix].C.x = ViCol; + PtDest[ViPix].C.y = ViRow; + + ViPix++; + + if ( ViPix >= MaxDestESz) { + err_retfail ( -1, (ERR_OUT,"Abort => Stopped %d pixels at 0 listed, destination array size reached", ViPix) ); + } + + } + + } // End for ( ViCol ) + + } // End for ( ViRow ) + + } + + // Print 1 + + else { + + for ( ViCol = 0; ViCol < MIS1__COL_NB; ViCol++ ) { + + for ( ViRow = 0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + if ( (*PtSrcMat)[ViCol][ViRow] == 1 ) { + + PtDest[ViPix].C.x = ViCol; + PtDest[ViPix].C.y = ViRow; + + ViPix++; + + if ( ViPix >= MaxDestESz) { + err_retfail ( -1, (ERR_OUT,"Abort => Stopped %d pixels at 1 listed, destination array size reached", ViPix) ); + } + + } + + + } // End for ( ViCol ) + + } // End for ( ViRow ) + + + } + + return (ViPix); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FSelPixListToMat ( MIS1__TPixXY* PtSrcList, UInt32 SrcPixNb , MIS1__TMatPixSelPix* PtDestMat, SInt8 SrcListZeroOne ) +* +* \brief : Build a matrix from the list +* +* \param : None +* +* \param : SrcListZeroOne - 0 => Source list contains pixels at 0 \n +* - 1 => Source list contains pixels at 1 \n +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 22/06/2020 +* \date : Doc date : 22/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FSelPixListToMat ( MIS1__TPixXY* PtSrcList, UInt32 SrcPixNb , MIS1__TMatPixSelPix* PtDestMat, SInt8 SrcListZeroOne ) { + + UInt16 ViCol; + UInt16 ViRow; + SInt32 ViPix; + + + // Check param + + err_retnull ( PtSrcList, (ERR_OUT,"Abort => PtSrcList == NULL") ); + + err_retnull ( PtDestMat, (ERR_OUT,"Abort => PtDestMat == NULL") ); + + // --------------------------------------------- + // Source list contains pixels at 0 + // --------------------------------------------- + + if ( SrcListZeroOne == 0 ) { + + // Fill matrix with 1 + + for ( ViCol = 0; ViCol < MIS1__COL_NB; ViCol++ ) { + + for ( ViRow = 0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + (*PtDestMat)[ViCol][ViRow] = 1; + + } // End for ( ViCol ) + + } // End for ( ViRow ) + + + // Set pixels at 0 + + for ( ViPix = 0 ; ViPix < SrcPixNb; ViPix++ ) { + (*PtDestMat)[PtSrcList[ViPix].C.x][PtSrcList[ViPix].C.y] = 0; + } + + + } // End if ( SrcListZeroOne == 0 ) + + + // --------------------------------------------- + // Source list contains pixels at 1 + // --------------------------------------------- + + else { + + // Fill matrix with 0 + + for ( ViCol = 0; ViCol < MIS1__COL_NB; ViCol++ ) { + + for ( ViRow = 0; ViRow < MIS1__ROW_NB; ViRow++ ) { + + (*PtDestMat)[ViCol][ViRow] = 0; + + } // End for ( ViCol ) + + } // End for ( ViRow ) + + + // Set pixels at 1 + + for ( ViPix = 0 ; ViPix < SrcPixNb; ViPix++ ) { + (*PtDestMat)[PtSrcList[ViPix].C.x][PtSrcList[ViPix].C.y] = 1; + } + + + } // End else + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FPixListPrint ( MIS1__TPixXY* PtSrcList, UInt32 SrcPixNb, SInt32 ExitAFterNPrints, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* +* \brief : Print pixels x, y list +* +* \param : None +* +* +* \param : ExitAFterNPrints - Exit function after N pixels print in order to not lock the system \n +* n <= 0 => Not used, print all pixels \n +* n > 0 => Exit after printing n pixels +* +* \param : PrintDest - Print destination, \n +* 0 => No print, \n +* 1 => msg file , 2 => Memo, 3 => Msg file + Memo \n +* 4 => text file, 5 => Text file + Memo \n +* \n +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 22/06/2020 +* \date : Doc date : 22/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FPixListPrint ( MIS1__TPixXY* PtSrcList, UInt32 SrcPixNb, SInt32 ExitAFterNPrints, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + SInt32 ViPix; + + char VMsg[GLB_CMT_SZ]; + + + // Check param + + err_retnull ( PtSrcList, (ERR_OUT,"Abort => PtSrcList == NULL") ); + + + // Print + + MIS1__FPrintStr ( "------------------------------", PrintDest, Memo, PtFile ); + sprintf ( VMsg, "Print pixels list = %d pixels", SrcPixNb ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "------------------------------", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "", PrintDest, Memo, PtFile ); + + for ( ViPix = 0; ViPix < SrcPixNb; ViPix++ ) { + + if ( ViPix >= ExitAFterNPrints ) { + msg (( MSG_OUT, "Abort before end => Max pix nb to print = %d reached", ExitAFterNPrints )); + MIS1__FPrintStr ( MSG_OUT, PrintDest, Memo, PtFile ); + err_retfail ( -1, (ERR_OUT,"%s", MSG_OUT) ); + } + + sprintf ( VMsg, "Pix [%.04d,%.04d] = 1", PtSrcList[ViPix].C.x, PtSrcList[ViPix].C.y ); + + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FBuildFileNameSuffix ( char* Src, char* Dest, UInt16 MaxDestSz, SInt32 Suffix) +* +* \brief : Add a suffix to a file name +* +* \param : Src - Source file name string +* +* \param : Dest - Destination file name string +* +* \param : MaxDestSz - Maximum size of destination string, including terminal 0 +* +* \param : Suffix - The number suffix to add, inot used if < 0 +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 23/06/2020 +* \date : Doc date : 23/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +MIS1__FBuildFileNameSuffix ( char* Src, char* Dest, UInt16 MaxDestSz, SInt32 Suffix) { + + SInt16 VFileNameLength; + char VFileNameWithoutExt[GLB_FILE_PATH_SZ]; + + // Check param + + err_retnull ( Src, (ERR_OUT,"Abort => Src == NULL ") ); + + err_retnull ( Dest,(ERR_OUT,"Abort => Dest == NULL ") ); + + // Brute force method for dest size checking + + if ( MaxDestSz < GLB_FILE_PATH_SZ ) { + err_retfail ( -1, (ERR_OUT,"Abort => Destination max sz = %d < GLB_FILE_PATH_SZ = %d ", MaxDestSz, GLB_FILE_PATH_SZ) ); + } + + // Build file name + + VFileNameLength = strlen (Src); + + if ( Suffix >= 0) { + strncpy ( VFileNameWithoutExt, Src, VFileNameLength-4 ); // Cpy src without extension + VFileNameWithoutExt[VFileNameLength-4] = 0; + sprintf ( Dest, "%s_%.4d.bin", VFileNameWithoutExt, Suffix ); + } + + else { + sprintf ( Dest, "%s", Src ); + } + + + err_retok (( ERR_OUT, "" )); + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunCnfLUpdStepSubStep ( UInt32 Step, UInt32 SubStep, MIS1__TRunCnfLight* PtDest ) +* +* \brief : Update files names for Step, SubStep +* +* \param : RunRootDir - Run root directory, without terminal / +* +* \param : RunNo - Run number +* +* \param : PtDest - Pointer to MIS1__TRunCnfLight record +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 23/06/2020 +* \date : Doc date : 23/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunCnfLUpdStepSubStep ( UInt32 Step, UInt32 SubStep, MIS1__TRunCnfLight* PtDest ) { + + // Check param + + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + + if ( Step >= MIS1__CAR_MAX_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => Step = %d > Max = %d", Step, MIS1__CAR_MAX_STEP_NB - 1) ); + } + + if ( SubStep >= MIS1__CAR_MAX_SUB_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => SubStep = %d > Max = %d", SubStep, MIS1__CAR_MAX_SUB_STEP_NB - 1) ); + } + + + // Set + + PtDest->CurStepNo = Step; + PtDest->CurSubStepNo = SubStep; + + // Build files names + + sprintf ( PtDest->CurStepFileFpcBin , "%s/run_%d_%d_step.bin" , PtDest->DirData, PtDest->ParRunNo, PtDest->CurStepNo ); + sprintf ( PtDest->CurSubStepsFileFpcBin, "%s/run_%d_%d_sub_step.bin", PtDest->DirData, PtDest->ParRunNo, PtDest->CurStepNo ); + sprintf ( PtDest->CurSubStepsFileRawBin, "%s/run_%d_%d_raw.bin", PtDest->DirData, PtDest->ParRunNo, PtDest->CurStepNo ); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunCnfLSet ( UInt32 Format, char* RunRootDir, UInt32 RunNo, UInt32 StepNb, UInt32 SubStepNb, UInt32 SubStepMode, UInt32 FrNb, SInt8 SaveRaw, SInt8 SaveSubStepFpc, SInt8 SaveStepFpc, MIS1__TRunCnfLight* PtDest ) +* +* \brief : Set run conf light +* +* \param : RunRootDir - Run root directory, without terminal / +* +* \param : RunNo - Run number +* +* \param : PtDest - Pointer to MIS1__TRunCnfLight record +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 23/06/2020 +* \date : Doc date : 23/06/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunCnfLSet ( UInt32 Format, char* RunRootDir, UInt32 RunNo, UInt32 StepNb, UInt32 SubStepNb, UInt32 SubStepMode, UInt32 FrNb, SInt8 SaveRaw, SInt8 SaveSubStepFpc, SInt8 SaveStepFpc, MIS1__TRunCnfLight* PtDest ) { + + // Check param + + err_retnull ( RunRootDir, (ERR_OUT,"Abort => RunRootDir == NULL") ); + + err_retnull ( PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + // Reset destination record + + memset ( PtDest, 0, sizeof (MIS1__TRunCnfLight) ); + + + if ( StepNb > MIS1__CAR_MAX_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => StepNb = %d > Max = %d", StepNb, MIS1__CAR_MAX_STEP_NB) ); + } + + if ( SubStepNb > MIS1__CAR_MAX_SUB_STEP_NB ) { + err_retfail ( -1, (ERR_OUT,"Abort => SubStepNb = %d > Max = %d", SubStepNb, MIS1__CAR_MAX_SUB_STEP_NB) ); + } + + /*!< Data format version in a human readable way */ + + switch ( Format ) { + + case 0 : { + sprintf ( PtDest->ParFormatStr, "ParFormat = %d => Default format", Format ); + break; } + + case 1 : { + sprintf ( PtDest->ParFormatStr, "ParFormat = %d => Format No 1", Format ); + break; } + + default : { + sprintf ( PtDest->ParFormatStr, "ParFormat = %d => Unknown format => Abort", Format ); + err_retfail ( -1, (ERR_OUT,"MsgFail") ); + break; } + + } + + /*!< SubStepMode version in a human readable way */ + + switch ( SubStepMode ) { + + case 0 : { + sprintf ( PtDest->ParSubStepModeStr, "SubStepMode = %d => Default sub step mode", SubStepMode ); + break; } + + case 1 : { + sprintf ( PtDest->ParSubStepModeStr, "SubStepMode = %d => Sub step mode 1", SubStepMode ); + break; } + + default : { + sprintf ( PtDest->ParSubStepModeStr, "SubStepMode = %d => Unknown sub step mode => Abort", SubStepMode ); + err_retfail ( -1, (ERR_OUT,"MsgFail") ); + break; } + + } + + + // Build + + // Param + + PtDest->ParFormat = Format; /*!< Data format version */ + + + PtDest->ParRunNo = RunNo; /*!< Run number */ + PtDest->ParStepNb = StepNb; /*!< Steps nb = scan param step nb */ + PtDest->ParSubStepNb = SubStepNb; /*!< Sub steps nb = number of pixels groups needed to perform a step */ + + PtDest->ParSubStepMode = SubStepMode; /*!< Sub step mode = how is configured each sub step */ + + PtDest->ParFrNb = FrNb; /*!< Frame number used for each sustep / step */ + + // TO BE DONE + // Building ParASteps, ParASubSteps, in function of SubStepMode + // + // + // MIS1__TStepPar ParASteps[MIS1__CAR_MAX_STEP_NB]; /*!< Parametrs of each step */ + // MIS1__TSubStepPar ParASubSteps[MIS1__CAR_MAX_SUB_STEP_NB]; /*!< Parametrs of each sub step = pixels tested */ + + PtDest->ParSaveRaw = SaveRaw; /*!< Save raw data for each sub steps */ + PtDest->ParSaveSubStepFpc = SaveSubStepFpc; /*!< Save FPC for each sub step */ + PtDest->ParSaveStepFpc = SaveStepFpc; /*!< Save FPC for each step */ + + + sprintf ( PtDest->ParRootDir, "%s", RunRootDir ); // Ex : C:/tmp/iphc/msis1/res/ + + + // Inf + + sprintf ( PtDest->Dir, "%s/run_%d", PtDest->ParRootDir, PtDest->ParRunNo ); // Ex : C:/tmp/iphc/msis1/res/run_0 + + sprintf ( PtDest->DirData, "%s/data", PtDest->Dir ); // Ex : C:/tmp/iphc/msis1/res/run_0/data + sprintf ( PtDest->DirTxt , "%s/txt" , PtDest->Dir ); // Ex : C:/tmp/iphc/msis1/res/run_0/txt + sprintf ( PtDest->DirPlot, "%s/plot", PtDest->Dir ); // Ex : C:/tmp/iphc/msis1/res/run_0/plot + + + +// sprintf ( VCumFile, "%s/data/run_%d_%d_cum.bin", APP__VGRunDir, APP__VGRunNo, APP__VGRunFileIndex0 ); + + + // Files + + PtDest->CurStepNo = 0; + PtDest->CurSubStepNo = 0; + + + MIS1__FRunCnfLUpdStepSubStep ( PtDest->CurStepNo, PtDest->CurSubStepNo, PtDest ); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRunCnfLPrint ( MIS1__TRunCnfLight* PtSrc, SInt8 PrintDest, TMemo* Memo, char* FileName) +* +* \brief : Print MIS1__TRunCnfLight record +* +* \param : PtSrc - Ptr to record +* +* \param : PrintDest - Print destination, +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* +* \param : FileName - Fine path +name if PrintDest = 4 or 5 +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 07/10/2020 +* \date : Doc date : 07/10/2020 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FRunCnfLPrint ( MIS1__TRunCnfLight* PtSrc, SInt8 PrintDest, TMemo* Memo, char* FileName) { + + FILE* VPtFile; + char VStr[GLB_CMT_SZ]; + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + // Create text file + + if ( (PrintDest == 4) || (PrintDest == 5) ) { + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + VPtFile = fopen ( FileName, "wt" ); + + err_retnull ( VPtFile, (ERR_OUT,"Abort => Create text file = %s failed !", FileName) ); + } + + // Print + + MIS1__FPrintStr ( "================================================", PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParFormat = %d", PtSrc->ParFormat ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParFormatStr = %s ", PtSrc->ParFormatStr ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + MIS1__FPrintStr ( "------------------------------------------------", PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParRunNo = %d", PtSrc->ParRunNo ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParStepNb = %d", PtSrc->ParStepNb ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParSubStepNb = %d", PtSrc->ParSubStepNb ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParSubStepMode = %d", PtSrc->ParSubStepMode ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParSubStepModeStr = %s ", PtSrc->ParSubStepModeStr ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParFrNb = %d", PtSrc->ParFrNb ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "MIS1__TStepPar - Not printed" ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "MIS1__TSubStepPar - Not printed"); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + MIS1__FPrintStr ( "------------------------------------------------", PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParSaveRaw = %d", PtSrc->ParSaveRaw ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParSaveSubStepFpc = %d", PtSrc->ParSaveSubStepFpc ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "ParSaveStepFpc = %d", PtSrc->ParSaveStepFpc ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + MIS1__FPrintStr ( "------------------------------------------------", PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "Dir = %s", PtSrc->Dir ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "DirData = %s", PtSrc->DirData ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "DirTxt = %s", PtSrc->DirTxt ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "DirPlot ", PtSrc->DirPlot ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + + sprintf ( VStr, "CurStepFileFpcBin = %s", PtSrc->CurStepFileFpcBin ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + + sprintf ( VStr, "CurSubStepsFileFpcBin = %s", PtSrc->CurSubStepsFileFpcBin ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + + sprintf ( VStr, "CurSubStepsFileRawBin = %s", PtSrc->CurSubStepsFileRawBin ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "CurStepNo = %d", PtSrc->CurStepNo ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + sprintf ( VStr, "CurSubStepNo = %d", PtSrc->CurSubStepNo ); + MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + + + // sprintf ( VStr, " ", ); + // MIS1__FPrintStr ( VStr, PrintDest, Memo, VPtFile ); + + + + // Close text file + + if ( (PrintDest == 4) || (PrintDest == 5) ) { + fclose ( VPtFile ); + } + + err_retok (( ERR_OUT, "" )); + +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FFuncNotFinished () +* +* \brief : Terminates library operation => To be called at end of program +* +* \param : None +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* \todo : This function code has not been finished, please write the end ;-) +* +* Items not filled now : +* bug : No +* +* \date : Date : 11/04/2019 +* \date : Doc date : 11/04/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FFuncNotFinished () { + + MIS1__VGBeginDone = 0; + + + if ( MIS1__VGBeginDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FBegin (...) has not been called !") ); + } + + err_retok (( ERR_OUT, "" )); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FFuncWithBug () +* +* \brief : Terminates library operation => To be called at end of program +* +* \param : None +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* \bug : There may be a bug in this function, please fix it ;-) +* +* \date : Date : 11/04/2019 +* \date : Doc date : 11/04/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__FFuncWithBug () { + + MIS1__VGBeginDone = 0; + + + if ( MIS1__VGBeginDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => MIS1__FBegin (...) has not been called !") ); + } + + + err_retok (( ERR_OUT, "" )); + +} + + + +// Class MIS1__TCCarWarnErr + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 _FClearAcqTrailInfo ( SInt8 MSisId ) +* +* \brief : MIS1__TCCarWarnErr constructor. +* +* \param : None +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : Private method +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::_FClearAcqTrailInfo ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + + memset ( &ATrailFlags[MSisId][0], 0, MIS1__MAX_FR_NB_PER_ACQ * sizeof (ATrailFlags [0][0]) ); + memset ( &ATrailFrCnt[MSisId][0], 0, MIS1__MAX_FR_NB_PER_ACQ * sizeof (ATrailFrCnt [0][0]) ); + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TCCarWarnErr () +* +* \brief : MIS1__TCCarWarnErr constructor. +* +* \param : None +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* \bug : There may be a bug in this function, please fix it ;-) +* +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +MIS1__TCCarWarnErr::MIS1__TCCarWarnErr () { + + SafetyTag = 0x16646660; // To check if loaded file has been created by this class + + DateVersion = 0x23032101; // Date = 23/03/2021 - Version = 1 + + WarnErrCnt = 0; + WarnErrCntTot = 0; + ListIsFull = 0; + + sprintf ( CstWarnErrType2Str [MIS1__WE_RECORD_EMPTY], "MIS1__WE_RECORD_EMPTY" ); + sprintf ( CstWarnErrType2Str [MIS1__WE_SW_ERR] , "MIS1__WE_SW_ERR" ); + sprintf ( CstWarnErrType2Str [MIS1__WE_SW_REG_OVF] , "MIS1__WE_SW_REG_OVF" ); + sprintf ( CstWarnErrType2Str [MIS1__WE_SW_ACQ_TRUNC], "MIS1__WE_SW_ACQ_TRUNC" ); + sprintf ( CstWarnErrType2Str [MIS1__WE_MSIS_FR_OVF] , "MIS1__WE_MSIS_FR_OVF" ); + + FReset (); + +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : ~MIS1__TCCarWarnErr () +* +* \brief : MIS1__TCCarWarnErr destructor. +* +* \param : None +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* \bug : There may be a bug in this function, please fix it ;-) +* +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +MIS1__TCCarWarnErr::~MIS1__TCCarWarnErr () { +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FReset () +* +* \brief : Clear all W/E => Reset all fields. +* +* \param : None +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 23/03/2021 +* \date : Doc date : 23/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FReset () { + + WarnErrCnt = 0; + WarnErrCntTot = 0; + ListIsFull = 0; + + + memset ( AWarnErrTotCnt, 0, sizeof(AWarnErrTotCnt[0][0]) * MIS1__WE_MAX_MSIS_NB * MIS1__WE_NB ); + memset ( AWarnErrCnt , 0, sizeof(AWarnErrCnt[0][0]) * MIS1__WE_MAX_MSIS_NB * MIS1__WE_NB ); + + memset ( ATrailFlags, 0, sizeof(ATrailFlags[0][0]) * MIS1__WE_MAX_MSIS_NB * MIS1__MAX_FR_NB_PER_ACQ ); + memset ( ATrailFrCnt, 0, sizeof(ATrailFrCnt[0][0]) * MIS1__WE_MAX_MSIS_NB * MIS1__MAX_FR_NB_PER_ACQ ); + + memset ( AWarnErr , 0, sizeof(AWarnErr[0]) * MIS1__MAX_CAR_WARN_ERR_NB ); + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FResetList () +* +* \brief : Clear the list of W/E records, W/E counters are not resetted. +* +* \param : None +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 24/03/2021 +* \date : Doc date : 24/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FResetList () { + + WarnErrCnt = 0; + ListIsFull = 0; + + memset ( ATrailFlags, 0, sizeof(ATrailFlags[0][0]) * MIS1__WE_MAX_MSIS_NB * MIS1__MAX_FR_NB_PER_ACQ ); + memset ( ATrailFrCnt, 0, sizeof(ATrailFrCnt[0][0]) * MIS1__WE_MAX_MSIS_NB * MIS1__MAX_FR_NB_PER_ACQ ); + + memset ( AWarnErr , 0, sizeof(AWarnErr[0]) * MIS1__MAX_CAR_WARN_ERR_NB ); + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : ~MIS1__TCCarWarnErr () +* +* \brief : MIS1__TCCarWarnErr destructor. +* +* \param : None +* +* \return : Error code ( On 11/04/2019 it returns always 0 ) \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* \bug : There may be a bug in this function, please fix it ;-) +* +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FChkMSisId ( SInt8 MSisId ) { + + if ( (MSisId < 0) || (MSisId >= MIS1__WE_MAX_MSIS_NB) ) { + return (-1); + } + + return (MSisId); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqSwErrRstTotCnt ( SInt8 MSisId ) +* : +* \brief : Reset the total sw errors counter \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqSwErrRstTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + AWarnErrTotCnt[MSisId][MIS1__WE_SW_ERR] = 0; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfRstTotCnt ( SInt8 MSisId ) +* : +* \brief : Reset the total sw errors region ovf +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfRstTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + AWarnErrTotCnt[MSisId][MIS1__WE_SW_REG_OVF] = 0; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncRstTotCnt ( SInt8 MSisId ) +* : +* \brief : Reset the total acq truncated total counter +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncRstTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + AWarnErrTotCnt[MSisId][MIS1__WE_SW_ACQ_TRUNC] = 0; + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FMSisFrOvfRstTotCnt ( SInt8 MSisId ) +* : +* \brief : Reset the total MSis fr OVF counter \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FMSisFrOvfRstTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + AWarnErrTotCnt[MSisId][MIS1__WE_MSIS_FR_OVF] = 0; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FRstAllTotCnt ( SInt8 MSisId ) +* : +* \brief : Reset ALL the total counters \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FRstAllTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + memset ( AWarnErrTotCnt, 0, sizeof(AWarnErrTotCnt[0][0]) * MSisId * MIS1__WE_NB ); + + return (0); +} + + + + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqSwErrGetTotCnt ( SInt8 MSisId ) +* : +* \brief : Returns the total sw errors counter \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqSwErrGetTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + return (AWarnErrTotCnt[MSisId][MIS1__WE_SW_ERR]); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfGetTotCnt () +* : +* \brief : Returns the total sw errors region ovf +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfGetTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + return (AWarnErrTotCnt[MSisId][MIS1__WE_SW_REG_OVF]); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncGetTotCnt ( SInt8 MSisId ) +* : +* \brief : Returns the total acq truncated total counter +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncGetTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + return (AWarnErrTotCnt[MSisId][MIS1__WE_SW_ACQ_TRUNC]); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FMSisFrOvfGetTotCnt ( SInt8 MSisId ) +* : +* \brief : Returns the total MSis fr OVF counter \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FMSisFrOvfGetTotCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + return (AWarnErrTotCnt[MSisId][MIS1__WE_MSIS_FR_OVF]); +} + + + +// 998 + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqSwErrRstCnt ( SInt8 MSisId ) +* : +* \brief : Reset the sw errors counter \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/03/2021 +* \date : Doc date : 24/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqSwErrRstCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + AWarnErrCnt[MSisId][MIS1__WE_SW_ERR] = 0; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfRstCnt ( SInt8 MSisId ) +* : +* \brief : Reset the sw errors region ovf +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/03/2021 +* \date : Doc date : 24/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfRstCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + AWarnErrCnt[MSisId][MIS1__WE_SW_REG_OVF] = 0; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncRstCnt ( SInt8 MSisId ) +* : +* \brief : Reset the acq truncated total counter +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/03/2021 +* \date : Doc date : 24/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncRstCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + AWarnErrCnt[MSisId][MIS1__WE_SW_ACQ_TRUNC] = 0; + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FMSisFrOvfRstCnt ( SInt8 MSisId ) +* : +* \brief : Reset the MSis fr OVF counter \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/03/2021 +* \date : Doc date : 24/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FMSisFrOvfRstCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + AWarnErrCnt[MSisId][MIS1__WE_MSIS_FR_OVF] = 0; + + return (0); +} + + + + +// 999 + + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqSwErrGetCnt ( SInt8 MSisId ) +* : +* \brief : Returns the sw errors counter \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqSwErrGetCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + return (AWarnErrCnt[MSisId][MIS1__WE_SW_ERR]); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfGetCnt () +* : +* \brief : Returns the sw errors region ovf +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfGetCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + return (AWarnErrCnt[MSisId][MIS1__WE_SW_REG_OVF]); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncGetCnt ( SInt8 MSisId ) +* : +* \brief : Returns the acq truncated total counter +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/03/2021 +* \date : Doc date : 02/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncGetCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + return (AWarnErrCnt[MSisId][MIS1__WE_SW_ACQ_TRUNC]); +} + + + +// 888 + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FDaqErrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val, MIS1__EWarnErr ErrType ) +* : +* \brief : Add a DAQ error, generic function called by FDaqSwErrAdd (), FDaqSwRegOvfrAdd (), FDaqAcqTruncAdd () \n +* : +* \param : - +* : +* \return : Errors counter or sw error code +* : >= 0 - Daq error counter +* : < 0 - Sw error code +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FDaqErrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val, MIS1__EWarnErr ErrType ) { + + SInt32 VRet; + MIS1__TWarnErr* VPtWarnErr; + + + + // Check param + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + // Update errors counters + + AWarnErrTotCnt[MSisId][ErrType]++; + AWarnErrCnt[MSisId][ErrType]++; + + WarnErrCntTot++; + + // Add record + + if ( WarnErrCnt >= MIS1__MAX_CAR_WARN_ERR_NB ) { + err_warning (( ERR_OUT, "Abort list is full => WarnErrCnt = %d >= MIS1__MAX_CAR_WARN_ERR_NB = %d", WarnErrCnt, MIS1__MAX_CAR_WARN_ERR_NB )); + return (-2); + } + + + VPtWarnErr = &AWarnErr[WarnErrCnt]; + + VPtWarnErr->MSisId = MSisId; + VPtWarnErr->RunId = RunId; + VPtWarnErr->AcqId = AcqId; + VPtWarnErr->FrIdInAcq = FrId; + VPtWarnErr->StepId = StepId; + VPtWarnErr->SubStepId = SubStepId; + VPtWarnErr->Type = ErrType; + VPtWarnErr->MSisFrCnt = MSisFrCnt; + VPtWarnErr->Cnt = AWarnErrTotCnt[MSisId][ErrType]; // Total errors counter is stored in record + VPtWarnErr->Code = Code; + VPtWarnErr->Val = Val; + + WarnErrCnt++; + + + return (AWarnErrTotCnt[MSisId][ErrType]); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FDaqSwErrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ) +* : +* \brief : Add a DAQ sw error \n +* : +* \param : - +* : +* \return : Errors counter or sw error code +* : >= 0 - Daq error counter +* : < 0 - Sw error code +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FDaqSwErrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ) { + + return ( FDaqErrAdd ( MSisId, RunId, AcqId, FrId, StepId, SubStepId, MSisFrCnt, Code, Val, MIS1__WE_SW_ERR ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FDaqSwRegOvfrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ) +* : +* \brief : Add a DAQ sw region OVF error \n +* : +* \param : - +* : +* \return : Errors counter or sw error code +* : >= 0 - Daq error counter +* : < 0 - Sw error code +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FDaqSwRegOvfrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ) { + + return ( FDaqErrAdd ( MSisId, RunId, AcqId, FrId, StepId, SubStepId, MSisFrCnt, Code, Val, MIS1__WE_SW_REG_OVF ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FDaqAcqTruncAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ) +* : +* \brief : Add a DAQ acq truncated error \n +* : +* \param : - +* : +* \return : Errors counter or sw error code +* : >= 0 - Daq error counter +* : < 0 - Sw error code +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FDaqAcqTruncAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ) { + + return ( FDaqErrAdd ( MSisId, RunId, AcqId, FrId, StepId, SubStepId, MSisFrCnt, Code, Val, MIS1__WE_SW_ACQ_TRUNC ) ); + +} + + + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FAcqMSisFrOvfAdd ( SInt8 MSisId, UInt8 OvfFlags, UInt32 MSisFrCnt, UInt32 AcqFrId ) +* : +* \brief : Add MSis frame OVF flags + fr cnt to the list, to be called on each fr of one acq \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/02/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FAcqMSisFrOvfAdd ( SInt8 MSisId, UInt8 OvfFlags, UInt32 MSisFrCnt, UInt32 AcqFrId ) { + + SInt32 VRet; + UInt32* VPtCnt; + UInt32* VPtTotCnt; + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + + // Since 23/03/2021 + + VPtCnt = &AWarnErrCnt[MSisId][MIS1__WE_MSIS_FR_OVF]; + VPtTotCnt = &AWarnErrTotCnt[MSisId][MIS1__WE_MSIS_FR_OVF]; + + if ( *VPtCnt < UINT_MAX ) { + (*VPtCnt)++; + } + + if ( *VPtTotCnt < UINT_MAX ) { + (*VPtTotCnt)++; + } + + if ( AcqFrId >= MIS1__MAX_FR_NB_PER_ACQ ) { + err_warning (( ERR_OUT, "Abort, update counters only, no list built => AcqFrId = %d >= MIS1__MAX_FR_NB_PER_ACQ = %d", AcqFrId, MIS1__MAX_FR_NB_PER_ACQ )); + return (-2); + } + + + ATrailFlags[MSisId][AcqFrId] = OvfFlags; + ATrailFrCnt[MSisId][AcqFrId] = MSisFrCnt; + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TCCarWarnErr::FAcqMSisFrOvfCount ( SInt8 List, SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt16 StepId, UInt16 SubStepId, UInt32 AcqFrNb ) +* : +* \brief : Update the Acq OVF counters, to be called at end of each acq \n +* : +* \param : List - List or not the OVF, 0 => count OVF but no list done, 1 => count OVF + build list +* : +* \return : Ovf nb + Error code +* : >= 0 - OVF nb +* : < 0 - Error +* : +* \warning : Globals : APP_VGResATrail +* \warning : Remark : Must be called only ONE time at end of ACQ, after counting W/R it resets ACq trailers infos +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 26/02/2021 +* \date : Rev : 23/03/2021 +* \date : Doc date : 26/02/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TCCarWarnErr::FAcqMSisFrOvfCount ( SInt8 List, SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt16 StepId, UInt16 SubStepId, UInt32 AcqFrNb ) { + + SInt32 VRet; + SInt32 ViFr; + SInt32 VOvfCnt; + MIS1__TWarnErr* VPtWarnErr; + + + // Check param + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + if ( AcqFrNb > MIS1__MAX_FR_NB_PER_ACQ ) { + _FClearAcqTrailInfo ( MSisId ); + err_retfail ( -1, (ERR_OUT,"Abort => AcqFrNb = %d > MIS1__MAX_FR_NB_PER_ACQ = %d", AcqFrNb, MIS1__MAX_FR_NB_PER_ACQ) ); + } + + + // Scan frames + + + // Count OVF in current acq in all cases + + + VOvfCnt = 0; + + for ( ViFr = 0; ViFr < AcqFrNb; ViFr++ ) { + + if ( ATrailFlags[MSisId][ViFr] > 0 ) { + VOvfCnt++; + } + + } // End for ( ViFr ) + + + // No space in list => Return ovf nb in current acq + + if ( WarnErrCnt >= MIS1__MAX_CAR_WARN_ERR_NB ) { + + WarnErrCntTot += VOvfCnt; + + _FClearAcqTrailInfo ( MSisId ); + + // err_warning (( ERR_OUT, "VOvfCnt = %d, MSis OVF cnt = %d, WE nb = %d", VOvfCnt, FMSisFrOvfGetCnt ( 0 /* MSisId */ ), FWarnErrGetNbTot () )); + + if ( ListIsFull == 0 ) { + err_warning (( ERR_OUT, "Abort list is full => WarnErrCnt = %d >= MIS1__MAX_CAR_WARN_ERR_NB = %d", WarnErrCnt, MIS1__MAX_CAR_WARN_ERR_NB )); + ListIsFull = 1; + } + + return (VOvfCnt); + } + + + + if ( List ) { + + for ( ViFr = 0; ViFr < AcqFrNb; ViFr++ ) { + + if ( ATrailFlags[MSisId][ViFr] > 0 ) { + + if ( WarnErrCnt >= MIS1__MAX_CAR_WARN_ERR_NB ) { + + WarnErrCntTot += VOvfCnt; + + _FClearAcqTrailInfo ( MSisId ); + + if ( ListIsFull == 0 ) { + err_warning (( ERR_OUT, "Abort list is full => WarnErrCnt = %d >= MIS1__MAX_CAR_WARN_ERR_NB = %d", WarnErrCnt, MIS1__MAX_CAR_WARN_ERR_NB )); + ListIsFull = 1; + } + + return (VOvfCnt); + } + + VPtWarnErr = &AWarnErr[WarnErrCnt]; + + VPtWarnErr->RunId = RunId; + VPtWarnErr->AcqId = AcqId; + VPtWarnErr->FrIdInAcq = ViFr; + VPtWarnErr->StepId = StepId; + VPtWarnErr->SubStepId = SubStepId; + VPtWarnErr->Type = MIS1__WE_MSIS_FR_OVF; + VPtWarnErr->MSisFrCnt = ATrailFrCnt[MSisId][ViFr]; + VPtWarnErr->Cnt = VOvfCnt; // Cpt of MSis 1 OVF in this acquisiiton + VPtWarnErr->Val = ATrailFlags[MSisId][ViFr]; + + WarnErrCnt++; + + } + + } // End for ( ViFr ) + + } + + + WarnErrCntTot += VOvfCnt; + + // Clear Acq trailers info + + _FClearAcqTrailInfo ( MSisId ); + + return (VOvfCnt); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : UInt32 MIS1__TCCarWarnErr::FMSisFrOvfGetCnt ( SInt8 MSisId ) +* : +* \brief : Returns the MSis fr OVF counter, to be called at any time \n +* : +* \param : None - +* : +* \return : MSis fr OVF counter +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/03/2021 +* \date : Doc date : 01/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +UInt32 MIS1__TCCarWarnErr::FMSisFrOvfGetCnt ( SInt8 MSisId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + return (AWarnErrCnt[MSisId][MIS1__WE_MSIS_FR_OVF] ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : UInt32 MIS1__TCCarWarnErr::FAcqMSisFrOvfGetFlags ( SInt8 MSisId, UInt32 FrId ) +* : +* \brief : Returns the MSis OVF flags of one frame of current acq, to be called at any time \n +* : +* \param : None - +* : +* \return : MSis fr OVF counter +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/03/2021 +* \date : Doc date : 01/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +UInt32 MIS1__TCCarWarnErr::FAcqMSisFrOvfGetFlags ( SInt8 MSisId, UInt32 FrId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + if ( FrId >= MIS1__MAX_FR_NB_PER_ACQ ) { + err_retfail ( -1, (ERR_OUT,"Abort => FrId = %d >= MIS1__MAX_FR_NB_PER_ACQ = %d", FrId, MIS1__MAX_FR_NB_PER_ACQ ) ); + } + + return (ATrailFlags[MSisId][FrId]); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : UInt32 MIS1__TCCarWarnErr::FAcqMSisFrOvfGetFrCnt ( SInt8 MSisId, UInt32 FrId ) +* : +* \brief : Returns the MSis fr cnt of one frame of current acq, to be called at any time \n +* : +* \param : None - +* : +* \return : MSis fr OVF counter +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/03/2021 +* \date : Doc date : 01/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +UInt32 MIS1__TCCarWarnErr::FAcqMSisFrOvfGetFrCnt ( SInt8 MSisId , UInt32 FrId ) { + + err_retfail ( FChkMSisId (MSisId), (ERR_OUT,"Abort => MSisId = %d is not allowed", MSisId ) ); + + if ( FrId >= MIS1__MAX_FR_NB_PER_ACQ ) { + err_retfail ( -1, (ERR_OUT,"Abort => FrId = %d >= MIS1__MAX_FR_NB_PER_ACQ = %d", FrId, MIS1__MAX_FR_NB_PER_ACQ ) ); + } + + return (ATrailFrCnt[MSisId][FrId]); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FWarnErrGetNb () +* : +* \brief : Returns the warning, erros nb, to be called at any time \n +* : +* \param : None - +* : +* \return : +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/03/2021 +* \date : Doc date : 01/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FWarnErrGetNb () { + + return ( WarnErrCnt ); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FWarnErrGetNbTot () +* : +* \brief : Returns the warning, erros nb, to be called at any time \n +* : +* \param : None - +* : +* \return : +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/03/2021 +* \date : Doc date : 01/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FWarnErrGetNbTot () { + + return ( WarnErrCntTot ); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FWarnErrPrint ( UInt32 First, UInt32 Nb, SInt8 PrintListHeader, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) +* : +* \brief : Returns the warning, erros nb, to be called at any time \n +* : +* \param : PrintDest - Print destination, +* : 0 => No print, +* : 1 => msg file , 2 => Memo, 3 => Msg file + Memo +* : 4 => text file, 5 => Text file + Memo +* : +* \return : +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 01/03/2021 +* \date : Doc date : 01/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FWarnErrPrint ( UInt32 First, UInt32 Nb, SInt8 PrintListHeader, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ) { + + UInt32 Vi; + UInt32 ViLast; + MIS1__TWarnErr* VPtRec; + char VMsg[GLB_CMT_SZ]; + + // Check param + + ViLast = First + Nb - 1; + + if ( First >= WarnErrCnt ) { + err_retfail ( -1, (ERR_OUT,"Abort record out of list => First = %d >= WarnErrCnt = %d", First, WarnErrCnt) ); + } + + if ( ViLast >= WarnErrCnt ) { + err_retfail ( -1, (ERR_OUT,"Abort record out of list => ViLast = %d >= WarnErrCnt = %d", ViLast, WarnErrCnt) ); + } + + // Print + + if ( PrintListHeader ) { + MIS1__FPrintStr ( "==================================", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( " Characterization Warning / Error ", PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "----------------------------------", PrintDest, Memo, PtFile ); + sprintf ( VMsg, "Total nb of W/E = %d", FWarnErrGetNbTot () ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + sprintf ( VMsg, "Nb of W/E in file = %d", FWarnErrGetNb () ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + MIS1__FPrintStr ( "==================================", PrintDest, Memo, PtFile ); + } + + + + for ( Vi = First; Vi <= ViLast; Vi++ ) { + + VPtRec = &AWarnErr[Vi]; + + MIS1__FPrintStr ( "--------------------------------------------", PrintDest, Memo, PtFile ); + + sprintf ( VMsg, "Rec [%.4d] : MSisId = %d, Run = %d, Acq = %d, FrInAcq = %d, Step = %d, SubStep = %d ", Vi, VPtRec->MSisId, VPtRec->RunId, VPtRec->AcqId, VPtRec->FrIdInAcq, VPtRec->StepId, VPtRec->SubStepId ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + + sprintf ( VMsg, "Rec [%.4d] : Type = %s : Cnt = %d, Code = %d, Val = %d, MSis fr cnt = %d", Vi, CstWarnErrType2Str[VPtRec->Type], VPtRec->Cnt, VPtRec->Code, VPtRec->Val, VPtRec->MSisFrCnt ); + MIS1__FPrintStr ( VMsg, PrintDest, Memo, PtFile ); + + if ( (Vi % 100) == 0 ) { + Application->ProcessMessages (); + } + + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FBinFileSave ( char* FileName ) +* : +* \brief : Save warning / errors list to a binary file \n +* : +* \param : FileName - Name of the file +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 23/03/2021 +* \date : Doc date : 23/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FBinFileSave ( char* FileName ) { + + SInt32 VRet; + UInt32 VMaxRecSz; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + // Check param + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + // Calc size of biggest record to be written by "PubFSeqWrite ()" to file + + VMaxRecSz = MIS1__MAX_CAR_WARN_ERR_NB * sizeof ( MIS1__TWarnErr ); + + // Conf TCBinFile + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_WRITE, VMaxRecSz, VMaxRecSz, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"Abort=> Conf for file %s creation failed !", FileName ) ); + + // Create file + + VRet = VBinFile.PubFCreate (); + err_retfail ( VRet, (ERR_OUT,"Abort=> File %s creation failed !", FileName ) ); + + + // Write safety tag + + VRet = VBinFile.PubFSeqWrite ( &SafetyTag, sizeof (SafetyTag) ); + err_retfail ( VRet, (ERR_OUT,"Abort=> Saving record to file %s failed !", FileName ) ); + + + // Write date + version + + VRet = VBinFile.PubFSeqWrite ( &DateVersion, sizeof (DateVersion) ); + err_retfail ( VRet, (ERR_OUT,"Abort=> Saving record to file %s failed !", FileName ) ); + + // Write records nb + + VRet = VBinFile.PubFSeqWrite ( &WarnErrCnt, sizeof (WarnErrCnt) ); + err_retfail ( VRet, (ERR_OUT,"Abort=> Saving record to file %s failed !", FileName ) ); + + // Write tot warnings, errors nb + + VRet = VBinFile.PubFSeqWrite ( &WarnErrCntTot, sizeof (WarnErrCntTot) ); + err_retfail ( VRet, (ERR_OUT,"Abort=> Saving record to file %s failed !", FileName ) ); + + // Write records + + VRet = VBinFile.PubFSeqWrite ( AWarnErr, MIS1__MAX_CAR_WARN_ERR_NB * sizeof ( MIS1__TWarnErr ) ); + err_retfail ( VRet, (ERR_OUT,"Abort=> Saving record to file %s failed !", FileName ) ); + + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> Closing file %s failed !", FileName ) ); + + err_retok (( ERR_OUT, "" )); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FBinFileSave ( char* Directory, char* FileName ) +* : +* \brief : Save warning / errors list to a binary file \n +* : +* \param : FileName - Name of the file +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/03/2021 +* \date : Doc date : 24/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FBinFileSave ( char* Directory, char* FileName ) { + + char VFilePath[GLB_FILE_PATH_SZ]; + + sprintf ( VFilePath, "%s\\%s", Directory, FileName ); + + return ( FBinFileSave ( VFilePath ) ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FBinFileLoad ( char* FileName ) +* : +* \brief : Load warning / errors list to a binary file \n +* : +* \param : FileName - Name of the file +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 23/03/2021 +* \date : Doc date : 23/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FBinFileLoad ( char* FileName ) { + + SInt32 VRet; + UInt32 VMaxRecSz; + UInt32 VRecSz; + UInt32 VDateVersionFromFile; + UInt32 VSafetyTagFromFile; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + // Check param + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + + // Reset class fields + + FReset (); + + + + // Calc size of biggest record to be written by "PubFSeqWrite ()" to file + + VMaxRecSz = MIS1__MAX_CAR_WARN_ERR_NB * sizeof ( MIS1__TWarnErr ); + + // Conf TCBinFile + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_READ, VMaxRecSz, VMaxRecSz, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + + + err_retfail ( VRet, (ERR_OUT,"Abort=> Conf for file %s loading failed !", FileName ) ); + + // Open file + + VRet = VBinFile.PubFOpen(); + err_retfail ( VRet, (ERR_OUT,"Abort=> Loading file %s failed !", FileName ) ); + + + // Read safety tag + + VRecSz = sizeof (SafetyTag); + + VRet = VBinFile.PubFSeqRead ( &VSafetyTagFromFile, VRecSz /* MaxDestSz */, VRecSz /* DataSzToRead */ ); + + if ( VRet < 0 ) { + VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> Reading safety tag from file %s failed !", FileName ) ); + } + + if ( VSafetyTagFromFile != SafetyTag ) { + VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> SafetyTag from file = %X <> Class SafetyTag = %X", VSafetyTagFromFile, SafetyTag ) ); + } + + + + + // Read date + version + + VRecSz = sizeof (DateVersion); + + VRet = VBinFile.PubFSeqRead ( &VDateVersionFromFile, VRecSz /* MaxDestSz */, VRecSz /* DataSzToRead */ ); + + if ( VRet < 0 ) { + VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> Reading date / version from file %s failed !", FileName ) ); + } + + if ( VDateVersionFromFile != DateVersion ) { + VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> DateVersion from file = %X <> Class DateVersion = %X", VDateVersionFromFile, DateVersion ) ); + } + + // Read records nb + + VRecSz = sizeof (WarnErrCnt); + + VRet = VBinFile.PubFSeqRead ( &WarnErrCnt, VRecSz /* MaxDestSz */, VRecSz /* DataSzToRead */ ); + + if ( VRet < 0 ) { + VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> Reading records nb from file %s failed !", FileName ) ); + } + + // Read tot warnings, erros nb + + VRecSz = sizeof (WarnErrCntTot); + + VRet = VBinFile.PubFSeqRead ( &WarnErrCntTot, VRecSz /* MaxDestSz */, VRecSz /* DataSzToRead */ ); + + if ( VRet < 0 ) { + VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> Reading total warnings, errors nb from file %s failed !", FileName ) ); + } + + + // Read records + + VRecSz = MIS1__MAX_CAR_WARN_ERR_NB * sizeof ( MIS1__TWarnErr ); + + VRet = VBinFile.PubFSeqRead ( AWarnErr, VRecSz /* MaxDestSz */, VRecSz /* DataSzToRead */ ); + + if ( VRet < 0 ) { + VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> Reading records from file %s failed !", FileName ) ); + } + + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"Abort=> Closing file %s failed !", FileName ) ); + + err_retok (( ERR_OUT, "" )); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 FBinFileLoad ( char* Directory, char* FileName ) +* : +* \brief : Load warning / errors list to a binary file \n +* : +* \param : FileName - Name of the file +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/03/2021 +* \date : Doc date : 24/03/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__TCCarWarnErr::FBinFileLoad ( char* Directory, char* FileName ) { + + char VFilePath[GLB_FILE_PATH_SZ]; + + sprintf ( VFilePath, "%s\\%s", Directory, FileName ); + + return ( FBinFileLoad ( VFilePath ) ); + +} + + +#endif // End of #ifndef CC_MSIS1_BDF_LIGHT + + + +// =================================================================================== +// * Global variable +// * +// =================================================================================== + +SInt32 MIS1__BT_VGDecodecFrWarnErr = 0; // Used by MIS1__BT_FBtDecodeFrGetWarnErr ( UInt8 Reset ) + // Should be in *.var but I don't want to distribute this file + // => It must be here + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : char* MIS1__FFrHeader2Str ( MIS1__TDsFrHeader* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) +* : +* \brief : Converts the data stream frame header field in a string +* : +* \param : PtSrc - A pointer to the header +* : +* \param : DestStr - Destination string +* : +* \param : DestStrSz - Size of destination string +* : +* \param : Mode - Print mode, reserved for future use +* : +* \return : A string which contains the frame header +* : - DestStr if provided as non NULL pointer and if size > required +* : - A static local string in case DestStr can't be used +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 07/05/2019 +* \date : Doc date : 07/05/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +char* MIS1__FFrHeader2Str ( MIS1__TDsFrHeader* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) { + + static char VRetStr[GLB_CMT_SZ]; + SInt32 VStrLen; + UInt32 VFrCnt; + + // Check header pointer + + if ( PtSrc == NULL ) { + sprintf ( VRetStr, "Abort => PtSrc == NULL" ); + err_error (( ERR_OUT, "%s", VRetStr )); + return (VRetStr); + } + + // Builts frame counter + + VFrCnt = PtSrc->F.FC0 + (PtSrc->F.FC1 << 8) + (PtSrc->F.FC2 << 16) + (PtSrc->F.FC3 << 24); + + // Builts result string + + // 24/05/2021 + + if ( Mode == 0 ) { + sprintf ( VRetStr, "#H : [W7]=%x [W6]=%x [W5]=%x [W4]=%x [W3H]=%x [W2H]=%x [W1H]=%x [W0H]=%x(H) - FrCnt = %d (D))", PtSrc->F.W7, PtSrc->F.W6, PtSrc->F.W5, PtSrc->F.W4, PtSrc->F.W3H, PtSrc->F.W2H, PtSrc->F.W1H, PtSrc->F.W0H, VFrCnt ); + } + + else { + sprintf ( VRetStr, "#H : [W7]=%X [W6]=%X [W5]=%X [W4]=%X [W3]=%X [W2]=%X [W1]=%X [W0]=%x(H) - FrCnt = %d (D))", PtSrc->AW16[7], PtSrc->AW16[6], PtSrc->AW16[5], PtSrc->AW16[4], PtSrc->AW16[3], PtSrc->AW16[2], PtSrc->AW16[1], PtSrc->AW16[0], VFrCnt ); + } + + + VStrLen = strlen ( VRetStr ); + + // Copy result to DestStr if possible + errors messages + + if ( DestStr == NULL ) { + err_error (( ERR_OUT, "DestStr == NULL => Returns local variable, DestStr not updated" )); + } + + if ( DestStrSz <= VStrLen ) { + err_error (( ERR_OUT, "DestStrSz=%d <= VStrLen=%d => Returns local variable, DestStrSz is too small", DestStrSz, VStrLen )); + } + + if ( (DestStr != NULL) && (DestStrSz > VStrLen) ) { + strcpy ( DestStr, VRetStr ); + return (DestStr); + } + + else { + return (VRetStr); + } + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : char* MIS1__FFrTrailer2Str ( MIS1__TDsFrTrailer* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) +* : +* \brief : Converts the data stream frame trailer field in a string +* : +* \param : PtSrc - A pointer to the trailer +* : +* \param : DestStr - Destination string +* : +* \param : DestStrSz - Size of destination string +* : +* \param : Mode - Print mode, reserved for future use +* : +* \return : A string which contains the frame trailer +* : - DestStr if provided as non NULL pointer and if size > required +* : - A static local string in case DestStr can't be used +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 02/07/2019 +* \date : Doc date : 02/07/2019 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +char* MIS1__FFrTrailer2Str ( MIS1__TDsFrTrailer* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ) { + + static char VRetStr[GLB_CMT_SZ]; + SInt32 VStrLen; + UInt32 VFrCnt; + + // Check header pointer + + if ( PtSrc == NULL ) { + sprintf ( VRetStr, "Abort => PtSrc == NULL" ); + err_error (( ERR_OUT, "%s", VRetStr )); + return (VRetStr); + } + + + // Builts result string + + + sprintf ( VRetStr, "[W1]= Tag = %x - [W0] = Flags = %x (H) = FrOvf %d - RegOvf %d - SRegOvf %d - FSLimit %d", PtSrc->F.Tag, PtSrc->F.Flags, PtSrc->B.FrOvf, PtSrc->B.RegOvf, PtSrc->B.SRegOvf, PtSrc->B.FSLimit ); + + + VStrLen = strlen ( VRetStr ); + + // Copy result to DestStr if possible + errors messages + + if ( DestStr == NULL ) { + err_error (( ERR_OUT, "DestStr == NULL => Returns local variable, DestStr not updated" )); + } + + if ( DestStrSz <= VStrLen ) { + err_error (( ERR_OUT, "DestStrSz=%d <= VStrLen=%d => Returns local variable, DestStrSz is too small", DestStrSz, VStrLen )); + } + + if ( (DestStr != NULL) && (DestStrSz > VStrLen) ) { + strcpy ( DestStr, VRetStr ); + return (DestStr); + } + + else { + return (VRetStr); + } + +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqIdsRecPrint ( MIS1__TBtAcqIds* Pt ) +* +* \brief : +* +* \param : Pt - Pointer to record +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 14/05/2021 +* \date : Doc date : 14/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__BT_FAcqIdsRecPrint ( MIS1__TBtAcqIds* Pt ) { + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + + // Print + + + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, " Acq Ids fields " )); + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, " AcqIdInDaq = %.4d", Pt->AcqIdInDaq )); + msg (( MSG_OUT, " AcqIdInRun = %.4d", Pt->AcqIdInRun )); + msg (( MSG_OUT, " AcqIdInBuff = %.4d", Pt->AcqIdInBuff )); + msg (( MSG_OUT, " AcqIdInFile = %.4d", Pt->AcqIdInFile )); + msg (( MSG_OUT, " FileId = %.4d", Pt->FileId )); + msg (( MSG_OUT, " TimeStamp1 = %.4d", Pt->TimeStamp1 )); + msg (( MSG_OUT, " TimeStamp2 = %.4d", Pt->TimeStamp2 )); + msg (( MSG_OUT, " DataType = %.4d", Pt->DataType )); + + + err_retok (( ERR_OUT, "Ok" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqResRecPrint ( MIS1__TBtAcqRes* Pt, SInt32 PrintFrCnt, SInt32 PrintFiredPixels ) +* +* \brief : +* +* \param : Pt - Pointer to record +* +* \param : PrintFrCnt - Print frames counters values, < 0 => All, 0 => None, > 0 => PrintFrCnt frames +* +* \param : PrintFiredPixels - Print fired pixels 0 / 1 +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 14/05/2021 +* \date : Doc date : 14/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__BT_FAcqResRecPrint ( MIS1__TBtAcqRes* Pt, SInt32 PrintFrCnt, SInt32 PrintFiredPixels ) { + + SInt32 ViFr; + SInt8 ViMSis; + + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + + // Print + + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, " Acq results " )); + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "ErrNb = %.4d", Pt->ErrNb )); + msg (( MSG_OUT, "TrigNb = %.4d", Pt->TrigNb )); + msg (( MSG_OUT, "FrNb = %.4d", Pt->FrNb )); + msg (( MSG_OUT, "FrNbTruncated = %.4d", Pt->FrNbTruncated )); + msg (( MSG_OUT, "FrNbOvf = %.4d", Pt->FrNbOvf )); + msg (( MSG_OUT, "FrNbSwErr = %.4d", Pt->FrNbSwErr )); + msg (( MSG_OUT, "" )); + + + if ( PrintFrCnt < 0 ) { + PrintFrCnt = Pt->FrNb; + } + + if ( PrintFrCnt ) { + + msg (( MSG_OUT, "Frame conters list" )); + + for ( ViFr = 0; ViFr < PrintFrCnt; ViFr++ ) { + msg (( MSG_OUT, "Frame[%.4d] Fr cnt MSis : [0] = %.6d, [1] = %.6d, [2] = %.6d, [3] = %.6d, [4] = %.6d, [5] = %.6d ", ViFr, Pt->FrCnt[ViFr][0], Pt->FrCnt[ViFr][1], Pt->FrCnt[ViFr][2], Pt->FrCnt[ViFr][3], Pt->FrCnt[ViFr][4], Pt->FrCnt[ViFr][5] )); + } + + msg (( MSG_OUT, "" )); + } + + + msg (( MSG_OUT, "Tot fired pixels nb = %.4d", Pt->FiredPixNb )); + + // 14/05/2021 + + if ( PrintFiredPixels ) { + + for ( ViMSis = 0; ViMSis < MIS1__BT_MAX_REAL_MSIS_NB_ACQ; ViMSis++ ) { + msg (( MSG_OUT, "Fired pixels MSis [%d] Matrix [0] = %.4d, [1] = %.4d[2] = %.4d, [3] = %.4d", ViMSis , Pt->AFiredPixNb[ViMSis][0], Pt->AFiredPixNb[ViMSis][1], Pt->AFiredPixNb[ViMSis][2], Pt->AFiredPixNb[ViMSis][3] )); + } + + } + + + err_retok (( ERR_OUT, "Ok" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FTrigRecPrint ( SInt32 TrigNb, MIS1__TBtTrigRec* Pt ) +* +* \brief : +* +* \param : TrigNb - Nmber of triggers to print if > 0, -1 => All, 0 => None +* +* \param : Pt - Pointer to record +* +* \param : +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 04/05/2021 +* \date : Doc date : 04/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__BT_FTrigRecPrint ( SInt32 TrigNb, MIS1__TBtTrigRec* Pt ) { + + UInt32 ViTrig; + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + + if ( TrigNb < 0 ) { + TrigNb = Pt->TrigNb; + } + + if ( TrigNb > MIS1__BT_MAX_TRIG_NB_PER_ACQ ) { + err_warning (( ERR_OUT, "TrigNb = %d > MIS1__BT_MAX_TRIG_NB_PER_ACQ = %d => Prints only first %d", TrigNb, MIS1__BT_MAX_TRIG_NB_PER_ACQ, MIS1__BT_MAX_TRIG_NB_PER_ACQ )); + TrigNb = MIS1__BT_MAX_TRIG_NB_PER_ACQ; + } + + + if ( TrigNb > Pt->TrigNb ) { + err_warning (( ERR_OUT, "TrigNb = %d > TrigRec.TrigNb = %d => Prints only first %d", TrigNb, Pt->TrigNb, Pt->TrigNb )); + TrigNb = Pt->TrigNb; + } + + + // Print + + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, " Triggers list " )); + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, "Trig nb = %d", Pt->TrigNb )); + msg (( MSG_OUT, "" )); + + + + for ( ViTrig = 0; ViTrig < TrigNb; ViTrig++ ) { + msg (( MSG_OUT, "Trig [%.4d] = %.4d [D]= %.4X [H]", ViTrig, Pt->ATrig[ViTrig], Pt->ATrig[ViTrig] )); + } + + + err_retok (( ERR_OUT, "Ok" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqRawHeadRecPrint ( MIS1__TBtAcqRawHead* Pt, SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels ) +* +* \brief : +* +* \param : Pt - Pointer to record +* +* \param : PrintTriggers - Print triggers, -1 => All, 0 => No, > 0 => value = nb of triggers to print +* +* \param : PrintFrCnt - Print frames counters, -1 => All, 0 => No, > 0 => value = nb of frames to print +* +* \param : PrintFiredPixels - Print fired pixels, 0 / 1 +* +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 14/05/2021 +* \date : Doc date : 14/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__BT_FAcqRawHeadRecPrint ( MIS1__TBtAcqRawHead* Pt, SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels ) { + + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + + // Print + + msg (( MSG_OUT, "****************************************" )); + msg (( MSG_OUT, " Acq header " )); + msg (( MSG_OUT, "****************************************" )); + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "TagBeg = %.8X", Pt->TagBeg )); + msg (( MSG_OUT, "Offset = %.4d", Pt->Offset )); + msg (( MSG_OUT, "FullRecSz = %.4d", Pt->FullRecSz )); + msg (( MSG_OUT, "DataSz = %.4d", Pt->DataSz )); + msg (( MSG_OUT, "" )); + + + MIS1__BT_FAcqIdsRecPrint ( &Pt->Ids ); + + + if ( PrintTriggers != 0 ) { + MIS1__BT_FTrigRecPrint ( PrintTriggers /* TrigNb */, &Pt->Trigs ); + } + + MIS1__BT_FAcqResRecPrint ( &Pt->Res, PrintFrCnt, PrintFiredPixels ); + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqRawPrint ( MIS1__TBtAcqRawRec* Pt, SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels, UInt8 DataWSize, UInt32 FirstDataW, UInt32 NbDataW, UInt8 VRS ) +* +* \brief : +* +* \param : Pt - Pointer to acq raw / +* +* \param : PrintTriggers - Print triggers, < 0 => ALl, 0 => No, value > 0 => value = nb of triggers to print +* +* \param : PrintFrCnt - Print frames counters, < 0 => ALL, 0 => No, > 0 for PrintFrCnt frames +* +* \param : PrintFiredPixels - Print fired pixels for all MSis, all matrices 0 / 1 + +* \param : DataWSize - Size of W to print for data part, can be 8, 16, 32, 64 bits +* +* \param : FirstDataW - First W to print +* +* \param : NbDataWW - Nb W to print +* +* \param : VRS - Record type 0 => Fixed Record Size, 1 => Variable Record Size +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 04/05/2021 +* \date : Doc date : 04/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__BT_FAcqRawPrint ( MIS1__TBtAcqRawRec* Pt, SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels, UInt8 DataWSize, UInt32 FirstDataW, UInt32 NbDataW, UInt8 VRS ) { + + + SInt32 VRet; + SInt32 ViW; + SInt32 VLastW; // Signed to handle case NbDataW == 0 => VLastW = -1 + SInt32 VMaxAcqDataWSz; // Signed to handle case NbDataW == 0 => VLastW = -1 + UInt32 V64High; + UInt32 V64Low; + + + // Check param + + if ( VRS > 1 ) { + err_retfail ( -1, (ERR_OUT,"Abort => VRS = %d <> 0, 1", VRS) ); + } + + // **************************** + // Find max data part size + // **************************** + + + if ( VRS == 0 ) { + + switch ( DataWSize ) { + + case 8 : { + VMaxAcqDataWSz = MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W8; + break; } + + case 16 : { + VMaxAcqDataWSz = MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W16; + break; } + + case 32 : { + VMaxAcqDataWSz = MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W32; + break; } + + case 64 : { + VMaxAcqDataWSz = MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W64; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => DataWSize = %d <> 8, 16, 32, 64", DataWSize ) ); + break; } + } + + } + + else { + + + switch ( DataWSize ) { + + case 8 : { + VMaxAcqDataWSz = MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W8; + break; } + + case 16 : { + VMaxAcqDataWSz = MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W16; + break; } + + case 32 : { + VMaxAcqDataWSz = MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W32; + break; } + + case 64 : { + VMaxAcqDataWSz = MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W64; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => DataWSize = %d <> 8, 16, 32, 64", DataWSize ) ); + break; } + } + + + } + + + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + VLastW = FirstDataW + NbDataW - 1; + + + + + if ( NbDataW > VMaxAcqDataWSz ) { + err_retfail ( -1, (ERR_OUT,"Abort => NbDataW%d = %d > Max nb = %d ", DataWSize, NbDataW, VMaxAcqDataWSz ) ); + } + + if ( VLastW >= VMaxAcqDataWSz ) { + err_retfail ( -1, (ERR_OUT,"Abort => VLastW%d = %d >= Max nb = %d ", DataWSize, VLastW, VMaxAcqDataWSz ) ); + } + + + // **************************** + // Print + // **************************** + + + // Print header + + MIS1__BT_FAcqRawHeadRecPrint ( &Pt->Head, PrintTriggers, PrintFrCnt, PrintFiredPixels ); + + // Print data part + + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, " Data fields " )); + + + switch ( DataWSize ) { + + + case 8 : { + + for ( ViW = FirstDataW; ViW <= VLastW; ViW++ ) { + msg (( MSG_OUT, "Data U8[%.4d] = %.2X", ViW, Pt->MSisData.Au8[ViW] )); + } + + break; } + + + case 16 : { + + for ( ViW = FirstDataW; ViW <= VLastW; ViW++ ) { + msg (( MSG_OUT, "Data U16[%.4d] = %.4X", ViW, Pt->MSisData.Au16[ViW] )); + } + + break; } + + + case 32 : { + + for ( ViW = FirstDataW; ViW <= VLastW; ViW++ ) { + msg (( MSG_OUT, "Data U32[%.4d] = %.8X", ViW, Pt->MSisData.Au32[ViW] )); + } + + break; } + + + case 64 : { + + for ( ViW = FirstDataW; ViW <= VLastW; ViW++ ) { + + V64High = (Pt->MSisData.Au64[ViW] & 0xFFFFFFFF00000000) >> 32; + V64Low = (Pt->MSisData.Au64[ViW] & 0x00000000FFFFFFFF); + msg (( MSG_OUT, "Data U64[%.4d] = %.8X %.8X", ViW, V64High, V64Low )); + } + + break; } + + + } + + + err_retok (( ERR_OUT, "Ok" )); + + +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqRawRecCheckSz ( UInt32* PtSz ) +* +* \brief : Check AcqRaw record size / compiler options +* +* \param : PtSz - Pointer to get size, optional => set to NULL if not used +* +* +* +* \return : \n +* : 1 - Size if OK \n +* : 0 - Size if not = size under Windows => Check compiler options \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 12/05/2021 +* \date : Doc date : 12/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FAcqRawRecCheckSz ( UInt32* PtSz ) { + + UInt32 VSz; + + VSz = sizeof (MIS1__TBtAcqRawRec); + + + if ( PtSz != NULL ) { + *PtSz = VSz; + } + + if ( VSz == 100 ) { + return (1); + } + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FUserEndianConv ( void* Pt, UInt32 Sz ) +* +* \brief : Convert binary data if CPU is not little endian +* +* \param : Pt - Pointer to record to convert +* +* \param : Sz - record size in W8 + +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 19/05/2021 +* \date : Doc date : 19/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FUserEndianConv ( void* Pt, UInt32 Sz ) { + + // Pointers to access the source buffer as W8, W16 or W32 + + UInt8* VPtW8 = (UInt8*) Pt; + UInt16* VPtW16 = (UInt16*) Pt; + UInt32* VPtW32 = (UInt32*) Pt; + + // RAW data from DAQ are saved in little endian bytes ordering because CPU is Intel + // If this library is executed by a CPU which is not little endian, byte must be swapped + // Motorola CPU for exampel are bg endian + + + // To convert byte order you can either use the source buffer and a small temporary buffer + // of few bytes to convert for example W32 by W32. You can also allocate a big buffer in + // this function is it is easier or more efficient but don't forget to free it at end of function + + + err_warning (( ERR_OUT, "User endian conversion function called BUT it does nothing => User should implement little / big endian conversion !" )); // Remove this message when data conv will be implemented + + + // The function must returns 0 if ok, -1 or any negative number in case of error + + + // return (-1); // Value to return in case of error + + + return (0); // Value returned in case there is no error +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecordLoad ( char* FileName, void* Pt, UInt32 Sz, UInt8 FormatVers ) +* +* \brief : Loads a record from disk + check HeadChk fields +* +* \param : FileName - File +* +* \param : Pt - Pointer to record +* +* \param : Sz - record size in W8 + +* \return : Error code \n +* : 0, 1 - OK 1 = endian conversion done, 0 = no conversion done \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 13/05/2021 +* \date : Doc date : 13/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FRecordLoad ( char* FileName, void* Pt, UInt32 Sz, UInt8 FormatVers ) { + + SInt32 VRet; + SInt32 VEndianConvDone; + FILE* VPfSrc; + SInt32 VReadSz; + UInt32 VExpectedTagBegin; + // MIS1__TBtRecHeadChk* VPtHeadChk = ( MIS1__TBtRecHeadChk*) Pt; + + MIS1__TBtRecHeadChk* VPtHeadChk; + + + VPtHeadChk = ( MIS1__TBtRecHeadChk*) Pt; + + // Chekc param + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + err_retnull ( Sz, (ERR_OUT,"Abort => Sz == 0") ); + + // Init + + VExpectedTagBegin = MIS1__BT_REC_TAG_BEGIN | FormatVers; + + VEndianConvDone = 0; + + // Reset destination record + + memset ( Pt, 0, Sz ); + + // Read + + + VPfSrc = fopen ( FileName, "rb" ); + + err_retnull ( VPfSrc, (ERR_OUT,"Source file %s open failed", FileName ) ); + + VReadSz = fread ( Pt, 1 /* byte size */ , Sz /* bytes number */, VPfSrc ); + + // Check size read + + if ( VReadSz != Sz ) { + fclose (VPfSrc); + err_retfail ( -1, (ERR_OUT,"Abort => Record sz on disk = %d W8 <> Record size = %d => W linker align pb or bad format", VReadSz, Sz ) ); + } + + // Close file + + fclose (VPfSrc); + + + // Check endianness => Call conersion function if needed + + if ( VPtHeadChk->TagEndian != MIS1__BT_REC_TAG_ENDIAN ) { + + VEndianConvDone = 1; + + err_warning (( ERR_OUT, "CPU must be little endian, it is %d (0 => little endian, 1 => big endian, -1 => ?)", MIS1__FIsCpuBigEndian () )); + + VRet = MIS1__FUserEndianConv ( Pt, Sz ); + + err_retfail ( VRet, (ERR_OUT,"Abort => User endian conversion function MIS1__FUserEndianConv ( Pt, Sz ) has failed ! Ret = %d", VRet) ); + + } + + + + // Check endianness + begin tag after endian conversion + + if ( VPtHeadChk->TagEndian != MIS1__BT_REC_TAG_ENDIAN ) { + + err_error (( ERR_OUT, "CPU must be little endian, it is %d (0 => little endian, 1 => big endian, -1 => ?)", MIS1__FIsCpuBigEndian () )); + + err_retfail ( -1, (ERR_OUT,"Abort => Tag endian field = %X <> MIS1__BT_REC_TAG_ENDIAN = %X", VPtHeadChk->TagEndian, MIS1__BT_REC_TAG_ENDIAN ) ); + } + + + if ( VPtHeadChk->TagBeg != VExpectedTagBegin ) { + err_retfail ( -1, (ERR_OUT,"Abort => Tag begin field = %X <> (MIS1__BT_REC_TAG_BEGIN | Version) = %X", VPtHeadChk->TagBeg, VExpectedTagBegin ) ); + } + + + return ( VEndianConvDone ); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__FRecordSave ( char* FileName, void* Pt, UInt32 Sz, UInt8 FormatVers ) +* +* \brief : Saves a record to disk +* +* \param : FileName - File +* +* \param : Pt - Pointer to record +* +* \param : Sz - record size in W8 +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 13/05/2021 +* \date : Doc date : 13/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__FRecordSave ( char* FileName, void* Pt, UInt32 Sz, UInt8 FormatVers ) { + + FILE* VPfDest; + SInt32 VWriteSz; + SInt32 VRet; + // MIS1__TBtRecHeadChk* VPtHeadChk = ( MIS1__TBtRecHeadChk*) Pt; + + MIS1__TBtRecHeadChk* VPtHeadChk; + + + VPtHeadChk = ( MIS1__TBtRecHeadChk*) Pt; + + // Chekc param + + err_retnull ( FileName, (ERR_OUT,"Abort => FileName == NULL") ); + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + err_retnull ( Sz, (ERR_OUT,"Abort => Sz == 0") ); + + + // Set tags + + VPtHeadChk->TagBeg = MIS1__BT_REC_TAG_BEGIN | FormatVers; + VPtHeadChk->TagEndian = MIS1__BT_REC_TAG_ENDIAN; + + // Write + + + VPfDest = fopen ( FileName, "wb" ); + + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s open failed", FileName ) ); + + VWriteSz = fwrite ( Pt, 1 /* byte size */, Sz, VPfDest ); + + + // Check + + if ( VWriteSz != Sz ) { + err_retfail ( -1, (ERR_OUT,"Abort => Record sz written on disk = %d W8 <> Record size = %d => File I/O problem", VWriteSz, Sz ) ); + } + + + fclose (VPfDest); + + err_retok (( ERR_OUT, "Ok" )); + +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtRunCnfRecLoad ( char* FileName, MIS1__TBtRunCnfRec* Pt, UInt8 FormatVers ) +* +* \brief : Loads from disk run conf record +* +* \param : FileName - File +* +* \param : Pt - Pointer to record +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 13/05/2021 +* \date : Doc date : 13/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FBtRunCnfRecLoad ( char* FileName, MIS1__TBtRunCnfRec* Pt, UInt8 FormatVers ) { + + SInt32 VRet; + + VRet = MIS1__FRecordLoad ( FileName, Pt, sizeof (MIS1__TBtRunCnfRec), FormatVers ); + + err_retfail ( VRet, (ERR_OUT,"Load run conf record has failed ! Ret = %d", VRet) ); + + err_retok (( ERR_OUT, "Ok" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtRunCnfRecSave ( char* FileName, MIS1__TBtRunCnfRec* P, UInt8 FormatVerst ) +* +* \brief : Saves run conf recordto disk +* +* \param : FileName - File +* +* \param : Pt - Pointer to record +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 13/05/2021 +* \date : Doc date : 13/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FBtRunCnfRecSave ( char* FileName, MIS1__TBtRunCnfRec* Pt, UInt8 FormatVers ) { + + SInt32 VRet; + + VRet = MIS1__FRecordSave ( FileName, Pt, sizeof (MIS1__TBtRunCnfRec), FormatVers ); + + err_retfail ( VRet, (ERR_OUT,"Save run conf record has failed ! Ret = %d", VRet) ); + + err_retok (( ERR_OUT, "Ok" )); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtRunCnfRecPrint ( MIS1__TBtRunCnfRec* Pt ) +* +* \brief : Prints run conf record +* +* \param : Pt - Pointer to record +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 13/05/2021 +* \date : Doc date : 13/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FBtRunCnfRecPrint ( MIS1__TBtRunCnfRec* Pt ) { + + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL" ) ); + + // Print + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "===========================================================================" )); + msg (( MSG_OUT, " Run config record" )); + msg (( MSG_OUT, "===========================================================================" )); + msg (( MSG_OUT, "" )); + + + msg (( MSG_OUT, "TagBeg = %.8X", Pt->HeadChk.TagBeg )); /*!< Should be == MIS1__BT_REC_TAG_BEGIN, with B7B0 = Data format version */ + msg (( MSG_OUT, "TagEndian = %.8X", Pt->HeadChk.TagEndian )); /*!< Should be == M MIS1__BT_REC_TAG_ENDIAN */ + + // WHen a parameter is not used it can be set to -1 + + msg (( MSG_OUT, "RunNo = %.4d", Pt->RunNo )); /*!< No of run */ + msg (( MSG_OUT, "AcqNb = %.4d", Pt->AcqNb )); /*!< Acquisitions nb in run */ + msg (( MSG_OUT, "FrNbPerAcq = %.4d", Pt->FrNbPerAcq )); /*!< Frames nb / acquisition */ + msg (( MSG_OUT, "AcqNbPerFile = %.4d", Pt->AcqNbPerFile )); /*!< Acquisitions nb / file */ + msg (( MSG_OUT, "MinTrigNb = %.4d", Pt->MinTrigNb )); /*!< Minimun triggers nb to stored and acquisition */ + msg (( MSG_OUT, "MaxTrigNb = %.4d", Pt->MaxTrigNb )); /*!< Maximum triggers nb to stored and acquisition */ + msg (( MSG_OUT, "RunMode = %.4d", Pt->RunMode )); /*!< Run mode => TB defined later => Probably RAW / TRIGGERS ONLY */ + msg (( MSG_OUT, "ProcMode = %.4d", Pt->ProcMode )); /*!< Processing mode => TB defined later */ + msg (( MSG_OUT, "SaveMode = %.4d", Pt->SaveMode )); /*!< Save mode => TB defined later, 0 => don't save */ + msg (( MSG_OUT, "TrigMode = %.4d", Pt->TrigMode )); /*!< Trigger mode => TB defined later */ + msg (( MSG_OUT, "RunTrgPreFrNb = %.4d", Pt->RunTrgPreFrNb )); /*!< For trigger only runs => Nb of frames stored before trigger */ + msg (( MSG_OUT, "RunTrgPostFrNb = %.4d", Pt->RunTrgPostFrNb )); /*!< For trigger only runs => Nb of frames stored after trigger */ + + + msg (( MSG_OUT, "DmaPacketW64Sz = %.4d", Pt->DmaPacketW64Sz )); /*!< DMA packet size used for Flex RIO => for info only */ + + msg (( MSG_OUT, "RunCmt = %s", Pt->RunCmt )); /*!< User run comment */ + + msg (( MSG_OUT, "RunRawIndexFilePrefix = %s", Pt->RunRawIndexFilePrefix )); /*!< Name of the index file Prefix for raw data run */ + msg (( MSG_OUT, "RunRawDataFilePrefix = %s", Pt->RunRawDataFilePrefix )); /*!< Name of the raw data file prefix = name without the file number ext RUN_777_ */ + + msg (( MSG_OUT, "RunTrgIndexFilePrefix = %s", Pt->RunTrgIndexFilePrefix )); /*!< Name of the index file Prefix for "triggers only" data run */ + msg (( MSG_OUT, "RunTrgDataFilePrefix = %s", Pt->RunTrgDataFilePrefix )); /*!< Name of the "triggers only" data file prefix = name without the file number ext RUN_777_ */ + + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtRunIndexfRecLoad ( char* FileName, MIS1__TBtRunRawIndexRec* Pt, UInt8 FormatVers ) +* +* \brief : Loads from disk run raw index record +* +* \param : FileName - File +* +* \param : Pt - Pointer to record +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 13/05/2021 +* \date : Doc date : 13/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +SInt32 MIS1__BT_FBtRunIndexRecLoad ( char* FileName, MIS1__TBtRunRawIndexRec* Pt, UInt8 FormatVers ) { + + SInt32 VRet; + + VRet = MIS1__FRecordLoad ( FileName, Pt, sizeof (MIS1__TBtRunRawIndexRec), FormatVers ); + + err_retfail ( VRet, (ERR_OUT,"Load run raw index record has failed ! Ret = %d", VRet) ); + + err_retok (( ERR_OUT, "Ok" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtRunIndexfReccSave ( char* FileName, MIS1__TBtRunRawIndexRec* Pt, UInt8 FormatVers ) +* +* \brief : Saves run conf recordto disk +* +* \param : FileName - File +* +* \param : Pt - Pointer to record +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 13/05/2021 +* \date : Doc date : 13/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FBtRunIndexfRecSave ( char* FileName, MIS1__TBtRunRawIndexRec* Pt, UInt8 FormatVers ) { + + SInt32 VRet; + + VRet = MIS1__FRecordSave ( FileName, Pt, sizeof (MIS1__TBtRunRawIndexRec), FormatVers ); + + err_retfail ( VRet, (ERR_OUT,"Save raw index record has failed ! Ret = %d", VRet) ); + + err_retok (( ERR_OUT, "Ok" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtRunIndexRecPrint ( MIS1__TBtRunRawIndexRec* Pt, UInt32 PrintTriggers, UInt8 PrintFrCnt, UInt8 PrintFiredPixels ) +* +* \brief : Prints run conf record +* +* \param : Pt - Pointer to record +* +* \return : Error code \n +* : 0 - OK \n +* : < 0 - Error \n +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 13/05/2021 +* \date : Doc date : 13/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FBtRunIndexRecPrint ( MIS1__TBtRunRawIndexRec* Pt, UInt32 PrintTriggers, UInt8 PrintFrCnt, UInt8 PrintFiredPixels ) { + + SInt32 VRet; + SInt32 Vi; + MIS1__TBtAcqRawHead* VPtAcqHead; + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort => Pt == NULL" ) ); + + // Print + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "===========================================================================" )); + msg (( MSG_OUT, " Run index record" )); + msg (( MSG_OUT, "===========================================================================" )); + msg (( MSG_OUT, "" )); + + msg (( MSG_OUT, "TagBeg = %.8X", Pt->HeadChk.TagBeg )); /*!< Should be == MIS1__BT_REC_TAG_BEGIN, with B7B0 = Data format version */ + msg (( MSG_OUT, "TagEndian = %.8X", Pt->HeadChk.TagEndian )); /*!< Should be == M MIS1__BT_REC_TAG_ENDIAN */ + + msg (( MSG_OUT, "AcqNbInFile = %.4d", Pt->AcqNbInFile )); /*!< Acquisition number in the file (index and data) */ + + + + + msg (( MSG_OUT, "" )); + + for ( Vi=0; Vi < 10 /* Pt->AcqNbInFile */; Vi++ ) { + + VPtAcqHead = &Pt->AAcqHead[Vi]; + + MIS1__BT_FAcqRawHeadRecPrint ( VPtAcqHead, PrintTriggers, PrintFrCnt, PrintFiredPixels ); + } + + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : int32_t MIS1__FIsCpuBigEndian +* +* \brief : Returns 1 if CPU is big endian, 0 if little endian, -1 is unknown +* +* \param : None - +* +* \return : Returns 1 if CPU isbig endian, 0 if little endian, -1 is unknown +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* +* Items not filled now : \n +* todo : +* +* bug : +* +* \date : Date : 19/05/2021 +* \date : Doc date : 19/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +int32_t MIS1__FIsCpuBigEndian () { + + unsigned long int VTest = 0x11223344; + + unsigned char* VPtTest = (UInt8*) &VTest; + + if ( (VPtTest[0] == 0x11 ) && (VPtTest[1] == 0x22 ) && (VPtTest[2] == 0x33 ) && (VPtTest[3] == 0x44 ) ) { + return (1); + } + + if ( (VPtTest[0] == 0x44 ) && (VPtTest[1] == 0x33 ) && (VPtTest[2] == 0x22 ) && (VPtTest[3] == 0x11 ) ) { + return (0); + } + + return (-1); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtRunRead () +* : +* \brief : Constructor \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtRunRead::MIS1__TBtRunRead () { + + _FBegin (); + +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : ~MIS1__TBtRunRead () +* : +* \brief : Destructor \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtRunRead::~MIS1__TBtRunRead () { + + + err_error (( ERR_OUT, "~MIS1__TBtRunRead () called" )); + + _FEnd (); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::FIsCpuBigEndian () +* : +* \brief : Destructor \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 19/05/2021 +* \date : Doc date : 19/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::FIsCpuBigEndian () { + + _CpuIsBigEndian = MIS1__FIsCpuBigEndian (); + + return ( _CpuIsBigEndian ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::_FBegin () +* : +* \brief : Class initilization = Init variables, alloc meme, eror + general messages enable / disable \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Called by constructor +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::_FBegin () { + + SInt32 VRet; + SInt32 VDemoVar; + + + // ----------------------------------------------------------- + // Init error messages lib + // ----------------------------------------------------------- + + ERR_FBegin ( 1 /* Enable */, FErrLogSetFilename () /* FilePath */ ); + + // Set log level, can be + // + // ERR_LOG_LVL_NONE + // ERR_LOG_LVL_ALL + // ERR_LOG_LVL_WARNINGS_ERRORS + // ERR_LOG_LVL_ERRORS + + _ErrLogSetLevel = ERR_LOG_LVL_ALL; + + ERR_FSetFileLogLevel ( _ErrLogSetLevel /* LogLevel */ ); + ERR_FSetUserLogLevel ( _ErrLogSetLevel /* LogLevel */ ); + + // Install error log print user function + + ERR_FSetUserErrorFunc ( &MIS1__TBtRunRead_FErrLogUsrPrint ); + + + // Test error logging + + err_trace (( ERR_OUT, "Trace message : VDemoVar = %d", VDemoVar )); + err_error (( ERR_OUT, "Warning message : VDemoVar = %d", VDemoVar )); + err_warning (( ERR_OUT, "Error message : VDemoVar = %d", VDemoVar )); + + + + // ----------------------------------------------------------- + // Init general messages lib + // ----------------------------------------------------------- + + MSG_FBegin ( 1 /* Enable */, FMsgLogSetFilename () /* FilePath */ ); + + // Set log level, only 127 available now + + _MsgLogSetLevel = 127; + + MSG_FSetFileLogLevel ( _MsgLogSetLevel /* Level */ ); + MSG_FSetUserLogLevel ( _MsgLogSetLevel /* Level */ ); + + // Install user function + + MSG_FSetUserMsgFunc ( &MIS1__TBtRunRead_FMsgLogUsrPrint ); + + + // Test messages logging + + msg (( MSG_OUT, "General message : VDemoVar = %d", VDemoVar )); + + + // ----------------------------------------------------------- + // Get CPU endianness + // ----------------------------------------------------------- + + FIsCpuBigEndian (); // Result in _CpuIsBigEndian : 0 = Little, 1 = Big, -1 = ??? + + + // ----------------------------------------------------------- + // Reset fields + // ----------------------------------------------------------- + + _LastError = 0; + + _RunConfLoaded = 0; + _RunNo = 0; + + + + _AcqHeadSzW8 = 0; + _AcqMaxTotSzW8 = 0; + _AcqMaxDataSzW8 = 0; + + _PtAcqRaw = NULL; + + _CurAcqId = 0; + _CurRawFileId = -1; + _CurAcqIdInFile = -1; + + _NewAcqId = 0; + _NewRawFileId = -1; + _NewAcqIdInFile = -1; + + + _CurRawFilePt = NULL; + _CurIndexFilePt = NULL; + + + _HeadPrintTriggers = 10; // Print triggers, -1 => All, 0 => No, > 0 => value = nb of triggers to print + _HeadPrintFrCnt = 10; // Print frames counters, -1 => All, 0 => No, > 0 => value = nb of frames to print + _HeadPrintFiredPixels = 1; // Print fired pixels, 0 / 1 + + + memset ( &_RunCnfRec, 0, sizeof (MIS1__TBtRunCnfRec) ); + + + + + _DbgPrint = 1; + + + err_retok (( ERR_OUT, "Ok" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::_FEnd () +* : +* \brief : Class finalization = free meme etc \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Called by destructor +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::_FEnd () { + + SInt32 VRet; + + + + err_retok (( ERR_OUT, "Ok" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : char* MIS1__TBtRunRead::FErrLogSetFilename () +* : +* \brief : Sets errors messages log file name and returns it \n +* : Can be called to locate the error file directory and name +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Called by constructor => File name can' t be modified later ! +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +char* MIS1__TBtRunRead::FErrLogSetFilename () { + + SInt32 VRet; + static char VErrLogFile[GLB_FILE_PATH_SZ] = MIS1__TBtRunRead_DEF_ERR_LOG_FILE; + + + return ( VErrLogFile ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : char* MIS1__TBtRunRead::FMsgLogSetFilename () +* : +* \brief : Sets general messages log file name and returns it \n +* : Can be called to locate the general messages file directory and name +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Called by constructor => File name can' t be modified later ! +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +char* MIS1__TBtRunRead::FMsgLogSetFilename () { + + SInt32 VRet; + static char VMsgLogFile[GLB_FILE_PATH_SZ] = MIS1__TBtRunRead_DEF_MSG_LOG_FILE; + return ( VMsgLogFile ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::FErrLogSetLevel ( SInt8 LogLevel ) +* : +* \brief : Sets error log level, by default it is set to ERR_LOG_LVL_ALL, \n +* it can be \n +* \n +* ERR_LOG_LVL_NONE \n +* ERR_LOG_LVL_ALL \n +* ERR_LOG_LVL_WARNINGS_ERRORS \n +* ERR_LOG_LVL_ERRORS \n +* +* : +* \param : LogLevel - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Called by desconstructor +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::FErrLogSetLevel ( SInt8 LogLevel ) { + + SInt32 VRet; + + _ErrLogSetLevel = LogLevel; + + ERR_FSetFileLogLevel ( _ErrLogSetLevel /* LogLevel */ ); + ERR_FSetUserLogLevel ( _ErrLogSetLevel /* LogLevel */ ); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::FMsgLogSetLevel ( SInt8 LogLevel ) +* : +* \brief : Sets general log level, by default it is set 127 <=> ALL, it can be 0..127 +* : +* \param : LogLevel - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Called by desconstructor +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::FMsgLogSetLevel ( SInt8 LogLevel ) { + + SInt32 VRet; + + _MsgLogSetLevel = LogLevel; + + + MSG_FSetFileLogLevel ( _MsgLogSetLevel /* Level */ ); + MSG_FSetUserLogLevel ( _MsgLogSetLevel /* Level */ ); + + + err_retok (( ERR_OUT, "" )); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtRunRead::FErrGetLastMsg () +* : +* \brief : Gets last error message as a string +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Called by desconstructor +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 19/05/2021 +* \date : Doc date : 19/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +char* MIS1__TBtRunRead::FErrGetLastMsg () { + + return ( ERR_FGetLastErrMsg () ); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : char* MIS1__TBtRunRead::FMsgGetLastMsg () +* : +* \brief : Gets last general message as a string +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Called by desconstructor +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 19/05/2021 +* \date : Doc date : 19/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +char* MIS1__TBtRunRead::FMsgGetLastMsg () { + + return ( MSG_FGetLastMsgLong ( 0 /* Chan */ ) ); + +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead_FErrLogUsrPrint ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ) +* : +* \brief : User can implement here his own errors messages printing function \n +* : +* \param : Type - Type of message = T, W, E => Trace, Warning, Error +* : +* \param : ErrLocation - File and function names + source file line where the error has occured +* : +* \param : ErrUserMsg - The message set by user in addition to Type and ErrLocation +* : +* \param : FullMsg - The full message as written in log file = Type + ErrLocation + ErrUserMsg +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Not called by user, automatically called each time an error macro is executed +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead_FErrLogUsrPrint ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ) { + + SInt32 VRet; + + char VErrMsg[GLB_CMT_SZ]; + + // Message reformating can be done like this + // + // sprintf ( VErrMsg, "Type = %c, Location = %s, Msg = %s ", Type, ErrLocation, ErrUserMsg ); + + + #ifdef CC_APP_GUI_CPP + FrmMain->PgMain_MemErr->Lines->Add ( FullMsg ); + #endif + + #ifdef CC_APP_ERR_LOG_VIA_PRINTF + printf ( "%s", FullMsg ); + #endif + + + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead_FMsgLogUsrPrint { char* Msg ) +* : +* \brief : User can implement here his own general messages printing function \n +* : +* \param : Msg - The message to print +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Not called by user, automatically called each time a general message macro is executed +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead_FMsgLogUsrPrint ( char* Msg ) { + + SInt32 VRet; + char VMsg[GLB_CMT_SZ]; + + + #ifdef CC_APP_GUI_CPP + FrmMain->PgMain_MemMsg->Lines->Add ( Msg ); + #endif + + #ifdef CC_APP_MSG_LOG_VIA_PRINTF + printf ( "%s", Msg ); + #endif + + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::FRunConf ( char* RunRootDir, UInt32 RunNo, UInt8 PrintRunHeader, UInt8 FormatVers ) +* : +* \brief : Configures the run to read \n +* : +* \param : RunRootDir - Root directory of run, ex : c:\data if run 777 is in c:\data\777 +* : +* \param : RunNo - Run number, ex : 777 +* : +* \param : FormatVers - Version of record format, please set it to MIS1__BT_RUN_RD_FILE_FORMAT +* : +* \param : PrintRunHeader - If 1, the run header info will be printed in messages log file +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/05/2021 +* \date : Doc date : 17/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::FRunConf ( char* RunRootDir, UInt32 RunNo, UInt8 PrintRunHeader, UInt8 FormatVers ) { + + SInt32 VRet; + + + // Check param + + err_retnull ( RunRootDir, (ERR_OUT,"Abort => RunRootDir == NULL") ); + + // Check status + + if ( _RunConfLoaded == 1 ) { + err_warning (( ERR_OUT, "Abort => A run (No %d) is already loaded => Close it before loading a new one", _RunNo )); + err_retok (( ERR_OUT, "Ok" )); + } + + + _RunNo = RunNo; + _LastError = -1; + + + // Resets variable & record + + _RunConfLoaded = 0; + + memset ( &_RunCnfRec, 0, sizeof (MIS1__TBtRunCnfRec) ); + + // Build run header filename + + sprintf ( _RunRootDir, "%s", RunRootDir ); + + sprintf ( _RunConfFileName, "%s/%d/RUN_%d_CONF.bin", RunRootDir, RunNo, RunNo ); // C:\Data\msis1\777\RUN_777_CONF.bin + + err_trace (( ERR_OUT, "Try to load run no %d, run conf / header file = %s", RunNo, _RunConfFileName )); + + // Loads record + + VRet = MIS1__BT_FBtRunCnfRecLoad ( _RunConfFileName, &_RunCnfRec, FormatVers ); + + err_retfail ( VRet, (ERR_OUT,"Loading run no %d, run conf / header file = %s failed ! Ret = %d", RunNo, _RunConfFileName, VRet ) ); + + err_trace (( ERR_OUT, "Run conf file loaded :-)" )); + + // Prints info + + if ( PrintRunHeader ) { + + VRet = MIS1__BT_FBtRunCnfRecPrint ( &_RunCnfRec ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Printing run conf file record failed ! Ret = %d", VRet) ); + + } + + // ------------------------------ + // Calculated Acq max size + // ------------------------------ + + _PtAcqRaw = (MIS1__TBtAcqRawRec*) malloc ( sizeof (MIS1__TBtAcqRawRec) ); // Alloc Acq (fixed size) only to get a record for header size calcualtion + + err_retnull ( _PtAcqRaw, (ERR_OUT,"Abort => Allocation of one Acq buffer (for sizes calculation) of %d W8 failed !", sizeof (MIS1__TBtAcqRawRec) ) ); + + // Before 19/05/2021, using static allocation of Acq record for sizes calculation + // + // _AcqHeadSzW8 = (UInt32) ((UInt8*) &_AcqRaw.MSisData.Au64[0] - (UInt8*) &_AcqRaw); // Since 17/05/2021 + + + // Since 19/05/2021, using dynamic allocation of Acq record for sizes calculation (to reduce static variables volume) + + _AcqHeadSzW8 = (UInt32) ((UInt8*) &_PtAcqRaw->MSisData.Au64[0] - (UInt8*) _PtAcqRaw); + + // _AcqMaxTotSzW8 = _AcqHeadSzW8 + ( _RunCnfRec.FrNbPerAcq * MIS1__BT_MAX_MSIS_NB_ACQ * MIS1__BT_TOT_FRAME_SZ_W8 ); // Since 17/05/2021 and Before 31/05/2021 + + _AcqMaxDataSzW8 = ( _RunCnfRec.FrNbPerAcq * MIS1__BT_MAX_MSIS_NB_ACQ * MIS1__BT_TOT_FRAME_SZ_W8 ); // Since 31/05/2021 : _AcqMaxDataSzW8 added to check size on Acq data read from file + _AcqMaxTotSzW8 = _AcqHeadSzW8 + _AcqMaxDataSzW8; // Since 31/05/2021 + + free ( _PtAcqRaw ); // It will be allocated hereafter with the add-hoc size + + + err_trace (( ERR_OUT, "1 Acq = %d frames : _AcqHeadSzW8 = %d W8, _AcqMaxTotSzW8 = %d W8", _RunCnfRec.FrNbPerAcq, _AcqHeadSzW8, _AcqMaxTotSzW8 )); + + + // ------------------------------ + // Alloc memory for one Acq + // ------------------------------ + + _PtAcqRaw = (MIS1__TBtAcqRawRec*) malloc ( _AcqMaxTotSzW8 ); + + err_retnull ( _PtAcqRaw, (ERR_OUT,"Abort => Allocation of one Acq buffer (for Acq storage) of %d W8 failed !", _AcqMaxTotSzW8) ); + + + // Set fields + + + _CurAcqId = 0; + _CurRawFileId = -1; + _CurAcqIdInFile = -1; + + _NewAcqId = 0; + _NewRawFileId = -1; + _NewAcqIdInFile = -1; + + _CurRawFilePt = NULL; + _CurIndexFilePt = NULL; + + _LastRawFileId = (_RunCnfRec.AcqNb / _RunCnfRec.AcqNbPerFile) - 1; + + _RunConfLoaded = 1; + _LastError = 0; + + err_retok (( ERR_OUT, "Ok" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::FRunClose () +* : +* \brief : Closes a run (free mem, reset variables, etc ...) \n +* : +* \param : None +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 16/05/2021 +* \date : Doc date : 16/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::FRunClose () { + + SInt32 VRet; + char VMsg[GLB_CMT_SZ]; + + + VRet = 0; + + // Free memory + + #ifndef CC_NOT_CPP_BUILDER + + try { + + if ( _PtAcqRaw != NULL ) { + free ( _PtAcqRaw ); + } + + _PtAcqRaw = NULL; + + } + + catch ( Exception& VException ) { + err_error (( ERR_OUT, "free Acq exception = %s", VException.Message.c_str() )); + VRet= -1; + } + + + #else + + if ( _PtAcqRaw != NULL ) { + free ( _PtAcqRaw ); + } + + _PtAcqRaw = NULL; + + #endif + + + + // Close files + + #ifndef CC_NOT_CPP_BUILDER + + try { + + if ( _CurRawFilePt != NULL ) { + fclose ( _CurRawFilePt ); + } + + if ( _CurIndexFilePt != NULL ) { + fclose ( _CurIndexFilePt ); + } + + } + + catch ( Exception& VException ) { + err_error (( ERR_OUT, "Close files exception = %s", VException.Message.c_str() )); + VRet= -1; + } + + + #else + + if ( _CurRawFilePt != NULL ) { + fclose ( _CurRawFilePt ); + } + + if ( _CurIndexFilePt != NULL ) { + fclose ( _CurIndexFilePt ); + } + + + #endif + + + // Reset variables + + _RunConfLoaded = 0; + _RunNo = 0; + + _AcqHeadSzW8 = 0; + _AcqMaxTotSzW8 = 0; + _AcqMaxDataSzW8 = 0; + + _CurRawFilePt = NULL; + _CurIndexFilePt = NULL; + + + + err_retval ( VRet, ( ERR_OUT, "Error = %d", VRet ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtRunCnfRec* MIS1__TBtRunRead::FRunHeaderGet ( UInt8 Print ) +* : +* \brief : Returns a pointer to current run header, prints info in log file if Print == 1 \n +* : +* \param : Print - Prints info in log file if Print == 1 +* : +* \return : A pointer to run conf record MIS1__TBtRunCnfRec*, NULL if error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/05/2021 +* \date : Doc date : 17/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +MIS1__TBtRunCnfRec* MIS1__TBtRunRead::FRunHeaderGet ( UInt8 Print ) { + + SInt32 VRet; + + // Check + + if ( _RunConfLoaded < 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => No run conf loaded !") ); + } + + + // Print + + if ( Print ) { + + VRet = MIS1__BT_FBtRunCnfRecPrint ( &_RunCnfRec ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Printing run conf file record failed ! Ret = %d", VRet) ); + + } + + + return ( &_RunCnfRec ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::FAcqFirst ( UInt8 ChkHead, UInt8 PrintHead ) +* : +* \brief : Returns a pointer to the first Acq of run \n +* : \n +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Sequential / random access via index selection to be implemented in this method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::FAcqFirst ( UInt8 ChkHead, UInt8 PrintHead ) { + + SInt32 VRet; + MIS1__TBtAcqRawRec* VPtAcq; + + + // Now on 18/05/2021 only sequential access is available + // Selection between sequential and random access via index will be implemented here + // + // Rq : It can seen as useless to implement random access to get the first acq of a run + // and it is, but some initialization for FAcqNextSeq (...) can be required to be done here + // that is why I have written this long block of comment ;-) + + VPtAcq = _FAcqFirstSeq ( ChkHead, PrintHead ); + + return ( VPtAcq ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::FAcqNext ( UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) +* : +* \brief : Returns a pointer to the xext Acq of run \n +* : \n +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* \param : PtReachEn - A pointer on a flag set to 1 if end of file is reached, set it to NULL if not used +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Sequential / random access via index selection to be implemented in this method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::FAcqNext ( UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) { + + SInt32 VRet; + MIS1__TBtAcqRawRec* VPtAcq; + + + // Now on 18/05/2021 only sequential access is available + // Selection between sequential and random access via index will be implemented here + + VPtAcq = _FAcqNextSeq ( ChkHead, PrintHead, PtReachEnd ); + + return ( VPtAcq ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::FAcqGoto ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) +* : +* \brief : Returns a pointer to the xext Acq of run \n +* : \n +* : +* \param : AcqId - Id / No of the Acq +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* \param : PtReachEn - A pointer on a flag set to 1 if end of file is reached, set it to NULL if not used +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Sequential / random access via index selection to be implemented in this method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::FAcqGoto ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) { + + SInt32 VRet; + MIS1__TBtAcqRawRec* VPtAcq; + + + // Now on 18/05/2021 only sequential access is available + // Selection between sequential and random access via index will be implemented here + + VPtAcq = _FAcqGotoSeq ( AcqId, ChkHead, PrintHead, PtReachEnd ); + + return ( VPtAcq ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::FAcqGetPt () +* : +* \brief : Returns a pointer to current Acq loaded in memory \n +* : +* \param : None - +* : +* \return : A pointer to the Acq +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::FAcqGetPt () { + + return ( _PtAcqRaw ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::FAcqPrint ( MIS1__TBtAcqRawRec* Pt, SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels, UInt8 DataWSize, UInt32 FirstDataW, UInt32 NbDataW, UInt8 VRS ) +* : +* \brief : Print one Acq : the one pointer by Pt or the current one loaded n memory if Pt == NULL \n +* : +* \param : Pt - Pointer to Acq, if NULL => Uses Acq loaded in mem = _PtAcqRaw +* : +* \param : PrintTriggers - Prints trigger, -1 => All, 0 => None, N > 0 => Prints first N triggers +* : +* \param : PrintFrCnt - Prints frames counters x 6 MSis 1, -1 => All frames, 0 => None, N > 0 => Prints first N frames +* : +* \param : PrintFiredPixels - Prints fired pixels for each MSis 1, each sub matrix, 0 => No, 1 => Yes +* : +* \param : DataWSize - Size of W to print for data part, can be 8, 16, 32, 64 bits +* +* \param : FirstDataW - First W to print +* +* \param : NbDataWW - Nb W to print +* +* \param : VRS - Record type 0 => Fixed Record Size, 1 => Variable Record Size + +* \param : - +* : +* \param : - +* : +* \param : - +* : + + +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::FAcqPrint ( MIS1__TBtAcqRawRec* Pt, SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels, UInt8 DataWSize, UInt32 FirstDataW, UInt32 NbDataW, UInt8 VRS ) { + + SInt32 VRet; + + if ( Pt == NULL ) { + Pt = _PtAcqRaw; + } + + VRet = MIS1__BT_FAcqRawPrint ( Pt, PrintTriggers, PrintFrCnt, PrintFiredPixels, DataWSize, FirstDataW, NbDataW, VRS ); + + err_retfail ( VRet, (ERR_OUT,"Abort => Printing acq failed !" ) ); + + err_retok (( ERR_OUT, "Ok" )); + +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::FAcqHeadPrintOptSet ( SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels ) +* : +* \brief : Confifures the header printing option used by Acq scanning functions like FAcqFirst (...), FAcqNext (...), FAcqGoto (...) \n +* : +* \param : PrintTriggers - Print triggers, -1 => All, 0 => No, > 0 => value = nb of triggers to print +* +* \param : PrintFrCnt - Print frames counters, -1 => All, 0 => No, > 0 => value = nb of frames to print +* +* \param : PrintFiredPixels - Print fired pixels, 0 / 1 +* +* \return : Always 0 +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 19/05/2021 +* \date : Doc date : 19/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +// Confifures the header printing option used by Acq scanning functions like FAcqFirst (...), FAcqNext (...), FAcqGoto (...) + +SInt32 MIS1__TBtRunRead::FAcqHeadPrintOptSet ( SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels ) { + + _HeadPrintTriggers = PrintTriggers; // Print triggers, -1 => All, 0 => No, > 0 => value = nb of triggers to print + _HeadPrintFrCnt = PrintFrCnt; // Print frames counters, -1 => All, 0 => No, > 0 => value = nb of frames to print + _HeadPrintFiredPixels = PrintFiredPixels; // Print fired pixels, 0 / 1 + + + err_retok (( ERR_OUT, "Ok" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : UInt32 MIS1__TBtRunRead::FMeasTimeStart () +* : +* \brief : Starts execution time measurement \n +* : +* \param : None - +* : +* \return : Always 0 +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +UInt32 MIS1__TBtRunRead::FMeasTimeStart () { + + + _MeasTimeEndMS = 0; + _MeasTimeMS = 0; + + + #ifndef CC_NOT_CPP_BUILDER + _MeasTimeBegMS = GetTickCount (); + + #else + _MeasTimeBegMS = 0; + #endif + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : UInt32 MIS1__TBtRunRead::FMeasTimeStop () +* : +* \brief : Stops execution time measurement \n +* : +* \param : None - +* : +* \return : Execution time in ms +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +UInt32 MIS1__TBtRunRead::FMeasTimeStop () { + + + #ifndef CC_NOT_CPP_BUILDER + _MeasTimeEndMS = GetTickCount (); + _MeasTimeMS = _MeasTimeEndMS - _MeasTimeBegMS; + + #else + _MeasTimeEndMS = 0; + _MeasTimeMS = _MeasTimeEndMS - _MeasTimeBegMS; + #endif + + + return ( _MeasTimeMS ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : UInt32 MIS1__TBtRunRead::FMeasTimeGetMs () +* : +* \brief : Gets result in ms of execution time measurement \n +* : +* \param : None - +* : +* \return : Execution time in ms +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +UInt32 MIS1__TBtRunRead::FMeasTimeGetMs () { + + + return ( _MeasTimeMS ); +} + + + + +UInt32 MIS1__FConvMsToTime ( UInt32 Ms, UInt8* PtHour, UInt8* PtMin, UInt8* PtSec, UInt16* PtMs ) { + + UInt8 VHour; + UInt8 VMin; + UInt8 VSec; + UInt16 VMs; + UInt32 VRem1; + UInt32 VRem2; + + + + VHour = Ms / 3600000; + + VRem1 = Ms % 3600000; + + VMin = VRem1 / 60000; + + VRem2 = VRem1 % 60000; + + VSec = VRem2 / 1000; + + VMs = VRem2 % 1000; + + + + if ( PtHour != NULL ) { + *PtHour = VHour; + } + + if ( PtMin != NULL ) { + *PtMin = VMin; + } + + if ( PtSec != NULL ) { + *PtSec = VSec; + } + + if ( PtMs != NULL ) { + *PtMs = VMs; + } + + + + return (Ms); +} + + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : UInt32 MIS1__TBtRunRead::FMeasTimeGetHHMMSSCC ( UInt8* PtHour, UInt8* PtMin, UInt8* PtSec, UInt16* PtMs ) +* : +* \brief : Gets result in HH:MM:SS:1/100 of execution time measurement \n +* : +* \param : PtHour - +* +* \param : PtMin - +* +* \param : PtSec - +* +* \param : PtCent - +* +* \return : Execution time in ms +* +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +// + +UInt32 MIS1__TBtRunRead::FMeasTimeGetHMSMS ( UInt8* PtHour, UInt8* PtMin, UInt8* PtSec, UInt16* PtMs ) { + + + MIS1__FConvMsToTime ( _MeasTimeMS, PtHour, PtMin, PtSec, PtMs ); + + + return ( _MeasTimeMS ); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead:: +* : +* \brief : \n +* : +* \param : None - +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/05/2021 +* \date : Doc date : 17/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::F () { + + SInt32 VRet; + + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::_FBuildNewAcqFile ( UInt32 AcqNo, UInt8 Print ) +* : +* \brief : Create the file name which should contains one Acq, result sets in \n +* : _NewRawFileId, _NewAcqIdInFile , _NewRawFileName, _NewIndexFileName \n +* : +* \param : AcqNo - No of the acquisiton 0 to acq nb in run - 1 +* : +* \param : Print - If 1 => Prints result via an error trace message +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 17/05/2021 +* \date : Doc date : 17/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::_FBuildNewAcqFile ( UInt32 AcqNo, UInt8 Print ) { + + SInt32 VRet; + + + MIS1__TBtRunRead_CHECK_RET_S32 + + // Calc + + _NewAcqId = AcqNo; + + _NewRawFileId = AcqNo / _RunCnfRec.AcqNbPerFile; + _NewAcqIdInFile = AcqNo % _RunCnfRec.AcqNbPerFile; + + // Check + + if ( _NewRawFileId > _LastRawFileId ) { + err_retfail ( -1, (ERR_OUT,"Abort => AcqNo = %d > AcqNb in run = %d => AcqNo = 00..%d", AcqNo, _RunCnfRec.AcqNb, 0, _RunCnfRec.AcqNb - 1) ); + } + + + if ( _NewAcqIdInFile >= _RunCnfRec.AcqNbPerFile ) { + err_retfail ( -1, (ERR_OUT,"Abort => AcqId in run = %d is out of run fileAcqId = 0..%d", _NewAcqIdInFile, _RunCnfRec.AcqNbPerFile - 1) ); + } + + + + sprintf ( _NewRawFileName , "%s/%d/RUN_%d_RD_%d.bin", _RunRootDir, _RunNo, _RunNo, _NewRawFileId ); // RUN_777_RD_0.bin + + sprintf ( _NewIndexFileName, "%s/%d/RUN_%d_RDI_%d.bin", _RunRootDir, _RunNo, _RunNo, _NewRawFileId ); // RUN_777_RDI_0.bin + + + if ( Print ) { + err_trace (( ERR_OUT, "AcqNo = %d is in file %s which contains %d acq, its position in file is acq no = %d", AcqNo, _NewRawFileName, _RunCnfRec.AcqNbPerFile, _NewAcqIdInFile )); + err_trace (( ERR_OUT, "Index file is %s", _NewIndexFileName )); + } + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead::_FBuildNewFile ( UInt32 FileId, UInt8 Print ) +* : +* \brief : Create the file name which corresponds to FileId, result sets in \n +* : _NewRawFileId, _NewRawFileName, _NewIndexFileName \n +* : +* \param : FileId - File id +* : +* \param : Print - If 1 => Prints result via an error trace message +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__TBtRunRead::_FBuildNewFile ( UInt32 FileId, UInt8 Print ) { + + SInt32 VRet; + + + MIS1__TBtRunRead_CHECK_RET_S32 + + // Calc + + _NewRawFileId = FileId; + + // Check + + if ( _NewRawFileId > _LastRawFileId ) { + err_retfail ( -1, (ERR_OUT,"Abort => _NewRawFileId = %d > _LastRawFileId = %d", _NewRawFileId, _LastRawFileId) ); + } + + + sprintf ( _NewRawFileName , "%s/%d/RUN_%d_RD_%d.bin", _RunRootDir, _RunNo, _RunNo, _NewRawFileId ); // RUN_777_RD_0.bin + + sprintf ( _NewIndexFileName, "%s/%d/RUN_%d_RDI_%d.bin", _RunRootDir, _RunNo, _RunNo, _NewRawFileId ); // RUN_777_RDI_0.bin + + + if ( Print ) { + err_trace (( ERR_OUT, "Raw dat file is %s, Index file is %s", _NewRawFileName, _NewIndexFileName )); + } + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FFirstAcqOfRawFileGetSeq ( UInt32 RawFileId, UInt8 ChkHead, UInt8 PrintHead ) +* : +* \brief : Returns a pointer to the first Acq of one raw data file \n +* : \n +* : +* \param : RawFileId - The NO / Id of raw data file +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* : +* \return : A pointer to Acq record MIS1__TBtAcqRawRec*, NULL if error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FFirstAcqOfRawFileGetSeq ( UInt32 RawFileId, UInt8 ChkHead, UInt8 PrintHead ) { + + SInt32 VRet; + SInt32 VRecNbRead; + + // Check + + MIS1__TBtRunRead_CHECK_RET_NULL + + + // Check param + + if ( RawFileId > _LastRawFileId ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => RawFileId > Last file id of run = %d", RawFileId, _LastRawFileId) ); + } + + + // Sets first acq of file + + _CurAcqIdInFile = 0; + + // -------------------------- + // Open file + // -------------------------- + + + // If current file is not the one we want to read from (including if no file opened => _CurRawFileId == -1) + // => Close it + // => Create new filename + // => Open new file + + if ( _CurRawFileId != RawFileId ) { + + // Close current file + + err_trace (( ERR_OUT, "Close raw file Id = %d", _CurRawFileId )); + + if ( _CurRawFilePt != NULL ) { + fclose ( _CurRawFilePt ); + } + + else { + err_warning (( ERR_OUT, "Strange : raw file id = %d is opened but file ptr == NULL !!!", _CurRawFileId )); + } + + _CurRawFilePt = NULL; + + // Create new file name + + VRet = _FBuildNewFile ( RawFileId, _DbgPrint ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Build raw file name Id = %d failed ! Ret = %d", RawFileId, VRet) ); + + // Set current file name, id to new + + _CurRawFileId = _NewRawFileId; + + sprintf ( _CurRawFileName, "%s", _NewRawFileName ); + + // Open new file + + _CurRawFilePt = fopen ( _CurRawFileName, "rb" ); + + if ( _CurRawFilePt == NULL ) { + err_error (( ERR_OUT, "Abort => Open raw file = %s failed !", _CurRawFileName )); + return (NULL); + } + + + } // End if ( _CurRawFileId != RawFileId ) + + + // If current file is the one we want to read from + // => Goto beginning of file + + if ( _CurRawFileId == RawFileId ) { + + err_trace (( ERR_OUT, "Set filez ptr to beginning of file %s", _CurRawFileName )); + + if ( fseek ( _CurRawFilePt, 0 /* ofs */, SEEK_SET ) != 0 ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Set file cursor at beginning of file = %s failed !", _CurRawFileName ) ); + } + + } + + // ---------------------- + // Read first Acq + // ---------------------- + + // Read header + + + VRecNbRead = fread ( &_PtAcqRaw->Head, _AcqHeadSzW8 /* Record size */ , 1 /* Record number */, _CurRawFilePt ); + + if ( VRecNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq header of first acq, file = %s failed ! Sys = %s", _CurRawFileName, _strerror ( "" ) ) ); + } + + + // Check endianness & convert + + if ( _CpuIsBigEndian ) { + + VRet = MIS1__FUserEndianConv ( &_PtAcqRaw->Head, _AcqHeadSzW8 ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => MIS1__FUserEndianConv (...) convert Acq header failed ! Ret = %d", VRet) ); + + // Check if endianness ok + + if ( _PtAcqRaw->Head.TagBeg != MIS1__BT_REC_TAG_BEGIN ) { + + err_retfailnull ( -1, (ERR_OUT,"Abort => Record TagBeg = %X <> MIS1__BT_REC_TAG_BEGIN = %X => Bad endian conversion or bad data format version", _PtAcqRaw->Head.TagBeg, MIS1__BT_REC_TAG_BEGIN ) ); + + } + + } + + + if ( PrintHead ) { + VRet = MIS1__BT_FAcqRawHeadRecPrint ( &_PtAcqRaw->Head, _HeadPrintTriggers, _HeadPrintFrCnt, _HeadPrintFiredPixels ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Print first acq header failed ! Ret = %d", VRet) ); + } + + + // Read data + + // 333 + + // Check size + // 31/05/2021 : Add size checking, handled by fread under Windows (generates invalid argument error), but Linux ? + portability ? => Add check + + if ( _PtAcqRaw->Head.DataSz > _AcqMaxDataSzW8 ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Acq No %d Data size = %d W8 > Allocated size = %d W8", _PtAcqRaw->Head.Ids.AcqIdInRun, _PtAcqRaw->Head.DataSz, _AcqMaxDataSzW8 ) ); + } + + // err_trace (( ERR_OUT, "Read data sz = %d W8", _PtAcqRaw->Head.DataSz )); + + VRecNbRead = fread ( &_PtAcqRaw->MSisData, _PtAcqRaw->Head.DataSz /* Record size */ , 1 /* Record number */, _CurRawFilePt ); + + if ( VRecNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq data of first acq, file = %s failed ! Sys = %s", _CurRawFileName, _strerror ( "" ) ) ); + } + + + // Check endianness & convert + + if ( _CpuIsBigEndian ) { + + VRet = MIS1__FUserEndianConv ( &_PtAcqRaw->MSisData, _PtAcqRaw->Head.DataSz ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => MIS1__FUserEndianConv (...) convert Acq data failed ! Ret = %d", VRet) ); + + } + + + + return (_PtAcqRaw); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FNextAcqOfRawFileGetSeq ( UInt32 RawFileId, , UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) +* : +* \brief : Returns a pointer to next Acq of one raw data file \n +* : \n +* : +* \param : RawFileId - The NO / Id of raw data file +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* \param : PtReachEn - A pointer on a flag set to 1 if end of file is reached, set it to NULL if not used +* : +* \return : A pointer to Acq record MIS1__TBtAcqRawRec*, NULL if error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FNextAcqOfRawFileGetSeq ( UInt32 RawFileId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) { + + + SInt32 VRet; + SInt32 VRecNbRead; + + // Check + + MIS1__TBtRunRead_CHECK_RET_NULL + + + // Check param + + if ( RawFileId > _LastRawFileId ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => RawFileId > Last file id of run = %d", RawFileId, _LastRawFileId) ); + } + + + // Update current acq in file + + _CurAcqIdInFile++; + + + err_trace (( ERR_OUT, "_CurAcqIdInFile = %d, _RunCnfRec.AcqNbPerFile = %d", _CurAcqIdInFile, _RunCnfRec.AcqNbPerFile )); + + // If end of file has been reached + + if ( _CurAcqIdInFile >= _RunCnfRec.AcqNbPerFile ) { + + _CurAcqIdInFile = _RunCnfRec.AcqNbPerFile; + + if ( PtReachEnd != NULL ) { + *PtReachEnd = 1; + } + + return (_PtAcqRaw); + } + + + if ( PtReachEnd != NULL ) { + *PtReachEnd = 0; + } + + + // Check if file is already open + // => If not Call _FFirstAcqOfRawFileGetSeq (...) + + if ( _CurRawFileId != RawFileId ) { + + err_warning (( ERR_OUT, "Try to go to next Acq of file %s which is not opened => Call _FFirstAcqOfRawFileGetSeq ()", _CurRawFileName )); + + return ( _FFirstAcqOfRawFileGetSeq ( RawFileId, ChkHead, PrintHead ) ); + + } + + + // Check if file ptr is ok + + if ( _CurRawFilePt == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => File pointer is NULL, Raw file = %s", _CurRawFileName ) ); + } + + // --------------------------------------- + // Read next acq + // --------------------------------------- + + // Read header + + + VRecNbRead = fread ( &_PtAcqRaw->Head, _AcqHeadSzW8 /* Record size */ , 1 /* Record number */, _CurRawFilePt ); + + if ( VRecNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq header of next acq, file = %s failed ! Sys = %s", _CurRawFileName, _strerror ( "" ) ) ); + } + + + // Check endianness & convret + + if ( _CpuIsBigEndian ) { + + VRet = MIS1__FUserEndianConv ( &_PtAcqRaw->Head, _AcqHeadSzW8 ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => MIS1__FUserEndianConv (...) Acq header failed ! Ret = %d", VRet) ); + + // Check if endianness ok + + if ( _PtAcqRaw->Head.TagBeg != MIS1__BT_REC_TAG_BEGIN ) { + + err_retfailnull ( -1, (ERR_OUT,"Abort => Record TagBeg = %X <> MIS1__BT_REC_TAG_BEGIN = %X => Bad endian conversion or bad data format version", _PtAcqRaw->Head.TagBeg, MIS1__BT_REC_TAG_BEGIN ) ); + + } + + } + + + + if ( PrintHead ) { + VRet = MIS1__BT_FAcqRawHeadRecPrint ( &_PtAcqRaw->Head, _HeadPrintTriggers, _HeadPrintFrCnt, _HeadPrintFiredPixels ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Print next acq header failed ! Ret = %d", VRet) ); + } + + + // Read data + + // Check size + // 31/05/2021 : Add size checking, handled by fread under Windows (generates invalid argument error), but Linux ? + portability ? => Add check + + if ( _PtAcqRaw->Head.DataSz > _AcqMaxDataSzW8 ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Acq No %d Data size = %d W8 > Allocated size = %d W8", _PtAcqRaw->Head.Ids.AcqIdInRun, _PtAcqRaw->Head.DataSz, _AcqMaxDataSzW8 ) ); + } + + + // 333 + + // err_trace (( ERR_OUT, "Read data sz = %d W8", _PtAcqRaw->Head.DataSz )); + + VRecNbRead = fread ( &_PtAcqRaw->MSisData, _PtAcqRaw->Head.DataSz /* Record size */ , 1 /* Record number */, _CurRawFilePt ); + + if ( VRecNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq data of next acq, file = %s failed ! Sys = %s", _CurRawFileName, _strerror ( "" ) ) ); + } + + + + // Check endianness & convert + + if ( _CpuIsBigEndian ) { + + VRet = MIS1__FUserEndianConv ( &_PtAcqRaw->MSisData, _PtAcqRaw->Head.DataSz ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => MIS1__FUserEndianConv (...) convert Acq data failed ! Ret = %d", VRet) ); + + } + + + return (_PtAcqRaw); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FAcqFirstSeq ( UInt8 ChkHead, UInt8 PrintHead ) +* : +* \brief : Returns a pointer to the first Acq of run \n +* : \n +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FAcqFirstSeq ( UInt8 ChkHead, UInt8 PrintHead ) { + + SInt32 VRet; + MIS1__TBtAcqRawRec* VPtAcq; + + // Check + + MIS1__TBtRunRead_CHECK_RET_NULL + + + // Set first Acq + + _CurAcqId = 0; + + // Read first Acq + + VPtAcq = _FFirstAcqOfRawFileGetSeq ( 0 /* RawFileId */, ChkHead, PrintHead ); + + if ( VPtAcq == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read first acq of run failed ! file = %s", _CurRawFileName ) ); + } + + return ( VPtAcq ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FAcqNextSeq ( UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) +* : +* \brief : Returns a pointer to the xext Acq of run \n +* : \n +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* \param : PtReachEn - A pointer on a flag set to 1 if end of file is reached, set it to NULL if not used +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FAcqNextSeq ( UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) { + + SInt32 VRet; + UInt32 VRawFileId; + MIS1__TBtAcqRawRec* VPtAcq; + + // Check + + MIS1__TBtRunRead_CHECK_RET_NULL + + + // Set current Acq and calc raw file id + + _CurAcqId++; + + if ( _CurAcqId >= _RunCnfRec.AcqNb ) { + + _CurAcqId = _RunCnfRec.AcqNb; + + // msg (( MSG_OUT, "End of run reached : _CurAcqId = %d, _RunCnfRec.AcqNb = %d", _CurAcqId, _RunCnfRec.AcqNb )); // 03/06/2021 Debug + + if ( PtReachEnd != NULL ) { + *PtReachEnd = 1; + } + + return ( _PtAcqRaw ); + + } + + + if ( PtReachEnd != NULL ) { + *PtReachEnd = 0; + } + + // Calc raw file id + + VRawFileId = _CurAcqId / _RunCnfRec.AcqNbPerFile; + + // msg (( MSG_OUT, "_CurAcqId = %d, _RunCnfRec.AcqNbPerFile = %d, VRawFileId = %d", _CurAcqId, _RunCnfRec.AcqNbPerFile, VRawFileId )); // 03/06/2021 Debug + + + // Read next Acq + + if ( ( _CurAcqId % _RunCnfRec.AcqNbPerFile) == 0 ) { + + // msg (( MSG_OUT, "_FFirstAcqOfRawFileGetSeq (...)" )); // // 03/06/2021 Debug + + VPtAcq = _FFirstAcqOfRawFileGetSeq ( VRawFileId, ChkHead, PrintHead ); + + } + + else { + + // msg (( MSG_OUT, "_FNextAcqOfRawFileGetSeq (...)" )); // 03/06/2021 Debug + + VPtAcq = _FNextAcqOfRawFileGetSeq ( VRawFileId /* RawFileId */, ChkHead, PrintHead, PtReachEnd ); + } + + + + if ( VPtAcq == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read next acq No = %d of run failed ! file = %s", _CurAcqId, _CurRawFileName ) ); + } + + return ( VPtAcq ); + +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FAcqGotoSeq ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) +* : +* \brief : Returns a pointer to the xext Acq of run \n +* : \n +* : +* \param : AcqId - Id / No of the Acq +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* \param : PtReachEn - A pointer on a flag set to 1 if end of file is reached, set it to NULL if not used +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Rev : 30/05/2021 : Reduce acces time if AcqId is in current opened run file +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FAcqGotoSeq ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) { + + SInt32 VRet; + UInt32 VRawFileId; + SInt32 ViAcq; + MIS1__TBtAcqRawRec* VPtAcq; + + // Check + + MIS1__TBtRunRead_CHECK_RET_NULL + + // Check param + + if ( _CurAcqId >= _RunCnfRec.AcqNb ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq No = %d > Nb of acq in run = %d", AcqId, _RunCnfRec.AcqNb ) ); + } + + + // Calc raw file id + + VRawFileId = AcqId / _RunCnfRec.AcqNbPerFile; + + + // 30/05/2021 : If Acq to go is in current run file + + if ( VRawFileId == _CurRawFileId ) { + + // msg (( MSG_OUT, "Search GOTO Acq = %d in current run file Id = %d", AcqId, _CurRawFileId )); + + // AcqId == current one => Done + + if ( AcqId == _CurAcqId ) { + return ( _PtAcqRaw ); + } + + // AcqId < current one => goto first Acq of file + + if ( AcqId < _CurAcqId ) { + + // msg (( MSG_OUT, "Search GOTO Acq = %d in current run file Id = %d => Goto first Acq", AcqId, _CurRawFileId )); + + VPtAcq = _FFirstAcqOfRawFileGetSeq ( VRawFileId, ChkHead, 0 /* PrintHead */ ); + + if ( VPtAcq == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq No = %d of run failed ! file = %s", AcqId, _CurRawFileName ) ); + } + + // If AcqId is the first one of the run => Done + + if ( VPtAcq->Head.Ids.AcqIdInRun == AcqId) { + + _CurAcqId = AcqId; // 03/06/2021 Debug + + if ( PrintHead ) { + VRet = MIS1__BT_FAcqRawHeadRecPrint ( &VPtAcq->Head, _HeadPrintTriggers, _HeadPrintFrCnt, _HeadPrintFiredPixels ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Print acq header failed ! Ret = %d", VRet) ); + } + + return ( VPtAcq ); + } + + } // End if ( AcqId < _CurAcqId ) + + + // Scan Acq + + // msg (( MSG_OUT, "Search GOTO Acq = %d in current run file Id = %d => Scan Acqs", AcqId, _CurRawFileId )); + + + for ( ViAcq = 1; ViAcq < _RunCnfRec.AcqNbPerFile; ViAcq++ ) { + + VPtAcq = _FNextAcqOfRawFileGetSeq ( VRawFileId /* RawFileId */, ChkHead, 0 /* PrintHead */, PtReachEnd ); + + if ( VPtAcq == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq No = %d of run failed ! file = %s", AcqId, _CurRawFileName ) ); + } + + if ( VPtAcq->Head.Ids.AcqIdInRun == AcqId) { + + _CurAcqId = AcqId; // 03/06/2021 Debug + + if ( PrintHead ) { + VRet = MIS1__BT_FAcqRawHeadRecPrint ( &VPtAcq->Head, _HeadPrintTriggers, _HeadPrintFrCnt, _HeadPrintFiredPixels ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Print acq header failed ! Ret = %d", VRet) ); + } + + return ( VPtAcq ); + + } // End if ( VPtAcq->Head.Ids.AcqIdInRun == AcqId) + + } // End for (ViAcq ) + + + + } // End if ( VRawFileId == _CurRawFileId ) + + + // 30/05/2021 : If Acq to go is NOT in current run file + + + // Scan the acq of file + + + if ( PtReachEnd != NULL ) { + *PtReachEnd = 0; + } + + + VPtAcq = _FFirstAcqOfRawFileGetSeq ( VRawFileId, ChkHead, 0 /* PrintHead */ ); + + if ( VPtAcq == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq No = %d of run failed ! file = %s", AcqId, _CurRawFileName ) ); + } + + + if ( VPtAcq->Head.Ids.AcqIdInRun == AcqId) { + + _CurAcqId = AcqId; // 03/06/2021 Debug + + if ( PrintHead ) { + VRet = MIS1__BT_FAcqRawHeadRecPrint ( &VPtAcq->Head, _HeadPrintTriggers, _HeadPrintFrCnt, _HeadPrintFiredPixels ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Print acq header failed ! Ret = %d", VRet) ); + } + + return ( VPtAcq ); + } + + + for ( ViAcq = 1; ViAcq < _RunCnfRec.AcqNbPerFile; ViAcq++ ) { + + VPtAcq = _FNextAcqOfRawFileGetSeq ( VRawFileId /* RawFileId */, ChkHead, 0 /* PrintHead */, PtReachEnd ); + + if ( VPtAcq == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq No = %d of run failed ! file = %s", AcqId, _CurRawFileName ) ); + } + + if ( VPtAcq->Head.Ids.AcqIdInRun == AcqId) { + + _CurAcqId = AcqId; // 03/06/2021 Debug + + if ( PrintHead ) { + VRet = MIS1__BT_FAcqRawHeadRecPrint ( &VPtAcq->Head, _HeadPrintTriggers, _HeadPrintFrCnt, _HeadPrintFiredPixels ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Print acq header failed ! Ret = %d", VRet) ); + } + + return ( VPtAcq ); + + } // End if ( VPtAcq->Head.Ids.AcqIdInRun == AcqId) + + } // End for (ViAcq ) + + + return ( NULL ); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FAcqGotoSeq_before_300521 ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) +* : +* \brief : Returns a pointer to the xext Acq of run \n +* : \n +* : +* \param : AcqId - Id / No of the Acq +* : +* \param : ChkHead - Checks header fields values +* : +* \param : PrintHead - Prints header fields +* : +* \param : PtReachEn - A pointer on a flag set to 1 if end of file is reached, set it to NULL if not used +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +MIS1__TBtAcqRawRec* MIS1__TBtRunRead::_FAcqGotoSeq_before_300521 ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ) { + + + SInt32 VRet; + UInt32 VRawFileId; + SInt32 ViAcq; + MIS1__TBtAcqRawRec* VPtAcq; + + // Check + + MIS1__TBtRunRead_CHECK_RET_NULL + + // Check param + + if ( _CurAcqId >= _RunCnfRec.AcqNb ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq No = %d > Nb of acq in run = %d", AcqId, _RunCnfRec.AcqNb ) ); + } + + + // Calc raw file id + + VRawFileId = AcqId / _RunCnfRec.AcqNbPerFile; + + + // Scan the acq of file + + + if ( PtReachEnd != NULL ) { + *PtReachEnd = 0; + } + + + VPtAcq = _FFirstAcqOfRawFileGetSeq ( VRawFileId, ChkHead, 0 /* PrintHead */ ); + + if ( VPtAcq == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq No = %d of run failed ! file = %s", AcqId, _CurRawFileName ) ); + } + + + if ( VPtAcq->Head.Ids.AcqIdInRun == AcqId) { + + + if ( PrintHead ) { + VRet = MIS1__BT_FAcqRawHeadRecPrint ( &VPtAcq->Head, _HeadPrintTriggers, _HeadPrintFrCnt, _HeadPrintFiredPixels ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Print acq header failed ! Ret = %d", VRet) ); + } + + + return ( VPtAcq ); + } + + + for ( ViAcq = 1; ViAcq < _RunCnfRec.AcqNbPerFile; ViAcq++ ) { + + VPtAcq = _FNextAcqOfRawFileGetSeq ( VRawFileId /* RawFileId */, ChkHead, 0 /* PrintHead */, PtReachEnd ); + + if ( VPtAcq == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"Abort => Read acq No = %d of run failed ! file = %s", AcqId, _CurRawFileName ) ); + } + + if ( VPtAcq->Head.Ids.AcqIdInRun == AcqId) { + + if ( PrintHead ) { + VRet = MIS1__BT_FAcqRawHeadRecPrint ( &VPtAcq->Head, _HeadPrintTriggers, _HeadPrintFrCnt, _HeadPrintFiredPixels ); + + err_retfailnull ( VRet, (ERR_OUT,"Abort => Print acq header failed ! Ret = %d", VRet) ); + } + + + return ( VPtAcq ); + } + + } + + + return ( NULL ); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead:: +* : +* \brief : \n +* : \n +* : +* \param : - +* : +* \param : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__TBtRunRead:: +* : +* \brief : \n +* : \n +* : +* \param : - +* : +* \param : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : Privare method +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 18/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_F +* : +* \brief : \n +* : \n +* : +* \param : - +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqW16A* MIS1__BT_FBtAcqW16AAlloc ( UInt8 Alloc, UInt32* PtRecSz ) +* : +* \brief : Allocates the MIS1__TBtAcqW16A records \n +* : \n +* : +* \param : Alloc - 0 => Returns record size via PtRecSz, 1 => Alloc record + returns size +* : +* \param : PtRecSz - Pointer to record size, set to NULL if not used +* : +* \return : A pointer to IS1__TBtAcqW16A or NULL in case of error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 22/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +MIS1__TBtAcqW16A* MIS1__BT_FBtAcqW16AAlloc ( UInt8 Alloc, UInt32* PtRecSz ) { + + MIS1__TBtAcqW16A* VPtRec; + UInt32 VRecSz; + + + VRecSz = sizeof (MIS1__TBtAcqW16A); + + + // Update size + + if ( PtRecSz != NULL ) { + *PtRecSz = VRecSz; + } + + // Returns only size => No record allocation + + if ( Alloc == 0 ) { + err_retval ( NULL, ( ERR_OUT, "Ok, retunrs size only, no record allocation") ); + } + + + VPtRec = (MIS1__TBtAcqW16A*) malloc ( VRecSz ); + + if ( VPtRec == NULL ) { + err_error (( ERR_OUT, "Abort => Allocation of %d W8 fro MIS1__TBtAcqW16A failed ! ", VRecSz )); + return (NULL); + } + + + // Reset record + + memset ( VPtRec, 0, VRecSz ); + + // Set info fields + + VPtRec->TotRecSz = VRecSz; + VPtRec->MaxFrNb = MIS1__BT_VRS_MAX_FR_NB_PER_ACQ; + VPtRec->FrNb = 0; + + err_trace (( ERR_OUT, "Ok" )); + + return (VPtRec); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtAcqW16AFree ( MIS1__TBtAcqW16A* PtRec ) +* : +* \brief : Free the MIS1__TBtAcqW16A* record \n +* : \n +* : +* \param : PtRec - The record to free +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 22/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__BT_FBtAcqW16AFree ( MIS1__TBtAcqW16A* PtRec ) { + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + // Free + + free ( PtRec ); + + err_retok (( ERR_OUT, "Ok" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : double MIS1__BT_FBtAcqW16AFill ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl, UInt8 FuncVers ) +* : +* \brief : Convert MIS1__TBtAcqRawRec to MIS1__TBtAcqW16A record, FuncVers sets the function used to convert \n +* : \n +* : +* \param : PtSrc - Pointer to source record MIS1__TBtAcqRawRec +* : +* \param : PtDest - Pointer to destination record MIS1__TBtAcqW16A +* : +* \param : FrNb - Frames nb to convert, if -1 => All frames from source record +* : +* \param : MeasExecTime - Measure exec time 0 = No, 1 = Yes +* +* \param : PrintLvl - Debug print level, 0 = No, 1 = Print record sizes, 2 = More print, to be implemented +* : +* \param : FuncVers - Select the conversion function used => in order to test different implementations \n +* : 0 => MIS1__BT_FBtAcqW16AFill_v0, 1 => MIS1__BT_FBtAcqW16AFill_v1, etc +* : +* \return : Execution time in us or error code +* : >= 0 - Execution time in us +* : < 0 - Error code +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 22/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +double MIS1__BT_FBtAcqW16AFill ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl, UInt8 FuncVers ) { + + double VRet; + + // Check param + + err_retnull (PtSrc, (ERR_OUT,"Abort => PtSrc == NULL") ); + + err_retnull (PtDest, (ERR_OUT,"Abort => PtDest == NULL") ); + + + if ( FrNb == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => FrNb == 0 => Nothing to do") ); + } + + if ( FrNb > MIS1__BT_FRS_MAX_FR_NB_PER_ACQ ) { + err_retfail ( -1, (ERR_OUT,"Abort => FrNb = %d > MIS1__BT_FRS_MAX_FR_NB_PER_ACQ = %d ", FrNb, MIS1__BT_FRS_MAX_FR_NB_PER_ACQ ) ); + } + + if ( FrNb > PtSrc->Head.Res.FrNb ) { + err_retfail ( -1, (ERR_OUT,"Abort => FrNb = %d > PtSrc->Head.Res.FrNb = %d ", FrNb, PtSrc->Head.Res.FrNb ) ); + } + + + if ( FrNb > PtDest->MaxFrNb ) { + err_retfail ( -1, (ERR_OUT,"Abort => FrNb = %d > PtDest->MaxFrNb = %d ", FrNb, PtDest->MaxFrNb ) ); + } + + // Propagates AcqId info to destination MIS1__TBtAcqW16A + + PtDest->AcqId = PtSrc->Head.Ids.AcqIdInRun; + + // Propagates Acq header info to destination MIS1__TBtAcqW16A + + PtDest->AcqRawHead = PtSrc->Head; // Added on 30/05/22021 // 789 + + // Call the conversion function + + switch ( FuncVers ) { + + case 0 : { + VRet = MIS1__BT_FBtAcqW16AFill_v0 ( PtSrc, PtDest, FrNb, MeasExecTime, PrintLvl ); + break; } + + + case 10 : { + VRet = MIS1__BT_FBtAcqW16AFill_v10 ( PtSrc, PtDest, FrNb, MeasExecTime, PrintLvl ); + break; } + + + case 80 : { + VRet = MIS1__BT_FBtAcqW16AFill_v80 ( PtSrc, PtDest, FrNb, MeasExecTime, PrintLvl ); + break; } + + + default : { + err_retfail ( -1, (ERR_OUT,"Abort => FuncVers = %d which is not supported", FuncVers) ); + break; } + + + } + + // Check for errors + + err_retfail ( VRet, (ERR_OUT,"Abort => Conversion failed ! Conv function ret = %d", VRet ) ); + + // + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : double MIS1__BT_FBtAcqW16AFill_v0 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) +* : +* \brief : Convert MIS1__TBtAcqRawRec to MIS1__TBtAcqW16A record, SIMPLE COPY, implementation V0 \n +* : +* \param : PtSrc - Pointer to source record MIS1__TBtAcqRawRec +* : +* \param : PtDest - Pointer to destination record MIS1__TBtAcqW16A +* : +* \param : FrNb - Frames nb to convert, if -1 => All frames from source record, value <> -1 are not handled +* : +* \param : MeasExecTime - Measure exec time 0 = No, 1 = Yes +* +* \param : PrintLvl - Debug print level, 0 = No, 1 = Print record sizes, 2 = More print, to be implemented +* : +* : +* : +* \return : Execution time in us or error code +* : >= 0 - Execution time in us +* : < 0 - Error code +* : +* \warning : Globals : +* \warning : Remark : WARNING THis function makes a simple copy, no conversion, used to measure execution time of memcpy +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 22/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +double MIS1__BT_FBtAcqW16AFill_v0 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) { + + double VExecTimeUs; + + + + // Check param + + // ---------------------------------------------- + // WARNING + // ---------------------------------------------- + // + // NO parameters checking to save executiuin time, it is done in MIS1__BT_FBtAcqW16AFill (...) + // => This function SHOULD not be called directly, but only via MIS1__BT_FBtAcqW16AFill (...) + // => In case you need to call it directly => Check para�eters you provide + + // Measure exec time + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + TIME__FMeasTimeUsBegin ( 0 /* Index */ ); + } + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + #endif + + + + // Update size fields + + if ( FrNb < 0 ) { + FrNb = PtSrc->Head.Res.FrNb; + } + + + PtDest->FrNb = FrNb; // Frames nb in source Acq converted in MIS1__TBtAcqW16A + + PtDest->MSisW16Nb = 0; // Size of each MSis 1 "cnanel" in W16 => Set to 0 to generate an error + // because data are not formatted by this funciton for pxiels decoding in a next step + + // Convert => Simple cpy + + memcpy ( &PtDest->AAMsis[0][0], PtSrc->MSisData.Au8, PtSrc->Head.DataSz ); + + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + VExecTimeUs = TIME__FMeasTimeUsEnd ( 0 /* Index */ ); + } + + else { + VExecTimeUs = 0; + } + + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + VExecTimeUs = 0; // No exec time measurement implementation => Returns 0 + + #endif + + + + return (VExecTimeUs); +} + + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : double MIS1__BT_FBtAcqW16AFill_v10 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) +* : +* \brief : Convert MIS1__TBtAcqRawRec to MIS1__TBtAcqW16A record, for 1 channel, implementation V10 \n +* : +* \param : PtSrc - Pointer to source record MIS1__TBtAcqRawRec +* : +* \param : PtDest - Pointer to destination record MIS1__TBtAcqW16A +* : +* \param : FrNb - Frames nb to convert, if -1 => All frames from source record +* : +* \param : MeasExecTime - Measure exec time 0 = No, 1 = Yes +* +* \param : PrintLvl - Debug print level, 0 = No, 1 = Print record sizes, 2 = More print, to be implemented +* : +* : +* : +* \return : Execution time in us or error code +* : >= 0 - Execution time in us +* : < 0 - Error code +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 22/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +double MIS1__BT_FBtAcqW16AFill_v10 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) { + + UInt32 VSrcSzW64; // Size of the full acq memory in W64 + UInt32 VSrcSzW128; // Size of the full acq memory in W64 + UInt32 VSrcLowOfsW64; // Offset in W64 of high half of memory + UInt32 VSrcChanSzW16; + UInt32 VSrcChanSzW128; + UInt32 VSrcChanHafSzW16; + double VExecTimeUs; + + + UInt32 ViW128; + + UInt64* VPtSLowW64; // Pt on src low half of acq memory + UInt64* VPtSHighW64; // Pt on src low half of acq memory + + UInt16* VPtSCh0Low; // Pt src Chip 0, low half of acq memory = In0 + UInt16* VPtSCh0High; // Pt src Chip 0, high half of acq memory = In8 + UInt16* VPtDCh0; // Pt dest Chip 0 + + UInt32 ViW16; + SInt32 VNotAnIntegerW128NbPerFr; + + + // Check param + + // ---------------------------------------------- + // WARNING + // ---------------------------------------------- + // + // NO parameters checking to save executiuin time, it is done in MIS1__BT_FBtAcqW16AFill (...) + // => This function SHOULD not be called directly, but only via MIS1__BT_FBtAcqW16AFill (...) + // => In case you need to call it directly => Check para�eters you provide + + // Measure exec time + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + TIME__FMeasTimeUsBegin ( 0 /* Index */ ); + } + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + #endif + + + + // Convert + + // Convets all frames + + if ( FrNb < 0 ) { + VSrcSzW128 = PtSrc->Head.DataSz / 16; + FrNb = PtSrc->Head.Res.FrNb; + } + + + // Selects a fraction of all frames from beginning => TBC if it generates no bug ... + + else { + VSrcSzW128 = PtSrc->Head.DataSz / 16; + VSrcSzW128 = VSrcSzW128 * ( FrNb / PtSrc->Head.Res.FrNb ); + } + + + VSrcSzW64 = VSrcSzW128 * 2; + + + VSrcLowOfsW64 = VSrcSzW64 / 2; + + VSrcChanSzW16 = PtSrc->Head.DataSz / 16; // divide by 8 because 8 chan, divide by 2 W8 => W16 + VSrcChanHafSzW16 = VSrcChanSzW16 / 2; + + VSrcChanSzW128 = VSrcSzW128 / 8; // Divide by 8 because 8 chan + + PtDest->MSisW16Nb = VSrcSzW128; // Size of each MSis 1 channel in W16 + + VPtSLowW64 = PtSrc->MSisData.Au64; + VPtSHighW64 = &PtSrc->MSisData.Au64[VSrcLowOfsW64]; + + // Chan 0 ptr init + + VPtSCh0Low = (UInt16*) VPtSLowW64; + VPtSCh0High = (UInt16*) VPtSHighW64; + VPtDCh0 = &PtDest->AAMsis[0][0]; + + // Update size fields + + PtDest->FrNb = FrNb; // Frames nb in source Acq converted in MIS1__TBtAcqW16A + + + // Debug print + + if ( PrintLvl >= 1 ) { + msg (( MSG_OUT, "Src size = %d W128 => %d W128 / Chan", VSrcSzW128, VSrcChanSzW128 )); + msg (( MSG_OUT, "Src size = %d W64 = %d W16", VSrcSzW64, VSrcSzW64 * 8 )); + msg (( MSG_OUT, "Src low W64 pos = 0 " )); + msg (( MSG_OUT, "Src high W64 pos = %d W16 ", VSrcChanHafSzW16 )); + msg (( MSG_OUT, "Dest chan sz = %d W16 ", VSrcChanSzW16 )); + } + + + // Convert + + ViW16 = 0; + + for ( ViW128 = 0; ViW128 < VSrcChanSzW128; ViW128++ ) { + + VPtDCh0[ViW16] = *VPtSCh0Low; // W0 + VPtSCh0Low += 8; + ViW16++; + VPtDCh0[ViW16] = *VPtSCh0Low; // W1 + VPtSCh0Low += 8; + ViW16++; + VPtDCh0[ViW16] = *VPtSCh0Low; // W2 + VPtSCh0Low += 8; + ViW16++; + VPtDCh0[ViW16] = *VPtSCh0Low; // W3 + VPtSCh0Low += 8; + ViW16++; + + + VPtDCh0[ViW16] = *VPtSCh0High; // W4 + VPtSCh0High += 8; + ViW16++; + VPtDCh0[ViW16] = *VPtSCh0High; // W5 + VPtSCh0High += 8; + ViW16++; + VPtDCh0[ViW16] = *VPtSCh0High; // W6 + VPtSCh0High += 8; + ViW16++; + VPtDCh0[ViW16] = *VPtSCh0High; // W7 + VPtSCh0High += 8; + ViW16++; + + + } // End for + + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + VExecTimeUs = TIME__FMeasTimeUsEnd ( 0 /* Index */ ); + } + + else { + VExecTimeUs = 0; + } + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + VExecTimeUs = 0; // No exec time measurement implementation => Returns 0 + + + #endif + + + + return (VExecTimeUs); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : double MIS1__BT_FBtAcqW16AFill_v80 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) +* : +* \brief : Convert MIS1__TBtAcqRawRec to MIS1__TBtAcqW16A record, for 8 channels, implementation V80 \n +* : +* \param : PtSrc - Pointer to source record MIS1__TBtAcqRawRec +* : +* \param : PtDest - Pointer to destination record MIS1__TBtAcqW16A +* : +* \param : FrNb - Frames nb to convert, if -1 => All frames from source record +* : +* \param : MeasExecTime - Measure exec time 0 = No, 1 = Yes +* +* \param : PrintLvl - Debug print level, 0 = No, 1 = Print record sizes, 2 = More print, to be implemented +* : +* : +* : +* \return : Execution time in us or error code +* : >= 0 - Execution time in us +* : < 0 - Error code +* : +* \warning : Globals : +* \warning : Remark : WARNING => ONLY 2 channels IMPLEMENTED on 22/05/2021 +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 22/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +double MIS1__BT_FBtAcqW16AFill_v80 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) { + + UInt32 VSrcSzW64; // Size of the full acq memory in W64 + UInt32 VSrcSzW128; // Size of the full acq memory in W64 + UInt32 VSrcLowOfsW64; // Offset in W64 of high half of memory + UInt32 VSrcChanSzW16; + UInt32 VSrcChanSzW128; + UInt32 VSrcChanHafSzW16; + double VExecTimeUs; + + + UInt32 ViW128; + + UInt16* VPtSLowW16; // Pt on src low half of acq memory + UInt16* VPtSHighW16; // Pt on src low half of acq memory + + UInt16* VPtSCh0Low; // Pt src Chip 0, low half of acq memory = In0 + UInt16* VPtSCh0High; // Pt src Chip 0, high half of acq memory = In8 + UInt16* VPtDCh0; // Pt dest Chip 0 + + UInt16* VPtSCh1Low; // Pt src Chip 1, low half of acq memory = In0 + UInt16* VPtSCh1High; // Pt src Chip 1, high half of acq memory = In8 + UInt16* VPtDCh1; // Pt dest Chip 1 + + UInt16* VPtSCh2Low; // Pt src Chip 2, low half of acq memory = In0 + UInt16* VPtSCh2High; // Pt src Chip 2, high half of acq memory = In8 + UInt16* VPtDCh2; // Pt dest Chip 2 + + UInt16* VPtSCh3Low; // Pt src Chip 3, low half of acq memory = In0 + UInt16* VPtSCh3High; // Pt src Chip 3, high half of acq memory = In8 + UInt16* VPtDCh3; // Pt dest Chip 3 + + UInt16* VPtSCh4Low; // Pt src Chip 4, low half of acq memory = In0 + UInt16* VPtSCh4High; // Pt src Chip 4, high half of acq memory = In8 + UInt16* VPtDCh4; // Pt dest Chip 4 + + UInt16* VPtSCh5Low; // Pt src Chip 5, low half of acq memory = In0 + UInt16* VPtSCh5High; // Pt src Chip 5, high half of acq memory = In8 + UInt16* VPtDCh5; // Pt dest Chip 5 + + UInt16* VPtSCh6Low; // Pt src trig chan = [6], low half of acq memory = In7 + UInt16* VPtSCh6High; // Pt src trig chan = [6], high half of acq memory = In15 + UInt16* VPtDCh6; // Pt dest trig chan = [6] + + + + UInt32 ViW16; + UInt32 ViW16Trig; + + + // Check param + + // ---------------------------------------------- + // WARNING + // ---------------------------------------------- + // + // NO parameters checking to save executiuin time, it is done in MIS1__BT_FBtAcqW16AFill (...) + // => This function SHOULD not be called directly, but only via MIS1__BT_FBtAcqW16AFill (...) + // => In case you need to call it directly => Check para�eters you provide + + // Measure exec time + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + TIME__FMeasTimeUsBegin ( 0 /* Index */ ); + } + + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + + #endif + + + + // Convert + + // Convets all frames + + if ( FrNb < 0 ) { + VSrcSzW128 = PtSrc->Head.DataSz / 16; + FrNb = PtSrc->Head.Res.FrNb; + } + + + // Selects a fraction of all frames from beginning => TBC if it generates no bug ... + + else { + VSrcSzW128 = PtSrc->Head.DataSz / 16; + VSrcSzW128 = VSrcSzW128 * ( FrNb / PtSrc->Head.Res.FrNb ); + } + + + VSrcSzW64 = VSrcSzW128 * 2; + + + VSrcLowOfsW64 = VSrcSzW64 / 2; + + VSrcChanSzW16 = PtSrc->Head.DataSz / 16; // divide by 8 because 8 chan, divide by 2 W8 => W16 + VSrcChanHafSzW16 = VSrcChanSzW16 / 2; + + VSrcChanSzW128 = VSrcSzW128 / 8; // divide by 8 because 8 chan + + PtDest->MSisW16Nb = VSrcSzW128; // Size of each MSis 1 channel in W16 + + VPtSLowW16 = (UInt16*) PtSrc->MSisData.Au64; + VPtSHighW16 = (UInt16*) &PtSrc->MSisData.Au64[VSrcLowOfsW64]; + + // Chan 0 ptr init + + VPtSCh0Low = VPtSLowW16; + VPtSCh0High = VPtSHighW16; + VPtDCh0 = &PtDest->AAMsis[0][0]; + + // Chan 1 ptr init + + VPtSCh1Low = VPtSLowW16 + 1; + VPtSCh1High = VPtSHighW16 + 1; + VPtDCh1 = &PtDest->AAMsis[1][0]; + + // Chan 2 ptr init + + VPtSCh2Low = VPtSLowW16 + 2; + VPtSCh2High = VPtSHighW16 + 2; + VPtDCh2 = &PtDest->AAMsis[2][0]; + + // Chan 3 ptr init + + VPtSCh3Low = VPtSLowW16 + 3; + VPtSCh3High = VPtSHighW16 + 3; + VPtDCh3 = &PtDest->AAMsis[3][0]; + + // Chan 4 ptr init + + VPtSCh4Low = VPtSLowW16 + 4; + VPtSCh4High = VPtSHighW16 + 4; + VPtDCh4 = &PtDest->AAMsis[4][0]; + + // Chan 5 ptr init + + VPtSCh5Low = VPtSLowW16 + 5; + VPtSCh5High = VPtSHighW16 + 5; + VPtDCh5 = &PtDest->AAMsis[5][0]; + + // Chan 6 ptr init + + VPtSCh6Low = VPtSLowW16 + 7; + VPtSCh6High = VPtSHighW16 + 7; + VPtDCh6 = &PtDest->AAMsis[6][0]; + + + + // Update size fields + + PtDest->FrNb = FrNb; // Frames nb in source Acq converted in MIS1__TBtAcqW16A + + + // Debug print + + if ( PrintLvl >= 1 ) { + msg (( MSG_OUT, "Src size = %d W128 => %d W128 / Chan", VSrcSzW128, VSrcChanSzW128 )); + msg (( MSG_OUT, "Src size = %d W64 = %d W16", VSrcSzW64, VSrcSzW64 * 8 )); + msg (( MSG_OUT, "Src low W64 pos = 0 " )); + msg (( MSG_OUT, "Src high W64 pos = %d W16 ", VSrcChanHafSzW16 )); + msg (( MSG_OUT, "Dest chan sz = %d W16 ", VSrcChanSzW16 )); + } + + + // Convert + + ViW16 = 0; + ViW16Trig = 0; + + for ( ViW128 = 0; ViW128 < VSrcChanSzW128; ViW128++ ) { + + // Trigger on D15 + + VPtDCh6[ViW16Trig] = *VPtSCh6Low; // Trig + VPtSCh6Low += 8; + ViW16Trig++; + VPtDCh6[ViW16Trig] = *VPtSCh6Low; // Trig + VPtSCh6Low += 8; + ViW16Trig++; + VPtDCh6[ViW16Trig] = *VPtSCh6Low; // Trig + VPtSCh6Low += 8; + ViW16Trig++; + VPtDCh6[ViW16Trig] = *VPtSCh6Low; // Trig + VPtSCh6Low += 8; + ViW16Trig++; + + + + // Low memory part + + VPtDCh0[ViW16] = *VPtSCh0Low; // W0 - CH0 + VPtSCh0Low += 8; + VPtDCh1[ViW16] = *VPtSCh1Low; // W0 - CH1 + VPtSCh1Low += 8; + VPtDCh2[ViW16] = *VPtSCh2Low; // W0 - CH2 + VPtSCh2Low += 8; + VPtDCh3[ViW16] = *VPtSCh3Low; // W0 - CH3 + VPtSCh3Low += 8; + VPtDCh4[ViW16] = *VPtSCh4Low; // W0 - CH4 + VPtSCh4Low += 8; + VPtDCh5[ViW16] = *VPtSCh5Low; // W0 - CH5 + VPtSCh5Low += 8; + ViW16++; + + + VPtDCh0[ViW16] = *VPtSCh0Low; // W1 - CH0 + VPtSCh0Low += 8; + VPtDCh1[ViW16] = *VPtSCh1Low; // W1 - CH1 + VPtSCh1Low += 8; + VPtDCh2[ViW16] = *VPtSCh2Low; // W1 - CH2 + VPtSCh2Low += 8; + VPtDCh3[ViW16] = *VPtSCh3Low; // W1 - CH3 + VPtSCh3Low += 8; + VPtDCh4[ViW16] = *VPtSCh4Low; // W1 - CH4 + VPtSCh4Low += 8; + VPtDCh5[ViW16] = *VPtSCh5Low; // W1 - CH5 + VPtSCh5Low += 8; + ViW16++; + + VPtDCh0[ViW16] = *VPtSCh0Low; // W2 - CH0 + VPtSCh0Low += 8; + VPtDCh1[ViW16] = *VPtSCh1Low; // W2 - CH1 + VPtSCh1Low += 8; + VPtDCh2[ViW16] = *VPtSCh2Low; // W2 - CH2 + VPtSCh2Low += 8; + VPtDCh3[ViW16] = *VPtSCh3Low; // W2 - CH3 + VPtSCh3Low += 8; + VPtDCh4[ViW16] = *VPtSCh4Low; // W2 - CH4 + VPtSCh4Low += 8; + VPtDCh5[ViW16] = *VPtSCh5Low; // W2 - CH5 + VPtSCh5Low += 8; + ViW16++; + + VPtDCh0[ViW16] = *VPtSCh0Low; // W3 - CH0 + VPtSCh0Low += 8; + VPtDCh1[ViW16] = *VPtSCh1Low; // W3 - CH1 + VPtSCh1Low += 8; + VPtDCh2[ViW16] = *VPtSCh2Low; // W3 - CH2 + VPtSCh2Low += 8; + VPtDCh3[ViW16] = *VPtSCh3Low; // W3 - CH3 + VPtSCh3Low += 8; + VPtDCh4[ViW16] = *VPtSCh4Low; // W3 - CH4 + VPtSCh4Low += 8; + VPtDCh5[ViW16] = *VPtSCh5Low; // W3 - CH5 + VPtSCh5Low += 8; + ViW16++; + + + // High memory part + + + VPtDCh0[ViW16] = *VPtSCh0High; // W4 - CH0 + VPtSCh0High += 8; + VPtDCh1[ViW16] = *VPtSCh1High; // W4 - CH1 + VPtSCh1High += 8; + VPtDCh2[ViW16] = *VPtSCh2High; // W4 - CH2 + VPtSCh2High += 8; + VPtDCh3[ViW16] = *VPtSCh3High; // W4 - CH3 + VPtSCh3High += 8; + VPtDCh4[ViW16] = *VPtSCh4High; // W4 - CH4 + VPtSCh4High += 8; + VPtDCh5[ViW16] = *VPtSCh5High; // W4 - CH5 + VPtSCh5High += 8; + ViW16++; + + + + VPtDCh0[ViW16] = *VPtSCh0High; // W5 - CH0 + VPtSCh0High += 8; + VPtDCh1[ViW16] = *VPtSCh1High; // W5 - CH1 + VPtSCh1High += 8; + VPtDCh2[ViW16] = *VPtSCh2High; // W5 - CH2 + VPtSCh2High += 8; + VPtDCh3[ViW16] = *VPtSCh3High; // W5 - CH3 + VPtSCh3High += 8; + VPtDCh4[ViW16] = *VPtSCh4High; // W5 - CH4 + VPtSCh4High += 8; + VPtDCh5[ViW16] = *VPtSCh5High; // W5 - CH5 + VPtSCh5High += 8; + ViW16++; + + VPtDCh0[ViW16] = *VPtSCh0High; // W6 - CH0 + VPtSCh0High += 8; + VPtDCh1[ViW16] = *VPtSCh1High; // W6 - CH1 + VPtSCh1High += 8; + VPtDCh2[ViW16] = *VPtSCh2High; // W6 - CH2 + VPtSCh2High += 8; + VPtDCh3[ViW16] = *VPtSCh3High; // W6 - CH3 + VPtSCh3High += 8; + VPtDCh4[ViW16] = *VPtSCh4High; // W6 - CH4 + VPtSCh4High += 8; + VPtDCh5[ViW16] = *VPtSCh5High; // W6 - CH5 + VPtSCh5High += 8; + ViW16++; + + VPtDCh0[ViW16] = *VPtSCh0High; // W7 - CH0 + VPtSCh0High += 8; + VPtDCh1[ViW16] = *VPtSCh1High; // W7 - CH1 + VPtSCh1High += 8; + VPtDCh2[ViW16] = *VPtSCh2High; // W7 - CH2 + VPtSCh2High += 8; + VPtDCh3[ViW16] = *VPtSCh3High; // W7 - CH3 + VPtSCh3High += 8; + VPtDCh4[ViW16] = *VPtSCh4High; // W7 - CH4 + VPtSCh4High += 8; + VPtDCh5[ViW16] = *VPtSCh5High; // W7 - CH5 + VPtSCh5High += 8; + ViW16++; + + + } // End for + + + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + VExecTimeUs = TIME__FMeasTimeUsEnd ( 0 /* Index */ ); + } + + else { + VExecTimeUs = 0; + } + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + VExecTimeUs = 0; // No exec time measurement implementation => Returns 0 + + + #endif + + + + return (VExecTimeUs); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : double MIS1__BT_FBtAcqW16AFill_v80 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) +* : +* \brief : Convert MIS1__TBtAcqRawRec to MIS1__TBtAcqW16A record, for 8 channels, implementation V80 \n +* : +* \param : PtSrc - Pointer to source record MIS1__TBtAcqRawRec +* : +* \param : PtDest - Pointer to destination record MIS1__TBtAcqW16A +* : +* \param : FrNb - Frames nb to convert, if -1 => All frames from source record +* : +* \param : MeasExecTime - Measure exec time 0 = No, 1 = Yes +* +* \param : PrintLvl - Debug print level, 0 = No, 1 = Print record sizes, 2 = More print, to be implemented +* : +* : +* : +* \return : Execution time in us or error code +* : >= 0 - Execution time in us +* : < 0 - Error code +* : +* \warning : Globals : +* \warning : Remark : WARNING => ONLY 2 channels IMPLEMENTED on 22/05/2021 +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 22/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +double MIS1__BT_FBtAcqW16AFill_v80__010621_before_trig_upg ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) { + + UInt32 VSrcSzW64; // Size of the full acq memory in W64 + UInt32 VSrcSzW128; // Size of the full acq memory in W64 + UInt32 VSrcLowOfsW64; // Offset in W64 of high half of memory + UInt32 VSrcChanSzW16; + UInt32 VSrcChanSzW128; + UInt32 VSrcChanHafSzW16; + double VExecTimeUs; + + + UInt32 ViW128; + + UInt16* VPtSLowW16; // Pt on src low half of acq memory + UInt16* VPtSHighW16; // Pt on src low half of acq memory + + UInt16* VPtSCh0Low; // Pt src Chip 0, low half of acq memory = In0 + UInt16* VPtSCh0High; // Pt src Chip 0, high half of acq memory = In8 + UInt16* VPtDCh0; // Pt dest Chip 0 + + UInt16* VPtSCh1Low; // Pt src Chip 1, low half of acq memory = In0 + UInt16* VPtSCh1High; // Pt src Chip 1, high half of acq memory = In8 + UInt16* VPtDCh1; // Pt dest Chip 1 + + UInt16* VPtSCh2Low; // Pt src Chip 2, low half of acq memory = In0 + UInt16* VPtSCh2High; // Pt src Chip 2, high half of acq memory = In8 + UInt16* VPtDCh2; // Pt dest Chip 2 + + UInt16* VPtSCh3Low; // Pt src Chip 3, low half of acq memory = In0 + UInt16* VPtSCh3High; // Pt src Chip 3, high half of acq memory = In8 + UInt16* VPtDCh3; // Pt dest Chip 3 + + UInt16* VPtSCh4Low; // Pt src Chip 4, low half of acq memory = In0 + UInt16* VPtSCh4High; // Pt src Chip 4, high half of acq memory = In8 + UInt16* VPtDCh4; // Pt dest Chip 4 + + UInt16* VPtSCh5Low; // Pt src Chip 5, low half of acq memory = In0 + UInt16* VPtSCh5High; // Pt src Chip 5, high half of acq memory = In8 + UInt16* VPtDCh5; // Pt dest Chip 5 + + UInt32 ViW16; + + + // Check param + + // ---------------------------------------------- + // WARNING + // ---------------------------------------------- + // + // NO parameters checking to save executiuin time, it is done in MIS1__BT_FBtAcqW16AFill (...) + // => This function SHOULD not be called directly, but only via MIS1__BT_FBtAcqW16AFill (...) + // => In case you need to call it directly => Check para�eters you provide + + // Measure exec time + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + TIME__FMeasTimeUsBegin ( 0 /* Index */ ); + } + + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + + #endif + + + + // Convert + + // Convets all frames + + if ( FrNb < 0 ) { + VSrcSzW128 = PtSrc->Head.DataSz / 16; + FrNb = PtSrc->Head.Res.FrNb; + } + + + // Selects a fraction of all frames from beginning => TBC if it generates no bug ... + + else { + VSrcSzW128 = PtSrc->Head.DataSz / 16; + VSrcSzW128 = VSrcSzW128 * ( FrNb / PtSrc->Head.Res.FrNb ); + } + + + VSrcSzW64 = VSrcSzW128 * 2; + + + VSrcLowOfsW64 = VSrcSzW64 / 2; + + VSrcChanSzW16 = PtSrc->Head.DataSz / 16; // divide by 8 because 8 chan, divide by 2 W8 => W16 + VSrcChanHafSzW16 = VSrcChanSzW16 / 2; + + VSrcChanSzW128 = VSrcSzW128 / 8; // divide by 8 because 8 chan + + PtDest->MSisW16Nb = VSrcSzW128; // Size of each MSis 1 channel in W16 + + VPtSLowW16 = (UInt16*) PtSrc->MSisData.Au64; + VPtSHighW16 = (UInt16*) &PtSrc->MSisData.Au64[VSrcLowOfsW64]; + + // Chan 0 ptr init + + VPtSCh0Low = VPtSLowW16; + VPtSCh0High = VPtSHighW16; + VPtDCh0 = &PtDest->AAMsis[0][0]; + + // Chan 1 ptr init + + VPtSCh1Low = VPtSLowW16 + 1; + VPtSCh1High = VPtSHighW16 + 1; + VPtDCh1 = &PtDest->AAMsis[1][0]; + + // Chan 2 ptr init + + VPtSCh2Low = VPtSLowW16 + 2; + VPtSCh2High = VPtSHighW16 + 2; + VPtDCh2 = &PtDest->AAMsis[2][0]; + + // Chan 3 ptr init + + VPtSCh3Low = VPtSLowW16 + 3; + VPtSCh3High = VPtSHighW16 + 3; + VPtDCh3 = &PtDest->AAMsis[3][0]; + + // Chan 4 ptr init + + VPtSCh4Low = VPtSLowW16 + 4; + VPtSCh4High = VPtSHighW16 + 4; + VPtDCh4 = &PtDest->AAMsis[4][0]; + + // Chan 4 ptr init + + VPtSCh5Low = VPtSLowW16 + 5; + VPtSCh5High = VPtSHighW16 + 5; + VPtDCh5 = &PtDest->AAMsis[5][0]; + + + // Update size fields + + PtDest->FrNb = FrNb; // Frames nb in source Acq converted in MIS1__TBtAcqW16A + + + // Debug print + + if ( PrintLvl >= 1 ) { + msg (( MSG_OUT, "Src size = %d W128 => %d W128 / Chan", VSrcSzW128, VSrcChanSzW128 )); + msg (( MSG_OUT, "Src size = %d W64 = %d W16", VSrcSzW64, VSrcSzW64 * 8 )); + msg (( MSG_OUT, "Src low W64 pos = 0 " )); + msg (( MSG_OUT, "Src high W64 pos = %d W16 ", VSrcChanHafSzW16 )); + msg (( MSG_OUT, "Dest chan sz = %d W16 ", VSrcChanSzW16 )); + } + + + // Convert + + ViW16 = 0; + + for ( ViW128 = 0; ViW128 < VSrcChanSzW128; ViW128++ ) { + + // Low memory part + + VPtDCh0[ViW16] = *VPtSCh0Low; // W0 - CH0 + VPtSCh0Low += 8; + VPtDCh1[ViW16] = *VPtSCh1Low; // W0 - CH1 + VPtSCh1Low += 8; + VPtDCh2[ViW16] = *VPtSCh2Low; // W0 - CH2 + VPtSCh2Low += 8; + VPtDCh3[ViW16] = *VPtSCh3Low; // W0 - CH3 + VPtSCh3Low += 8; + VPtDCh4[ViW16] = *VPtSCh4Low; // W0 - CH4 + VPtSCh4Low += 8; + VPtDCh5[ViW16] = *VPtSCh5Low; // W0 - CH5 + VPtSCh5Low += 8; + ViW16++; + + + VPtDCh0[ViW16] = *VPtSCh0Low; // W1 - CH0 + VPtSCh0Low += 8; + VPtDCh1[ViW16] = *VPtSCh1Low; // W1 - CH1 + VPtSCh1Low += 8; + VPtDCh2[ViW16] = *VPtSCh2Low; // W1 - CH2 + VPtSCh2Low += 8; + VPtDCh3[ViW16] = *VPtSCh3Low; // W1 - CH3 + VPtSCh3Low += 8; + VPtDCh4[ViW16] = *VPtSCh4Low; // W1 - CH4 + VPtSCh4Low += 8; + VPtDCh5[ViW16] = *VPtSCh5Low; // W1 - CH5 + VPtSCh5Low += 8; + ViW16++; + + VPtDCh0[ViW16] = *VPtSCh0Low; // W2 - CH0 + VPtSCh0Low += 8; + VPtDCh1[ViW16] = *VPtSCh1Low; // W2 - CH1 + VPtSCh1Low += 8; + VPtDCh2[ViW16] = *VPtSCh2Low; // W2 - CH2 + VPtSCh2Low += 8; + VPtDCh3[ViW16] = *VPtSCh3Low; // W2 - CH3 + VPtSCh3Low += 8; + VPtDCh4[ViW16] = *VPtSCh4Low; // W2 - CH4 + VPtSCh4Low += 8; + VPtDCh5[ViW16] = *VPtSCh5Low; // W2 - CH5 + VPtSCh5Low += 8; + ViW16++; + + VPtDCh0[ViW16] = *VPtSCh0Low; // W3 - CH0 + VPtSCh0Low += 8; + VPtDCh1[ViW16] = *VPtSCh1Low; // W3 - CH1 + VPtSCh1Low += 8; + VPtDCh2[ViW16] = *VPtSCh2Low; // W3 - CH2 + VPtSCh2Low += 8; + VPtDCh3[ViW16] = *VPtSCh3Low; // W3 - CH3 + VPtSCh3Low += 8; + VPtDCh4[ViW16] = *VPtSCh4Low; // W3 - CH4 + VPtSCh4Low += 8; + VPtDCh5[ViW16] = *VPtSCh5Low; // W3 - CH5 + VPtSCh5Low += 8; + ViW16++; + + + // High memory part + + + VPtDCh0[ViW16] = *VPtSCh0High; // W4 - CH0 + VPtSCh0High += 8; + VPtDCh1[ViW16] = *VPtSCh1High; // W4 - CH1 + VPtSCh1High += 8; + VPtDCh2[ViW16] = *VPtSCh2High; // W4 - CH2 + VPtSCh2High += 8; + VPtDCh3[ViW16] = *VPtSCh3High; // W4 - CH3 + VPtSCh3High += 8; + VPtDCh4[ViW16] = *VPtSCh4High; // W4 - CH4 + VPtSCh4High += 8; + VPtDCh5[ViW16] = *VPtSCh5High; // W4 - CH5 + VPtSCh5High += 8; + ViW16++; + + + + VPtDCh0[ViW16] = *VPtSCh0High; // W5 - CH0 + VPtSCh0High += 8; + VPtDCh1[ViW16] = *VPtSCh1High; // W5 - CH1 + VPtSCh1High += 8; + VPtDCh2[ViW16] = *VPtSCh2High; // W5 - CH2 + VPtSCh2High += 8; + VPtDCh3[ViW16] = *VPtSCh3High; // W5 - CH3 + VPtSCh3High += 8; + VPtDCh4[ViW16] = *VPtSCh4High; // W5 - CH4 + VPtSCh4High += 8; + VPtDCh5[ViW16] = *VPtSCh5High; // W5 - CH5 + VPtSCh5High += 8; + ViW16++; + + VPtDCh0[ViW16] = *VPtSCh0High; // W6 - CH0 + VPtSCh0High += 8; + VPtDCh1[ViW16] = *VPtSCh1High; // W6 - CH1 + VPtSCh1High += 8; + VPtDCh2[ViW16] = *VPtSCh2High; // W6 - CH2 + VPtSCh2High += 8; + VPtDCh3[ViW16] = *VPtSCh3High; // W6 - CH3 + VPtSCh3High += 8; + VPtDCh4[ViW16] = *VPtSCh4High; // W6 - CH4 + VPtSCh4High += 8; + VPtDCh5[ViW16] = *VPtSCh5High; // W6 - CH5 + VPtSCh5High += 8; + ViW16++; + + VPtDCh0[ViW16] = *VPtSCh0High; // W7 - CH0 + VPtSCh0High += 8; + VPtDCh1[ViW16] = *VPtSCh1High; // W7 - CH1 + VPtSCh1High += 8; + VPtDCh2[ViW16] = *VPtSCh2High; // W7 - CH2 + VPtSCh2High += 8; + VPtDCh3[ViW16] = *VPtSCh3High; // W7 - CH3 + VPtSCh3High += 8; + VPtDCh4[ViW16] = *VPtSCh4High; // W7 - CH4 + VPtSCh4High += 8; + VPtDCh5[ViW16] = *VPtSCh5High; // W7 - CH5 + VPtSCh5High += 8; + ViW16++; + + + } // End for + + + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + VExecTimeUs = TIME__FMeasTimeUsEnd ( 0 /* Index */ ); + } + + else { + VExecTimeUs = 0; + } + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + VExecTimeUs = 0; // No exec time measurement implementation => Returns 0 + + + #endif + + + + return (VExecTimeUs); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtAcqW16APrintMSisU16 ( MIS1__TBtAcqW16A* Pt, UInt8 MSisId, UInt32 FirstW16, UInt32 W16Nb ) +* : +* \brief : Print the raw data of one MSis of MIS1__TBtAcqW16A* record \n +* : +* \param : Pt - Pointer to record MIS1__TBtAcqRawRec +* : +* \param : MSisId - 0..5 = MSis 0 to 5, 6,7 = Trigegrs channels +* : +* \param : FirstW16 - First W16 to print +* : +* \param : W16Nb - Nb of W16 to print +* : +* : +* \return : Execution time in us or error code +* : >= 0 - Execution time in us +* : < 0 - Error code +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 22/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__BT_FBtAcqW16APrintMSisU16 ( MIS1__TBtAcqW16A* Pt, UInt8 MSisId, UInt32 FirstW16, UInt32 W16Nb ) { + + SInt32 VRet; + SInt32 VLastW16; + SInt32 VMaxW16NbPerChan; // Calculated from record size + SInt32 VW16NbPerChan; // Calculated from number of frames in record + SInt32 ViW16; + + // Check param + + err_retnull (Pt, (ERR_OUT,"Abort => Pt == NULL") ); + + if ( MSisId >= MIS1__BT_MAX_MSIS_NB_ACQ ) { + err_retfail ( -1, (ERR_OUT,"Abort => MSisId = %d >= MIS1__BT_MAX_MSIS_NB_ACQ = %d", MSisId, MIS1__BT_MAX_MSIS_NB_ACQ) ); + } + + if ( W16Nb == 0 ) { + VLastW16 = -1; + } + + else { + VLastW16 = FirstW16 + W16Nb - 1; + } + + VMaxW16NbPerChan = MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W16; + VW16NbPerChan = MIS1__BT_TOT_FRAME_SZ_W16 * Pt->FrNb; + + if (VLastW16 >= VMaxW16NbPerChan) { + err_retfail ( -1, (ERR_OUT,"Abort => VLastW16 = %d >= Max W16 nb / chan in record = %d", VLastW16, VMaxW16NbPerChan) ); + } + + if (VLastW16 >= VW16NbPerChan) { + err_retfail ( -1, (ERR_OUT,"Abort => VLastW16 = %d >= W16 nb in record = %d (function of frames nb)", VLastW16, VW16NbPerChan) ); + } + + + // Print + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "Print MSis No %d, W16 from no %d to %d (%d W16 total)", MSisId, FirstW16, VLastW16, W16Nb )); + msg (( MSG_OUT, "" )); + + for ( ViW16 = FirstW16; ViW16 <= VLastW16; ViW16++ ) { + + msg (( MSG_OUT, "MSis[%d] W16[%.4d] = %X", MSisId, ViW16, Pt->AAMsis[MSisId][ViW16] )); + + } + + + err_retok (( ERR_OUT, "Ok" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : MIS1__TBtAcqDec* MIS1__BT_FBtAcqDecAlloc ( UInt8 Alloc, UInt32* PtRecSz ) +* : +* \brief : Allocates the MIS1__TBtAcqDec record \n +* : \n +* : +* \param : Alloc - 0 => Returns record size via PtRecSz, 1 => Alloc record + returns size +* : +* \param : PtRecSz - Pointer to record size, set to NULL if not used +* : +* \return : A pointer to MIS1__TBtAcqDec or NULL in case of error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/05/2021 +* \date : Doc date : 24/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +MIS1__TBtAcqDec* MIS1__BT_FBtAcqDecAlloc ( UInt8 Alloc, UInt32* PtRecSz ) { + + MIS1__TBtAcqDec* VPtRec; + UInt32 VRecSz; + + + VRecSz = sizeof (MIS1__TBtAcqDec); + + + // Update size + + if ( PtRecSz != NULL ) { + *PtRecSz = VRecSz; + } + + // Returns only size => No record allocation + + if ( Alloc == 0 ) { + err_retval ( NULL, ( ERR_OUT, "Ok, retunrs size only, no record allocation") ); + } + + + VPtRec = (MIS1__TBtAcqDec*) malloc ( VRecSz ); + + if ( VPtRec == NULL ) { + err_error (( ERR_OUT, "Abort => Allocation of %d W8 fro MIS1__TBtAcqDec failed ! ", VRecSz )); + return (NULL); + } + + + // Reset record + + memset ( VPtRec, 0, VRecSz ); + + // Set info fields + + + + err_trace (( ERR_OUT, "Ok" )); + + return (VPtRec); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtAcqDecFree ( MIS1__TBtAcqDec* PtRec ) +* : +* \brief : Free the MIS1__TBtAcqDec* record \n +* : \n +* : +* \param : PtRec - The record to free +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/05/2021 +* \date : Doc date : 24/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + +SInt32 MIS1__BT_FBtAcqDecFree ( MIS1__TBtAcqDec* PtRec ) { + + // Check param + + err_retnull ( PtRec, (ERR_OUT,"Abort => PtRec == NULL") ); + + // Free + + free ( PtRec ); + + err_retok (( ERR_OUT, "Ok" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FBtDecodeFrGetWarnErr ( UInt8 Reset ) +* +* \brief : Returns warning / errors counter of MIS1__BT_FBtDecodeFrLight (...), MIS1__BT_FBtDecodeFr (...) \n +* +* \param : Reset - 0 => Do nothing, 1 => Reset warning / errors counter +* +* : +* \return : Warnign / Errors count +* : = 0 - No warning, no error +* : > 0 - Warnings + errors count +* : < 0 - Ovf of the counter ... +* : +* \warning : Globals : +* \warning : Remark : Reset = 1 should never be needed, but who knows ... +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 30/05/2021 +* \date : Rev : 30/05/2021 +* \date : Doc date : 24/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FBtDecodeFrGetWarnErr ( UInt8 Reset ) { + + + if ( Reset == 1 ) { + MIS1__BT_VGDecodecFrWarnErr = 0; + } + + return ( MIS1__BT_VGDecodecFrWarnErr ); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : double MIS1__BT_FBtDecodeFrLight ( MIS1__TBtAcqW16A* PtSrc, MIS1__TBtAcqDec* PtDest, SInt8 MSisId, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) +* +* \brief : Decode the frames for one MSis 1 : List frames, exytract fr header, fr cnt but NO PIXELS DECODING \n +* +* \param : PtSrc - Pointer to source record MIS1__TBtAcqW16A +* +* \param : PtDest - Pointer to destination record MIS1__TBtAcqDec +* +* \param : MSisId - If of the MSis to deocde 0 to MIS1__BT_MAX_REAL_MSIS_NB_ACQ-1 +* +* \param : FrNb - Frames nb to convert, if -1 => All frames from source record (NOT HANDLED NOW => Full frame decoding) +* : +* \param : MeasExecTime - Measure exec time 0 = No, 1 = Yes +* +* \param : PrintLvl - Debug print level, 0 = No, 1 = Print record sizes, 2 = More print, to be implemented +* : +* : +* : +* \return : Execution time in us or error code +* : >= 0 - Execution time in us +* : < 0 - Error code +* : +* \warning : Globals : +* \warning : Remark : WARNING => ONLY 2 channels IMPLEMENTED on 22/05/2021 +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/05/2021 +* \date : Rev : 25/05/2021 +* \date : Doc date : 24/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +double MIS1__BT_FBtDecodeFrLight ( MIS1__TBtAcqW16A* PtSrc, MIS1__TBtAcqDec* PtDest, SInt8 MSisId, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) { + + SInt32 VRetOk; + double VExecTimeUs; + + SInt32 VSrcW16; // W16 to convert + // UInt16* VPtSrcW16; // Pointer to W16 to convert + + UInt32 VW16Nb; // Total W16 nb to process for this MSis 1 + SInt32 ViW16; // Index of W16 processed + SInt32 VFrCnt; // Counter of detected frames = counter of MSis 1 frame headers in data stream + SInt32 VFakeHdCnt; // Counter of fake headers => first W16 is header tag but not following 7 W16 + SInt32 VFrWithoutTrailerCnt; // Counter of frames without trailer + SInt32 ViW16CurHead; // First W16 of current header + + + + TW128As8W16 VFrHd; // Frame header (128 bits) + UInt16 VFrHdW0; // Frame header W0 + UInt16 VFrHdW1; // Frame header W1 + UInt16 VFrHdW2; // Frame header W2 + UInt16 VFrHdW3; // Frame header W3 + UInt16 VFrHdW4; // Frame header W4 + UInt16 VFrHdW5; // Frame header W5 + UInt16 VFrHdW6; // Frame header W6 + UInt16 VFrHdW7; // Frame header W7 + + + + SInt32 VRegCntInFr; // Counter of regiosn in frame + SInt32 VRegCntInAcq; // Counter of regiosn in Acq + SInt32 VPixCntInFr; // Counter of pixels in each frame + SInt32 VPixCntInAcq; // Counter of pixels in Acq + + // Flags + + UInt8 VFrWithoutTrailer; // Flag to handle frames without a trailer at the end, a header can starts + UInt8 VTrailerDetected; // Flag => trailer detected in current frame scanning + UInt8 VFrTooLong; // Flag => frame length > max possible + UInt8 VFrEnd; // Flag => end of frame = OR of previois flags + + + MIS1__TBtFrDecHead* VPtFrDecHead; + + + + // Check param + + // ---------------------------------------------- + // WARNING + // ---------------------------------------------- + // + // NO parameters checking to save execution time, it is done in ... + // => This function SHOULD not be called directly, but only via ... + // => In case you need to call it directly => Check parameters you provide + + // Measure exec time + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + TIME__FMeasTimeUsBegin ( 0 /* Index */ ); + } + + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + + #endif + + // Propagates AcqId and Triggers nb + + PtDest->AcqId = PtSrc->AcqId; + PtDest->TrigNb = PtSrc->AcqRawHead.Trigs.TrigNb; // Added on 30/05/2021 + + + // Init var + + VRetOk = 1; + + VW16Nb = PtSrc->MSisW16Nb; + ViW16CurHead = 0; + VFrCnt = 0; + VFakeHdCnt = 0; + VFrWithoutTrailerCnt = 0; + + + VFrWithoutTrailer = 0; + VTrailerDetected = 0; + VFrTooLong = 0; + VFrEnd = 0; + + + VRegCntInFr = 0; + VPixCntInFr = 0; + VRegCntInAcq = 0; + VPixCntInAcq = 0; + + + VPtFrDecHead = &PtDest->ResAAFrHead[MSisId][0]; + + // Reset frames truncated & errors counters - 30/05/2021 + + PtDest->ResAFrNbTrunc[MSisId] = 0; + PtDest->ResAFrNbErr[MSisId] = 0; + + // Reset decoding function warnings + errors counter - 30/05/2021 + + MIS1__BT_VGDecodecFrWarnErr = 0; + + // ------------------------------------------------------------- + // Frames decoding + // ------------------------------------------------------------- + + + if ( PrintLvl ) { + msg (( MSG_OUT, "Decode MSis No %d, Src frame = %d W16", MSisId, VW16Nb )); + } + + + for ( ViW16 = 0; ViW16 < VW16Nb; ) { + + // Try to handle frames without trailer + // - the first header field (W0) has already been detected at end of previous frame, don't read it again it is already here + + if ( VFrWithoutTrailer == 0 ) { + VSrcW16 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + } + + // Detects first W16, W0 of a frame header + + if ( (VSrcW16 & 0xFF00) == 0xFE00 ) { + + ViW16CurHead = ViW16 - 1; + + VFrHdW0 = VSrcW16; + + // Checks that next 7 are also frame header tags + + VFrHdW1 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW2 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW3 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW4 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW5 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW6 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW7 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + + // Header confirmed + + // if ( 1 ) { + + if ( ((VFrHdW1 & 0xFF00) == 0xFE00) && ((VFrHdW2 & 0xFF00) == 0xFE00) && ((VFrHdW3 & 0xFF00) == 0xFE00) && ((VFrHdW4 & 0xFF00) == 0xFE00) && ((VFrHdW5 & 0xFF00) == 0xFE00) && ((VFrHdW6 & 0xFF00) == 0xFE00) && ((VFrHdW7 & 0xFF00) == 0xFE00) ) { + + // Reset regions cnt, fired pixels cnt, flags + + VRegCntInFr = 0; + VPixCntInFr = 0; + + VFrWithoutTrailer = 0; + VTrailerDetected = 0; + VFrTooLong = 0; + VFrEnd = 0; + + + // Update frame header results + + VPtFrDecHead->MSisId = MSisId; + VPtFrDecHead->FrId = VFrCnt; + + VFrCnt++; + + // Extract header + + VPtFrDecHead->MSisFrHead.AW16[0] = VFrHdW0; + VPtFrDecHead->MSisFrHead.AW16[1] = VFrHdW1; + VPtFrDecHead->MSisFrHead.AW16[2] = VFrHdW2; + VPtFrDecHead->MSisFrHead.AW16[3] = VFrHdW3; + VPtFrDecHead->MSisFrHead.AW16[4] = VFrHdW4; + VPtFrDecHead->MSisFrHead.AW16[5] = VFrHdW5; + VPtFrDecHead->MSisFrHead.AW16[6] = VFrHdW6; + VPtFrDecHead->MSisFrHead.AW16[7] = VFrHdW7; + + // Extract frames counter + + VPtFrDecHead->FrCnt = (VFrHdW0 &0xFF) + ((VFrHdW1 & 0xFF) << 8) + ((VFrHdW2 & 0xFF) << 16) + ((VFrHdW3 & 0xFF) << 24); + + if ( PrintLvl >= 2 ) { + msg (( MSG_OUT, "Header detected (Cnt = %.4d) : W7 = %X, W6 = %X, W5 = %X, W4 = %X, W3 = %X, W2 = %X, W1 = %X , W0 = %X", VFrCnt, VFrHdW7, VFrHdW6, VFrHdW5, VFrHdW4, VFrHdW3, VFrHdW2, VFrHdW1, VFrHdW0 )); + } + + + VPtFrDecHead->FirstDataW16Pos = ViW16CurHead + 8; + + // Result fields not calculated now + + VPtFrDecHead->Errors = 0; + VPtFrDecHead->FrDataSzW16 = 0; + VPtFrDecHead->RegionNb = 0; + VPtFrDecHead->FiredPixNb = 0; + VPtFrDecHead->MSisFrTrail.W16 = 0; + VPtFrDecHead->CheckSum = 0; + VPtFrDecHead->ATrigPosW16[0] = 0; + VPtFrDecHead->ATrigPosW16[MIS1__BT_FR_DEC_MAX_TRIG_NB - 1] = 0; + + + if ( PrintLvl >= 2 ) { + msg (( MSG_OUT, "FrCnt = %d", VPtFrDecHead->FrCnt )); + } + + // Processing frame + + + + // Scan frame + + while (1) { + + VSrcW16 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + + // Detects region + + if ( (VSrcW16 & 0xFF00) == 0xFD00 ) { + VRegCntInFr++; + VRegCntInAcq++; + + if ( PrintLvl >= 2 ) { + msg (( MSG_OUT, "FrCnt = %d - Region", VPtFrDecHead->FrCnt )); + } + + } + + + // Detects trailer + + if ( (VSrcW16 & 0xFF00) == 0xFF00 ) { + + VTrailerDetected = 1; + + VPtFrDecHead->MSisFrTrail.W16 = VSrcW16; + + // Calc fr data size + + VPtFrDecHead->FrDataSzW16 = ViW16 - VPtFrDecHead->FirstDataW16Pos - 1; + + // Reads checksum + + VSrcW16 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + + VPtFrDecHead->CheckSum = VSrcW16; + + if ( PrintLvl >= 2 ) { + msg (( MSG_OUT, "Fr No %.3d MSisFrCnt = %.6d - Trailer", VFrCnt, VPtFrDecHead->FrCnt )); + } + + } + + // Detects header => frame without trailer at the end + + if ( (VSrcW16 & 0xFF00) == 0xFE00 ) { + VFrWithoutTrailer = 1; + VFrWithoutTrailerCnt++; + + // Calc fr data size + + VPtFrDecHead->FrDataSzW16 = ViW16 - VPtFrDecHead->FirstDataW16Pos - 1; + } + + // Frame is too long : Decoding bug or MSis 1 side bug or unknown info / MSis 1 data stream + + if ( ViW16 >= VW16Nb ) { + VFrTooLong = 1; + + // Calc fr data size + + VPtFrDecHead->FrDataSzW16 = ViW16 - VPtFrDecHead->FirstDataW16Pos - 1; + } + + + VFrEnd = VTrailerDetected || VFrWithoutTrailer || VFrTooLong; + + // Pixel detected : Current W16 is not a region header, an empty W16 and is not an end of frame tag + + if ( (VFrEnd == 0) && ((VSrcW16 & 0xFF00) != 0xFD00) && (VSrcW16 != 0xFCAA) ) { + VPixCntInFr++; + VPixCntInAcq++; + } + + + // End of frame => Update frame header info + + if ( VFrEnd ) { + + VPtFrDecHead->Errors = 0; // Not handled now 25/05/2021 + VPtFrDecHead->ATrigPosW16[0] = 0; // Not handled now 25/05/2021 + VPtFrDecHead->ATrigPosW16[MIS1__BT_FR_DEC_MAX_TRIG_NB - 1] = 0; // Not handled now 25/05/2021 + + // VPtFrDecHead->FrDataSzW16 = 0; // Calculated before + // VPtFrDecHead->MSisFrTrail.W16 = 0; // Calculated before + // VPtFrDecHead->CheckSum = 0; // Calculated before + + VPtFrDecHead->RegionNb = VRegCntInFr; + VPtFrDecHead->FiredPixNb = VPixCntInFr; + + // Frame too long => Exits on error + // No time now to handle it in a better way => TBD later + // Upgraded on 29/05/2021 + // If it is the last frame of Acq => Warning, because the frame is probably only cut + // If it is NOT the last frame of Acq => Error because it should not happne => There is a problem + + if ( VFrTooLong ) { + + PtDest->ResAFrNbTrunc[MSisId]++; // Update truncated frames counter - 30/05/2021 + + MIS1__BT_VGDecodecFrWarnErr++; + + if ( VFrCnt >= PtSrc->FrNb ) { + VPtFrDecHead->Errors = MIS1__BT_FR_ERR_TRUNC_LAST_FR; + // err_warning (( ERR_OUT, "Stop frame processing max W16 nb = %d reached => VFrCnt = %d >= FrNbInAcq = %d => Last frame cut", VW16Nb, VFrCnt, PtSrc->FrNb )); + } + + else { + VPtFrDecHead->Errors = MIS1__BT_FR_ERR_TRUNC; + err_error (( ERR_OUT, "Stop frame processing max W16 nb = %d reached => VFrCnt = %d < FrNbInAcq = %d => MSis 1 or decoding sw bug !", VW16Nb, VFrCnt, PtSrc->FrNb )); + return (-1); + } + + } // End if ( VFrTooLong ) + + // Normal end of frame => break frame decoding loop + + break; + } + + } // End while (1) frame scanning + + + VPtFrDecHead++; + + } + + // Fake header + + else { + + VFakeHdCnt++; + + if ( PrintLvl >= 1 ) { + msg (( MSG_OUT, "Fake header detected (Cnt = %.4d) : W7 = %X, W6 = %X, W5 = %X, W4 = %X, W3 = %X, W2 = %X, W1 = %X , W0 = %X", VFakeHdCnt, VFrHdW7, VFrHdW6, VFrHdW5, VFrHdW4, VFrHdW3, VFrHdW2, VFrHdW1, VFrHdW0 )); + } + + } + + + } // End frame processing + + + + + } // End for + + + // Update results + + PtDest->ParFrNbInSrcAcq = PtSrc->FrNb; + + + PtDest->ResAFrNb[MSisId] = VFrCnt; + PtDest->ResAFrNbWoTrailer[MSisId] = VFrWithoutTrailerCnt; + PtDest->ResAFrFakeHeadCnt[MSisId] = VFakeHdCnt; + PtDest->ResARegNb[MSisId] = VRegCntInAcq; + PtDest->ResAPixNb[MSisId] = VPixCntInAcq; + + + if ( (VFrCnt == 0) || (VFakeHdCnt > 0) ) { + err_error (( ERR_OUT, "Error : VFrCnt = %d, VFakeHdCnt = %d", VFrCnt, VFakeHdCnt )); + VRetOk = -1; + } + + + if ( PrintLvl ) { + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "%d frames found, %d fake headers found", VFrCnt, VFakeHdCnt )); + msg (( MSG_OUT, "ViW16 = %d", ViW16 )); + + msg (( MSG_OUT, "" )); + } + + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + VExecTimeUs = TIME__FMeasTimeUsEnd ( 0 /* Index */ ); + } + + else { + VExecTimeUs = 0; + } + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + VExecTimeUs = 0; // No exec time measurement implementation => Returns 0 + + + #endif + + + + + return (VExecTimeUs * VRetOk ); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : double MIS1__BT_FBtDecodeFr ( MIS1__TBtAcqW16A* PtSrc, MIS1__TBtAcqDec* PtDest, SInt8 MSisId, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) +* +* \brief : Decode the frames for one MSis 1 : List frames, exytract fr header, fr cnt but NO PIXELS DECODING \n +* +* \param : PtSrc - Pointer to source record MIS1__TBtAcqW16A +* +* \param : PtDest - Pointer to destination record MIS1__TBtAcqDec +* +* \param : MSisId - If of the MSis to deocde 0 to MIS1__BT_MAX_REAL_MSIS_NB_ACQ-1 +* +* \param : FrNb - Frames nb to convert, if -1 => All frames from source record (NOT HANDLED NOW => Full frame decoding) +* : +* \param : MeasExecTime - Measure exec time 0 = No, 1 = Yes +* +* \param : PrintLvl - Debug print level, 0 = No, 1 = Print record sizes, 2 = More print, to be implemented +* : +* : +* : +* \return : Execution time in us or error code +* : >= 0 - Execution time in us +* : < 0 - Error code +* : +* \warning : Globals : +* \warning : Remark : WARNING => ONLY 2 channels IMPLEMENTED on 22/05/2021 +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2021 +* \date : Rev : +* \date : Doc date : 24/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +double MIS1__BT_FBtDecodeFr ( MIS1__TBtAcqW16A* PtSrc, MIS1__TBtAcqDec* PtDest, SInt8 MSisId, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ) { + + SInt32 VRetOk; + double VExecTimeUs; + + SInt32 VSrcW16; // W16 to convert + // UInt16* VPtSrcW16; // Pointer to W16 to convert + + UInt32 VW16Nb; // Total W16 nb to process for this MSis 1 + SInt32 ViW16; // Index of W16 processed + SInt32 VFrCnt; // Counter of detected frames = counter of MSis 1 frame headers in data stream + SInt32 VFakeHdCnt; // Counter of fake headers => first W16 is header tag but not following 7 W16 + SInt32 VFrWithoutTrailerCnt; // Counter of frames without trailer + SInt32 ViW16CurHead; // First W16 of current header + + + + TW128As8W16 VFrHd; // Frame header (128 bits) + UInt16 VFrHdW0; // Frame header W0 + UInt16 VFrHdW1; // Frame header W1 + UInt16 VFrHdW2; // Frame header W2 + UInt16 VFrHdW3; // Frame header W3 + UInt16 VFrHdW4; // Frame header W4 + UInt16 VFrHdW5; // Frame header W5 + UInt16 VFrHdW6; // Frame header W6 + UInt16 VFrHdW7; // Frame header W7 + + + + SInt32 VRegCntInFr; // Counter of regiosn in frame + SInt32 VRegCntInAcq; // Counter of regiosn in Acq + SInt32 VPixCntInFr; // Counter of pixels in each frame + SInt32 VPixCntInAcq; // Counter of pixels in Acq + + // Flags + + UInt8 VFrWithoutTrailer; // Flag to handle frames without a trailer at the end, a header can starts + UInt8 VTrailerDetected; // Flag => trailer detected in current frame scanning + UInt8 VFrTooLong; // Flag => frame length > max possible + UInt8 VFrEnd; // Flag => end of frame = OR of previois flags + + // Pixels decoding 25/05/2021 + + MIS1__TDsRegHeader VCurRegHead; // Current region + MIS1__TStdPix VCurPix; // Current pixel + + MIS1__TPixXY VResPix; // Decoded pixel x,y format to be stored in ResAAAFrPix[MSisId][FrId][PixNo] + MIS1__TPixXY* VPtResPix; // Pointer to current result pixel in ResAAAFrPix[MSisId][FrId][PixNo] + + + MIS1__TBtFrDecHead* VPtFrDecHead; + + + // Check param + + // ---------------------------------------------- + // WARNING + // ---------------------------------------------- + // + // NO parameters checking to save execution time, it is done in ... + // => This function SHOULD not be called directly, but only via ... + // => In case you need to call it directly => Check parameters you provide + + // Measure exec time + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + TIME__FMeasTimeUsBegin ( 0 /* Index */ ); + } + + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + + #endif + + + // Propagates AcqId and Triggers nb + + PtDest->AcqId = PtSrc->AcqId; + PtDest->TrigNb = PtSrc->AcqRawHead.Trigs.TrigNb; // Added on 30/05/2021 + + + // Init var + + VRetOk = 1; + + VW16Nb = PtSrc->MSisW16Nb; + ViW16CurHead = 0; + VFrCnt = 0; + VFakeHdCnt = 0; + VFrWithoutTrailerCnt = 0; + + + VFrWithoutTrailer = 0; + VTrailerDetected = 0; + VFrTooLong = 0; + VFrEnd = 0; + + + VRegCntInFr = 0; + VPixCntInFr = 0; + VRegCntInAcq = 0; + VPixCntInAcq = 0; + + VCurRegHead.W16 = 0; + VCurPix.W16 = 0; + + VResPix.C.x = 0; + VResPix.C.y = 0; + + VPtResPix = &PtDest->ResAAAFrPix[MSisId][0 /* Fr no */][0 /* Pix no */]; + + + + VPtFrDecHead = &PtDest->ResAAFrHead[MSisId][0]; + + // Reset frames truncated & errors counters - 30/05/2021 + + PtDest->ResAFrNbTrunc[MSisId] = 0; + PtDest->ResAFrNbErr[MSisId] = 0; + + // Reset decoding function warnings + errors counter - 30/05/2021 + + MIS1__BT_VGDecodecFrWarnErr = 0; + + + // ------------------------------------------------------------- + // Frames decoding + // ------------------------------------------------------------- + + + if ( PrintLvl ) { + msg (( MSG_OUT, "Decode MSis No %d, Src frame = %d W16", MSisId, VW16Nb )); + } + + + for ( ViW16 = 0; ViW16 < VW16Nb; ) { + + // Try to handle frames without trailer + // - the first header field (W0) has already been detected at end of previous frame, don't read it again it is already here + + if ( VFrWithoutTrailer == 0 ) { + VSrcW16 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + } + + // Detects first W16, W0 of a frame header + + if ( (VSrcW16 & 0xFF00) == 0xFE00 ) { + + ViW16CurHead = ViW16 - 1; + + VFrHdW0 = VSrcW16; + + // Checks that next 7 are also fraem header tags + + VFrHdW1 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW2 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW3 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW4 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW5 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW6 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + VFrHdW7 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + + // Header confirmed + + // if ( 1 ) { + + if ( ((VFrHdW1 & 0xFF00) == 0xFE00) && ((VFrHdW2 & 0xFF00) == 0xFE00) && ((VFrHdW3 & 0xFF00) == 0xFE00) && ((VFrHdW4 & 0xFF00) == 0xFE00) && ((VFrHdW5 & 0xFF00) == 0xFE00) && ((VFrHdW6 & 0xFF00) == 0xFE00) && ((VFrHdW7 & 0xFF00) == 0xFE00) ) { + + // Reset regions cnt, fired pixels cnt, flags + + VRegCntInFr = 0; + VPixCntInFr = 0; + + VFrWithoutTrailer = 0; + VTrailerDetected = 0; + VFrTooLong = 0; + VFrEnd = 0; + + VCurRegHead.W16 = 0; // Resets region header + + // Update frame header results + + VPtFrDecHead->MSisId = MSisId; + VPtFrDecHead->FrId = VFrCnt; + + // Sets ptr to destination pixels stream + + VPtResPix = &PtDest->ResAAAFrPix[MSisId][VFrCnt][0 /* Pix No */]; + + VFrCnt++; + + // Extract header + + VPtFrDecHead->MSisFrHead.AW16[0] = VFrHdW0; + VPtFrDecHead->MSisFrHead.AW16[1] = VFrHdW1; + VPtFrDecHead->MSisFrHead.AW16[2] = VFrHdW2; + VPtFrDecHead->MSisFrHead.AW16[3] = VFrHdW3; + VPtFrDecHead->MSisFrHead.AW16[4] = VFrHdW4; + VPtFrDecHead->MSisFrHead.AW16[5] = VFrHdW5; + VPtFrDecHead->MSisFrHead.AW16[6] = VFrHdW6; + VPtFrDecHead->MSisFrHead.AW16[7] = VFrHdW7; + + // Extract frames counter + + VPtFrDecHead->FrCnt = (VFrHdW0 &0xFF) + ((VFrHdW1 & 0xFF) << 8) + ((VFrHdW2 & 0xFF) << 16) + ((VFrHdW3 & 0xFF) << 24); + + if ( PrintLvl >= 3 ) { + msg (( MSG_OUT, "Header detected (Cnt = %.4d) : W7 = %X, W6 = %X, W5 = %X, W4 = %X, W3 = %X, W2 = %X, W1 = %X , W0 = %X", VFrCnt, VFrHdW7, VFrHdW6, VFrHdW5, VFrHdW4, VFrHdW3, VFrHdW2, VFrHdW1, VFrHdW0 )); + msg (( MSG_OUT, "FrCnt = %d", VPtFrDecHead->FrCnt )); + } + + + VPtFrDecHead->FirstDataW16Pos = ViW16CurHead + 8; + + // Result fields not calculated now + + VPtFrDecHead->Errors = 0; + VPtFrDecHead->FrDataSzW16 = 0; + VPtFrDecHead->RegionNb = 0; + VPtFrDecHead->FiredPixNb = 0; + VPtFrDecHead->MSisFrTrail.W16 = 0; + VPtFrDecHead->CheckSum = 0; + VPtFrDecHead->ATrigPosW16[0] = 0; + VPtFrDecHead->ATrigPosW16[MIS1__BT_FR_DEC_MAX_TRIG_NB - 1] = 0; + + + // Processing frame + + while (1) { + + VSrcW16 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + + // Detects region + + if ( (VSrcW16 & 0xFF00) == 0xFD00 ) { + + VRegCntInFr++; + VRegCntInAcq++; + + VCurRegHead.W16 = VSrcW16; + + if ( PrintLvl >= 2 ) { + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "Fr No %.3d : MSis 1 FrCnt = %d - Region No %.2d", VFrCnt - 1, VPtFrDecHead->FrCnt, VRegCntInFr - 1 )); + } + + continue; + } + + + // Detects trailer + + if ( (VSrcW16 & 0xFF00) == 0xFF00 ) { + + VTrailerDetected = 1; + + VPtFrDecHead->MSisFrTrail.W16 = VSrcW16; + + // Calc fr data size + + VPtFrDecHead->FrDataSzW16 = ViW16 - VPtFrDecHead->FirstDataW16Pos - 1; + + // Reads checksum + + VSrcW16 = PtSrc->AAMsis[MSisId][ViW16]; + ViW16++; + + VPtFrDecHead->CheckSum = VSrcW16; + + if ( PrintLvl >= 3 ) { + msg (( MSG_OUT, "Fr No %.3d MSisFrCnt = %.6d - Trailer", VFrCnt, VPtFrDecHead->FrCnt )); + } + + } + + // Detects header => frame without trailer at the end + + if ( (VSrcW16 & 0xFF00) == 0xFE00 ) { + VFrWithoutTrailer = 1; + VFrWithoutTrailerCnt++; + + // Calc fr data size + + VPtFrDecHead->FrDataSzW16 = ViW16 - VPtFrDecHead->FirstDataW16Pos - 1; + } + + // Frame is too long : Decoding bug or MSis 1 side bug or unknown info / MSis 1 data stream + + if ( ViW16 >= VW16Nb ) { + VFrTooLong = 1; + + // Calc fr data size + + VPtFrDecHead->FrDataSzW16 = ViW16 - VPtFrDecHead->FirstDataW16Pos - 1; + } + + + VFrEnd = VTrailerDetected || VFrWithoutTrailer || VFrTooLong; + + // Pixel detected : Current W16 is not a region header, an empty W16 and is not an end of frame tag + + // if ( (VFrEnd == 0) && ((VSrcW16 & 0xFF00) != 0xFD00) && (VSrcW16 != 0xFCAA) ) { // Test on region not needed now with continue at end of region block + + if ( (VFrEnd == 0) && (VSrcW16 != 0xFCAA) ) { + + VPixCntInFr++; + VPixCntInAcq++; + + VCurPix.W16 = VSrcW16; + + // Calcul de Y : DATA[15:7] (9 bits �quivalent � 10 bits DATA[15:6]/2) + + VResPix.C.y = VCurPix.F.PixAddr / 2; + + // Calcul de X : REGION_HEADER[5:0]*16+DATA[5:3]*2+DATA[6] xor DATA[7] + + VResPix.C.x = (VCurRegHead.F.Reg * 16) + (VCurPix.F.PeAddr * 2) + (VCurPix.B.b6 ^ VCurPix.B.b7); + + // Add in destination array + + if ( VPixCntInFr > MIS1__BT_FR_DEC_MAX_PIX_NB) { + err_warning (( ERR_OUT, "Cant add pixel, destination list is full with %d pixels : AcqId = %d, FrId = %d", MIS1__BT_FR_DEC_MAX_PIX_NB, PtSrc->AcqId, VFrCnt - 1 )); + } + + else { + *VPtResPix = VResPix; + VPtResPix++; + } + + // Print + + if ( PrintLvl >= 2 ) { + msg (( MSG_OUT, "Pixel : x = %d, y = %d", VResPix.C.x, VResPix.C.y )); + } + + } + + + // End of frame => Update frame header info + + if ( VFrEnd ) { + + VPtFrDecHead->Errors = 0; // Not handled now 25/05/2021 + VPtFrDecHead->ATrigPosW16[0] = 0; // Not handled now 25/05/2021 + VPtFrDecHead->ATrigPosW16[MIS1__BT_FR_DEC_MAX_TRIG_NB - 1] = 0; // Not handled now 25/05/2021 + + // VPtFrDecHead->FrDataSzW16 = 0; // Calculated before + // VPtFrDecHead->MSisFrTrail.W16 = 0; // Calculated before + // VPtFrDecHead->CheckSum = 0; // Calculated before + + VPtFrDecHead->RegionNb = VRegCntInFr; + VPtFrDecHead->FiredPixNb = VPixCntInFr; + + + + // Frame too long => Exits on error + // No time now to handle it in a better way => TBD later + // Upgraded on 29/05/2021 + // If it is the last frame of Acq => Warning, because the frame is probably only cut + // If it is NOT the last frame of Acq => Error because it should not happne => There is a problem + + + if ( VFrTooLong ) { + + PtDest->ResAFrNbTrunc[MSisId]++; // Update truncated frames counter - 30/05/2021 + + MIS1__BT_VGDecodecFrWarnErr++; + + if ( VFrCnt >= PtSrc->FrNb ) { + VPtFrDecHead->Errors = MIS1__BT_FR_ERR_TRUNC_LAST_FR; + // err_warning (( ERR_OUT, "Stop frame processing max W16 nb = %d reached => VFrCnt = %d >= FrNbInAcq = %d => Last frame cut", VW16Nb, VFrCnt, PtSrc->FrNb )); + } + + else { + VPtFrDecHead->Errors = MIS1__BT_FR_ERR_TRUNC; + err_error (( ERR_OUT, "Stop frame processing max W16 nb = %d reached => VFrCnt = %d < FrNbInAcq = %d => MSis 1 or decoding sw bug !", VW16Nb, VFrCnt, PtSrc->FrNb )); + return (-1); + } + + } // End if ( VFrTooLong ) + + + + + + + + + + + + // Normal end of frame => break frame decoding loop + + break; + } + + } // End while (1) frame scanning + + + VPtFrDecHead++; + + } + + // Fake header + + else { + + VFakeHdCnt++; + + if ( PrintLvl >= 1 ) { + msg (( MSG_OUT, "Fake header detected (Cnt = %.4d) : W7 = %X, W6 = %X, W5 = %X, W4 = %X, W3 = %X, W2 = %X, W1 = %X , W0 = %X", VFakeHdCnt, VFrHdW7, VFrHdW6, VFrHdW5, VFrHdW4, VFrHdW3, VFrHdW2, VFrHdW1, VFrHdW0 )); + } + + } + + + } // End frame processing + + + + + } // End for + + + // Update results + + PtDest->ParFrNbInSrcAcq = PtSrc->FrNb; + + + PtDest->ResAFrNb[MSisId] = VFrCnt; + PtDest->ResAFrNbWoTrailer[MSisId] = VFrWithoutTrailerCnt; + PtDest->ResAFrFakeHeadCnt[MSisId] = VFakeHdCnt; + PtDest->ResARegNb[MSisId] = VRegCntInAcq; + PtDest->ResAPixNb[MSisId] = VPixCntInAcq; + + + if ( (VFrCnt == 0) || (VFakeHdCnt > 0) ) { + err_error (( ERR_OUT, "Error : MSisId = %d, VFrCnt = %d, VFakeHdCnt = %d", MSisId, VFrCnt, VFakeHdCnt )); + VRetOk = -1; + } + + + if ( PrintLvl ) { + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "%d frames found, %d fake headers found", VFrCnt, VFakeHdCnt )); + msg (( MSG_OUT, "ViW16 = %d", ViW16 )); + + msg (( MSG_OUT, "" )); + } + + + #ifndef CC_NOT_CPP_BUILDER + + if ( MeasExecTime ) { + VExecTimeUs = TIME__FMeasTimeUsEnd ( 0 /* Index */ ); + } + + else { + VExecTimeUs = 0; + } + + #else + + // You can implement here exec tiome measurement for compiler <> C++ Builder + + VExecTimeUs = 0; // No exec time measurement implementation => Returns 0 + + + #endif + + + + + return (VExecTimeUs * VRetOk ); +} + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FFrDecHeadPrint ( MIS1__TBtFrDecHead* Pt, UInt8 PrintMode ) +* : +* \brief : Pritns frame header \n +* : \n +* : +* \param : Pt - Pointer to header +* : +* \param : PrintMode - 0 => Print all, 1 => Print only region, fired pixels cnt +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 24/05/2021 +* \date : Rev : 25/05/2021 +* \date : Doc date : 24/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FFrDecHeadPrint ( MIS1__TBtFrDecHead* Pt, UInt8 PrintMode ) { + + char VStrHead[GLB_CMT_SZ]; + char VStrTrail[GLB_CMT_SZ]; + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort Pt == NULL") ); + + // Convert head, trail to sting + + MIS1__FFrHeader2Str ( &Pt->MSisFrHead, VStrHead, GLB_CMT_SZ, 1 /* Mode */ ); + MIS1__FFrTrailer2Str ( &Pt->MSisFrTrail, VStrTrail, GLB_CMT_SZ, 0 /* Mode */ ); + + // Print + + if ( PrintMode == 0 ) { + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "Fr header MSis = %d, FrId = %.4d ", Pt->MSisId, Pt->FrId )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "MSis FrCnt = %.4d", Pt->FrCnt )); + msg (( MSG_OUT, "CheckSum = %.4d", Pt->CheckSum )); + msg (( MSG_OUT, "FiredPixNb = %.4d", Pt->FiredPixNb )); + msg (( MSG_OUT, "RegionNb = %.4d", Pt->RegionNb )); + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "Header = %s" , VStrHead )); + msg (( MSG_OUT, "Tailer = %s" , VStrTrail )); + msg (( MSG_OUT, "Errors = %d" , Pt->Errors )); + msg (( MSG_OUT, "FirstDataW16Pos = %.4d", Pt->FirstDataW16Pos )); + msg (( MSG_OUT, "FrDataSzW16 = %.4d", Pt->FrDataSzW16 )); + msg (( MSG_OUT, "ATrigPosW16[0] = %.4d", Pt->ATrigPosW16[0] )); + msg (( MSG_OUT, "ATrigPosW16[1] = %.4d", Pt->ATrigPosW16[1] )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "" )); + err_retok (( ERR_OUT, "Ok" )); + } // End if ( Mode == 0 ) + + if ( PrintMode == 1 ) { + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "MSis = %d, FrId = %.4d ", Pt->MSisId, Pt->FrId )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "FrCnt = %.4d", Pt->FrCnt )); + msg (( MSG_OUT, "FiredPixNb = %.4d", Pt->FiredPixNb )); + msg (( MSG_OUT, "RegionNb = %.4d", Pt->RegionNb )); + + err_retok (( ERR_OUT, "Ok" )); + } + + err_retok (( ERR_OUT, "Ok" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqDecPrintGen ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt8 PrintMode ) +* : +* \brief : Prints acq dec general fields, for ResAAFrHead => MIS1__BT_FFrDecHeadPrint (...) \n +* : \n +* : +* \param : Pt - Pointer to AcqDec +* : +* \param : MSisId - Id of MSis 1 to print, -1 => ALL +* : +* \param : PrintMode - 0 => Print all info, 1 => Print only region, fired pixels cnt +* +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2021 +* \date : Doc date : 25/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FAcqDecPrintGen ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt8 PrintMode ) { + + SInt32 VRet; + SInt8 ViMsis; + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort Pt == NULL") ); + + if ( MSisId >= MIS1__BT_MAX_REAL_MSIS_NB_ACQ ) { + err_retfail ( -1, (ERR_OUT,"Abort => MSisId = %d out of range 0..%d", MSisId, MIS1__BT_MAX_REAL_MSIS_NB_ACQ - 1) ); + } + + // Prints + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "Acq dec" )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "ParFrNbInSrcAcq = %d", Pt->ParFrNbInSrcAcq )); + + if ( MSisId >= 0 ) { + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "MSisId = %d", MSisId )); + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "ResAFrNb = %.3d", Pt->ResAFrNb[MSisId] )); + msg (( MSG_OUT, "ResAFrFakeHeadCnt = %.3d", Pt->ResAFrFakeHeadCnt[MSisId] )); + msg (( MSG_OUT, "ResAFrNbWoTrailer = %.3d", Pt->ResAFrNbWoTrailer[MSisId] )); + msg (( MSG_OUT, "RegionNb = %.3d", Pt->ResARegNb[MSisId] )); + msg (( MSG_OUT, "FiredPixNb = %.3d", Pt->ResAPixNb[MSisId] )); + msg (( MSG_OUT, "" )); + err_retok (( ERR_OUT, "Ok" )); + } + + + if ( MSisId < 0 ) { + + for ( ViMsis = 0; ViMsis < MIS1__BT_MAX_REAL_MSIS_NB_ACQ; ViMsis++ ) { + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "MSisId = %d", MSisId )); + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "ResAFrNb = %.3d", Pt->ResAFrNb[ViMsis] )); + msg (( MSG_OUT, "ResAFrFakeHeadCnt = %.3d", Pt->ResAFrFakeHeadCnt[ViMsis] )); + msg (( MSG_OUT, "ResAFrNbWoTrailer = %.3d", Pt->ResAFrNbWoTrailer[ViMsis] )); + msg (( MSG_OUT, "RegionNb = %.3d", Pt->ResARegNb[ViMsis] )); + msg (( MSG_OUT, "FiredPixNb = %.3d", Pt->ResAPixNb[ViMsis] )); + msg (( MSG_OUT, "" )); + } // End for + + } // End if + + + err_retok (( ERR_OUT, "Ok" )); +} + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqDecPrintPix ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt32 FrId, UInt32 MaxPixToPrint, UInt8 PrintMode ) +* : +* \brief : Prints acq dec pixels \n +* : \n +* +* \param : Pt - Pointer to AcqDec +* +* \param : MSisId - Id of MSis 1 from which to print pixels +* +* \param : FrId - Id of the frame to print +* +* \param : MaxPixToPrint - Maximum number of pixels to print, to avoid "endless" printing loop ... +* +* \param : PrintMode - For future use +* +* \return : Error code +* : 0 - OK +* : < 0 - Error ( -1 sw error, -2 more than MaxPixToPrint => exits before end +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 25/05/2021 +* \date : Doc date : 25/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FAcqDecPrintPix ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt32 FrId, UInt32 MaxPixToPrint, UInt8 PrintMode ) { + + SInt32 VRet; + SInt32 ViPix; + MIS1__TPixXY VPix; + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort Pt == NULL") ); + + err_retfail ( MSisId, (ERR_OUT,"Abort => MSisId = %d < 0", MSisId) ); + + if ( MSisId >= MIS1__BT_MAX_REAL_MSIS_NB_ACQ ) { + err_retfail ( -1, (ERR_OUT,"Abort => MSisId = %d out of range 0..%d", MSisId, MIS1__BT_MAX_REAL_MSIS_NB_ACQ - 1) ); + } + + if ( FrId >= Pt->ResAFrNb[MSisId] ) { + FrId = Pt->ResAFrNb[MSisId] - 1; + err_warning (( ERR_OUT, "FrId = %d it out of range, sets to last fr = %d", FrId, Pt->ResAFrNb[MSisId] - 1 )); + } + + + // Prints + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "Pixels acq dec : AcqId = %.4d, MSisId = %d, FrId = %.4d", Pt->AcqId, MSisId, FrId )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "" )); + + for ( ViPix = 0; ViPix < Pt->ResAAFrHead[MSisId][FrId].FiredPixNb; ViPix++ ) { + + if ( ViPix >= MaxPixToPrint ) { + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "Stop before end : Max pixels nb to print = %d reached", MaxPixToPrint )); + err_retfail ( -2, (ERR_OUT,"%s", MSG_OUT) ); + } + + VPix = Pt->ResAAAFrPix[MSisId][FrId][ViPix]; + + msg (( MSG_OUT, "Pixel[%.4d]: Y = %.4d - X = %.4d", ViPix, VPix.C.y, VPix.C.x )); + + } // End for + + + + err_retok (( ERR_OUT, "Ok" )); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqDecCheckFrCntOneMSis ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt8 PrintLvl, UInt32* PtErrNb ) +* : +* \brief : Check frame counter on one MSis = Check if it increases without missing codes 1 \n +* +* \param : Pt - Pointer to AcqDec +* +* \param : MSisId - Id of MSis 1 from which to print pixels +* +* \param : PritnLvl - Print level 0 = no, 1 = Final result, 2 = Each error, 3 = Print frame counter of all frames +* +* \param : PtErrNb - Pointer to an errors counter, set to NULL if not used +* +* +* \return : Error code +* : 1 - Frame counter error(s) +* : 0 - OK +* : < 0 - SW error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 28/05/2021 +* \date : Doc date : 28/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FAcqDecCheckFrCntOneMSis ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt8 PrintLvl, UInt32* PtErrNb ) { + + SInt32 VRet; + SInt32 VFrNb; + SInt32 ViFr; + UInt32 VFrCntBase; + UInt32 VFrCntExpected; + MIS1__TBtFrDecHead* VPtFrH; + SInt32 VErrCnt; + + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort Pt == NULL") ); + + err_retfail ( MSisId, (ERR_OUT,"Abort => MSisId = %d < 0", MSisId) ); + + if ( MSisId >= MIS1__BT_MAX_REAL_MSIS_NB_ACQ ) { + err_retfail ( -1, (ERR_OUT,"Abort => MSisId = %d out of range 0..%d", MSisId, MIS1__BT_MAX_REAL_MSIS_NB_ACQ - 1) ); + } + + + // Checking loop + + VPtFrH = &Pt->ResAAFrHead[MSisId][0]; // Get ptr on fr 0 + + VFrNb = Pt->ResAFrNb[MSisId]; + VFrCntBase = VPtFrH->FrCnt; + VFrCntExpected = VFrCntBase; + + VErrCnt = 0; + + for ( ViFr = 0; ViFr < VFrNb; ViFr++ ) { + + VPtFrH = &Pt->ResAAFrHead[MSisId][ViFr]; + + if ( VPtFrH->FrCnt != VFrCntExpected ) { + ++VErrCnt; + + if ( PrintLvl >= 2 ) { + msg (( MSG_OUT, "FrCnt error : AcqId[%.6d]MSisId[%d] FrId[%.6d] : FrCnt = %d <> Expected = %d", Pt->AcqId, MSisId, ViFr,VPtFrH->FrCnt, VFrCntExpected )); + } + + } + + else { + if ( PrintLvl == 3 ) { + msg (( MSG_OUT, "FrCnt : AcqId[%.6d]MSisId[%d] FrId[%.6d]: FrCnt = %d", Pt->AcqId, MSisId, ViFr, VPtFrH->FrCnt )); + } + } + + ++VFrCntExpected; + + } // End for ( ViFr ) + + // Prints + + if ( PrintLvl >= 1 ) { + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "Test FrCnt : AcqId[%.6d]MSisId[%d] on %d frames : %d errors", Pt->AcqId, MSisId, VFrNb, VErrCnt )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "" )); + } + + + // Returns result + + if ( PtErrNb != NULL ) { + *PtErrNb = VErrCnt; + } + + if ( VErrCnt > 0 ) { + return (1); + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_FAcqDecCheckFrCnt6MSis ( MIS1__TBtAcqDec* Pt, UInt8 PrintLvl, UInt32* PtErrNb ) +* : +* \brief : Check frame counter on 6 x MSis = Check if it increases without missing codes 1 \n +* +* \param : Pt - Pointer to AcqDec +* +* \param : PritnLvl - Print level 0 = no, 1 = Final result, 2 = Each error, 3 = Print frame counter of all frames +* +* \param : PtErrNb - Pointer to an errors counter, set to NULL if not used +* +* +* \return : Error code +* : 1 - Frame counter error(s) +* : 0 - OK +* : < 0 - SW error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 28/05/2021 +* \date : Doc date : 28/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + +SInt32 MIS1__BT_FAcqDecCheckFrCnt6MSis ( MIS1__TBtAcqDec* Pt, UInt8 PrintLvl, UInt32* PtErrNb ) { + + SInt32 VRet; + SInt32 VFrNb; + SInt32 ViFr; + SInt8 ViMSis; + UInt32 VFrCntBase; + UInt32 VFrCntExpected; + MIS1__TBtFrDecHead* VAPtFrH[MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; + SInt32 VErrCnt; + UInt8 VFrNbErr; + + + // Check param + + err_retnull ( Pt, (ERR_OUT,"Abort Pt == NULL") ); + + + // Get ptr on frames header + + for ( ViMSis = 0; ViMSis < MIS1__BT_MAX_REAL_MSIS_NB_ACQ; ViMSis++ ) { + VAPtFrH[ViMSis] = &Pt->ResAAFrHead[ViMSis][0]; // Get ptr on fr 0 + } + + + // Check if each MSis 1 contains the same frames nb + // Takes MSis no 0 as reference for frames nb + + VFrNb = Pt->ResAFrNb[0]; + + VFrNbErr = 0; + + for ( ViMSis = 1; ViMSis < MIS1__BT_MAX_REAL_MSIS_NB_ACQ; ViMSis++ ) { + + if ( Pt->ResAFrNb[ViMSis] != VFrNb ) { + ++VFrNbErr; + msg (( MSG_OUT, "FrNb difference AcqId[%.6d]MSisId[%d] = %d frames ", Pt->AcqId, ViMSis, Pt->ResAFrNb[ViMSis] )); + } + + } + + if ( VFrNbErr > 0 ) { + msg (( MSG_OUT, "FrNb difference AcqId[%.6d]MSisId[0] = %d frames ", Pt->AcqId, Pt->ResAFrNb[0] )); + msg (( MSG_OUT, "Error : Some MSis 1 have different frames nb !" )); + return (1); + } + + + // Take MSis 0 FrCnt as reference + + + VFrCntBase = VAPtFrH[0]->FrCnt; + VFrCntExpected = VFrCntBase; + + // Checking loop + + VErrCnt = 0; + + for ( ViFr = 0; ViFr < VFrNb; ViFr++ ) { + + for ( ViMSis = 0; ViMSis < MIS1__BT_MAX_REAL_MSIS_NB_ACQ; ViMSis++ ) { + + VAPtFrH[ViMSis] = &Pt->ResAAFrHead[ViMSis][ViFr]; + + if ( VAPtFrH[ViMSis]->FrCnt != VFrCntExpected ) { + + ++VErrCnt; + + if ( PrintLvl >= 2 ) { + msg (( MSG_OUT, "FrCnt error : AcqId[%.6d]MSisId[%d] FrId[%.6d] : FrCnt = %d <> Expected = %d", Pt->AcqId, ViMSis, ViFr, VAPtFrH[ViMSis]->FrCnt, VFrCntExpected )); + } + + } + + } // End for ( ViMSis ) + + + if ( PrintLvl == 3 ) { + msg (( MSG_OUT, "FrCnt : AcqId[%.6d] FrId[%.6d] : 0 = %.6d, 1 = %.6d, 2 = %.6d, 3 = %.6d, 4 = %.6d, 5 = %.6d", Pt->AcqId, ViFr, VAPtFrH[0]->FrCnt, VAPtFrH[1]->FrCnt, VAPtFrH[2]->FrCnt, VAPtFrH[3]->FrCnt, VAPtFrH[4]->FrCnt, VAPtFrH[5]->FrCnt )); + } + + ++VFrCntExpected; + + } // End for ( ViFr ) + + // Prints + + if ( PrintLvl >= 1 ) { + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "Test FrCnt : AcqId[%.6d] on %d frames : %d errors", Pt->AcqId, VFrNb, VErrCnt )); + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, "" )); + } + + + // Returns result + + if ( PtErrNb != NULL ) { + *PtErrNb = VErrCnt; + } + + if ( VErrCnt > 0 ) { + return (1); + } + + return (0); +} + + + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_F +* : +* \brief : \n +* : \n +* : +* \param : - +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/** +=================================================================================== +* \fn : SInt32 MIS1__BT_F +* : +* \brief : \n +* : \n +* : +* \param : - +* : +* : +* \return : Error code +* : 0 - OK +* : < 0 - Error +* : +* \warning : Globals : +* \warning : Remark : +* \warning : Level : +* : +* \warning : Items not filled now : +* todo : +* : +* bug : +* : +* \date : Date : 22/05/2021 +* \date : Doc date : 18/05/2021 +* \author : Name : Gilles CLAUS +* \author : E-mail : gilles.claus@iphc.cnrs.fr +* \author : Labo : IPHC +* +=================================================================================== +*/ +/* DOC_FUNC_END */ + + + +#endif + + + diff --git a/include/mimo_daq_lib/msis1_data.def b/include/mimo_daq_lib/msis1_data.def new file mode 100644 index 0000000..ed40e9f --- /dev/null +++ b/include/mimo_daq_lib/msis1_data.def @@ -0,0 +1,799 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\lib\com\maps\msis1\data\msis1_data.def +* \brief Goal : Macros definition of Mimosis 1 lib +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 03/05/2019 +* \date File date : 03/05/2019 +* \date Doc date : 03/05/2019 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IPHC 23 Rue du Loess 67037 STYRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + +#ifndef MIMOSIS1_DEF +#define MIMOSIS1_DEF + + + + +// =================================================================================== +// * Simple / short macros (comment not processed by DOXYGEN) +// * +// =================================================================================== + +// =================================================================================== +// * \brief general data stream macros +// * +// =================================================================================== + + +/** +=================================================================================== +* \def MIS1__CC_DATA_FORMAT_SINCE_V211 +* +* \brief Must be define for DAQ SW version >= 211, undefined otherwise \n +* \brief It must be specified in DAQ and run file reader applications \n +* \brief \n +* \brief It is a bit complicated to explain ... \n +* \brief \n +* \brief DAQ versions <= 210 use DAQ MSis 1 (X:\lib\win\daq_mimosis1) for buffers \n +* \brief handling and data saving on disk. But this lib is designed for buffers size \n +* \brief specified in W64, if it is not an integer W64 number, data saving to disk \n +* \brief will be corrupted. It is not a problem for RAW data which are N x W128, but \n +* \brief for processed data, like DEC format. This problem has beend etected during \n +* \brief DAQ app dev, in order to test DAQ, the record MIS1__TPixXY, MIS1__TDecFrPixHeader \n +* \brief sizes have been adjusted to be an integer W64 number (fields size, padding) \n * \brief +* \brief this configuration is used if MIS1__CC_DATA_FORMAT_SINCE_V211 is DISABLED +* \brief +* \brief DAQ versions >= 211 solve this problem by using a new library buffers files \n * \brief +* \brief (X:\lib\com\buffers_files) whihc handles buffers, files as W8, this configuration \n +* \brief is used if MIS1__CC_DATA_FORMAT_SINCE_V211 is ENABLED +* \brief +* \brief +* +* G.CLAUS 15/06/2020 +* +=================================================================================== +*/ + + +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// WARNING : This CC directive must be defined in applications app.def file, NOT HERE +// It is here - in commnet - to remeber you that it MUST be defined or NOT in applications +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// +// #define MIS1__CC_DATA_FORMAT_SINCE_V211 /*! Must be set or not in function of DAQ app version */ +// +// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + +/** +=================================================================================== +* \def MIS1_DEF_ERR_LOG_FILE +* +* \brief Default errors log file name +* +* G.CLAUS 01/07/2020 +* +=================================================================================== +*/ + +#define MIS1_DEF_ERR_LOG_FILE "c:/tmp/msis1_data_err.txt" + + +/** +=================================================================================== +* \def MIS1_DEF_LOG_LVL_ERRORS +* +* \brief Default errors log level +* +* G.CLAUS 01/07/2020 +* +=================================================================================== +*/ + +#define MIS1_DEF_LOG_LVL_ERRORS ERR_LOG_LVL_WARNINGS_ERRORS + + +/** +=================================================================================== +* \def MIS1__MAX_WARN_ERR_REC +* +* \brief Mimosis 1 maximum error / warnign record nb +* +* G.CLAUS 24/02/2021 +* +=================================================================================== +*/ + + +#define MIS1__MAX_WARN_ERR_REC 1000 + + +/** +=================================================================================== +* \def MIS1__MAX_OUT_NB +* +* \brief Mimosis 1 maximum outputs number = 8 +* +* G.CLAUS 14/11/2019 +* +=================================================================================== +*/ + +#define MIS1__MAX_OUT_NB 8 /*! Mimosis 1 maximum outputs number */ + + +/** +=================================================================================== +* \def MIS1__MAT_NB +* +* \brief Mimosis 1 matices nb = 8 +* +* G.CLAUS 14/05/021 +* +=================================================================================== +*/ + +#define MIS1__MAT_NB 4 /*! Mimosis 1 matices nb = 8 */ + + + +/** +=================================================================================== +* \def MIS1__COL_NB +* +* \brief Mimosis 1 columns number = 1024 +* +* G.CLAUS 14/05/2019 +* +=================================================================================== +*/ + +#define MIS1__COL_NB 1024 /*! Mimosis 1 columns number */ + + +//// + +/** +=================================================================================== +* \def MIS1__COL_PER_PE +* +* \brief Mimosis 1 columns number per priority encoder = 2 +* +* G.CLAUS 29/05/2019 +* +=================================================================================== +*/ + +#define MIS1__COL_PER_PE 2 /*! Mimosis 1 columns number per priority encoder */ + + +/** +=================================================================================== +* \def MIS1__STR_COL_LIST_MAX_SZ +* +* \brief Maximum length of string used to print columns list or pixels stateof one line +* +* G.CLAUS 23/05/2019 +* +=================================================================================== +*/ + +#define MIS1__STR_COL_LIST_MAX_SZ (MIS1__COL_NB * 15) /*! Maw lenght of columns list string */ + + +/** +=================================================================================== +* \def MIS1__ROW_NB +* +* \brief Mimosis 1 rows number = 504 +* +* G.CLAUS 14/05/2019 +* +=================================================================================== +*/ + +#define MIS1__ROW_NB 504 /*! Mimosis 1 rows number */ + + +/** +=================================================================================== +* \def MIS1__ROW_NB +* +* \brief Mimosis 1 pixels number = 1024 * 504 = 516 096 +* +* G.CLAUS 22/05/2019 +* +=================================================================================== +*/ + +#define MIS1__PIX_NB (MIS1__COL_NB * MIS1__ROW_NB) /*! Mimosis 1 pixels number */ + + +/** +=================================================================================== +* \def MIS1__PE_NB +* +* \brief Mimosis 1 PE total number for the whole matrix +* +* G.CLAUS 22/05/2019 +* +=================================================================================== +*/ + +#define MIS1__PE_NB (MIS1__COL_NB / 2) /*! Mimosis 1 PE total number */ + + +/** +=================================================================================== +* \def MIS1__PE_PER_REG +* +* \brief Mimosis 1 PE number per region = 8 +* +* G.CLAUS 14/05/2019 +* +=================================================================================== +*/ + +#define MIS1__PE_PER_REG 8 /*! Mimosis 1 PE number per region */ + + +/** +=================================================================================== +* \def MIS1__PE_PER_SREG +* +* \brief Mimosis 1 PE number per super region = 32 +* +* G.CLAUS 22/05/2019 +* +=================================================================================== +*/ + +#define MIS1__PE_PER_SREG (MIS1__PE_PER_REG * 4) /*! Mimosis 1 PE number per super region */ + +/** +=================================================================================== +* \def MIS1__COL_PER_REG +* +* \brief Mimosis 1 columns number per region = 16 +* +* G.CLAUS 29/05/2019 +* +=================================================================================== +*/ + +#define MIS1__COL_PER_REG 16 /*! Mimosis 1 columns number per region */ + + +/** +=================================================================================== +* \def MIS1__COL_PER_SREG +* +* \brief Mimosis 1 columns number per super region = 64 +* +* G.CLAUS 29/05/2019 +* +=================================================================================== +*/ + +#define MIS1__COL_PER_SREG 64 /*! Mimosis 1 columns number per region */ + + +/** +=================================================================================== +* \def MIS1__DS_MAX_REGION_NB +* +* \brief Maximum region nb in data stream, known value on 07/05/2019 is 64 +* +* It is used to define the size of the pointer array on the regions + data blocs +* contained in one frame. One frame mean data stream between header and trailer +* it can be longer than Mimosis frame readout time = 5 us. +* +* G.CLAUS 07/05/2019 +* +=================================================================================== +*/ + +#define MIS1__DS_MAX_REGION_NB 64 /*! Maximum region nb in data stream / */ + +/** +=================================================================================== +* \def MIS1__DS_FR_HEADER_SZ_W16 +* +* \brief Frame header size in W16 fields units, known value on 07/05/2019 is 8 +* +* It idefines the array field size of the frame header union +* +* G.CLAUS 07/05/2019 +* +=================================================================================== +*/ + +#define MIS1__DS_FR_HEADER_SZ_W16 8 + +/** +=================================================================================== +* \def MIS1__DS_REG_HEADER_SZ_W16 +* +* \brief Region header size in W16 fields units, known value on 07/05/2019 is 2 +* +* It idefines the array field size of the region header union +* +* G.CLAUS 07/05/2019 +* +=================================================================================== +*/ + +// #define MIS1__DS_REG_HEADER_SZ_W16 2 // Seems to be not needed, regsion header sz = 1 W16 + + + +/** +=================================================================================== +* \def MIS1__DS_TOT_FRAME_SZ_W128 +* +* \brief Maximum size in W128 of one frame (header, data, iddle, checksum, trailer) +* +* G.CLAUS 02/07/2019 +* +=================================================================================== +*/ + +// #define MIS1__DS_TOT_FRAME_SZ_W128 (100 * 8) + +// 02/06/2020 - Increase max frame length, following discussion with FM +// +// Max 5 us frame size = 100 W128 +// Data frame can run over 8 x 5 us frames => x 8 +// x 8 has to be checked with FM later + +// 17/07/2020 +// Set again max frame length to 100 W128 and not 800 W128 because +// - DAQ FW doesn't work if block size read by sw < 256 W64, therefore in case of small +// frame length (few data), fr nb / acq must be increased, and this is not possible max fr size +// = 800 W128 because buffers allocation will fail. +// - Max frame size = 100 W128 allows for ~ 800 pixels / frame, which in enough for tests + +#define MIS1__DS_TOT_FRAME_SZ_W128 100 + + +/** +=================================================================================== +* \def MIS1__DS_TOT_FRAME_SZ_W64 +* +* \brief Maximum size in W64 of one frame (header, data, iddle, checksum, trailer) +* +* G.CLAUS 06/12/2019 +* +=================================================================================== +*/ + +#define MIS1__DS_TOT_FRAME_SZ_W64 MIS1__DS_TOT_FRAME_SZ_W128 * 2 + + +/** +=================================================================================== +* \def MIS1__DS_TOT_FRAME_SZ_W32 +* +* \brief Maximum size in W32 of one frame (header, data, iddle, checksum, trailer) +* +* G.CLAUS 06/12/2019 +* +=================================================================================== +*/ + +#define MIS1__DS_TOT_FRAME_SZ_W32 MIS1__DS_TOT_FRAME_SZ_W128 * 4 + + +/** +=================================================================================== +* \def MIS1__DS_TOT_FRAME_SZ_W16 +* +* \brief Maximum size in W16 of one frame (header, data, iddle, checksum, trailer) +* +* G.CLAUS 02/07/2019 +* +=================================================================================== +*/ + +#define MIS1__DS_TOT_FRAME_SZ_W16 MIS1__DS_TOT_FRAME_SZ_W128 * 8 + + +/** +=================================================================================== +* \def MIS1__FRAME_PIX_LIST_MAX_PIX_NB +* +* \brief Maximum number of pixels in MIS1__TFrPixList +* +* G.CLAUS 08/06/2020 +* +=================================================================================== +*/ + +#define MIS1__FRAME_PIX_LIST_MAX_PIX_NB 800 + + +/** +=================================================================================== +* \def MIS1__DS_TOT_FRAME_SZ_W8 +* +* \brief Maximum size in W8 of one frame (header, data, iddle, checksum, trailer) +* +* G.CLAUS 06/12/2019 +* +=================================================================================== +*/ + +#define MIS1__DS_TOT_FRAME_SZ_W8 MIS1__DS_TOT_FRAME_SZ_W128 * 16 + + +// =================================================================================== +// * Simple / short macros (comment not processed by DOXYGEN) +// * +// =================================================================================== + + +// =================================================================================== +// * \brief Macro tags to indentify the type of W16 in data stream +// * +// =================================================================================== + + +/** +=================================================================================== +* \enum MIS1__EDsTag +* +* \brief Tags to identify the type of W16 in data stream +* +* +* G.CLAUS 06/05/2019 +* +=================================================================================== +*/ + +typedef enum { + + MIS1__DS_TAG_EMPTY = 0XFCAA, /*!< Data stream word tag (b15b00) indicating an empty W16 */ + MIS1__DS_TAG_HEADER = 0XFE00, /*!< Data stream word tag (b15b08) indicating a header W16 */ + MIS1__DS_TAG_TRAILER = 0XFF00, /*!< Data stream word tag (b15b08) indicating a trailer W16 */ + MIS1__DS_TAG_REGION = 0XFD00, /*!< Data stream word tag (b15b08) indicating a region header w16 */ + MIS1__DS_TAG_SPARE_1 = 0XFC00, /*!< Data stream word tag (b15b08) indicating a spare W16 No 1 */ + MIS1__DS_TAG_SPARE_2 = 0XFD8, /*!< Data stream word tag (b15b07) indicating a spare W16 No 2 */ + +} MIS1__EDsTag; + + + +/** +=================================================================================== +* \def MIS1__ +* +* \brief Maximum size in W64 of one frame (header, data, iddle, checksum, trailer) +* +* G.CLAUS 09/04/2020 +* +=================================================================================== +*/ + +#define MIS1__MAX_W64_NB_PER_FR MIS1__DS_TOT_FRAME_SZ_W64 // Before 02/06/2020 =>200 + +#define MIS1__MAX_FR_NB_PER_ACQ 8100 // Before 26/02/21 => 1010, Before 02/06/2020 => 1010, before 17/07/2020 => 110 + +#define MIS1__MAX_BUFFERED_ACQ_NB 110 // Before 08/06/20 => 1000 03/06/2020 => Can be reduced if nedded, because max ~ 30-100 acq bufferised + +#define MIS1__MAX_W64_PER_ACQ (MIS1__MAX_FR_NB_PER_ACQ * MIS1__MAX_W64_NB_PER_FR) + + +/** +=================================================================================== +* \def MIS1__MAX_OUT_NB +* +* \brief Mimosis 1 maximum outputs number = 8 +* +* G.CLAUS 16/06/2020 +* +=================================================================================== +*/ + +#define MIS1__RUN_CONF_FFORMAT_TAG 0x5ABCDE00 /*! Conf file tag, low 8 bits = can be use for format version */ + +#define MIS1__RUN_STATUS_FFORMAT_TAG 0x1633CA00 /*! Status file tag, low 8 bits = can be use for format version */ + + +/** +=================================================================================== +* \def MIS1__MAX_RUN_FILES +* +* \brief Maximum number of TRunFiles items in MIS1__VGARunFile array +* +* G.CLAUS 25/05/2020 +* +=================================================================================== +*/ + +#define MIS1__MAX_RUN_FILES 10 + + +#define MIS1__MAX_OBUFF_PER_RUN_FILES 6 // Raw index and data + + +// =================================================================================== +// * Complex macros (comment not processed by DOXYGEN) +// * +// =================================================================================== + + +/** +=================================================================================== +* \def MIS1__MACRO_COMPLICATED_TO_EXPLAIN +* +* \brief Short macro explanation, must fit in one line +* +* Longer macro explaction, can take +* ... +* ... +* ... +* can take many lines +* +* G.CLAUS 11/04/2019 +* +=================================================================================== +*/ + + +#define MIS1__MACRO_COMPLICATED_TO_EXPLAIN 100 + +/** +=================================================================================== +* \def MIS1__CAR_MAX_STEP_NB +* +* \brief Maximum number of steps for characterization = nb of thresholds in a scan +* +* G.CLAUS 18/06/2020 +* +=================================================================================== +*/ + +#define MIS1__CAR_MAX_STEP_NB 60 // Before 16/11/2020 50 + + +/** +=================================================================================== +* \def MIS1__CAR_MAX_SUB_STEP_NB +* +* \brief Maximum number of sub steps for characterization, one sub step = one group \n +* of pixels selected (the whole matrix can't be selected at one time) +* +* G.CLAUS 18/06/2020 +* +=================================================================================== +*/ + +#define MIS1__CAR_MAX_SUB_STEP_NB 505 + + +/** +=================================================================================== +* \def MSIS1__CAR_NB_MAX_TH_REG +* +* \brief Maximum number of bias registers to configure one step of threshol scan +* +* G.CLAUS 18/06/2020 +* +=================================================================================== +*/ + +#define MSIS1__CAR_NB_MAX_BIAS_REG 4 + + +/** +=================================================================================== +* \def MIS1__CAR_MSIS1_MAX_REG_NB +* +* \brief Maximum number of MSis1 registers (DAC, etc), stored for each characterization step \n +* DAC nb = 15 + 2 pulse length = 17 => Use 32 regsitsers +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +#define MIS1__CAR_MSIS1_MAX_REG_NB 32 + + + +/** +=================================================================================== +* \def MIS1__CAR_MSIS1_MAX_SCAN_PAR_NB +* +* \brief Maximum number of MSis1 scannning parameters, set to 6 +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +#define MIS1__CAR_MSIS1_MAX_SCAN_PAR_NB 6 + + +/** +=================================================================================== +* \def MIS1__WE_MAX_MSIS_NB +* +* \brief Maximum number of MSis1 for MIS1__TCCarWarnErr class +* +* G.CLAUS 26/02/2021 +* +=================================================================================== +*/ + +#define MIS1__WE_MAX_MSIS_NB 6 + +/** +=================================================================================== +* \enum MIS1__EWarnErr +* +* \brief Tags to identify warnign, errors +* +* +* G.CLAUS 26/02/2021 +* +=================================================================================== +*/ + +typedef enum { + + MIS1__WE_RECORD_EMPTY, /*!< Record is empty = not used */ + MIS1__WE_SW_ERR, /*!< SW acq truncated */ + MIS1__WE_SW_REG_OVF, /*!< SW region overflow */ + MIS1__WE_SW_ACQ_TRUNC, /*!< SW acq truncated */ + MIS1__WE_MSIS_FR_OVF, /*!< MSis 1 frame overflow (flags bits of trailer field) */ + MIS1__WE_NB + +} MIS1__EWarnErr; + + +/** +=================================================================================== +* \def MIS1__CAR_MSIS1_MAX_SCAN_PAR_NB +* +* \brief Maximum number of MSis1 scannning parameters, set to 6 +* +* G.CLAUS 26/02/2021 +* +=================================================================================== +*/ + +#define MIS1__MAX_CAR_WARN_ERR_NB 10000 + + + +// =================================================================================== +// COnstant for MSis 1 beam tests +// +// +// +// G.CLAUS 21/05/2021 +// +// =================================================================================== + + + +#ifndef MIS1__TBtRunRead_DEF_ERR_LOG_FILE + #define MIS1__TBtRunRead_DEF_ERR_LOG_FILE "C:/iphc/C4PI/sw/log/err_MIS1__TBtRunRead.txt" // 21/05/2021 +#endif + +//#ifndef MIS1__TBtRunRead_DEF_MSG_LOG_FILE +// #define MIS1__TBtRunRead_DEF_MSG_LOG_FILE "C:/iphc/C4PI/sw/log/msg_MIS1__TBtRunRead.txt" // 21/05/2021 +//#endif + + +#define MIS1__BT_REC_TAG_BEGIN 0x66778800 // Record beginning tag = first W32 of a record + // 0x667788 = fixed part + // 00 = Data format version, OR done with function parameter => LET IT TO 00 in MIS1__BT_REC_TAG_BEGIN !!! + +#define MIS1__BT_REC_TAG_ENDIAN 0x11223344 // Record endian tag = Secoond W32 of a record, if used + + +#define MIS1__BT_MAX_ACQ_PER_FILE 120 + + +// File format version + +#define MIS1__BT_RUN_CONF_FILE_FORMAT 1 // Run conf file format version + +#define MIS1__BT_RUN_RD_FILE_FORMAT 1 // Run RD = Raw Data, file format version +#define MIS1__BT_RUN_RDI_FILE_FORMAT 1 // Run RDI = Raw Data Index, file format version + +#define MIS1__BT_RUN_TD_FILE_FORMAT 1 // Run TD = Trigger Data, file format version +#define MIS1__BT_RUN_TDI_FILE_FORMAT 1 // Run TDI = Trigger Data Index, file format version + + +#define MIS1__BT_SUP_FRAME_FACTOR 8 // Super frame multiplicator or factor, one frame can bu up to MIS1__BT_SUP_FRAME_FACTOR normal frame size + +#define MIS1__BT_TOT_FRAME_SZ_W128 (25 * MIS1__BT_SUP_FRAME_FACTOR) // 100 W16 / OUT x 2 OUT = 200 W16 = 25 W128 to be checked !!! // 31/05/2021 => X 8 + +#define MIS1__BT_TOT_FRAME_SZ_W64 (MIS1__BT_TOT_FRAME_SZ_W128 * 2) +#define MIS1__BT_TOT_FRAME_SZ_W32 (MIS1__BT_TOT_FRAME_SZ_W128 * 4) +#define MIS1__BT_TOT_FRAME_SZ_W16 (MIS1__BT_TOT_FRAME_SZ_W128 * 8) +#define MIS1__BT_TOT_FRAME_SZ_W8 (MIS1__BT_TOT_FRAME_SZ_W128 * 16) + + +#define MIS1__BT_MAX_MSIS_NB_ACQ 8 + +#define MIS1__BT_MAX_REAL_MSIS_NB_ACQ 6 + + + +#define MIS1__BT_MAX_TRIG_NB_PER_ACQ 4095 + +// Fixed Record Size (FRS) parameters + +#define MIS1__BT_FRS_MAX_FR_NB_PER_ACQ 1000 // Max allowed = 3000, more => linker bug, static structure too big + +#define MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W8 (MIS1__BT_MAX_MSIS_NB_ACQ * MIS1__BT_FRS_MAX_FR_NB_PER_ACQ * MIS1__BT_TOT_FRAME_SZ_W8) + +#define MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W16 (MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W8 / 2) + +#define MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W32 (MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W8 / 4) + +#define MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W64 (MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W8 / 8) + + +// Variable Record Size Size (VRS) parameters + + +#define MIS1__BT_VRS_MAX_FR_NB_PER_ACQ 6000 // 7000 // 10000 + +#define MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W8 (MIS1__BT_MAX_MSIS_NB_ACQ * MIS1__BT_VRS_MAX_FR_NB_PER_ACQ * MIS1__BT_TOT_FRAME_SZ_W8) + +#define MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W16 (MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W8 / 2) + +#define MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W32 (MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W8 / 4) + +#define MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W64 (MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W8 / 8) + + +// 24/05/2021 Decoded frames, acq + +#define MIS1__BT_FR_DEC_MAX_TRIG_NB 2 +#define MIS1__BT_FR_DEC_MAX_PIX_NB (200 * 8) // 2 out/MSis 1 => 2 x 100 = 200 W16 / MSis / fr => Max 200 pixels / fr + + +#define MIS1__TBtRunRead_CHECK_RET_S32 { \ + \ + if ( _RunConfLoaded < 1 ) { \ + err_retfail ( -1, (ERR_OUT,"Abort => No run loaded !") ); \ + } \ + \ + err_retfail ( _LastError, (ERR_OUT,"Abort => Due to previous error not cleared !") ); \ +} + + + +#define MIS1__TBtRunRead_CHECK_RET_NULL { \ +\ + if ( _RunConfLoaded < 1 ) { \ + err_retfailnull ( -1, (ERR_OUT,"Abort => No run loaded !") ); \ + } \ + \ + err_retfailnull ( _LastError, (ERR_OUT,"Abort => Due to previous error not cleared !") ); \ + } + + + + +#endif \ No newline at end of file diff --git a/include/mimo_daq_lib/msis1_data.typ b/include/mimo_daq_lib/msis1_data.typ new file mode 100644 index 0000000..c39468d --- /dev/null +++ b/include/mimo_daq_lib/msis1_data.typ @@ -0,0 +1,2800 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\lib\com\maps\msis1\data\msis1_data.typ +* \brief Goal : Types definition of Mimosis 1 lib +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 03/05/2019 +* \date File date : 03/05/2019 +* \date Doc date : 03/05/2019 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IPHC 23 Rue du Loess 67037 STYRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + + +#ifndef MIMOSIS1_DATA_TYP +#define MIMOSIS1_DATA_TYP + + + +/** +=================================================================================== +* \typedef MIS1__TMSis1DacList +* +* \brief Short explanation of typedef +* +* Also defined in app.typ => should be removed from app.typ +* ... +* ... +* ... +* can take many lines +* +* G.CLAUS 17/11/2020 +* +=================================================================================== +*/ + +typedef enum MIS1__EMSis1DacList { + + MIS1__DAC_IBIAS, /*!< */ + MIS1__DAC_ITHR, /*!< */ + MIS1__DAC_IDB, /*!< */ + MIS1__DAC_VRESET, /*!< */ + MIS1__DAC_VPL, /*!< */ + MIS1__DAC_VPH, /*!< */ + MIS1__DAC_VPH_FINE, /*!< */ + MIS1__DAC_VCASP, /*!< */ + MIS1__DAC_VCASNA, /*!< */ + MIS1__DAC_VCASNB, /*!< */ + MIS1__DAC_VCASNC, /*!< */ + MIS1__DAC_VCASND, /*!< */ + MIS1__DAC_VCASN2, /*!< */ + MIS1__DAC_VCLIP, /*!< */ + MIS1__DAC_IBUFBIAS, /*!< */ + MIS1__DAC_NB + +} MIS1__TMSis1DacList; + + + + +/** +=================================================================================== +* \struct MIS1__TFrameW128 +* +* \brief Contains one frame as N x W128 +* +* Longer C structure explanation +* ... +* ... +* ... +* can take many lines +* +* G.CLAUS 26/07/2019 +* +=================================================================================== +*/ + + +typedef struct { + + TW128As8W16 AW128[MIS1__DS_TOT_FRAME_SZ_W128]; /*!< Frame as an array of W128 */ + +} MIS1__TFrameW128; + + + +/** +=================================================================================== +* \struct MIS1__TDxErrCnt +* +* \brief Contains the data errors on each Dx (D0..D7), used by data checking functions +* +* +* G.CLAUS 14/11/2019 +* +=================================================================================== +*/ + + +typedef struct { + + SInt32 AErrCnt[MIS1__MAX_OUT_NB]; /*!< Frame as an array of W128 */ + +} MIS1__TDxErrCnt; + + + + +/** +=================================================================================== +* \union MIS1__TDsFrHeader +* +* \brief Data stream frame header +* +* \n - Fields W7 = W6 = W5 = W4 = 0xFE00, W3H = W2H = W1H = W0H = 0xFE +* \n - Frames counter can be built from fields FC0, FC1, FC2, FC3, FC0 = B0B7, FC1 = B24B31 +* +* G.CLAUS 07/05/2019 +* +=================================================================================== +*/ + +typedef union { + + UInt16 AW16[MIS1__DS_FR_HEADER_SZ_W16]; /*!< Frame header seen as an array of W16 */ + + struct + { + UInt8 FC0; /*!< Frame counter B00..B07, access via F.FC0 */ + UInt8 W0H; /*!< B08..B15 of W16 no 0 = LSW, access via F.W0H */ + + UInt8 FC1; /*!< Frame counter B08..B15, access via F.FC1 */ + UInt8 W1H; /*!< B08..B15 of W16 no 1 = LSW, access via F.W1H */ + + UInt8 FC2; /*!< Frame counter B16..B23, access via F.FC2 */ + UInt8 W2H; /*!< B08..B15 of W16 no 2 = LSW, access via F.W2H */ + + UInt8 FC3; /*!< Frame counter B24..B31, access via F.FC3 */ + UInt8 W3H; /*!< B08..B15 of W16 no 3 = LSW, access via F.W3H */ + + UInt16 W4; /*!< W16 no 4, access via F.W4 */ + UInt16 W5; /*!< W16 no 5, access via F.W5 */ + UInt16 W6; /*!< W16 no 6, access via F.W6 */ + UInt16 W7; /*!< W16 no 7, access via F.W7 */ + } F; + +} MIS1__TDsFrHeader; + + +/** +=================================================================================== +* \union MIS1__TDsRegHeader +* +* \brief Data stream region header +* +* +* G.CLAUS 07/05/2019 +* +=================================================================================== +*/ + +typedef union { + + // UInt16 AW16[MIS1__DS_REG_HEADER_SZ_W16]; /*!< Region header seen as an array of W16 */ + + UInt16 W16; /*!< Region header as one W16 */ + + struct + { + UInt16 Reg : 6; /*!< Region id, access via F.Reg */ + UInt16 Zero : 2; /*!< Two bits at 0, access via F.Zero */ + UInt16 Tag : 8; /*!< Region header tag = 0xFD, access via F.Tag */ + } F; + +} MIS1__TDsRegHeader; + + +/** +=================================================================================== +* \union MIS1__TDsPixData +* +* \brief Data stream checksun +* +* +* G.CLAUS 14/05/2019 +* +=================================================================================== +*/ + +typedef union { + + UInt16 W16; /*!< Pixels data as one W16 */ + + struct + { + UInt16 Code : 3; /*!< Code = state of 3 pixels following first one, access via F.Code*/ + UInt16 PeAddr : 3; /*!< Priority encoder address, access via F.PeAddr */ + UInt16 FirstPixAddr : 10; /*!< Address of first pixel 0..503 = No pixel, it is not the PE/pixelline ! \n access via F.FirstPixAddr */ + } F; + +} MIS1__TDsPixData; + + + + +/** +=================================================================================== +* \union MIS1__TStdPix +* +* \brief Short explanation of C union +* +* Longer C union explanation +* ... +* ... +* ... +* can take many lines +* +* G.CLAUS 25/05/2021 +* +=================================================================================== +*/ + +typedef union { + + UInt16 W16; /*!< Full word, access via w16 */ + + struct + { + UInt16 Code : 3; /*!< B00..B02 = Code, not used on MSis1, access via f.Code */ + UInt16 PeAddr : 3; /*!< B03..B05 = PE adddress, access via f.PeAddr */ + UInt16 PixAddr : 10; /*!< B06..B15 = Pixel address = row, access via f.PixAddr */ + } F; + + struct + { + UInt16 b0 : 1; /*!< Bit0, access via b.b0 */ + UInt16 b1 : 1; /*!< Bit1, access via b.b1 */ + UInt16 b2 : 1; /*!< Bit2, access via b.b2 */ + UInt16 b3 : 1; /*!< Bit3, access via b.b3 */ + UInt16 b4 : 1; /*!< Bit4, access via b.b4 */ + UInt16 b5 : 1; /*!< Bit5, access via b.b5 */ + UInt16 b6 : 1; /*!< Bit6, access via b.b6 */ + UInt16 b7 : 1; /*!< Bit7, access via b.b7 */ + UInt16 b8 : 1; /*!< Bit0, access via b.b8 */ + UInt16 b9 : 1; /*!< Bit1, access via b.b9 */ + UInt16 b10 : 1; /*!< Bit2, access via b.b10 */ + UInt16 b11 : 1; /*!< Bit3, access via b.b11 */ + UInt16 b12 : 1; /*!< Bit4, access via b.b12 */ + UInt16 b13 : 1; /*!< Bit5, access via b.b13 */ + UInt16 b14 : 1; /*!< Bit6, access via b.b14 */ + UInt16 b15 : 1; /*!< Bit7, access via b.b15 */ + } B; + + +} MIS1__TStdPix; + + + + + +/** +=================================================================================== +* \union MIS1__TDsCheckSum +* +* \brief Data stream checksun +* +* +* G.CLAUS 07/05/2019 +* +=================================================================================== +*/ + +typedef union { + + UInt16 W16; /*!< Checksum as one W16 */ + + struct + { + UInt16 Low : 8; /*!< Checksum low byte B0B7, access via W8.Low */ + UInt16 High : 8; /*!< Checksum high byte B8B15, access via W8.High */ + } W8; + +} MIS1__TDsCheckSum; + + + +/** +=================================================================================== +* \union MIS1__TDsFrTrailer +* +* \brief Data stream frame trailer +* +* +* G.CLAUS 07/05/2019 +* +=================================================================================== +*/ + +typedef union { + + UInt16 W16; /*!< Frame trailer seen as one W16 */ + + struct + { + UInt8 Flags : 8; /*!< Frame trailer flags, access via F.Flags */ + UInt8 Tag : 8; /*!< Frame trailer tag = 0xFF, access via F.Tag */ + } F; + + struct + { + UInt16 FrOvf : 1; /*!< Frameo verflow,access via B.FrOvf */ + UInt16 RegOvf : 1; /*!< Region overflow, access via B.RegOvf */ + UInt16 SRegOvf : 1; /*!< Super region overflow, access via B.SRegOvf */ + UInt16 FSLimit : 1; /*!< Frame size limit active, access via B.FSLimit */ + UInt16 Bit4 : 1; /*!< NU, access via B.Bit4 */ + UInt16 Bit5 : 1; /*!< NU, access via B.Bit5 */ + UInt16 Bit6 : 1; /*!< NU, access via B.Bit6 */ + UInt16 Bit7 : 1; /*!< NU, access via B.Bit7 */ + + UInt16 Bit8 : 1; /*!< Bit of tag field, access via B.Bit8 */ + UInt16 Bit9 : 1; /*!< Bit of tag field, access via B.Bit9 */ + UInt16 Bit10 : 1; /*!< Bit of tag field, access via B.Bit10 */ + UInt16 Bit11 : 1; /*!< Bit of tag field, access via B.Bit11 */ + UInt16 Bit12 : 1; /*!< Bit of tag field, access via B.Bit12 */ + UInt16 Bit13 : 1; /*!< Bit of tag field, access via B.Bit13 */ + UInt16 Bit14 : 1; /*!< Bit of tag field, access via B.Bit14 */ + UInt16 Bit15 : 1; /*!< Bit of tag field, access via B.Bit15 */ + + } B; + + +} MIS1__TDsFrTrailer; + + +/** +=================================================================================== +* \struct MIS1__TDsFrEwChkSumTrailer +* +* \brief Mimosis 1 data stream frame trailer = Empty words + Check sum + Trailer +* +* It contains +* \n - Frame information generated by HW, FW or SW +* \n -- HW = generated by Mimosis, like HwFrNo +* \n -- FW = generated by FW, like FwTimeStamp +* \n -- SW = generated by SW, like SwFrNo +* \n +* \n - Pointer on data stream fields +* +* G.CLAUS 06/05/2019 +* +=================================================================================== +*/ + + +typedef union { + + UInt16 AW16[8]; /*!< AW16[7] .. AW16[2] = Empty word = 0xFCAA, AW16[1] = Check sum, AW16[0] = Trailer = Flags */ + + struct { + + MIS1__TDsFrTrailer Trailer; /*!< Trailer = Flags */ + + MIS1__TDsCheckSum CheckSum; /*!< Checksum */ + + UInt16 AEmptyW16[6]; + + } F; + +} MIS1__TDsFrEwChkSumTrailer; + + + +typedef struct { + + UInt16 AW16[8]; /*!< AW16[7] .. AW16[2] = Empty word = 0xFCAA, AW16[1] = Check sum, AW16[0] = Trailer = Flags */ + + MIS1__TDsCheckSum CheckSum; /*!< Checksum */ + + MIS1__TDsFrTrailer Trailer; /*!< Trailer = Flags */ + +} MIS1__TDsFrEwChkSumTrailer___OLD; + + +/** +=================================================================================== +* \struct MIS1__TDsFr +* +* \brief Mimosis 1 data stream frame stucture +* +* It contains +* \n - Frame information generated by HW, FW or SW +* \n -- HW = generated by Mimosis, like HwFrNo +* \n -- FW = generated by FW, like FwTimeStamp +* \n -- SW = generated by SW, like SwFrNo +* \n +* \n - Pointer on data stream fields +* +* G.CLAUS 06/05/2019 +* +=================================================================================== +*/ + +typedef struct { + + void* PtPrevFr; /*!< Pointer on previous frame, should be casted to MIS1__TDsFr* */ + void* PtNextFr; /*!< Pointer on next frame, should be casted to MIS1__TDsFr* */ + + UInt32 SwDataSrc; /*!< Data source = No of Mimosis 1, etc, W32 available */ + UInt32 FwTimeStamp; /*!< Frame time stamp generated by FW, resolution to be defined <= 5 us (5 us => 238 days) */ + UInt32 HwFrNo; /*!< Index of the frame generated by Mimosis 1, starting at 0 */ + UInt32 SwFrNo; /*!< Index of the frame generated by SW, starting at 0 */ + + MIS1__TDsFrHeader* PtFrHead; /*!< Pointer on frame header */ + + MIS1__TDsRegHeader* APtRegHead[MIS1__DS_MAX_REGION_NB]; /*!< Array of pointers on regions headers */ + + UInt16* APtRegData[MIS1__DS_MAX_REGION_NB]; /*!< Array of pointers on regions data */ + + MIS1__TDsCheckSum* PtCheckSum; + + MIS1__TDsFrTrailer* PtFrTrailer; + +} MIS1__TDsFr; + + +// =================================================================================== +// * Mimosis 1 emulation (comment not processed by DOXYGEN) +// * +// =================================================================================== + + +/** +=================================================================================== +* \union MIS1__TPixXY +* +* \brief Mimosis 1 pixel coordinates union, mainly used for emulation +* +* +* G.CLAUS 22/05/2019 +* +=================================================================================== +*/ + + +#ifdef MIS1__CC_DATA_FORMAT_SINCE_V211 + + typedef union { + + SInt16 Axy[2]; /*!< Pixel coordinates array [0] = x, [1] = y */ + + struct { + SInt16 x; /*!< Pixel coordinates structure C.x, C.y */ + SInt16 y; + } C; + + } MIS1__TPixXY; + +#else + + typedef union { + + SInt32 Axy[2]; /*!< Pixel coordinates array [0] = x, [1] = y */ + + struct { + SInt32 x; /*!< Pixel coordinates structure C.x, C.y */ + SInt32 y; + } C; + + } MIS1__TPixXY; + + +#endif + +/** +=================================================================================== +* \struct MIS1__TDecFrPixHeader +* +* \brief Mimosis 1 frame fired pixels list +* +* +* G.CLAUS 08/06/2019 +* +=================================================================================== +*/ + +#ifdef MIS1__CC_DATA_FORMAT_SINCE_V211 + + typedef struct { + + UInt16 AcqIdInBuff; /*!< AcqId <= 65535 */ + UInt16 FrIdInBuff; /*!< FrId <= 65535 */ + UInt16 PixNb; /*!< Number of pixels */ + UInt32 MSis1FrCnt; /*!< Frame counter from MSis 1 */ + UInt16 MSis1ChkSum; /*!< Check sum from MSis 1 */ + UInt16 MSis1Flags; /*!< Flags from MSis 1 */ + + } MIS1__TDecFrPixHeader; + + +#else + + typedef struct { + + UInt16 AcqIdInBuff; /*!< AcqId <= 65535 */ + UInt16 FrIdInBuff; /*!< FrId <= 65535 */ + UInt16 PixNb; /*!< Number of pixels */ + UInt32 MSis1FrCnt; /*!< Frame counter from MSis 1 */ + UInt16 MSis1ChkSum; /*!< Check sum from MSis 1 */ + UInt16 MSis1Flags; /*!< Flags from MSis 1 */ + + UInt32 Padding1; + UInt32 Padding2; + + } MIS1__TDecFrPixHeader; + + +#endif + + +/** +=================================================================================== +* \struct MIS1__TDecFrPix +* +* \brief Mimosis 1 frame fired pixels list +* +* +* G.CLAUS 08/06/2019 +* +=================================================================================== +*/ + +typedef struct { + + MIS1__TDecFrPixHeader H; /*!< Header */ + + MIS1__TPixXY APix[MIS1__FRAME_PIX_LIST_MAX_PIX_NB]; /*!< List of pixels in each frame */ + +} MIS1__TDecFrPix; + + + + + + +/** +=================================================================================== +* \struct MIS1__TPixXYS +* +* \brief Mimosis 1 pixel coordinates + state struct, mainly used for emulation +* +* +* G.CLAUS 22/05/2019 +* +=================================================================================== +*/ + +typedef struct { + + MIS1__TPixXY PixXY; /*!< Pixel coordinates MIS1__TPixXY */ + + SInt32 PixState; /*!< Pixel state 0 / 1 or more (S32) => Can be used to count hits */ + +} MIS1__TPixXYS; + + +/** +=================================================================================== +* \struct MIS1__TPixXYSP +* +* \brief Mimosis 1 pixel coordinates + state + PE info struct, mainly used for emulation +* +* +* G.CLAUS 22/05/2019 +* +=================================================================================== +*/ + +typedef struct { + + MIS1__TPixXYS PixXYS; /*!< Pixel coordinates + state MIS1__TPixXYS */ + + SInt16 Region; /*!< Region No 0..63 */ + SInt16 SRegion; /*!< Super region No 0..15 */ + + SInt16 PeNoInMatrix; /*!< Priority encoder No in matrix => 0..MIS1__PE_NB-1 = 511 */ + SInt16 PeNoInRegion; /*!< Priority encoder No in region => 0..MIS1__PE_PER_REG-1 = 7 */ + SInt16 PeNoInSRegion; /*!< Priority encoder No in super region => 0..MIS1__PE_PER_SREG-1 = 31 */ + SInt16 PeRow; /*!< Priority encoder row => 0..MIS1__ROW_NB-1 = 503 */ + SInt16 PeAddr; /*!< Priority encoder addr */ + +} MIS1__TPixXYSP; + + +/** +=================================================================================== +* \typedef MIS1__TMatPixS32 +* +* \brief Mimosis 1 pixels matrix as bit (in fact SInt32) Mat[x,y], mainly used for emulation and plot +* +* +* G.CLAUS 22/05/2019 +* +=================================================================================== +*/ + +// Two types definition because src editor can't dectect "array typedef" + +typedef SInt32 MIS1__TTMatPixS32[MIS1__COL_NB][MIS1__ROW_NB] ; + +typedef MIS1__TTMatPixS32 MIS1__TMatPixS32; + + +/** +=================================================================================== +* \typedef MIS1__TMatPixFloat +* +* \brief Mimosis 1 pixels matrix as bit (in fact SInt32) Mat[x,y], mainly used for emulation and plot +* +* +* G.CLAUS 17/09/2020 +* +=================================================================================== +*/ + +// Two types definition because src editor can't dectect "array typedef" + +typedef float MIS1__TTMatPixFloat[MIS1__COL_NB][MIS1__ROW_NB] ; + +typedef MIS1__TTMatPixFloat MIS1__TMatPixFloat; + + + +/** +=================================================================================== +* \typedef MIS1__TMatScanFloat +* +* \brief Mimosis 1 +* +* +* G.CLAUS 30/09/2020 +* +=================================================================================== +*/ + +// Two types definition because src editor can't dectect "array typedef" + +typedef float MIS1__TTMatScanFloat[MIS1__COL_NB][MIS1__ROW_NB][MIS1__CAR_MAX_STEP_NB]; + +typedef MIS1__TTMatScanFloat MIS1__TMatScanFloat; + + + +/** +=================================================================================== +* \typedef MIS1__TRecResScanPar +* +* \brief Mimosis 1 +* +* +* G.CLAUS 24/11/2020 +* +=================================================================================== +*/ + + + +typedef struct { + + // ------------------------------- + // Parameters used for the scan + // ------------------------------- + + UInt32 ParFirstStep; // First val of scan reg in LSB + UInt32 ParLastStep; // Last val of scan reg in LSB + UInt32 ParStepNb; // Step nb of the scan + + UInt32 ParFrNb; + + UInt32 AParScanRegVal[MIS1__CAR_MAX_STEP_NB]; // 16/11/2020 + + UInt32 ParADac[MIS1__DAC_NB]; + + + char ParMatrixPulsed; // A, B, C, D + + UInt32 ParFirstRowPulsed; + UInt32 ParLastRowPulsed; + UInt32 ParFirstColPulsed; + UInt32 ParLastColPulsed; + + UInt32 ParRowNbPulsedTogether; // Nb of rows pulsed at the same time + + UInt32 ParPixPulseAA; + UInt32 ParPixPulseAB; + + + char ParScConfFile[GLB_FILE_PATH_SZ]; + + SInt8 ParFileFormat; // 0 => U16, 1 => S32 + + // ------------------------------- + // Parameters used for analysis + // ------------------------------- + + // Fired count in % used for calculation of AResScanRegValForLowPCent, AResScanRegValForHighPCent, AResScanRegValForMidPCent + // The results ScanRegValLow, Mid, High are used to find if scan has been done in good dynamic range or if s-curves are cut + + UInt32 ParLowPCent; + UInt32 ParMidPCent; + UInt32 ParHighPCent; + + + +} MIS1__TRecResScanPar; + + +/** +=================================================================================== +* \typedef MIS1__TRecResScanPar +* +* \brief Mimosis 1 +* +* +* G.CLAUS 24/11/2020 +* +=================================================================================== +*/ + + + +typedef struct { + + // ------------------------------- + // Results of scan + // ------------------------------- + + MIS1__TMatScanFloat ResMat; // Matrix with fired count in % for each step + + + float APCentMin [MIS1__COL_NB][MIS1__ROW_NB]; // Min value of % for each pixel, should be 0 % + float APCentMax [MIS1__COL_NB][MIS1__ROW_NB]; // Max value of % for each pixel, should be<= 100 % + + float AResScanRegValForLowPCent [MIS1__COL_NB][MIS1__ROW_NB]; // Scan parameter value for low fired count %, example for 10 % + float AResScanRegValForHighPCent[MIS1__COL_NB][MIS1__ROW_NB]; // Scan parameter value for high fired count %, example for 90 % + float AResScanRegValForMidPCent [MIS1__COL_NB][MIS1__ROW_NB]; // Scan parameter value for mid fired count %, example for 50 % + + +} MIS1__TRecResScanRes; + + +/** +=================================================================================== +* \typedef MIS1__TRecResScanPar +* +* \brief Mimosis 1 +* +* +* G.CLAUS XX/10/2020 +* +=================================================================================== +*/ + + +typedef struct { + + // WARNING => It is nor allowed to add fields here !!! + // + // if more fields are needed => add them in MIS1__TRecResScanPar or MIS1__TRecResScanRes + // + // because record can be saved as "P+R" or only "P" in order to save disk space if R (results) are not needed + + MIS1__TRecResScanPar P; // Run / scan parameters + MIS1__TRecResScanRes R; // Run / scan results : pixels % for each scan step, etc ... + + +} MIS1__TRecResScan; + + + +typedef struct { + + // ------------------------------- + // Parameters used for the scan + // ------------------------------- + + UInt32 ParFirstStep; + UInt32 ParLastStep; + UInt32 ParStepNb; + + UInt32 ParFrNb; + + UInt32 AParScanRegVal[MIS1__CAR_MAX_STEP_NB]; // 16/11/2020 + + UInt32 ParADac[MIS1__DAC_NB]; + + + char ParMatrixPulsed; // A, B, C, D + + UInt32 ParFirstRowPulsed; + UInt32 ParLastRowPulsed; + UInt32 ParFirstColPulsed; + UInt32 ParLastColPulsed; + + UInt32 ParPixPulseAA; + UInt32 ParPixPulseAB; + + + char ParScConfFile[GLB_FILE_PATH_SZ]; + + + + // ------------------------------- + // Parameters used for analysis + // ------------------------------- + + // Fired count in % used for calculation of AResScanRegValForLowPCent, AResScanRegValForHighPCent, AResScanRegValForMidPCent + // The results ScanRegValLow, Mid, High are used to find if scan has been done in good dynamic range or if s-curves are cut + + UInt32 ParLowPCent; + UInt32 ParMidPCent; + UInt32 ParHighPCent; + + // ------------------------------- + // Results of scan + // ------------------------------- + + MIS1__TMatScanFloat ResMat; // Matrix with fired count in % for each step + + + float APCentMin [MIS1__COL_NB][MIS1__ROW_NB]; // Min value of % for each pixel, should be 0 % + float APCentMax [MIS1__COL_NB][MIS1__ROW_NB]; // Max value of % for each pixel, should be<= 100 % + + float AResScanRegValForLowPCent [MIS1__COL_NB][MIS1__ROW_NB]; // Scan parameter value for low fired count %, example for 10 % + float AResScanRegValForHighPCent[MIS1__COL_NB][MIS1__ROW_NB]; // Scan parameter value for high fired count %, example for 90 % + float AResScanRegValForMidPCent [MIS1__COL_NB][MIS1__ROW_NB]; // Scan parameter value for mid fired count %, example for 50 % + + +} MIS1__TRecResScan__old; + + + +/** +=================================================================================== +* \typedef MIS1__TMatPixXYSP +* +* \brief Mimosis 1 pixels matrix MIS1__TMatPixXYSP, Mat[x,y], mainly used for emulation and plot +* +* +* G.CLAUS 22/05/2019 +* +=================================================================================== +*/ + +// Two types definition because src editor can't dectect "array typedef" + + +typedef MIS1__TPixXYSP MIS1__TTMatPixXYSP[MIS1__COL_NB][MIS1__ROW_NB]; + +typedef MIS1__TTMatPixXYSP MIS1__TMatPixXYSP; + + + +#ifndef CC_MSIS1_BDF_LIGHT + + +/** +=================================================================================== +* \typedef MIS1__TRecInfWarnErr +* +* \brief Mimosis 1 +* +* +* G.CLAUS 24/02/2021 +* +=================================================================================== +*/ + + + +typedef struct { + + SInt8 MSisId; + UInt32 RunId; + UInt32 AcqId; + UInt32 FrIdInAcq; + UInt16 StepId; + UInt16 SubStepId; + + UInt8 Type; // Warning, error type + // + // MIS1__WE_RECORD_EMPTY /*!< Record is emmpty = not used */ + // MIS1__WE_SW_ERR, /*!< SW error */ + // MIS1__WE_SW_REG_OVF, /*!< SW region overflow */ + // MIS1__WE_SW_ACQ_TRUNC, /*!< SW acq truncated */ + // MIS1__WE_MSIS_FR_OVF /*!< MSis 1 frame overflow (flags bits of trailer field) */ + + + + UInt32 MSisFrCnt; // MSis frame counter of the frame on which the OVF has occured + + SInt32 Cnt; // Warning, error counter + SInt32 Code; // Warning, error code + SInt32 Val; // Warning, error value + +} MIS1__TWarnErr; + + + +/** +=================================================================================== +* \typedef MIS1__TRecScanStatusHeader +* +* \brief Mimosis 1 +* +* +* G.CLAUS 24/02/2021 +* +=================================================================================== +*/ + + + +typedef struct { + + char Comment[GLB_CMT_SZ]; + + +} MIS1__TRecScanStatusHeader; + + +/** +=================================================================================== +* \typedef MIS1__TRecScanStatus +* +* \brief Mimosis 1 +* +* +* G.CLAUS 24/02/2021 +* +=================================================================================== +*/ + + + +typedef struct { + + MIS1__TRecScanStatusHeader; + + MIS1__TWarnErr AWarnErr[MIS1__MAX_WARN_ERR_REC]; + +} MIS1__TRecScanStatus; + + + +/** +=================================================================================== +* \typedef MIS1__TMatPixCntU16 +* +* \brief Mimosis 1 fired pixels count matrix +* +* +* G.CLAUS 03/06/2020 +* +=================================================================================== +*/ + +// Two types definition because src editor can't dectect "array typedef" + +typedef UInt16 MIS1__TTMatPixCntU16[MIS1__COL_NB][MIS1__ROW_NB]; + +typedef MIS1__TTMatPixCntU16 MIS1__TMatPixCntU16; + +/** +=================================================================================== +* \struct MIS1__TPe +* +* \brief Mimosis 1 priority encoder structure, mainly used for emulation +* +* +* G.CLAUS 14/05/2019 +* +=================================================================================== +*/ + +typedef struct { + + SInt8 AColLeft[MIS1__ROW_NB]; /*!< State (0/1) of pixels in left column of PE */ + SInt8 AColRight[MIS1__ROW_NB]; /*!< State (0/1) of pixels in right column of PE */ + +} MIS1__TPe; + + +/** +=================================================================================== +* \struct MIS1__TReg +* +* \brief Mimosis 1 region structure, mainly used for emulation +* +* +* G.CLAUS 14/05/2019 +* +=================================================================================== +*/ + +typedef union { + + MIS1__TPe APe[MIS1__PE_PER_REG]; /*!< Priority encodeurs array - 8 PE / region */ + + SInt8 AAPix[MIS1__COL_PER_REG][MIS1__ROW_NB]; /*!< Pixels array AAPix[x,y] */ + +} MIS1__TReg; + + + +// =================================================================================== +// * Union example (comment not processed by DOXYGEN) +// * +// =================================================================================== + + +/** +=================================================================================== +* \union MIS1__TU8Union +* +* \brief Short explanation of C union +* +* Longer C union explanation +* ... +* ... +* ... +* can take many lines +* +* G.CLAUS 11/04/2019 +* +=================================================================================== +*/ + +typedef union { + + UInt8 w8; /*!< Full byte, access via w8 */ + + struct + { + UInt8 b0 : 1; /*!< Bit0, access via b.b0 */ + UInt8 b1 : 1; /*!< Bit1, access via b.b1 */ + UInt8 b2 : 1; /*!< Bit2, access via b.b2 */ + UInt8 b3 : 1; /*!< Bit3, access via b.b3 */ + UInt8 b4 : 1; /*!< Bit4, access via b.b4 */ + UInt8 b5 : 1; /*!< Bit5, access via b.b5 */ + UInt8 b6 : 1; /*!< Bit6, access via b.b6 */ + UInt8 b7 : 1; /*!< Bit7, access via b.b7 */ + } b; + +} MIS1__TU8Union; + + +/** +=================================================================================== +* \typedef MIS1__TDsTag +* +* \brief Type MIS1__TDsTag = MIS1__EDsTag +* +* +* G.CLAUS 06/05/2019 +* +=================================================================================== +*/ + +typedef MIS1__EDsTag MIS1__TDsTag; + + +/** +=================================================================================== +* \typedef MIS1__TAcqFrList +* +* \brief Type MIS1__TAcqFrList = Acquisition frames pointers list +* +* +* G.CLAUS 08/04/2020 +* +=================================================================================== +*/ + +typedef struct { + + SInt32 ResAcqId; // Id of acquisition, field added on 12/05/2020 + UInt32 ResAcqSz; // Size of acquisition in W8, field added on 12/05/2020 + + // UInt16 ResFrNb; // Frames number calculated by frames listing operation, should be equal to VReqFrNbPerAcq requested by user + UInt32 ResFrNb; // 12/05/2020 UInt16 => UInt32 - Frames number calculated by frames listing operation, should be equal to VReqFrNbPerAcq requested by user + + void* ResPtAcqBeg; // Pointer on beginning of acq memory block + void* ResAPtFrHead[MIS1__MAX_FR_NB_PER_ACQ]; // Array of pointers on headers (available after frame listing execution) + void* ResAPtFrData[MIS1__MAX_FR_NB_PER_ACQ]; // Array of pointers on data parts (available after frame listing execution) + void* ResAPtFrTrail[MIS1__MAX_FR_NB_PER_ACQ]; // Array of pointers on trailers (available after frame listing execution) + +} MIS1__TAcqFrList; + + +/** +=================================================================================== +* \typedef MIS1__TAcqFrMap +* +* \brief Type MIS1__TAcqFrMap = Mapping of frames in one acq = offset in W8 / beginning +* +* +* G.CLAUS 08/04/2020 +* +=================================================================================== +*/ + + +typedef struct { + + SInt32 ResAcqId; // Id of acquisition, field added on 12/05/2020 + UInt32 ResAcqSz; // Size of acquisition in W8, field added on 12/05/2020 + + // UInt16 ResFrNb; // Frames number calculated by frames listing operation, should be equal to VReqFrNbPerAcq requested by user + UInt32 ResFrNb; // 12/05/2020 UInt16 => UInt32 - Frames number calculated by frames listing operation, should be equal to VReqFrNbPerAcq requested by user + + void* ResPtAcqBeg; // Pointer on beginning of acq memory block + + UInt32 ResAcqPos; // Position of Acq / Beginning of file in W8 + UInt32 ResAPosFrHead[MIS1__MAX_FR_NB_PER_ACQ]; // Array of headers position in W8 / beginning of Acq (available after frame listing execution) + UInt32 ResAPosFrData[MIS1__MAX_FR_NB_PER_ACQ]; // Array of data parts position in W8 / beginning of Acq (available after frame listing execution) + UInt32 ResAPosFrTrail[MIS1__MAX_FR_NB_PER_ACQ]; // Array of trailers position in W8 / beginning of Acq (available after frame listing execution) + +} MIS1__TAcqFrMap; + + + + +/** +=================================================================================== +* \typedef MIS1__TDecFrList +* +* \brief Type MIS1__TDecFrList = Decoded data frames list +* +* +* G.CLAUS 09/06/2020 +* +=================================================================================== +*/ + +typedef struct { + + SInt32 ResAcqIdInRun; // Id of acquisition + SInt16 ResFrNbInAcq; // Frames nb in the acq which contains this frame + SInt32 ResFrIdInAcq; // Id frame in its acquisition 0 to max fr nb per acq - 1 + UInt32 ResFrSz; // Size of frame in W8 + + void* ResPtFrBeg; + +} MIS1__TDecFrList; + + + + + +/** +=================================================================================== +* \typedef MIS1__TDecFrMap +* +* \brief Type MIS1__TDecFrMap = Decoded data frames mapping +* +* +* G.CLAUS 09/06/2020 +* +=================================================================================== +*/ + +typedef struct { + + SInt32 ResAcqIdInRun; // Id of acquisition + SInt16 ResFrNbInAcq; // Frames nb in the acq which contains this frame + SInt32 ResFrIdInAcq; // Id frame in its acquisition 0 to max fr nb per acq - 1 + UInt32 ResFrSz; // Size of frame in W8 + + void* ResPtFrBeg; + + UInt32 ResFrPos; // Position of fr / Beginning of file in W8 + +} MIS1__TDecFrMap; + + + + +/* ================================================== */ +/* 15/05/2020 moved from app.typ */ +/* 06/04/2020 definition in app.typ */ +/* ================================================== */ + + +// Enum for data processing mode + +typedef enum { + + PM_NONE, + PM_DECODE_FR, + PM_DECODE_FR_CNT_PIX, + PM_EMUL_DECODE_FR_DAQ_TEST, + PM_EMUL_DECODE_FR_FPC_DAQ_TEST, + PM_MODE_NB + +} MIS1__TProcMode; + + +/* ================================================== */ +/* 15/05/2020 moved from app.typ */ +/* 06/04/2020 definition in app.typ */ +/* ================================================== */ + + +// Enum for FPC saving mode mode +// WARNING => GUI control list must be in the same order as below + +typedef enum { + + MIS1__SFPC_NONE, + MIS1__SFPC_SUB_STEPS, + MIS1__SFPC_STEPS, + MIS1__SFPC_ALL, + MIS1__SFPC_NB + +} MIS1__TSaveFpc; + + + + +/* ================================================== */ +/* 15/05/2020 moved from app.typ */ +/* 06/04/2020 definition in app.typ */ +/* ================================================== */ + +// Run parameters + +typedef struct { + + + // -------------------------------------------------------------- + // File format, is here because it CAN'T be in MIS1__TRunConf + // -------------------------------------------------------------- + + UInt32 FileFormat; // MUST be equal to MIS1__RUN_CONF_FFORMAT_TAG + + // -------------------------------------------------------------- + // Run parameters + // -------------------------------------------------------------- + + SInt8 ParAllowRc; // Allow remote control, 0 => No, 1 => Yes + + // Most of fields have a clear name which doesn't need explanation + + UInt32 ParRunNo; + UInt32 ParTotFrNb; + UInt32 ParFrNbPerAcq; + UInt32 ParFrNbPerFile; // Field not used on 17/06/2020, set to 0 by GUI controls capture function + UInt32 ParAcqNbPerFile; + UInt32 ParBufferedAcqNb; + + // Processing mode + // - PM_NONE + // - PM_DECODE_FR + // - PM_DECODE_FR_CNT_PIX + // - PM_EMUL_DECODE_FR_DAQ_TEST + // - PM_EMUL_DECODE_FR_FPC_DAQ_TEST + + + MIS1__TProcMode ParProcMode; + + SInt8 ParProcPrintLvl; + + // Saving modes + + SInt8 ParSaveRaw; // Save raw data + SInt8 ParSaveDec; // Save decode data + SInt8 ParSaveFPC; // Save fired pixels count + + SInt8 ParDecFormat; // Decoded data format, only value 0 now = pixels list + + SInt8 ParProc; // Processing enabled = decode data, fired pixels count, etc ... + + SInt8 ParRunForever; // 0 => Run stops when TotFrNb is reached, + // 1 => Run continues after TotFrNb until "Stop Run" button is pressed + + char ParRunPrefix[GLB_FILE_PATH_SZ]; + char ParRunRootDir[GLB_FILE_PATH_SZ]; + + // -------------------------------------------------------------- + // Characterization parameters + // -------------------------------------------------------------- + + SInt8 ParCarMode; // Characterisation mode + // The hereafter parameters are used one if ParCarMode == 1 + // they are also hidden in MIS1__FRunParamInfPrint () if ParCarMode ==0 + // + // 0 => Normal run + // 1 => Characterization procedure + // - each file of a run corresponds to a characterization step + // - two modes + // - one file = scan of full matrix for one threshold, all sub steps are stored in the file + // this is the case for FPC data + // - one file = scan of a matrix fraction for one threshold, one sub step + // this is the case for RAW or DEC data + + + + SInt8 ParCarStepNb; // Number of pulse / threshold steps for the S curve scan + SInt16 ParCarSubStepNb; // Number of substep = measure of a fraction of the matrix ( max 800 pixels) + + SInt16 SubStepPixConfId; // Configuration used for pixels selection for characterization + + SInt16 ParCarSubStepFrNb; // Frames nb required to get "good results" = fr nb acquired for each sub step + // the values of ParSubStepAcqNb, ParFrNbPerAcq will be set to get ParCarSubStepFrNb + // with best efficiency + + SInt16 ParCarSubStepAcqNb; // Number of acq for each sub step, please read ParCarSubStepFrNb comment + SInt16 ParCarFrNbPerAcq; // Number of frames per acq, please read ParCarSubStepFrNb comment + + UInt16 ParCarPulsFirst; // First pulse level used for S curve scan + UInt16 ParCarPulsStep; // Pulse step level used for S curve scan + UInt16 ParCarPulsLast; // Last pulse level used for S curve scan + + + UInt16 ParCarAAStepBias [MIS1__CAR_MAX_STEP_NB][MSIS1__CAR_NB_MAX_BIAS_REG]; // Bias registers to configure for each thresholdscan step + + SInt16 ParCarSubStepConfId[MIS1__CAR_MAX_SUB_STEP_NB]; // Selected pixels configuration for each sun step + + + +} MIS1__TRunPar; + + + +/* ================================================== */ +/* 15/05/2020 moved from app.typ */ +/* 06/04/2020 definition in app.typ */ +/* ================================================== */ + +// Info variables for run, data taking, ... + +typedef struct { + + // Info, tmp variables, etc ... + + // -------------------------------------------------------------- + // Info + // -------------------------------------------------------------- + + SInt8 InfSave; // Data will be saved InfSave = ParSaveRaw || ParSaveDec || ParSaveFPC + + UInt32 InfSaveFileNo; + + char InfRunDir[GLB_FILE_PATH_SZ]; // Run directory = ParRunRootDir + "Run No" + char InfSCFileName[GLB_FILE_PATH_SZ]; // File path of slow control config file + char InfRunConfFileName[GLB_FILE_PATH_SZ]; // File path of run config file + char InfRunStatusFileName[GLB_FILE_PATH_SZ]; // File path of run status file + + char InfRawIndexFileName[GLB_FILE_PATH_SZ]; // File path of raw data index file + char InfRawDataFileName[GLB_FILE_PATH_SZ]; // File path of raw data file + + char InfDecIndexFileName[GLB_FILE_PATH_SZ]; // File path of decoded data file + char InfDecDataFileName[GLB_FILE_PATH_SZ]; // File path of decoded data file + + char InfFPCSubStepsFileName[GLB_FILE_PATH_SZ]; // File path of fired pixels count sub steps data file + char InfFPCStepFileName[GLB_FILE_PATH_SZ]; // File path of fired pixels count step data file + + char InfCurFPCSubStepsFileName[GLB_FILE_PATH_SZ]; // Current file path of fired pixels count sub steps data file + char InfCurFPCStepFileName[GLB_FILE_PATH_SZ]; // Current file path of fired pixels count step data file + +} MIS1__TRunInf; + + +/* ================================================== */ +/* 15/05/2020 moved from app.typ */ +/* 06/04/2020 definition in app.typ */ +/* ================================================== */ + +// Run status + +typedef struct { + + UInt32 FileFormat; // MUST be equal to MIS1__RUN_STATUS_FFORMAT_TAG + + SInt16 ParGuiUpdRate; // GUI update rate 1 acq each ParGuiUpdRate acq + + SInt8 ParUpdOnlyAcqErrCnt; // Update only acq and total errors counters + + SInt8 ParOptDaqSpeed; // For future use + + SInt8 ResRunInProgress; // Data taking is running, 0 => No, 1 => Yes + + UInt32 ResAcqCnt; // Acquisition counter + UInt32 ResFrCnt; // Frames counter, Rq : frame nb / acq is not constant + float ResAcqRateHz; // Acquisition rate Hz + float ResFrRateHz; // Frames rate Hz, mean value over ... ? + + float ResMSis1FrRateHz; // MSis1 frame rate Hz is MSis1 or emulator is in constant fr nb mode + // othervise this result is NA + + float ResDaqEffPCent; // DAQ efficiency = DAQ frame rate Hz / MSis1 frame rate Hz + // if MSis1 or emulator is in constant fr nb mode, otherwise NA + + UInt32 ResFrNbInCurAcq; // Frame number in current acquisition displayed in GUI + +} MIS1__TRunStatus; + + +/* ================================================== */ +/* 19/05/2020 */ +/* For run conf file */ +/* ================================================== */ + +// Run status + +typedef struct { + + // ---------------------------- WARNING ----------------------------- + // No field can be added or remove in this record + // ------------------------------------------------------------------ + // This record MUST contain the following fields, not less, not more + // - MIS1__TRunPar RunPar; + // - MIS1__TRunInf RunInf; + // ------------------------------------------------------------------ + // Because in DAQ app MIS1__TRunConf is not used, but two consecutive + // fields MIS1__TRunPar, MIS1__TRunInfand and a pointer cast on + // MIS1__TRunPar* as MIS1__TRunConf* to access ... + // Bad coding, not fixed due to lack of time + // ------------------------------------------------------------------ + + MIS1__TRunPar RunPar; + + MIS1__TRunInf RunInf; + +} MIS1__TRunConf; + + + +/* ================================================== */ +/* 19/05/2020 */ +/* Test file header */ +/* ================================================== */ + +typedef struct { + + UInt32 StepNb; + + // Etc ... + + +} MIS1__TTestFileHead; + + + +/* ================================================== */ +/* 19/05/2020 */ +/* Test file step */ +/* ================================================== */ + +typedef struct { + + char InfSCFileName[GLB_FILE_PATH_SZ]; // File path of slow control config file + + // Following fields will to be redefined when doc will be available + + UInt16 MatFirstLine; + UInt16 MatLinesNb; + + UInt16 Threshold; // Etc .. + + +} MIS1__TTestFileStep; + + + +/* ================================================== */ +/* 19/05/2020 */ +/* Test file trailer */ +/* ================================================== */ + +typedef struct { + + UInt32 TestErrors; + + // Etc ... + + +} MIS1__TTestFileTrail; + + +/** +=================================================================================== +* \typedef MIS1__TTMatPixSelPix +* +* \brief Mimosis 1 pixels select matrix for test, emul, mask pixels +* +* +* G.CLAUS 18/06/2020 +* +=================================================================================== +*/ + +// Two types definition because src editor can't dectect "array typedef" + +typedef UInt8 MIS1__TTMatPixSelPix[MIS1__COL_NB][MIS1__ROW_NB]; + +typedef MIS1__TTMatPixSelPix MIS1__TMatPixSelPix; + + + +/** +=================================================================================== +* \typedef MIS1__TAcqProc +* +* \brief Type MIS1__TAcqProc = Acq processing +* +* +* G.CLAUS 09/06/2020 +* +=================================================================================== +*/ + + + +typedef struct { + + UInt16 HeadPattern[8]; // Expected header pattern { W0, W1, W2, W3, W4, W5, W6, W7 } + // { 0xFE00, 0xFE00, 0xFE00, 0xFE00, 0xFE04, 0xFE05, 0xFE06, 0xFE07 }; + // B0B7 of W0 to W3 contains frames counter, W0_B0B7 = FrCnt_B0B7, W3_B0B7 = FrCnt_B24B31 + // Pattern "Vers1" set at initialization, pattern configured in GUI is captured late + + // MIS1__TAcqFrList* AAcqFrListRaw [MIS1__MAX_BUFFERED_ACQ_NB]; + + MIS1__TAcqFrList* AAcqFrListRaw; + MIS1__TAcqFrMap* AAcqFrMapRaw; + + MIS1__TDecFrList* AFrListDec; + MIS1__TDecFrMap* AFrMapDec; + + void* AAcqFrDecBuff; // Buffers for data decoding, allocated at beginning of run + + + // MIS1__TAcqFrPixList* AAcqFrPixList; // Pixels list in acq,fr + + MIS1__TDecFrPix* ADecFrPix; // Pixels list in each frame + + + MIS1__TMatPixCntU16* PtSubStepPixCnt; // Fired pixels count for each sub step, same array used for all sub steps of one step + + MIS1__TMatPixCntU16* PtStepPixCnt; // Fired pixels count for each step, same array used for all steps + + + // Pointer to others records in order to reduce processing functions parameters number + // Init is done by MIS1__FAcqProcInitPtrFields ( PtAcqProc, Pt + + MIS1__TRunPar* PtRunPar; + MIS1__TRunInf* PtRunInf; + MIS1__TRunStatus* PtRunStatus; + FIL__TCBinFile* PtOStepFile; + FIL__TCBinFile* PtOSubStepsFile; + + +} MIS1__TAcqProc; + + + + +/** +=================================================================================== +* \struct MIS1__TRunFiles +* +* \brief Record which contains all fields to access MSis 1 DAQ run files +* +* This record contains ... +* +* G.CLAUS 25/05/2020 +* +=================================================================================== +*/ + + + +typedef struct { + + SInt8 FBeginDone; + SInt8 FOpenDone; + + MIS1__TRunConf RunConf; /*!< Contains RunPar, RunInf */ + + // MIS1__TRunPar RunPar; /*!< */ + // MIS1__TRunInf RunInf; + + MIS1__TRunStatus RunStatus; /*!< Run status record */ + + UInt16 RawFBuffIndexId; /*!< Id of OBuff for raw data index file */ + UInt16 RawFBuffDataId; /*!< Id of OBuff for raw data index file */ + + UInt16 DecFBuffIndexId; /*!< Id of OBuff for raw data index file - 10/06/2020 */ + UInt16 FBuffDecDataId; /*!< Id of OBuff for raw data index file - 10/06/2020 */ + + UInt32 AcqMaxSzW64; /*!< Maximum size of one acq in W64 */ + UInt32 AcqMaxSzW8; /*!< Maximum size of one acq in W8 */ + + SInt32 RawLoadedFileSuffix; /*!< Raw data file loaded in memory, -1 if no file loaded */ + + SInt32 DecLoadedFileSuffix; /*!< Dec data file loaded in memory, -1 if no file loaded */ + + SInt32 FpcStepLoadedFileSuffix; /*!< Fpc step data file loaded in memory, -1 if no file loaded */ + + SInt32 FpcSubStepLoadedFileSuffix; /*!< Fpc sub step data file loaded in memory, -1 if no file loaded */ + + + // ------------------------------------------------------------- + // Current acq or frame + // Fields used to access one acquisition or one frames + // ------------------------------------------------------------- + + SInt32 RawCurAcqId; /*!< Set by MIS1__FRunFilesRawPrivFindAcq ( AcqId, ObjId ) = Acq to read, -1 if error */ + SInt32 RawCurFrId; /*!< Set by MIS1__FRunFilesRawPrivFindFr ( FrId, ObjId ) = Fr to read, -1 if error */ + + + SInt32 DecCurAcqId; /*!< Set by MIS1__FRunFilesDecPrivFindAcq ( AcqId, ObjId ) = Acq to read, -1 if error */ + SInt32 DecCurFrId; /*!< Set by MIS1__FRunFilesDecPrivFindFr ( FrId, ObjId ) = Fr to read, -1 if error */ + + + SInt32 RawCurAcqFileSuffix; /*!< Suffix of file containing the acq or fr, calculated by, -1 if error */ + /*!< MIS1__FRunFilesRawPrivFindAcq () or MIS1__FRunFilesRawPrivFindFr (), -1 if error */ + + SInt32 RawCurAcqIdInFile; /*!< Calculated but not used on 10/06/20, set by MIS1__FRunFilesRawPrivFindAcq ( AcqId, ObjId ) = Acq Id in file, -1 if error */ + + + SInt32 DecCurAcqFileSuffix; /*!< Suffix of file containing the acq or fr, calculated by, -1 if error */ + /*!< MIS1__FRunFilesDecPrivFindAcq () or MIS1__FRunFilesDecPrivFindFr (), -1 if error */ + + SInt32 DecCurAcqIdInFile; /*!< Set by MIS1__FRunFilesDecPrivFindAcq ( AcqId, ObjId ) = Acq Id in file, -1 if error */ + + + + MIS1__TAcqFrMap* PtFileRawFrMap; /*!< Pointer to RAW acq frames map records of cutrent file loaded */ + UInt8* PtAcqRawMem; /*!< Pointer first acq of current RAW file loaded */ + + MIS1__TDecFrMap* PtFileDecFrMap; /*!< Pointer to DEC frames map records of cutrent file loaded */ + UInt8* PtAcqDecMem; /*!< Pointer first acq of current DEC file loaded */ + + + MIS1__TAcqFrList CurAcqRawFrList; /*!< Frames list of current RAW acq */ + + MIS1__TDecFrList ACurAcqDecFrList[MIS1__MAX_FR_NB_PER_ACQ]; /*!< Frames list of current DEC acq */ + + // ------------------------------------------------------------- + // FPC fields + // + // ------------------------------------------------------------- + + SInt32 FpcCurStepId; /*!< Set by MIS1__FRunFilesFpcPrivFindStep ( StepId, ObjId ) = Step to read, -1 if error */ + + SInt32 FpcCurSubStepId; /*!< Set by MIS1__FRunFilesFpcPrivFindSubStep ( SubStepId, ObjId ) = Step to read, -1 if error */ + + SInt32 FpcCurStepFileSuffix; /*!< Suffix of file containing the step, calculated by, -1 if error */ + /*!< MIS1__FRunFilesFpcPrivFindStep () , -1 if error */ + + SInt32 FpcCurSubStepFileSuffix; /*!< Suffix of file containing the sub step, calculated by, -1 if error */ + /*!< MIS1__FRunFilesFpcPrivFindSubStep () , -1 if error */ + + MIS1__TMatPixCntU16 StepMatPixCnt; /*!< Step fired pixels counter matrix */ + + MIS1__TMatPixCntU16 SubStepMatPixCnt; /*!< Sub step fired pixels counter matrix */ + + FIL__TCBinFile* PtFPCSubStepsBinFile; + FIL__TCBinFile* PtFPCStepBinFile; + +} MIS1__TRunFiles; + + + + +/** +=================================================================================== +* \struct MIS1__TPulseParam +* +* \brief Pulse parameters ( A/D, length, 1f/n, etc ... it does not include test pixels coordinates ) +* +* This record contains ... +* +* G.CLAUS 27/10/2020 +* +=================================================================================== +*/ + +#define CC_DBG_021120 + +#ifdef CC_DBG_021120 + +typedef struct { + + UInt16 PixPulse_A ; // = 25; // default 2,5 us => 25 // 1 us => 25 + UInt16 PixPulse_B ; // = 75; // default 2,5 us => 75 // 1 us => 45 + UInt8 ResetMatrixBeforeSetting ; // = 1; + UInt8 StartChipAfterSetting ; // = 1; + UInt8 PulseMask ; // = 2; // 0 = Mask, 1 = Pulse_D, 2 = Pulse_A + UInt8 ModPulse ; // = APP__VGMSisPulseMode; // 3; // 0 = 1f/1, 1 = 1f/2, 2 = 1f/4, 3 = 1f/8, 4 = 1f/16, 5 = 1f/32, 6 = 1f/64, 7 = 1f/128 + +} MIS1__TPulseParam; + + +#else + +typedef struct { + + uint16_t PixPulse_A ; // = 25; // default 2,5 us => 25 // 1 us => 25 + uint16_t PixPulse_B ; // = 75; // default 2,5 us => 75 // 1 us => 45 + uint8_t ResetMatrixBeforeSetting ; // = 1; + uint8_t StartChipAfterSetting ; // = 1; + uint8_t PulseMask ; // = 2; // 0 = Mask, 1 = Pulse_D, 2 = Pulse_A + uint8_t ModPulse ; // = APP__VGMSisPulseMode; // 3; // 0 = 1f/1, 1 = 1f/2, 2 = 1f/4, 3 = 1f/8, 4 = 1f/16, 5 = 1f/32, 6 = 1f/64, 7 = 1f/128 + +} MIS1__TPulseParam; + + +#endif + + +/** +=================================================================================== +* \struct MIS1__TPixCoordRangeU16 +* +* \brief A range of pixels coordinates FirstCol, LastCol, FirstRow, LastRow, U16 => for minimum space ... +* +* This record contains ... +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +typedef struct { + + UInt16 ParFirstCol; + UInt16 ParLastCol; + UInt16 ParFirstRow; + UInt16 ParLastRow; + + UInt32 resPixNb; // Calculated from above parameters + +} MIS1__TPixCoordRangeU16; + + + +/** +=================================================================================== +* \struct MIS1__TPixCoordRangeU32 +* +* \brief A range of pixels coordinates FirstCol, LastCol, FirstRow, LastRow, U32 => for Python easy readout ... +* +* This record contains ... +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +typedef struct { + + UInt32 ParFirstCol; + UInt32 ParLastCol; + UInt32 ParFirstRow; + UInt32 ParLastRow; + + UInt32 ResPixNb; // Calculated from above parameters + +} MIS1__TPixCoordRangeU32; + + + +/** +=================================================================================== +* \struct MIS1__TSubStepPar +* +* \brief Sun step parameters +* +* This record contains ... +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +typedef struct { + + MIS1__TPixCoordRangeU32 Pixels; + +} MIS1__TSubStepPar; + + +/** +=================================================================================== +* \struct MIS1__TMSis1Reg +* +* \brief MSis 1 registers +* +* This record contains ... +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +typedef struct { + + UInt32 AReg[MIS1__CAR_MSIS1_MAX_REG_NB]; + + // ... + +} MIS1__TMSis1Reg; + + + +/** +=================================================================================== +* \struct MIS1__TMSis1ScanPar +* +* \brief SMSis 1 scan parameters +* +* This record contains ... +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +typedef struct { + + UInt32 AScanPar[MIS1__CAR_MSIS1_MAX_SCAN_PAR_NB]; + +} MIS1__TMSis1ScanPar; + + + +/** +=================================================================================== +* \struct MIS1__TStepPar +* +* \brief Sun step parameters +* +* This record contains ... +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +typedef struct { + + + char SCConfFile[GLB_FILE_PATH_SZ]; + + MIS1__TMSis1Reg Reg; + MIS1__TMSis1ScanPar ScanPar; + + +} MIS1__TStepPar; + + + + +/** +=================================================================================== +* \struct MIS1__TRunFilesLight +* +* \brief Record which contains all fields to access MSis 1 DAQ LIGHT run files +* +* This record contains ... +* +* G.CLAUS 07/10/2020 +* +=================================================================================== +*/ + +typedef struct { + + // Param + + UInt32 ParFormat; /*!< Data format version */ + char ParFormatStr[GLB_CMT_SZ]; /*!< Data format version in a human readable way */ + + UInt32 ParRunNo; /*!< Run number */ + UInt32 ParStepNb; /*!< Steps nb = scan param step nb */ + UInt32 ParSubStepNb; /*!< Sub steps nb = number of pixels groups needed to perform a step */ + + UInt32 ParSubStepMode; /*!< Sub step mode = how is configured each sub step */ + char ParSubStepModeStr[GLB_CMT_SZ]; /*!< Sub step mode string = how is configured each sub step */ + + UInt32 ParFrNb; /*!< Frame number used for each sustep / step */ + + MIS1__TStepPar ParASteps[MIS1__CAR_MAX_STEP_NB]; /*!< Parametrs of each step */ + MIS1__TSubStepPar ParASubSteps[MIS1__CAR_MAX_SUB_STEP_NB]; /*!< Parametrs of each sub step = pixels tested */ + + UInt32 ParSaveRaw; /*!< Save raw data for each sub steps */ + UInt32 ParSaveSubStepFpc; /*!< Save FPC for each sub step */ + UInt32 ParSaveStepFpc; /*!< Save FPC for each step */ + + + char ParRootDir[GLB_FILE_PATH_SZ]; // Ex : C:/tmp/iphc/msis1/res/ + + + // Inf + + char Dir[GLB_FILE_PATH_SZ]; // Ex : C:/tmp/iphc/msis1/res/run_0 + char DirData[GLB_FILE_PATH_SZ]; // Ex : C:/tmp/iphc/msis1/res/run_0/data + char DirTxt[GLB_FILE_PATH_SZ]; // Ex : C:/tmp/iphc/msis1/res/run_0/txt + char DirPlot[GLB_FILE_PATH_SZ]; // Ex : C:/tmp/iphc/msis1/res/run_0/plot + + // Files + + + char CurStepFileFpcBin[GLB_FILE_PATH_SZ]; + char CurSubStepsFileFpcBin[GLB_FILE_PATH_SZ]; + char CurSubStepsFileRawBin[GLB_FILE_PATH_SZ]; + + // Var + + UInt32 CurStepNo; + UInt32 CurSubStepNo; + + + +} MIS1__TRunCnfLight; + + + +/** +=================================================================================== +* \class APP__TCCarWarnErr +* +* \brief Characterization warnig or error listing object +* +* Longer C structure explanation +* ... +* ... +* ... +* can take many lines +* +* G.CLAUS 26/02/2021 +* +=================================================================================== +*/ + + + + +class MIS1__TCCarWarnErr { + + public: + + MIS1__TCCarWarnErr (); + ~MIS1__TCCarWarnErr (); + + + + SInt32 FChkMSisId ( SInt8 MSisId ); + + // General reset functions + + SInt32 FReset (); + SInt32 FResetList (); + + + // Reset total counters + + SInt32 FDaqSwErrRstTotCnt ( SInt8 MSisId ); + SInt32 FDaqSwRegOvfRstTotCnt ( SInt8 MSisId ); + SInt32 FDaqAcqTruncRstTotCnt ( SInt8 MSisId ); + SInt32 FMSisFrOvfRstTotCnt ( SInt8 MSisId ); + + SInt32 FRstAllTotCnt ( SInt8 MSisId ); + + // Get total counters + + SInt32 FDaqSwErrGetTotCnt ( SInt8 MSisId ); + SInt32 FDaqSwRegOvfGetTotCnt ( SInt8 MSisId ); + SInt32 FDaqAcqTruncGetTotCnt ( SInt8 MSisId ); + SInt32 FMSisFrOvfGetTotCnt ( SInt8 MSisId ); + + // Reset counters + + SInt32 FDaqSwErrRstCnt ( SInt8 MSisId ); + SInt32 FDaqSwRegOvfRstCnt ( SInt8 MSisId ); + SInt32 FDaqAcqTruncRstCnt ( SInt8 MSisId ); + SInt32 FMSisFrOvfRstCnt ( SInt8 MSisId ); + + SInt32 FRstAllCnt ( SInt8 MSisId ); + + // Get counters + + SInt32 FDaqSwErrGetCnt ( SInt8 MSisId ); + SInt32 FDaqSwRegOvfGetCnt ( SInt8 MSisId ); + SInt32 FDaqAcqTruncGetCnt ( SInt8 MSisId ); + UInt32 FMSisFrOvfGetCnt ( SInt8 MSisId ); + + + // Add errors to the list + + SInt32 FDaqErrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val, MIS1__EWarnErr ErrType ); + + SInt32 FDaqSwErrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ); + SInt32 FDaqSwRegOvfrAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ); + SInt32 FDaqAcqTruncAdd ( SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt32 FrId, UInt16 StepId, UInt16 SubStepId, UInt32 MSisFrCnt, SInt32 Code, SInt32 Val ); + + + SInt32 FAcqMSisFrOvfAdd ( SInt8 MSisId, UInt8 OvfFlags, UInt32 MSisFrCnt, UInt32 AcqFrId ); + SInt32 FAcqMSisFrOvfCount ( SInt8 List, SInt8 MSisId, UInt32 RunId, UInt32 AcqId, UInt16 StepId, UInt16 SubStepId, UInt32 AcqFrNb ); + + + + + + + + + UInt32 FAcqMSisFrOvfGetFlags ( SInt8 MSisId, UInt32 FrId ); + UInt32 FAcqMSisFrOvfGetFrCnt ( SInt8 MSisId, UInt32 FrId ); + + SInt32 FWarnErrGetNb (); + SInt32 FWarnErrGetNbTot (); + SInt32 FWarnErrPrint ( UInt32 First, UInt32 Nb, SInt8 PrintListHeader, SInt8 PrintDest, TMemo* Memo, FILE* PtFile ); + + + SInt32 FBinFileSave ( char* FileName ); + SInt32 FBinFileLoad ( char* FileName ); + + SInt32 FBinFileSave ( char* Directory, char* FileName ); + SInt32 FBinFileLoad ( char* Directory, char* FileName ); + + + private: + + // Functions + + SInt32 _FClearAcqTrailInfo ( SInt8 MSisId ); // Set to 0 ATrailFlags, ATrailFrCnt of MSisId + + + // Fields + + char CstWarnErrType2Str [MIS1__WE_NB][50]; + + + + + SInt8 ListIsFull; // Flag used to stop printing warning messages when list is fulkl + + UInt32 AWarnErrTotCnt[MIS1__WE_MAX_MSIS_NB][MIS1__WE_NB]; // Warning, errors total couters, one for each type of warning / error + // MIS1__WE_SW_ERR, /*!< SW acq truncated */ + // MIS1__WE_SW_REG_OVF, /*!< SW region overflow */ + // MIS1__WE_SW_ACQ_TRUNC, /*!< SW acq truncated */ + // MIS1__WE_MSIS_FR_OVF, /*!< MSis 1 frame overflow (flags bits of trailer field) */ + // MIS1__WE_NB + + + UInt32 AWarnErrCnt[MIS1__WE_MAX_MSIS_NB][MIS1__WE_NB]; // Warning, errors couters, one for each type of warning / error + // MIS1__WE_SW_ERR, /*!< SW acq truncated */ + // MIS1__WE_SW_REG_OVF, /*!< SW region overflow */ + // MIS1__WE_SW_ACQ_TRUNC, /*!< SW acq truncated */ + // MIS1__WE_MSIS_FR_OVF, /*!< MSis 1 frame overflow (flags bits of trailer field) */ + // MIS1__WE_NB + + + + UInt8 ATrailFlags[MIS1__WE_MAX_MSIS_NB][MIS1__MAX_FR_NB_PER_ACQ]; // Copie of MSis 1 OVF flags of all frames of current acq + UInt32 ATrailFrCnt[MIS1__WE_MAX_MSIS_NB][MIS1__MAX_FR_NB_PER_ACQ]; // Copie of MSis 1 frame counter of all frames of current acq + + + + // Data to be written to the binay file + // in the follwing order ! + + UInt32 SafetyTag; // To check if loaded file has been created by this class + + UInt32 DateVersion; // Format 0xDDMMYYVV, with VV = version, ex : 23/03/2021 version 1 => 0x23032101 + + SInt32 WarnErrCnt; // Cpt of warning /error = index of last record in AWarnErr, LIMITED to MIS1__MAX_CAR_WARN_ERR_NB maximum + + SInt32 WarnErrCntTot; // Total cpt of warning /error = NOT LIMITED to MIS1__MAX_CAR_WARN_ERR_NB + + MIS1__TWarnErr AWarnErr[MIS1__MAX_CAR_WARN_ERR_NB]; + + +}; + + +#endif + + +/** +=================================================================================== +* \struct MIS1__TAcqIds +* +* \brief Identifiers of one acq +* +* +* G.CLAUS 01/05/2021 +* +=================================================================================== +*/ + +typedef struct { + + SInt32 AcqIdInDaq; /*!< Acq id in DAQ, -1 if not used, squence can be 0, 2 , 3 if Trig < Min */ + SInt32 AcqIdInRun; /*!< Acq id in run, -1 if not used */ + SInt32 AcqIdInBuff; /*!< Acq id in memory buffer, -1 if not used */ + SInt32 AcqIdInFile; /*!< Acq id in file, -1 if not used */ + SInt32 FileId; /*!< No of the file which contains the acq, -1 if not used */ + + UInt32 TimeStamp1; /*!< Time stamp, TBD */ + UInt32 TimeStamp2; + + SInt32 DataType; /*!< Data organization */ + +} MIS1__TBtAcqIds; + + +/** +=================================================================================== +* \struct MIS1__TAcqRes +* +* \brief Results of one acq +* +* +* G.CLAUS 01/05/2021 +* +=================================================================================== +*/ + +typedef struct { + + SInt32 ErrNb; /*!< Errors number, -1 if not used */ + + SInt32 TrigNb; /*!< Triggers number, -1 if not used */ + SInt32 FrNb; /*!< Frames number, -1 if not used */ + SInt32 FrNbTruncated; /*!< Frames number truncated ( > sw buffer sz ), -1 if not used */ + SInt32 FrNbOvf; /*!< Frames number with Mimosis OVF, -1 if not used */ + SInt32 FrNbSwErr; /*!< Frames number with a DAQ sw error, -1 if not used */ + + SInt32 FrCnt[MIS1__BT_FRS_MAX_FR_NB_PER_ACQ][MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; /*!< Signed => can be set < 0 in case cnt are desynchronized , Max fr nb ~ 3 H */ + + // 14/05/2021 + + UInt32 FiredPixNb; /*!< Total fired pixels nb for ALL matrices */ + UInt32 AFiredPixNb[MIS1__BT_MAX_REAL_MSIS_NB_ACQ][MIS1__MAT_NB]; /*!< Fired pixels nb per matrice */ + +} MIS1__TBtAcqRes; + + + + +/** +=================================================================================== +* \struct MIS1__TTrigRec +* +* \brief MSis DAQ triggers infp +* +* +* G.CLAUS 01/05/2021 +* +=================================================================================== +*/ + +typedef struct { + + SInt32 TrigNb; /*!< Triggers number, -1 if not used, redundant with MIS1__TBtAcqRes.TrigNb */ + + // Triggers, TBD + + UInt32 ATrig[MIS1__BT_MAX_TRIG_NB_PER_ACQ]; + + +} MIS1__TBtTrigRec; + + +/** +=================================================================================== +* \struct MIS1__TTrigRec +* +* \brief MSis DAQ triggers infp +* +* +* G.CLAUS 01/05/2021 +* +=================================================================================== +*/ + +#ifndef CC_MIS1__TBtAcqRawRec_BEFORE_110521 + +typedef struct { + + UInt32 TagBeg; /*!< Record beginning tag = first W32 of a record, B7B0 = Data format version */ + + UInt32 Offset; /*!< Position in W8 of record / beginning of file */ + UInt32 FullRecSz; /*!< Effective size in W8 of the acq <= sizeof (MIS1__TAcqRec) */ + UInt32 DataSz; /*!< Effective size in W8 of the data part <= */ + + MIS1__TBtAcqIds Ids; + + MIS1__TBtTrigRec Trigs; + + MIS1__TBtAcqRes Res; // MUST BE THE LAST FIELD (because it could become a variable size record) + + UInt32 Padding1_W32; // Added for compilation under Linux on 19/05/2021 + +} MIS1__TBtAcqRawHead; + + +#endif + + + +/** +=================================================================================== +* \struct MIS1__TBtAcqRec +* +* \brief MSis DAQ triggers infp +* +* +* G.CLAUS 01/05/2021 +* +=================================================================================== +*/ + +typedef struct { + + +#ifdef CC_MIS1__TBtAcqRawRec_BEFORE_110521 + + struct { + + UInt32 FullRecSz; /*!< Effective size of the acq <= sizeof (MIS1__TAcqRec) */ + UInt32 DataSz; /*!< Effective size of the data part <= */ + + MIS1__TBtAcqIds Ids; + + MIS1__TBtAcqRes Res; + + MIS1__TBtTrigRec Trigs; + + } Head; + +#else + + MIS1__TBtAcqRawHead Head; + +#endif + + + // Acq, TBD + + union { + + + UInt8 Au8 [MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W8]; /*!< Data part as a U arrray, effecive size is DataSz (in bytes) */ + UInt16 Au16[MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W16]; /*!< Data part as a U arrray, effecive size is DataSz (in bytes) */ + UInt32 Au32[MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W32]; /*!< Data part as a U arrray, effecive size is DataSz (in bytes) */ + UInt64 Au64[MIS1__BT_FRS_MAX_ACQ_DATA_SZ_W64]; /*!< Data part as a U arrray, effecive size is DataSz (in bytes) */ + + + } MSisData; + + +} MIS1__TBtAcqRawRec; + + +/** +=================================================================================== +* \struct MIS1__TBtRecHeader +* +* \brief Record header, MUST be at beginning of each conf / param record to be save to disk +* +* +* G.CLAUS 13/05/2021 +* +=================================================================================== +*/ + + +typedef struct { + + UInt32 TagBeg; /*!< Should be == MIS1__BT_REC_TAG_BEGIN, with B7B0 = Data format version */ + UInt32 TagEndian; /*!< Should be == MIS1__BT_REC_TAG_ENDIAN */ + + +} MIS1__TBtRecHeadChk; + +/** +=================================================================================== +* \struct MIS1__TBtRunCnfRec +* +* \brief Msis beam test DAQ run configuration record +* +* +* G.CLAUS 13/05/2021 +* +=================================================================================== +*/ + + +typedef struct { + + MIS1__TBtRecHeadChk HeadChk; /*!< Record header, MUST be at beginning of each conf / param record to be save to disk */ + + // WHen a parameter is not used it can be set to -1 + + SInt32 RunNo; /*!< No of run */ + SInt32 AcqNb; /*!< Acquisitions nb in run */ + SInt32 FrNbPerAcq; /*!< Frames nb / acquisition */ + SInt32 AcqNbPerFile; /*!< Acquisitions nb / file */ + SInt32 MinTrigNb; /*!< Minimun triggers nb to stored and acquisition */ + SInt32 MaxTrigNb; /*!< Maximum triggers nb to stored and acquisition */ + SInt32 RunMode; /*!< Run mode => TB defined later => Probably RAW / TRIGGERS ONLY */ + SInt32 ProcMode; /*!< Processing mode => TB defined later */ + SInt32 SaveMode; /*!< Save mode => TB defined later, 0 => don't save */ + SInt32 TrigMode; /*!< Trigger mode => TB defined later */ + SInt32 RunTrgPreFrNb; /*!< For trigger only runs => Nb of frames stored before trigger */ + SInt32 RunTrgPostFrNb; /*!< For trigger only runs => Nb of frames stored after trigger */ + + + SInt32 DmaPacketW64Sz; /*!< DMA packet size used for Flex RIO => for info only */ + + char RunCmt[GLB_CMT_SZ]; /*!< User run comment */ + + char RunRawIndexFilePrefix[GLB_FILE_PATH_SZ]; /*!< Name of the index file prefix for raw data run */ + char RunRawDataFilePrefix[GLB_FILE_PATH_SZ]; /*!< Name of the raw data file prefix = name without the file number ext RUN_777_ */ + + char RunTrgIndexFilePrefix[GLB_FILE_PATH_SZ]; /*!< Name of the index file prefix for "triggers only" data run */ + char RunTrgDataFilePrefix[GLB_FILE_PATH_SZ]; /*!< Name of the "triggers only" data file prefix = name without the file number ext RUN_777_ */ + + +} MIS1__TBtRunCnfRec; + + + +/** +=================================================================================== +* \struct MIS1__TBtRunCnfRec +* +* \brief Msis beam test DAQ run configuration record +* +* +* G.CLAUS 13/05/2021 +* +=================================================================================== +*/ + + +typedef struct { + + MIS1__TBtRecHeadChk HeadChk; /*!< Record header, MUST be at beginning of each conf / param record to be save to disk */ + + UInt32 AcqNbInFile; /*!< Acquisition number in the file (index and data) */ + + MIS1__TBtAcqRawHead AAcqHead[MIS1__BT_MAX_ACQ_PER_FILE]; + + + // UInt32 AAcqOffset[MIS1__BT_MAX_ACQ_PER_FILE]; /*!< Position in W8 of each acquisiiton record in file */ + // UInt16 AAcqTrigNb[MIS1__BT_MAX_ACQ_PER_FILE]; /*!< Nb of triggers in each acquisiiton */ + // UInt16 AAcqErrNb[MIS1__BT_MAX_ACQ_PER_FILE]; /*!< Nb of errors in each acquisition */ + + +} MIS1__TBtRunRawIndexRec; + + + +/** +=================================================================================== +* \class MIS1__TBtRunRead +* +* \brief Beam test run file reading class +* +* Longer C structure explanation +* ... +* ... +* ... +* can take many lines +* +* G.CLAUS 16/05/2021 +* +=================================================================================== +*/ + + + + +class MIS1__TBtRunRead { + + public: + + MIS1__TBtRunRead (); + ~MIS1__TBtRunRead (); + + // -------------------------------------------------------------- + // Public methods + // -------------------------------------------------------------- + + // Gets CPU endianness, returns : 0 if little endian, 1 if big endian, -1 if unknown + + SInt32 FIsCpuBigEndian (); + + + // Sets errors messages log file name (value hard coded in function body ;-) + // Can be called to locate the error file directory and name + // Errors file MUST be set at beginning of application by MIS1__TBtRunRead_DEF_ERR_LOG_FILE + + char* FErrLogSetFilename (); + + // Sets general messages log file name (value hard coded in function body ;-) + // Can be called to locate the general messages file directory and name + // Messages file MUST be set at beginning of applicationMIS1__TBtRunRead_DEF_MSG_LOG_FILE + + char* FMsgLogSetFilename (); + + // Sets error log level, by default it is set to ERR_LOG_LVL_ALL, it can be + // ERR_LOG_LVL_NONE + // ERR_LOG_LVL_ALL + // ERR_LOG_LVL_WARNINGS_ERRORS + // ERR_LOG_LVL_ERRORS + + SInt32 FErrLogSetLevel ( SInt8 LogLevel ); + + // Sets general log level, by default it is set 127 <=> ALL, it can be 0..127 + + SInt32 FMsgLogSetLevel ( SInt8 LogLevel ); + + // Gets last error message as a string + + char* FErrGetLastMsg (); + + // Gets last general message as a string + + char* FMsgGetLastMsg (); + + + // Configures the run to read + + SInt32 FRunConf ( char* RunRootDir, UInt32 RunNo, UInt8 PrintRunHeader, UInt8 FormatVers ); + + // Closes a run (free mem, reset variables, etc ...) + + SInt32 FRunClose (); + + + // Returns a pointer to current run header, prints info in log file if Print == 1 + + MIS1__TBtRunCnfRec* FRunHeaderGet ( UInt8 Print ); + + + // Returns a pointer to the first Acq of run + + MIS1__TBtAcqRawRec* FAcqFirst ( UInt8 ChkHead, UInt8 PrintHead ); + + // Returns a pointer to the next Acq of run + + MIS1__TBtAcqRawRec* FAcqNext ( UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ); + + + // Returns a pointer to the Acq of no = AcqId of run + + MIS1__TBtAcqRawRec* FAcqGoto ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ); + + // Returns a pointer to current Acq loaded in memory + + MIS1__TBtAcqRawRec* FAcqGetPt (); + + // Print one Acq : the one pointer by Pt or the current one loaded n memory if Pt == NULL + + SInt32 FAcqPrint ( MIS1__TBtAcqRawRec* Pt, SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels, UInt8 DataWSize, UInt32 FirstDataW, UInt32 NbDataW, UInt8 VRS ); + + + // Configures the header printing option used by Acq scanning functions like FAcqFirst (...), FAcqNext (...), FAcqGoto (...) + + SInt32 FAcqHeadPrintOptSet ( SInt32 PrintTriggers, SInt32 PrintFrCnt, SInt32 PrintFiredPixels ); + + + // Starts execution time measurement + + UInt32 FMeasTimeStart (); + + // Stops execution time measurement + + UInt32 FMeasTimeStop (); + + // Gets result in ms of execution time measurement + + UInt32 FMeasTimeGetMs (); + + // Gets result in HH:MM:SS:1/100 of execution time measurement + + UInt32 FMeasTimeGetHMSMS ( UInt8* PtHour, UInt8* PtMin, UInt8* PtSec, UInt16* PtMs ); + + + // + + SInt32 F (); + + // -------------------------------------------------------------- + // Privates methods in public part => Will be move later in Private part + // -------------------------------------------------------------- + + + // Class initilization = Init variables, alloc meme, eror + general messages enable / disable + // Called by constructor => End user should not need to call it + + SInt32 _FBegin (); + + // Class finalization = free meme etc + // Called by destructor => End user should not need to call it + + SInt32 _FEnd (); + + + // Create the file name which should contains one Acq, result sets in _CurRawFileId, _CurRawFileName + + SInt32 _FBuildNewAcqFile ( UInt32 AcqNo, UInt8 Print ); + + // Create the file name which corresponds to FileId, result sets in _NewRawFileId, _NewRawFileName, _NewIndexFileName + + SInt32 _FBuildNewFile ( UInt32 FileId, UInt8 Print ); + + // Returns a pointer to the first Acq of one raw data file + + MIS1__TBtAcqRawRec* _FFirstAcqOfRawFileGetSeq ( UInt32 RawFileId, UInt8 ChkHead, UInt8 PrintHead ); + + // Returns a pointer to next Acq of one raw data file + + MIS1__TBtAcqRawRec* _FNextAcqOfRawFileGetSeq ( UInt32 RawFileId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ); + + // Returns a pointer to the first Acq of run + + MIS1__TBtAcqRawRec* _FAcqFirstSeq ( UInt8 ChkHead, UInt8 PrintHead ); + + // Returns a pointer to the next Acq of run + + MIS1__TBtAcqRawRec* _FAcqNextSeq ( UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ); + + // Returns a pointer to the Acq of no = AcqId of run + + + // MIS1__TBtAcqRawRec* _FAcqGotoSeq__New ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ); + + + MIS1__TBtAcqRawRec* _FAcqGotoSeq ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ); + + MIS1__TBtAcqRawRec* _FAcqGotoSeq_before_300521 ( UInt32 AcqId, UInt8 ChkHead, UInt8 PrintHead, UInt8* PtReachEnd ); + + + + + private: + + + // -------------------------------------------------------------- + // Private fields + // -------------------------------------------------------------- + + + UInt8 _DbgPrint; + + SInt8 _ErrLogSetLevel; + SInt8 _MsgLogSetLevel; + + + SInt32 _CpuIsBigEndian; // 0 => CPU is little endian, 1 => CPU is big endian, -1 => CPU ??? + + + SInt32 _LastError; // Last error + + // Run conf + + MIS1__TBtRunCnfRec _RunCnfRec; // Run configuration / header record + + SInt8 _RunConfLoaded; // 0 => No run conf loaded, 1 => run conf loaded + + UInt32 _RunNo; + char _RunRootDir[GLB_FILE_PATH_SZ]; // Run root directory + char _RunConfFileName[GLB_FILE_PATH_SZ]; // File name of run config file ( == header file) + + SInt32 _LastRawFileId; // Id of last raw file of run, calculated from _RunCnfRec + + + // Size calculated from Run conf parameters + + UInt32 _AcqHeadSzW8; // Size of Acq header, can't be calculated by sizeof ( MIS1__TBtAcqRawHead ) => Read in FRunConf + UInt32 _AcqMaxDataSzW8; // Maximum data size of one Acq, it is calculated from Fr nb / Acq read at run configuration + UInt32 _AcqMaxTotSzW8; // Maximum size of one Acq, it is calculated from Fr nb / Acq read at run configuration from run header record + + // Acq + + // MIS1__TBtAcqRawRec _AcqRaw; + + MIS1__TBtAcqRawRec* _PtAcqRaw; + + // New Acq file id, rw filename, index filename, built by _FBuildNewAcqFile ( UInt32 AcqNo, UInt8 Print ) + + SInt32 _NewAcqId; // The Id of the new acq + + SInt32 _NewRawFileId; // No of the new raw data file + SInt32 _NewAcqIdInFile; // Posiiton of new acq in its file 0 .. N + char _NewRawFileName[GLB_FILE_PATH_SZ]; // Full file name + path of new raw data file + char _NewIndexFileName[GLB_FILE_PATH_SZ]; // Full file name + path of new index file (corresponding to _CurRawFileName ) + + + // Current run raw data file + + SInt32 _CurAcqId; // The Id of current acq + + SInt32 _CurRawFileId; // No of the current raw data file + SInt32 _CurAcqIdInFile; // Posiiton of current acq in its file 0 .. N + char _CurRawFileName[GLB_FILE_PATH_SZ]; // Full file name + path of current raw data file + char _CurIndexFileName[GLB_FILE_PATH_SZ]; // Full file name + path of current index file (corresponding to _CurRawFileName ) + + FILE* _CurRawFilePt; // Current raw data file pinter + FILE* _CurIndexFilePt; // Current index data file pinter + + + // Acq header printing options, used by run scanning functions like FAcqFirst (...), FAcqNext (...), FAcqGoto (...) + + SInt32 _HeadPrintTriggers; // Print triggers, -1 => All, 0 => No, > 0 => value = nb of triggers to print + SInt32 _HeadPrintFrCnt; // Print frames counters, -1 => All, 0 => No, > 0 => value = nb of frames to print + SInt32 _HeadPrintFiredPixels; // Print fired pixels, 0 / 1 + + + + // Execution time measurement + + UInt32 _MeasTimeBegMS; + UInt32 _MeasTimeEndMS; + UInt32 _MeasTimeMS; + + + + // -------------------------------------------------------------- + // Private methods + // -------------------------------------------------------------- + + + + +}; + + +/** +=================================================================================== +* \struct MIS1__TBt +* +* \brief Msis beam test DAQ run configuration record +* +* +* G.CLAUS 22/05/2021 +* +=================================================================================== +*/ + + +typedef struct { + + SInt32 AcqId; /*!< Id of the Acq, only used for messages printing */ + + UInt32 TotRecSz; /*!< Total record size, for info */ + SInt32 MaxFrNb; /*!< Max nb of frame allowed due to record size */ + SInt32 FrNb; /*!< Frames nb in source Acq converted in MIS1__TBtAcqW16A */ + + UInt32 MSisW16Nb; /*!< Size of each MSis 1 raw data stream */ + + MIS1__TBtAcqRawHead AcqRawHead; /*!< Copy of MIS1__TBtAcqRawRec Header field, may be remove later if useless */ + + // UInt16 AMsis[MIS1__BT_MAX_MSIS_NB_ACQ][MIS1__BT_VRS_MAX_ACQ_DATA_SZ_W16]; + + UInt16 AAMsis[MIS1__BT_MAX_MSIS_NB_ACQ][MIS1__BT_VRS_MAX_FR_NB_PER_ACQ * MIS1__BT_TOT_FRAME_SZ_W16]; + + +} MIS1__TBtAcqW16A; + + + +/** +=================================================================================== +* \typedef MIS1__TBtFrError +* +* \brief MSis 1 frame error +* +* ... +* ... +* ... +* +* G.CLAUS 30/05/2021 +* +=================================================================================== +*/ + +typedef enum MIS1__EBtFrError { + + MIS1__BT_FR_ERR_SW = -1, /*!< SW error */ + MIS1__BT_FR_ERR_OK = 0, /*!< No error, frame is ok */ + MIS1__BT_FR_ERR_TRUNC = 1, /*!< Frame is too long => has been truncated */ + MIS1__BT_FR_ERR_TRUNC_LAST_FR = 2, /*!< Frame is too long BUT it is the last one of the Acq => has been truncated */ + MIS1__BT_FR_ERR_NB + +} MIS1__TBtFrError; + + + +/** +=================================================================================== +* \struct MIS1__TBtFrDecHead +* +* \brief Msis BT, decoded frame header for one MSis 1: header record = MSis fr head, fr cnt, ptr to data +* +* +* G.CLAUS 24/05/2021 +* +=================================================================================== +*/ + + +typedef struct { + + UInt8 MSisId; /*!< MSis Id */ + UInt16 FrId; /*!< Frame no - MAX 65535 !!! But max FlexRIO fr / Acq = 65535 */ + + MIS1__TDsFrHeader MSisFrHead; /*!< Header of MSis 1, as it is in data stream */ + MIS1__TDsFrTrailer MSisFrTrail; /*!< Trailer of MSis 1, as it is in data stream */ + + UInt32 FrCnt; /*!< Frame counter extracted from MSisFrHead */ + + SInt32 Errors; /*!< Errors detected in frame, 0 = None, < 0 SW error in data decoding, > 0 Msis HW error, ovf etc => Values are defined by MIS1__TBtFrError */ + + SInt32 FrDataSzW16; /*!< Size of frame data part in W16 => Without header and trailer, < 0 => not calculated / error */ + SInt32 FirstDataW16Pos; /*!< Position of first W16 of frame in MIS1__TBtAcqW16A.AAMsis[MSisId][W16Id], unit = W16, < 0 => not calculated / error */ + SInt32 ATrigPosW16[MIS1__BT_FR_DEC_MAX_TRIG_NB]; /*!< Position of triggers in this frame (up to MIS1__BT_FR_DEC_MAX_TRIG_NB) in W16 , < 0 => No trigger, not calculated / error*/ + + UInt32 RegionNb; /*!< Nb of regions */ + UInt32 FiredPixNb; /*!< Nb of fired pixels */ + UInt16 CheckSum; /*!< Checksum */ + +} MIS1__TBtFrDecHead; + + +/** +=================================================================================== +* \struct MIS1__TBtAcqDec +* +* \brief Msis BT, decoded acquisiton, fixed size because : no time to develop dynamic, more efficient on exec time +* +* +* G.CLAUS 24/05/2021 +* +=================================================================================== +*/ + + +typedef struct { + + SInt32 AcqId; /*!< Id of the Acq, only used for messages printing */ + + SInt32 TrigNb; /*!< Triggers nb in the Acq, added on 30/05/2021 */ + + SInt32 ParFrNbInSrcAcq; /*!< Nb of frames in this Acq = Info from DAQ paramters */ + + SInt32 ResAFrNb [MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; /*!< Array of frames nb in each MSis1 (detected by frame decoding), index is [MSisId] */ + SInt32 ResAFrFakeHeadCnt[MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; /*!< Counter of fake header detected in frames, index is [MSisId] */ + SInt32 ResAFrNbWoTrailer[MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; /*!< Array of frames nb without trailer at the end in each MSis1 (detected by frame decoding), index is [MSisId] */ + SInt32 ResAFrNbTrunc [MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; /*!< Array of frames nb which have been truncated (detected by frame decoding), index is [MSisId] */ + SInt32 ResAFrNbErr [MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; /*!< Array of frames nb with error(s) detected by frame decoding), truncated fr is not counted as en error, index is [MSisId] */ + SInt32 ResARegNb [MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; /*!< Counter regions, index is [MSisId] */ + SInt32 ResAPixNb [MIS1__BT_MAX_REAL_MSIS_NB_ACQ]; /*!< Counter fired pixels, index is [MSisId] */ + + + + MIS1__TBtFrDecHead ResAAFrHead[MIS1__BT_MAX_REAL_MSIS_NB_ACQ][MIS1__BT_VRS_MAX_FR_NB_PER_ACQ]; /*!< Array of frames header, indexes are [MSisId][FrameId] */ + + /*!< Detected Pixel nb in one frame => ResAAFrHead[MSisId][FrId].FiredPixNb */ + + + MIS1__TPixXY ResAAAFrPix[MIS1__BT_MAX_REAL_MSIS_NB_ACQ][MIS1__BT_VRS_MAX_FR_NB_PER_ACQ][MIS1__BT_FR_DEC_MAX_PIX_NB]; /*!< List of pixels in frame, indexes [MSisId][FrameId][PixelId] */ + + +} MIS1__TBtAcqDec; + + +/*!< */ + + +#endif \ No newline at end of file diff --git a/include/mimo_daq_lib/msis1_data_exp.h b/include/mimo_daq_lib/msis1_data_exp.h new file mode 100644 index 0000000..e93e587 --- /dev/null +++ b/include/mimo_daq_lib/msis1_data_exp.h @@ -0,0 +1,69 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\lib\com\maps\msis1\data\msis1_data_exp.h +* \brief Goal : Functions prototypes of Mimosis 1 lib +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 12/05/2021 +* \date File date : 12/05/2021 +* \date Doc date : 12/05/2021 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IPHC 23 Rue du Loess 67037 STYRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + +#ifndef MIMOSIS1_DATA_EXP__H +#define MIMOSIS1_DATA_EXP__H + + +int32_t MIS1__FIsCpuBigEndian (); + +SInt32 MIS1__FTrigRecPrint ( UInt32 TrigNb, MIS1__TBtTrigRec* Pt ); +SInt32 MIS1__FAcqRawPrint ( MIS1__TBtAcqRawRec* Pt, UInt8 DataWSize, UInt32 FirstDataW, UInt32 NbDataW, UInt8 VRS ); + +SInt32 MIS1__TBtRunRead_FErrLogUsrPrint ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ); +SInt32 MIS1__TBtRunRead_FMsgLogUsrPrint ( char* Msg ); + + +// 22/05/2021 + +MIS1__TBtAcqW16A* MIS1__BT_FBtAcqW16AAlloc ( UInt8 Alloc, UInt32* PtRecSz ); +SInt32 MIS1__BT_FBtAcqW16AFree ( MIS1__TBtAcqW16A* PtRec ); + +double MIS1__BT_FBtAcqW16AFill ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl, UInt8 FuncVers ) ; +double MIS1__BT_FBtAcqW16AFill_v0 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ); +double MIS1__BT_FBtAcqW16AFill_v10 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ); +double MIS1__BT_FBtAcqW16AFill_v80 ( MIS1__TBtAcqRawRec* PtSrc, MIS1__TBtAcqW16A* PtDest, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ); +SInt32 MIS1__BT_FBtAcqW16APrintMSisU16 ( MIS1__TBtAcqW16A* Pt, UInt8 MSisId, UInt32 FirstW16, UInt32 W16Nb ); + +MIS1__TBtAcqDec* MIS1__BT_FBtAcqDecAlloc ( UInt8 Alloc, UInt32* PtRecSz ); + +SInt32 MIS1__BT_FBtAcqDecFree ( MIS1__TBtAcqDec* PtRec ); +double MIS1__BT_FBtDecodeFrLight ( MIS1__TBtAcqW16A* PtSrc, MIS1__TBtAcqDec* PtDest, SInt8 MSisId, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ); +SInt32 MIS1__BT_FBtDecodeFrGetWarnErr ( UInt8 Reset ); + +double MIS1__BT_FBtDecodeFr ( MIS1__TBtAcqW16A* PtSrc, MIS1__TBtAcqDec* PtDest, SInt8 MSisId, SInt32 FrNb, UInt8 MeasExecTime, UInt8 PrintLvl ); +SInt32 MIS1__BT_FFrDecHeadPrint ( MIS1__TBtFrDecHead* Pt, UInt8 PrintMode ); +SInt32 MIS1__BT_FAcqDecPrintGen ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt8 PrintMode ); +SInt32 MIS1__BT_FAcqDecPrintPix ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt32 FrId, UInt32 MaxPixToPrint, UInt8 PrintMode ); + +SInt32 MIS1__BT_FAcqDecCheckFrCntOneMSis ( MIS1__TBtAcqDec* Pt, SInt8 MSisId, UInt8 PrintLvl, UInt32* PtErrNb ); +SInt32 MIS1__BT_FAcqDecCheckFrCnt6MSis ( MIS1__TBtAcqDec* Pt, UInt8 PrintLvl, UInt32* PtErrNb ); + +char* MIS1__FFrHeader2Str ( MIS1__TDsFrHeader* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ); +char* MIS1__FFrTrailer2Str ( MIS1__TDsFrTrailer* PtSrc, char* DestStr, SInt32 DestStrSz, SInt32 Mode ); + + + + +#endif \ No newline at end of file diff --git a/include/mimo_daq_lib/sync_index_rec.c b/include/mimo_daq_lib/sync_index_rec.c new file mode 100755 index 0000000..9ae3f53 --- /dev/null +++ b/include/mimo_daq_lib/sync_index_rec.c @@ -0,0 +1,163 @@ +/******************************************************************************* +File : sync_index_rec.c +Goal : Functions to synchronized two DAQ files +Prj date : 18/07/2012 +File date : 18/07/2012 +Doc date : 18/07/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef SYNC_INDEX_REC_C +#define SYNC_INDEX_REC_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Return file size or negative value upon failure. + Author : Gilles CLAUS +*/ + /* =================================================================================== */ +/* DOC_FUNC_END */ +int GetFileSize ( char* FilePath ) { + + FILE* VPf; + int VFileSz = 0; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + printf( "GetFileSize: fopen fail !\n" ); + return -1; + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + printf( "GetFileSize: fseek SEEK_SET fail !\n" ); + return -1; + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + printf( "GetFileSize: fseek SEEK_END fail !\n" ); + return -1; + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + printf( "GetFileSize: ftell fail !" ); + return -1; + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + printf( "GetFileSize: fseek SEEK_SET fail !"); + return -1; + } + + if ( fclose (VPf) != 0 ) { + printf( "GetFileSize: fclose fail !" ); + return -1; + } + + return VFileSz; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : Read the file containing the synchronization information + : between two boards, each with its data file. + : For instance a board reading binary sensors + : and another board reading analog sensors. + : + Inputs : + : + : + Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : + Globals : None + : + Remark : None + : + Level : This is a user level function. + Date : 10/07/2012 + Doc date : + Modif : + Author : Gilles CLAUS + E-mail : claus@lepsi.in2p3.fr + Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +int GetSyncPointer ( char* FilePath, unsigned char* PtDest, int DestSz ) { + + int VRet; + FILE* VPfDest; + int VFileSz; + + + // Check param + + if( PtDest==NULL ) { + printf( "GetSyncPointer: PtDest == NULL !\n"); + return -1; + } + + // Measure file size + + VFileSz = GetFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + printf( "GetSyncPointer: Buffer size=%d < File size=%d.\n", DestSz, VFileSz ); + return -1; + } + + printf( "GetSyncPointer: TRACE => FileSize=%d\n", VFileSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + if( VPfDest == NULL ) { + printf( "GetSyncPointer: Source file %s open failed.\n", FilePath ); + return -1; + } + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + printf("SYNC Version is %d\n", ((APP__TSyncIndexRec*)PtDest)->Version); + + if ( VRet != 1 ) { + printf( "GetSyncPointer: Error reading source file %s.\n", FilePath ); + return -1; + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + printf( "GetSyncPointer: Error fclose source file %s.\n", FilePath ); + return -1; + } + + + // Return record nb + + return ( VFileSz / sizeof (APP__TSyncIndexRec) ); + +} + + +#endif \ No newline at end of file diff --git a/include/mimo_daq_lib/sync_index_rec.typ b/include/mimo_daq_lib/sync_index_rec.typ new file mode 100755 index 0000000..bd3bcd8 --- /dev/null +++ b/include/mimo_daq_lib/sync_index_rec.typ @@ -0,0 +1,57 @@ +/* ============== */ +/* 10/07/2012 */ +/* -------------- */ +/* Doc 18/07/2012 */ +/* ============== */ + +#ifndef SYNC_INDEX_REC_TYP +#define SYNC_INDEX_REC_TYP + +#define CC_UNIX // Specify operating system +#include "types.typ" + +typedef struct { + + // The fields needed to synchronize DUT & Telescope run are marked with a * + // The other fields are extra information, which may be use to make cross-check + + UInt32 Version; // Record version + + // DUT events information + + UInt32 DutEvId; // * Event identifier from 0 to NbMaxEventsInRun - 1 + UInt32 DutEvTag; // Event tag = Mi26 sync signal pulses count = Mi26 frames counter + UInt32 DutTrigLine; // Line read by DAQ when trigger has occurred + UInt32 DutTrigFrame; // Frame read by DAQ when trigger has occurred + UInt32 DutTrigNbTot; // Total number of triggers seen by DAQ since beginning of run + UInt32 DutTrigNbAccepted; // Number of triggers accepted by DAQ since beginning of run = number of events taken by DAQ + UInt32 DutSpareU32; // Reserved + + // Telescope information + + UInt32 TelBegEvFrId; // * First frame corresponding to DUT event + + // Frame which contains trigger info + // + UInt32 TelTrigFrId; // Frame id since begining of run => 0 .. NbMaxFramesInRun - 1 + UInt32 TelTrigAcqId; // Acquisition id since begining of run + UInt32 TelTrigFrIdInAcq; // Frame id in current acquisition => 0 .. NbMaxFramesPerAcq + UInt32 TelTrigEvTag; // Event tag = Mi26 frames counter + + // Three first triggers of the frame (TelTrigFrId) + // Unit is Mi26 clock TS => divide by 16 to get trigger line + // + UInt32 TelTrig0; // First trigger + UInt32 TelTrig1; // Second trigger + UInt32 TelTrig2; // Third trigger + + UInt32 TelFrTrigNb; // Total number of trigger of the frame (TelTrigFrId) + + UInt32 TelTrigSpareU32; // Reserved + + UInt32 TelEndEvFrId; // * Last frame corresponding to DUT event + +} APP__TSyncIndexRec; + +#endif + diff --git a/include/mimo_daq_lib/types.def b/include/mimo_daq_lib/types.def new file mode 100644 index 0000000..6957eb8 --- /dev/null +++ b/include/mimo_daq_lib/types.def @@ -0,0 +1,35 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.def +Goal : Limits of types. + : +Prj date : 2000 - 2002 +File date : +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*************************************************************/ + + +/*H**************************************************************************** +FILE : Types.def +BUT : Define types limts. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_DEF +#define TYPES_DEF + + +#define TYP_MIN_SINT32 0x80000000 +#define TYP_MAX_SINT32 0x7FFFFFFF + +#define W128_STR_MAX_SZ (48 + 10) // 1 W128 = 16 (W8 + Space) => 48 chars, + 10 spare chars + +#endif diff --git a/include/mimo_daq_lib/types.typ b/include/mimo_daq_lib/types.typ new file mode 100755 index 0000000..cf5bf9d --- /dev/null +++ b/include/mimo_daq_lib/types.typ @@ -0,0 +1,167 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.typ +Goal : Common basic types definitions. + : I never use default C types names ( char, int ... ) + : i redefined them here ( SInt8, UInt32 ... ). + : + : If something go wong on you'r plateform with C types + : definition you need to update this file. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + +#include "stdint.h" // added, JB 2013/02/11 + +/*H**************************************************************************** +FILE : Types.Typ +BUT : Define types. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_TYP +#define TYPES_TYP + + // typedef enum ELang { ELang_FRENCH, ELang_ENGLISH, ELang_GERMAN, ELang_LANG_NB } TLang; + +#ifndef NODEFTYPCHAR + +/* +17/11/04 GC + +BCPPB declares an identfier with the same name " Char " +this problem happens while compiling Mimo* JTAG application (MP). +This Char identifier is used in SpinEdit object. + +MP used conditionnal compilation, i decided to remove this Char +type definition, because i believe i never use it. +Wait and see ... + +*/ + +/* typedef unsigned char Char; */ + +#endif + +#ifndef UInt8 + typedef unsigned char UInt8; +#endif + +#ifndef UByte + typedef UInt8 UByte; +#endif + +#ifndef SInt8 + typedef signed char SInt8; +#endif + +#ifndef SByte + typedef SInt8 SByte; +#endif + +#ifndef UInt16 + typedef unsigned short UInt16; +#endif + +#ifndef UWord + typedef UInt16 UWord; +#endif + +#ifndef SInt16 + typedef short SInt16; +#endif + +#ifndef SWord + typedef SInt16 SWord; +#endif + +#ifndef UInt32 + //typedef unsigned long int UInt32; + typedef unsigned int UInt32; // correction for 64bits, JB 2011/10/28 +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + //typedef long int SInt32; + typedef int SInt32; // correction for 64bits, JB 2011/10/28 +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif + + +#ifdef CC_UNIX + +#ifndef UInt64 + typedef uint64_t UInt64; +#endif + +#ifndef SInt64 + typedef int64_t SInt64; +#endif + +#else + +#ifndef UInt64 + typedef unsigned __int64 UInt64; +#endif + +#ifndef SInt64 + typedef __int64 SInt64; +#endif + + +#endif + + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + + +#endif diff --git a/include/mimo_daq_lib/var_decl_def.h b/include/mimo_daq_lib/var_decl_def.h new file mode 100644 index 0000000..fc56ad4 --- /dev/null +++ b/include/mimo_daq_lib/var_decl_def.h @@ -0,0 +1,57 @@ + +/** +* ---------------------------------------------------------------------------------- +* \file X:\prj\win\mimosis_1\run_read_light_bt\com\var_decl_def.h +* \brief Goal : Macros for selection between variables creation, export +* \brief +* \brief +* \version : 1.0 +* \date Prj date : 12/05/2021 +* \date File date : 12/05/2021 +* \date Doc date : 12/05/2021 +* \author : Gilles CLAUS +* \author : gilles.claus@iphc.cnrs.fr +* \author : CNRS - IN2P3 - IPHC 23 Rue du Loess 67037 STRASBOURG +* +* Remark : None +* +* ---------------------------------------------------------------------------------- +* License : GNU General Public License +* +* ---------------------------------------------------------------------------------- +*/ + + + + +// ----------------------------------------------------------------------- +// Macros for variable definition / declaration +// ----------------------------------------------------------------------- + + +#ifdef CC_INTERFACE_FILE + + #define EXTERN + #define VAR_STATIC + #define VAR_INIT(x) =x + #define VAR_INIT_A2(x,y) ={x,y} + +#else + + #define EXTERN + #define VAR_STATIC + #define VAR_INIT(x) =x + #define VAR_INIT_A2(x,y) ={x,y} + + +#endif + +#ifdef APP_ROOT + #define VAR_DCL(Extern,Static,Var) Var; + #define VAR_DCL_INIT(Extern,Static,Var,Init) Var=Init; + #define VAR_DCL_INIT_A2(Extern,Static,Var,Init0,Init1) Var={Init0,Init1}; +#else + #define VAR_DCL(Extern,Static,Var) Extern Static Var; + #define VAR_DCL_INIT(Extern,Static,Var,Init) Extern Static Var VAR_INIT (Init); + #define VAR_DCL_INIT_A2(Extern,Static,Var,Init0,Init1) Extern Static Var VAR_INIT_A2 (Init0,Init1); +#endif diff --git a/include/pxi_daq_lib_config.h b/include/pxi_daq_lib_config.h new file mode 100644 index 0000000..300bba8 --- /dev/null +++ b/include/pxi_daq_lib_config.h @@ -0,0 +1,163 @@ +///////////////////////////////////////////// +// // +// PXI DAQ LIB VERSION configuration // +// // +///////////////////////////////////////////// +// Created by VR on March 20th, 2014 +///////////////////////////////////////////// + +//********************************************************************** +// 1) Choose the version of the library +// Define ONE of the two following directives +//********************************************************************** +//#define PXI_DAQ_LIB_VERSION_1_1 //for version pxi_daq_lib_v.1.1 (M-26/28) +#define PXI_DAQ_LIB_VERSION_1_2 //for version pxi_daq_lib_v.1.2 (M-26/28) +//#define PXI_DAQ_LIB_VERSION_2_1 //for version pxi_daq_lib_v.2.1 (FSBB) +//#define PXI_DAQ_LIB_VERSION_3_1 //for version pxi_daq_lib_v.3.1 (M-26/28 and FSBB) + +//////////////////////////////////////////// +// Some tests to avoid configuration ERROR : +// DO NOT MODIFY +//////////////////////////////////////////// +#ifdef PXI_DAQ_LIB_VERSION_1_1 + #ifdef PXI_DAQ_LIB_VERSION_1_2 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif + #ifdef PXI_DAQ_LIB_VERSION_2_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif + #ifdef PXI_DAQ_LIB_VERSION_3_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif +#endif + +#ifdef PXI_DAQ_LIB_VERSION_1_2 + #ifdef PXI_DAQ_LIB_VERSION_1_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif + #ifdef PXI_DAQ_LIB_VERSION_2_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif + #ifdef PXI_DAQ_LIB_VERSION_3_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif +#endif + +#ifdef PXI_DAQ_LIB_VERSION_2_1 + #ifdef PXI_DAQ_LIB_VERSION_1_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif + #ifdef PXI_DAQ_LIB_VERSION_1_2 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif + #ifdef PXI_DAQ_LIB_VERSION_3_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif +#endif + +#ifdef PXI_DAQ_LIB_VERSION_3_1 + #ifdef PXI_DAQ_LIB_VERSION_1_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif + #ifdef PXI_DAQ_LIB_VERSION_1_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif + #ifdef PXI_DAQ_LIB_VERSION_2_1 + #error in file pxi_daq_lib_config.h => Only one PXI_DAQ_LIB_VERSION can be enabled !!! + #endif +#endif + +//////////////////////////////////////////// + + +//********************************************************************** +// 2) Configure the library +// (don't mind the lib parameters you are not using) +//********************************************************************** +//****************** +// lib version 1.1 +//****************** +#ifdef PXI_DAQ_LIB_VERSION_1_1 + // The variable FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE is the maximum number of blocs in variable bloc size mode + // Define ONE of the two following directives (to use 50.000 or 200.000) as function of your DAQ version + + #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 // For DAQ version before 2012/11/20 + //#define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 200000 // For DAQ version after 2012/11/20 +#endif + +//****************** +// lib version 1.2 +//****************** +#ifdef PXI_DAQ_LIB_VERSION_1_2 + // STEP 1/2 : + // Define ONE of the three following directives + // => Check run files date in order to decide which one must be used + #define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + //#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + //#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + + // STEP 2/2 : + // Define one of the two followong directives + // => Check run files date in order to decide which one must be used + #define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + //#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 +#endif + + +//****************** +// lib version 2.1 +//****************** +#ifdef PXI_DAQ_LIB_VERSION_2_1 +// STEP 1/2 : +// Define ONE of the three following directives +// => Check run files date in order to decide which one must be used +//#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 +//#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 +#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + +// STEP 2/2 : +// Define one of the two followong directives +// => Check run files date in order to decide which one must be used +//#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 +#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + +#endif + +//****************** +// lib version 3.1 +//****************** +#ifdef PXI_DAQ_LIB_VERSION_3_1 +// STEP 1/2 : +// Define ONE of the three following directives +// => Check run files date in order to decide which one must be used +//#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 +//#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 +#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + +// STEP 2/2 : +// Define one of the two followong directives +// => Check run files date in order to decide which one must be used +//#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 +#define APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + +#endif + +//********************************************************************** +// 3) Recompile TAF !!! AFTER a 'make clean' command !!! +//********************************************************************** + + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// CONFIGS +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Group // User(s) // Experiment description // PXI_DAQ_LIB_VERSION // sub-config // +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// IPNL (FR) // Valerian // 2012/08 GSI 8*Mi26 PXIe // 1_2 // CC1_BEFORE_071112 ; CC2_BEFORE_JULY_2012 // +// // // // // // +// // // // // // +// // // // // // +// // // // // // +// // // // // // +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/include/pxi_daq_lib_v.0.0/asic.def b/include/pxi_daq_lib_v.0.0/asic.def new file mode 100755 index 0000000..77c3d84 --- /dev/null +++ b/include/pxi_daq_lib_v.0.0/asic.def @@ -0,0 +1,56 @@ + + +/******************************************************************************* +File : x:\lib\com\asic\asic.def +Goal : Macros definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_DEF +#define ASIC_DEF + + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef enum { + + ASIC__NONE, + ASIC__MI26, + ASIC__ULTIMATE1 + +} ASIC__TEAsicName; + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + ASIC__MI26_TRIG_RES__SIG_LINE, + ASIC__MI26_TRIG_RES__SIG_CLK, + ASIC__MI26_TRIG_RES__LINE + +} ASIC__MI26_TETrigRes; + + +#define ASIC__ENUM_TRIG_RES_NB 4 + +#endif diff --git a/include/pxi_daq_lib_v.0.0/asic.typ b/include/pxi_daq_lib_v.0.0/asic.typ new file mode 100755 index 0000000..ea2956f --- /dev/null +++ b/include/pxi_daq_lib_v.0.0/asic.typ @@ -0,0 +1,46 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.typ +Goal : Types definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_TYP +#define ASIC_TYP + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + SInt8 AsicNo; + SInt32 AcqNo; + SInt32 FrameNoInAcq; + SInt32 FrameNoInRun; + + SInt32 HitCnt; // Used for monitoring, if not set HitCnt = -1 + + // + + SInt32 ATrigRes[ASIC__ENUM_TRIG_RES_NB]; + + +} ASIC__TFrameStatus; + + +#endif diff --git a/include/pxi_daq_lib_v.0.0/daq_pxi.def b/include/pxi_daq_lib_v.0.0/daq_pxi.def new file mode 100755 index 0000000..2837cef --- /dev/null +++ b/include/pxi_daq_lib_v.0.0/daq_pxi.def @@ -0,0 +1,89 @@ + + +/******************************************************************************* +File : x:\lib\win\daq_pxi\daq_pxi.def +Goal : Macros definition of +Prj date : //200 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef DAQ_PXI_DEF +#define DAQ_PXI_DEF + +/* ======================== */ +/* Conditional Compilation */ +/* ======================== */ + + + +#define DPXI__MI26_SEARCH_TRIG_POS + +#define DPXI__MI26_EMUL_READ_6_MI26 // Read two times 3 Mi26 on same data lines + // Mi26 No 0, 1, 2 on In0,1 - In2,3 - In 4,5 + // Mi26 No 3, 4, 5 on In0,1 - In2,3 - In 4,5 + // used in DPXI_PRIV_FDeser6Mi26W32LsbFirst + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +typedef enum { + + DPXI__MI26_READ_MODE__REGISTER, + DPXI__MI26_READ_MODE__ZS + +} DPXI__MI26_TEReadMode; + + +typedef enum { + + DPXI__MI26_READ_MODE_PAR__REG_ID, + DPXI__MI26_READ_MODE_PAR__ZS_MODE + +} DPXI__MI26_TEReadModePar; + + +#define DPXI__READ_MODE_MAX_PAR_NB 2 + + +typedef enum { + + DPXI__HW_TRIG_PAR__OFFSET, + DPXI__HW_TRIG_PAR__WINDOW, + DPXI__HW_TRIG_PAR_NB + +} DPXI__TEHwTrigPar; + + + +#define STRING_LENGHT 256 //Can be any size + + + +#define DPXI__MI26_NB_MAX_MI26_PER_DAQ 8 + + + +#define DPXI__MI26_TRG_SEARCH__START 1 +#define DPXI__MI26_TRG_SEARCH__RUNNING 2 +#define DPXI__MI26_TRG_SEARCH__DONE 0 + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.0.0/globals.def b/include/pxi_daq_lib_v.0.0/globals.def new file mode 100755 index 0000000..b05484c --- /dev/null +++ b/include/pxi_daq_lib_v.0.0/globals.def @@ -0,0 +1,37 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_DEF +#define GLOBALS_DEF + +/* #include "y:/dd/sdev/src/com/c/com/include/globals_root.def" JB 2009/08/14*/ + +#ifndef ROOT_ROOT + #define GLB_READ_CR { while ( getchar () != '\n' ); }; +#endif + + +#ifndef ROOT_ROOT + #define GLB_KEYB_CR { while ( getchar () != '\n' ); } +#endif + + + +#endif diff --git a/include/pxi_daq_lib_v.0.0/maps.def b/include/pxi_daq_lib_v.0.0/maps.def new file mode 100755 index 0000000..7a798eb --- /dev/null +++ b/include/pxi_daq_lib_v.0.0/maps.def @@ -0,0 +1,49 @@ +/******************************************************************************* +File : x:\lib\com\maps\maps.def +Goal : Macros definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_DEF +#define MAPS_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define MAPS__TCDigTelMon_MAX_EV_NB 300 +#define MAPS__TCDigTelMon_MAX_PLANE_NB 6 +#define MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB 10000 +#define MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE 1000 + +#define MAPS__TCDigTelMon_CHK_PLANE_ID(Id) { if ( (Id < 0) || (Id >= MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + +#define MAPS__TCDigTelMon_CHK_PLANE_NB(Nb) { if ( (Nb <= 0) || (Nb > MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Nb, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + + +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME 0 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL 1 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS 2 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR 3 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS 4 + +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES 0 +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE 1 + + +#endif diff --git a/include/pxi_daq_lib_v.0.0/mi26.def b/include/pxi_daq_lib_v.0.0/mi26.def new file mode 100755 index 0000000..5d36c05 --- /dev/null +++ b/include/pxi_daq_lib_v.0.0/mi26.def @@ -0,0 +1,175 @@ +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26.def +Goal : Macros definition of Mi26 library. +: It provides Mi26 types definition and data handling functions. +Prj date : 24/11/2008 +File date : 24/11/2008 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_DEF +#define MI26_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define MI26__REG_DISCRI_BIT_SZ 1152 +#define MI26__REG_DISCRI_W32_SZ 36 + +#define MI26__REG_AFTER_ZS_BIT_SZ 160 +#define MI26__REG_AFTER_ZS_W32_SZ 5 + +#define MI26__REG_AFTER_MUX_BIT_SZ 160 +#define MI26__REG_AFTER_MUX_W32_SZ 5 + +#define MI26__MAT_DISCRI_LINES_NB 578 + +#define MI26__ZS_FFRAME_RAW_MAX_W16 1140 // 1142 + +#define MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 +#define MI26__ZS_FFRAME_MAX_STATES_REC 576 // one per line + +#define MI26__ZS_FFRAME_MODE0_2X80MHZ 0 +#define MI26__ZS_FFRAME_MODE1_2X40MHZ 1 +#define MI26__ZS_FFRAME_MODE2_1X80MHZ 2 + + +#define MI26__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 9216 +#define MI26__ZS_FFRAME_MODE_2X40MHZ_BIT_SZ 4608 +#define MI26__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 9216 + +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +#define MI26__ZS_FFRAME_MODE_2X40MHZ_W16_SZ 288 +#define MI26__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 576 + + + +// Id to select Mi26 register + +#define MI26__REG_DISCRI 0 +#define MI26__REG_AFTER_ZS 1 +#define MI26__REG_AFTER_MUX 2 +#define MI26__REG_DISCRI_SCAN 3 + +// ====================================== +// For MI26 discri analysis tools +// ====================================== + +// Submatrices number + +#define MI26__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define MI26__REG_BIAS_NB 19 + +#define MI26__REG_BIAS_ICLPDISC 0 +#define MI26__REG_BIAS_IPWRSW 1 +#define MI26__REG_BIAS_IBUF 2 +#define MI26__REG_BIAS_ID1PWRS 3 +#define MI26__REG_BIAS_ID2PWRS 4 +#define MI26__REG_BIAS_ILVDSTX 5 +#define MI26__REG_BIAS_ILVDS 6 +#define MI26__REG_BIAS_IVTST1 7 +#define MI26__REG_BIAS_IVTST2 8 +#define MI26__REG_BIAS_IANABUF 9 +#define MI26__REG_BIAS_IVDREF1D 10 +#define MI26__REG_BIAS_IVDREF1C 11 +#define MI26__REG_BIAS_IVDREF1B 12 +#define MI26__REG_BIAS_IVDREF1A 13 +#define MI26__REG_BIAS_IVDREF2 14 +#define MI26__REG_BIAS_IDIS1 15 +#define MI26__REG_BIAS_IDIS2 16 +#define MI26__REG_BIAS_IPXI 17 +#define MI26__REG_BIAS_IKIMO 18 + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define MI26__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define MI26__DIS_MEAS_STEP_PAR_FIRST 0 +#define MI26__DIS_MEAS_STEP_PAR_LAST (MI26__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define MI26__DIS_TEST_MAX_STEP_NB 30 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define MI26__NB_MAX_MI26_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define MI26__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define MI26__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define MI26__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// MI26__TCTelMon +// -------------------- + +#define MI26__COLOR_BROWN 0x000066CC +#define MI26__COLOR_ORANGE 0x0000A5FF +#define MI26__COLOR_YELLOW 0x0000FFFF +#define MI26__COLOR_GREEN 0x0000FF00 +#define MI26__COLOR_BLUE 0x00FF0000 +#define MI26__COLOR_VIOLET 0x00990066 + +#define MI26__TCTelMon__COL_PLANE_0 (TColor) MI26__COLOR_ORANGE +#define MI26__TCTelMon__COL_PLANE_1 (TColor) MI26__COLOR_BLUE +#define MI26__TCTelMon__COL_PLANE_2 (TColor) MI26__COLOR_BROWN +#define MI26__TCTelMon__COL_PLANE_3 (TColor) MI26__COLOR_YELLOW +#define MI26__TCTelMon__COL_PLANE_4 (TColor) MI26__COLOR_GREEN +#define MI26__TCTelMon__COL_PLANE_5 (TColor) MI26__COLOR_VIOLET + + +#define MI26__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define MI26__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define MI26__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + + +#endif diff --git a/include/pxi_daq_lib_v.0.0/mi26.typ b/include/pxi_daq_lib_v.0.0/mi26.typ new file mode 100755 index 0000000..c7f4247 --- /dev/null +++ b/include/pxi_daq_lib_v.0.0/mi26.typ @@ -0,0 +1,1195 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26.typ +Goal : Types definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 24/11/2008 +File date : 24/11/2008 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_TYP +#define MI26_TYP + +#ifdef ROOT_ROOT + typedef UInt32 MI26__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor MI26__TColor; +#endif + + + + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} MI26__TContext; + +/* ============================================================================ */ +/* Discri register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[MI26__REG_DISCRI_W32_SZ]; + SInt8 ADataBit[MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TRegDiscri; + +/* ============================================================================ */ +/* Discri register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[MI26__REG_DISCRI_W32_SZ]; + +} MI26__TRegDiscriW32; + + +/* ============================================================================ */ +/* Discri register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TRegDiscriBit; + + +/* ============================================================================ */ +/* Discri matrix dual view : W32 or Bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + MI26__TRegDiscri ALine[MI26__MAT_DISCRI_LINES_NB]; + +} MI26__TMatDiscri; + +/* ============================================================================ */ +/* Discri matrix view as W32 array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AALineW32[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_W32_SZ]; + +} MI26__TMatDiscriW32; + +/* ============================================================================ */ +/* Discri matrix view as bit array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TMatDiscriBit; + + +typedef struct { + + float AALineCol[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TMatDiscriBitf; + + +/* ============================================================================ */ +/* Discri matrix view as bit array - BUT scale 1/4 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 23/07/2009 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[MI26__MAT_DISCRI_LINES_NB / 2][MI26__REG_DISCRI_BIT_SZ / 2]; + +} MI26__TMatDiscriBitHalfScale; + + + +/* ============================================================================ */ +/* After Zero Sup register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[MI26__REG_AFTER_ZS_W32_SZ]; + SInt8 ADataBit[MI26__REG_AFTER_ZS_BIT_SZ]; + +} MI26__TRegAfterZs; + +/* ============================================================================ */ +/* After Zero Sup register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[MI26__REG_AFTER_ZS_W32_SZ]; + +} MI26__TRegAfterZsW32; + +/* ============================================================================ */ +/* After Zero Sup register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[MI26__REG_AFTER_ZS_BIT_SZ]; + +} MI26__TRegAfterZsBit; + + +/* ============================================================================ */ +/* After Mux register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[MI26__REG_AFTER_MUX_W32_SZ]; + SInt8 ADataBit[MI26__REG_AFTER_MUX_BIT_SZ]; + +} MI26__TRegAfterMux; + +/* ============================================================================ */ +/* After Mux register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[MI26__REG_AFTER_MUX_W32_SZ]; + +} MI26__TRegAfterMuxW32; + + +/* ============================================================================ */ +/* After Mux register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[MI26__REG_AFTER_MUX_BIT_SZ]; + +} MI26__TRegAfterMuxBit; + + + +/* ======================================================= */ +/* Frame provided by Mi26 DAQ, it's independent of output */ +/* mode BUT data are not organized as in MI26__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by MI26__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + + + UInt16 ADataW16[MI26__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +// SInt32 a; +// char Text[255]; + +} __TZsFFrameRaw; + + + + + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + + + UInt16 ADataW16[MI26__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} MI26__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} MI26__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} MI26__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + MI26__TStatesLine StatesLine; + MI26__TState AStates[MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} MI26__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by Mi26, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a MI26 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + MI26__TZsFStatesRec AStatesRec[MI26__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} MI26__TZsFFrame; // F in FFrame means Fixed size frame + + + + +#ifndef APP__RMV_MI26__TCDiscriFile +#ifndef APP__RMV_CLASSES + +// 31/01/2009 + +class MI26__TCDiscriFile : public FIL__TCBinFile { + + + private : + + protected : + + + public : + + MI26__TCDiscriFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~MI26__TCDiscriFile (); + + SInt32 PubFConf ( char* DataFile, SInt8 WriteRead, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetEvNb (); + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + SInt32 PubFWriteEv ( MI26__TMatDiscriW32* PtSrcMat ); + SInt32 PubFReadNextEv ( MI26__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + MI26__TMatDiscriW32* PubFReadNextEv (); + SInt32 PubFGotoEv ( SInt32 EvNo ); + SInt32 PubFReadEv ( SInt32 EvNo, MI26__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + MI26__TMatDiscriW32* PubFReadEv ( SInt32 EvNo ); + + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + +#endif +#endif + +/* ==================================================== */ +/* Discriminators test information file record */ +/* */ +/* - Test no */ +/* - Chip no / comment */ +/* - Number of steps */ +/* - Events nb / step */ +/* - Run no associated to each step */ +/* - Bias used for each step */ +/* - User defined parameters for each step */ +/* The can be used to convert udac / mv etc ... */ +/* */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.cnf contains the structure */ +/* MI26__TDisTestCnfFile */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + +// A copy of bias used for the current run +// 10/02/2009 + +typedef struct { + + UInt8 ABias[MI26__REG_BIAS_NB]; + +} MI26__TBiasCnf; + + +// All information about current discri measurement step +// 10/02/2009 + +typedef struct { + + SInt32 RunNo; + MI26__TBiasCnf Bias; + float APar[MI26__DIS_MEAS_STEP_MAX_PAR_NB]; + +} MI26__TDisMeasStep; + + +// Format of file discri_test_NNNN.cnf +// 10/02/2009 + +/*typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to MI26__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + +} MI26__TDisMeasHeader; + +typedef struct { + MI26__TDisMeasHeader Head; + MI26__TDisMeasStep AStep[MI26__DIS_TEST_MAX_STEP_NB]; +}MI26__TDisTestCnfFile;*/ + + +typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to MI26__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + + MI26__TDisMeasStep AStep[MI26__DIS_TEST_MAX_STEP_NB]; + + +} MI26__TDisTestCnfFile; + + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in sub matrices view mode => sub A, B, C, D */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 3D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED per submatrix. */ +/* => Header.SubMatView = 1 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* MI26__TDisHitCntAllSubMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of MI26__TDisHitCntAllSubMatStepData */ +/* - init a MI26__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + SInt32 TestNo; + SInt8 SubMatView; // 0 => whole matrix as single data piece + // 1 => submatrices A, B, C, D + SInt32 StepNb; + char CnfFileName[GLB_FILE_PATH_SZ]; + + +} MI26__TDisHitCntHeader; + + +typedef struct { + + float AAASubMat[MI26__SUB_MAT_NB][MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ / 4]; + +} MI26__TDisHitCntAllSubMatStepData; + +typedef struct { + + float AAAASubMat [MI26__DIS_TEST_MAX_STEP_NB][MI26__SUB_MAT_NB][MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ / 4]; + +} MI26__TDisHitCntAllSubMatStepDataMG; + +typedef struct { + + MI26__TDisHitCntHeader Header; + MI26__TDisHitCntAllSubMatStepData FirstStepData; + +} MI26__TDisHitCntAllSubMatFile; + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in whole matrix view mode */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 2D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED as ONE matrix. */ +/* => Header.SubMatView = 0 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* MI26__TDisHitCntMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of MI26__TDisHitCntMatStepData */ +/* - init a MI26__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + float AAMat[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TDisHitCntMatStepData; + + +typedef struct { + + MI26__TDisHitCntHeader Header; + MI26__TDisHitCntMatStepData FirstStepData; + +} MI26__TDisHitCntMatFile; + + + +typedef struct { + + SInt8 AALineCol[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ / 4]; + +} MI26__TQuaterMatDiscriBit; + +typedef struct { + + MI26__TColor AALineCol[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TMatDiscriColor; + + +typedef struct { + + MI26__TColor AALineCol[MI26__MAT_DISCRI_LINES_NB / 2][MI26__REG_DISCRI_BIT_SZ / 2]; + +} MI26__TMatDiscriColorHalfScale; + + +typedef struct { + + MI26__TColor AALineCol[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ / 4]; + +} MI26__TQuaterMatDiscriColor; + + +// To store "1" count on each discri for N events + +typedef struct { + + SInt32 ABit[MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TRegDiscriCumul; + + +// To store % of "1" on each discri for N events + +typedef struct { + + float ABit[MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TRegDiscriPerCent; + +// To store "1" count on whole matrix for N events + +typedef struct { + + UInt16 AALineCol[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TMatDiscriCumul; + + +typedef struct { + + UInt16 AALineCol[MI26__MAT_DISCRI_LINES_NB / 2][MI26__REG_DISCRI_BIT_SZ / 2]; + +} MI26__TMatDiscriCumulHalfScale; + + +// To store % of "1" on whole matrix for N events + +typedef struct { + + float AALineCol[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TMatDiscriPerCent; + + +typedef struct { + + float AALineCol[MI26__MAT_DISCRI_LINES_NB][MI26__REG_DISCRI_BIT_SZ]; + +} MI26__TQuaterMatDiscriPerCent; + + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + + +// DPXI__MI26_NB_MAX_MI26_PER_DAQ + +typedef MI26__TZsFFrame MI26__TAZsFFrame[MI26__NB_MAX_MI26_PER_DAQ]; + + + +typedef struct { + + // Date & Time + + UInt32 StartDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StartTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Asic conf + + UInt8 AsicName; // Value of enumerated ASIC__TEAsicName defined in asic.def + SInt8 AsicNb; // Number of Asic read by DAQ + + // Trigger mode + + SInt8 SwTrigEnabled; // Enable automatic start of acquisition on first trigger of a spill + // - 0 => Board starts upon acquisition request command, don't care about trigger + // - 1 => After acquisition request command, board wait on first trigger to start + // Trigger detection is done by sw, therefore it has a latency of N x 15 ms + + SInt8 HwTrigModeSavedData; // Trigger mode + // - 0 => Run contains all frames : with OR without trigger + // - 1 => Run contains ONLY frames with a trigger + + SInt32 HwTrigPar[MI26__TZSRunCnf__HW_TRIG_PAR_NB]; + + // Run parameters + + SInt32 RunNo; + SInt8 RunSave; + SInt8 RunSaveMode; + SInt32 RunEvNb; + SInt32 RunFileEvNb; + +} MI26__TZSRunCnf; + + +typedef struct { + + // Date & Time + + UInt32 StopDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StopTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Status + + SInt32 EvNbTaken; + SInt32 RejAcqNb; + SInt32 ARejAcqList[MI26__TZSRunRes__MAX_ACQ_REJ_NB]; + +} MI26__TZSRunRes; + + +// 09/07/2009 + +#ifndef APP__RMV_CLASSES + +class MI26__TCZsRunRW { + + private: + + SInt32 PrivFInitForNewRunLoading (); + + // Object + + FIL__TCBinFile* ProPtBinFile; + + protected: + + // Parameters + + char ProParRunDir[GLB_FILE_PATH_SZ]; + SInt32 ProParRunNo; + SInt32 ProParCurMi26No; + SInt32 ProParCurEvNo; + + SInt8 ProParMeasTime; + SInt8 ProParPrintMsg; + SInt8 ProParPrintEvHeader; + + // Informations from run conf file OR calculated + + char ProRunCnfFile[GLB_FILE_PATH_SZ]; + char ProRunResFile[GLB_FILE_PATH_SZ]; + + MI26__TZSRunCnf ProRecZSRunCnf; + MI26__TZSRunRes ProRecZSRunRes; + + SInt32 ProInfRunMi26Nb; + SInt32 ProInfRunEvNb; + SInt32 ProInfRunFileSz; + SInt32 ProInfRunEvNbPerFile; + SInt32 ProInfRunBlocNbPerFile; + SInt32 ProInfZsFFrameRawSz; + + // Intermediate variables for processing + + SInt8 ProConfDone; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + + + SInt8 ProLastEvAccessDoneInOneMi26Mode; + SInt32 ProCurBlocNoInRun; + SInt32 ProCurFileNo; + SInt32 ProCurBlocNoInFile; + char ProCurFileName[GLB_FILE_PATH_SZ]; + + MI26__TZsFFrameRaw* ProPtFFrameRaw; + + + public: + + MI26__TCZsRunRW (); + ~MI26__TCZsRunRW (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + SInt32 PubFSetMeasTime ( SInt8 Yes ); + SInt32 PubFSetPrintMsg ( SInt8 Print ); + SInt32 PubFSetPrintEvHeader ( SInt8 Print ); + + SInt32 PubFGetMeasTime (); + SInt32 PubFGetPrintMsg (); + SInt32 PubFGetPrintEvHeader (); + + SInt32 PubFGetMi26Nb (); + SInt32 PubFGetEvNb (); + SInt32 PubFGetEvNbPerFile (); + + SInt32 PubFLoadRun ( char* RunDir, UInt32 RunNo ); + + MI26__TZsFFrameRaw* PubFGotoEvOneMi26 ( SInt8 Mi26No, SInt32 EvNo ); + MI26__TZsFFrameRaw* PubFGotoEvAllMi26 ( SInt32 EvNo ); + + SInt32 PubFCloseRun (); + +}; + +#endif + +// 01/08/09 + +typedef struct { + + UInt32 IndexInEvWithHitList; + ASIC__TFrameStatus FrStatus; + +} MI26__TCTelMon_TEltListEvWithHitAllPlanes; + + +// 02/08/09 + +typedef struct { + + SInt16 x; + SInt16 y; + +} MI26__TCTelMon_THit; + +// 02/08/09 + +typedef struct { + + MI26__TCTelMon_THit AAHits[MAPS__TCDigTelMon_MAX_PLANE_NB][MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE]; + SInt32 AHitsNbPerPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + +} MI26__TCTelMon_TTrack; + +// 02/08/09 + +typedef struct { + + SInt8 Full; + SInt8 PlaneNb; + SInt32 EvNb; + MI26__TCTelMon_TTrack ATracks[MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB]; + + +} MI26__TCTelMon_TResRun; + + +// 17/07/09 + +#ifndef ROOT_ROOT + +#ifndef APP__RMV_CLASSES + +class MI26__TCTelMon : public MAPS__TCDigTelMon { + + private: + + SInt8 PrivStopProc; + + // ------------------------------------------- + // Plot colors of planes for coincidence mode + // ------------------------------------------- + + MI26__TColor PrivAPlanePlotColor[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // ------------------------------------------------------ + // Variables to store frames : pixel, cumul, plot color + // ------------------------------------------------------ + + MI26__TZsFFrameRaw* PrivPtAcqData; // Copy of Acq data, enabled if MakeLocalCpy parameter of PubFAddEvents (...) is set + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, MI26__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + SInt32 PrivAcqEvNb; // Event nb of current Acq = parameter EvNb of last PubFAddEvents (...) call + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, MI26__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + + MI26__TZsFFrame PrivZsFFrame; // Tmp var to store ZsFFrameRaw converted to ZsFFrame + // Used for each frame converted + + MI26__TMatDiscriBit PrivMatDiscriCoin; // Result for planeS coin plot AS PIXELS full scale matrix + MI26__TMatDiscriCumul PrivMatDiscriCoinCum; // Result for planeS coin cumul plot AS COUNT full scale matrix + + MI26__TMatDiscriBitHalfScale PrivMatDiscriBitHalfScale; // Result for planeS coin plot AS PIXELS 1/2 scale matrix + MI26__TMatDiscriCumulHalfScale PrivMatDiscriCumHalfScale; // Result for planeS coin cumul plot AS COUNT 1/2 scale matrix + + MI26__TMatDiscriColor PrivMatDispColor; // Result in matrix color data for ALL KINDS of plots + MI26__TMatDiscriColorHalfScale PrivMatDispColorHalfScale; // Result in 1/2 scale matrix color data for ALL KINDS of plots + + // ===================================================================== + // Lists to store informations results of events processing + // ===================================================================== + + // Flag to enable / disable list update + // It's useful to disable list update for data re-processing ( off-line ) with information of list + // because list informations should not been updates while using them for current data processing ... + // + // The following methods set this flag to one + // - PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ) + + SInt8 PriEnListUpdate; + + // --------------------------- + // List of events with trigger + // --------------------------- + + SInt32 PrivListEvWithTrigIndex; // Current elt index + SInt8 PrivListEvWithTrigFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithTrig[MI26__TCTelMon__EV_LIST_MAX_CHAN_NB]; + + // --------------------------- + // List of events with hit(s) + // --------------------------- + + SInt32 PrivListEvWithHitIndex; // Current elt index + SInt8 PrivListEvWithHitFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithHit[MI26__TCTelMon__EV_LIST_MAX_CHAN_NB]; // List + + // ----------------------------------------- + // List of events with hit(s) on all planes + // ----------------------------------------- + + SInt32 PrivListEvWithHitAllPlanesIndex; // Currenr elt index + SInt8 PrivListEvWithHitAllPlanesFull; // Full flag + SInt8 PrivListEvWithHitAllPlanesCurProcMode; // Current processing mode + // Uses to know if data must be reprocessed in cas user + // has changed list mode via ProPar.ListHitAllPlanesMode + + // The list array ( dynamic allocation ) + + MI26__TCTelMon_TEltListEvWithHitAllPlanes* PrivAListEvWithHitAllPlanes; + + // --------------------------------------------------------------------- + // Result run after data processing + // --------------------------------------------------------------------- + + MI26__TCTelMon_TResRun* PrivPtResRun; + + // --------------------------------------------------------------------- + // General init function : reset all variables, called by constructor + // --------------------------------------------------------------------- + + SInt32 PrivFInit (); + + // --------------------------------------------------------------------- + // Processing function + // --------------------------------------------------------------------- + + SInt32 PrivFConvZsFFrameToMatDiscriBitAndCumul ( SInt32 DbgEvNo, SInt8 Mode, SInt8 PlaneNo, SInt8 PlaneSelForCoin, SInt8 EvNo, SInt8 EvSelForPlot, MI26__TZsFFrame* PtSrc, MI26__TMatDiscriBit* PtDestFrameBit, MI26__TMatDiscriBit* PtDestCoinBit, MI26__TMatDiscriCumul* PtDestFrameCum, MI26__TMatDiscriCumul* PtDestCoinCum, SInt8 PrintLvl ); + + + // --------------------------------------------------------------------- + // Lists ( events with trigger / hit ) add events functions + // --------------------------------------------------------------------- + + SInt32 PrivFAddEvInListEvWithTrig ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt ); + SInt32 PrivFAddEvInListEvWithHit ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt, SInt8 HitOnAllPlanes, SInt8 SingleHitOnEachPlane ); + + protected: + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Process one frame = one event of plane specified by Id (0..5) + + SInt32 ProFProcessPlane ( SInt32 DbgEvNo, SInt8 Id, MI26__TZsFFrameRaw* PtSrc ); + + + + public: + + // -------------------------------------------------------------------------- + // Flag to select one Acq off-line processing / full RUN off-line processing + // -------------------------------------------------------------------------- + // Will be done via a method later + // 06/08/2009 + // -------------------------------------------------------------------------- + + SInt8 PubAcqOffLineProcOrRunOffLineProc; + + // ------------------------------------------- + // Constructor & Destructor + // ------------------------------------------- + + MI26__TCTelMon (); + ~MI26__TCTelMon (); + + // ------------------------------------------------------------ + // Begin method => MUST be called before ANY other function ! + // ------------------------------------------------------------ + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 MaxBuffEvNb ); + + // ------------------------------------------- + // GUI handling methods + // ------------------------------------------- + + #ifndef ROOT_ROOT + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGetGuiPar (); + + #endif + + // ------------------------------------------- + // Run control methods + // ------------------------------------------- + // Allocate / free buffers + // ------------------------------------------- + + SInt32 PubFStartRun ( SInt8 MapsNb ); + SInt32 PubFStopRun (); + + // ------------------------------------------- + // Monitoring control methods + // ------------------------------------------- + + SInt32 PubFStartMon (); + SInt32 PubFStopMon (); + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Add events in on-line monitoring mode and call data processing methods ( protected ) + + SInt32 PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt32 EvNb, MI26__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + // Off-line processing of data + // WARNING : NOW - 26/07/2009 - IT'S ONLY data of LAST acquisition ( data provided by last call to PubFAddEvents ) + // => Uses as events number the one of last acq + // => Force mode to "Process one Acq" AND update GUI parameters + + SInt32 PubFProcessOffLineCurAcq (); + SInt32 PubFProcessOffLineCurAcq2 (); + + // Select frame to plot + + SInt32 PubFGotoFirstFrame (); + SInt32 PubFGotoPrevFrame (); + SInt32 PubFGotoNextFrame (); + SInt32 PubFGotoLastFrame (); + + // ------------------------------------------- + // Results print methods + // ------------------------------------------- + + // Print list of events with a trigger detected => print SStatus record + + SInt32 PubPrintListEvWithTrig ( SInt8 Verbose ); + + // Print list of events with at least one hit in one plane => print SStatus record + + SInt32 PubPrintListEvWithHit ( SInt8 Verbose ); + + // Print list of events with hit on ALL planes => print SStatus record + + SInt32 PubPrintListEvWithHitOnAllPlanes ( SInt8 Verbose ); + + // Print res run + + SInt32 PubAllocResRun (); + SInt32 PubFreeResRun (); + SInt32 PubPrintResRun (); + SInt32 PubSaveResRun ( char* FileName ); + + + SInt32 PubFIsEvInListEvWithHitOnAllPlanes ( SInt32 EvNo ); + SInt32 PubFIsEvLastOfListEvWithHitOnAllPlanes ( SInt32 EvNo ); + + SInt32 PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ); + + + // ------------------------------------------- + // Results plot methods + // ------------------------------------------- + + // There is NO plot method in class. + // + // Because a call of a plot function ( from plot lib ) in DAQ supervisor thread doesn't work + // - nothing is displayed ! + // - this may crash the application + // I don't know why and have no time to study and understand this bug. I have found a workarround + // by calling the plot function in an application timer. + // + // The class request plot by setting the flag ProRequestPlot to 1 + // plot is done by "plot timer" callback in application which + // reset the flag ProRequestPlot after plot. + + // The application "plot timer" must know : + // - when he must plot --> Test variable pointed by PubFGetPtPlotRq () + // - the matrix to plot : full / half scale --> Test variable pointed by PubFGetPtDispFullMatrix () + // - the data to plot --> Read via pointer given by PubFGetPtFullMatCol () / PubFGetPtHalfMatCol () + // + // Polling of plot request and access to data is NOT DONE via method calls because + // - calling class methods in timer while other methods may be called in DAQ supervisor thread MAY cause problems => No detailed understanding, no time ... + // - it will save execution time by avoiding function call + + SInt8* PubFGetPtDispFullMatrix (); + MI26__TMatDiscriColor* PubFGetPtFullMatCol (); + MI26__TMatDiscriColorHalfScale* PubFGetPtHalfMatCol (); + + +}; + +#endif + + +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.0.0/types.typ b/include/pxi_daq_lib_v.0.0/types.typ new file mode 100755 index 0000000..829c736 --- /dev/null +++ b/include/pxi_daq_lib_v.0.0/types.typ @@ -0,0 +1,151 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.typ +Goal : Common basic types definitions. + : I never use default C types names ( char, int ... ) + : i redefined them here ( SInt8, UInt32 ... ). + : + : If something go wong on you'r plateform with C types + : definition you need to update this file. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +/*H**************************************************************************** +FILE : Types.Typ +BUT : Define types. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_TYP +#define TYPES_TYP + + // typedef enum ELang { ELang_FRENCH, ELang_ENGLISH, ELang_GERMAN, ELang_LANG_NB } TLang; + +#ifndef NODEFTYPCHAR + +/* +17/11/04 GC + +BCPPB declares an identfier with the same name " Char " +this problem happens while compiling Mimo* JTAG application (MP). +This Char identifier is used in SpinEdit object. + +MP used conditionnal compilation, i decided to remove this Char +type definition, because i believe i never use it. +Wait and see ... + +*/ + +/* typedef unsigned char Char; */ + +#endif + +#ifndef UInt8 + typedef unsigned char UInt8; +#endif + +#ifndef UByte + typedef UInt8 UByte; +#endif + +#ifndef SInt8 + typedef char SInt8; +#endif + +#ifndef SByte + typedef SInt8 SByte; +#endif + +#ifndef UInt16 + typedef unsigned short UInt16; +#endif + +#ifndef UWord + typedef UInt16 UWord; +#endif + +#ifndef SInt16 + typedef short SInt16; +#endif + +#ifndef SWord + typedef SInt16 SWord; +#endif + +#ifndef UInt32 + typedef unsigned long int UInt32; +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + typedef long int SInt32; +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif + + +#ifndef UInt64 + /* typedef unsigned __int64 UInt64; */ + typedef unsigned long long int UInt64; /* required for Linux */ +#endif + + +#ifndef SInt64 + /* typedef __int64 SInt64; */ + typedef long long int SInt64; /* required for Linux */ +#endif + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/asic.def b/include/pxi_daq_lib_v.1.0/asic.def new file mode 100755 index 0000000..a191e22 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/asic.def @@ -0,0 +1,92 @@ + + +/******************************************************************************* +File : x:\lib\com\asic\asic.def +Goal : Macros definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_DEF +#define ASIC_DEF + + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef enum { + + ASIC__NONE, + ASIC__MI26, + ASIC__ULT1 + +} ASIC__TEAsicName; + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__MI26_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__MI26_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__MI26_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__MI26_TRIG_TOT_NB // Total number of triggers + +} ASIC__MI26_TETrigRes; + + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__ULT1_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__ULT1_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__ULT1_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__ULT1_TRIG_TOT_NB // Total number of triggers + +} ASIC__ULT1_TETrigRes; + + +#define ASIC__ENUM_TRIG_RES_NB 4 + + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/asic.typ b/include/pxi_daq_lib_v.1.0/asic.typ new file mode 100755 index 0000000..51d7703 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/asic.typ @@ -0,0 +1,51 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.typ +Goal : Types definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_TYP +#define ASIC_TYP + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + SInt8 AsicNo; // Index of Asic <0..N-1> in case more than one is acquired + SInt32 AcqNo; // Index of current acquisition + SInt32 FrameNoInAcq; // Index of frame in acquisition <0..AcqFrameNb-1> + SInt32 FrameNoInRun; // Index of frame in run <0..TotEventNb-1> + + SInt32 HitCnt; // Counter of hits in frame + // Used for monitoring, may be not set, therefore HitCnt = -1 + + + SInt32 ATrigRes[ASIC__ENUM_TRIG_RES_NB]; // Information about trigger, see ASIC__MI26_TETrigRes in asic.def + // Parameters list index is + // ASIC__MI26_TRIG_RES__SIG_LINE + // ASIC__MI26_TRIG_RES__SIG_CLK + // ASIC__MI26_TRIG_RES__LINE + // ASIC__MI26_TRIG_TOT_NB + +} ASIC__TFrameStatus; + + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/asic.var b/include/pxi_daq_lib_v.1.0/asic.var new file mode 100755 index 0000000..452512e --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/asic.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.var +Goal : Variables definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_VAR +#define ASIC_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN VAR_STATIC SInt8 ASIC__VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/errors.c b/include/pxi_daq_lib_v.1.0/errors.c new file mode 100755 index 0000000..a263280 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/errors.c @@ -0,0 +1,336 @@ + +/******************************************************************************* +File : x:\lib\com\errors\errors.c +Goal : Implement errors messages print ( screen ) or log ( file ) functions. + : Each function use " errors macros " to log errors and return code. + : +Remark : The way it works is controlled by 3 globals variables + : ERR_VGLogClosed = 0 ( disable ) / 1 ( enable ) errors messages + : ERR_VGLogPath = '/tmp/errors.txt' = path of error logfile + : ERR_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_C +#define ERRORS_C + + +#ifdef CC_APP_OS9 + +char* strerror ( SInt32 errno ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + sprintf ( VMsgStr, "Not avalibale under OS9" ); + + return (VMsgStr); +} + +#endif + +#ifndef CC_APP_WINDOWS + + +char *_strerror ( char* UsrStr ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + #ifdef APP_ROOT + sprintf ( VMsgStr, "%s : No errno str because not supported by ROOT", UsrStr ); + #else + strncpy ( VMsgStr, UsrStr, ERR_USR_MSG_SZ-10 ); + strcat ( VMsgStr, " : " ); + strncat ( VMsgStr, strerror ( errno ), ERR_SYS_MSG_SZ-10 ); + #endif + + + return (VMsgStr); +} + + +#endif + +SInt32 ERR_FEnableLog ( SInt8 Enable ) { + + ERR_VGLogClosed = Enable; + ERR_VGFileLogEnable = Enable; + ERR_VGUserLogEnable = Enable; + + return (0); +} + +SInt32 ERR_EnableLog ( SInt8 Enable ) { + return ( ERR_FEnableLog ( Enable) ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetFileLogEnabled () { + return ( ERR_VGFileLogEnable ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetUserLogEnabled () { + return ( ERR_VGUserLogEnable ); +} + + +SInt32 ERR_FSetLogFilePath ( char* LogFilePath ) { + sprintf ( ERR_VGLogPath, "%s", LogFilePath ); + return (0); +} + +char* ERR_FGetLogFilePath () { + return ( ERR_VGLogPath ); +} + +SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath ) { + ERR_FEnableLog ( Enable ); + ERR_FSetLogFilePath ( FilePath ); + + return (0); +} + + +SInt32 ERR_FEnd () { + return (0); +} + + +SInt32 ERR_FStopLog ( SInt8 Stop ) { + ERR_VGFileDontLog = Stop; + return (0); +} + +/* 11/06/2005 */ + +SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel ) { + ERR_VGFileLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetFileLogLevel () { + return ( ERR_VGFileLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FLogLevel2Str ( SInt8 Lvl ) { + + static char VStr[GLB_CMT_SZ+1]; + + switch ( Lvl ) { + + case ERR_LOG_LVL_NONE : { + sprintf ( VStr, "ERR_LOG_LVL_NONE" ); + break; } + + case ERR_LOG_LVL_ALL : { + sprintf ( VStr, "ERR_LOG_LVL_ALL" ); + break; } + + case ERR_LOG_LVL_WARINGS_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_WARINGS_ERRORS" ); + break; } + + case ERR_LOG_LVL_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_ERRORS" ); + break; } + + default : { + sprintf ( VStr, "Unknow error level = %d", Lvl ); + break; } + + } + + return ( VStr ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetFileLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGFileLogLevel ) ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel ) { + ERR_VGUserLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetUserLogLevel () { + return ( ERR_VGUserLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FGetUserLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGUserLogLevel ) ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetErrLogConfStr () { + + static char VStr[GLB_CMT_SZ+1]; + + sprintf ( VStr, "Error log configuration \n\n - File log enabled = %d \n - File log level = %s \n - File stop log =%d \n - Log file name = %s \n - User log enabled = %d \n - User log level = %s \n - User stop log =%d \n\n", ERR_VGFileLogEnable, ERR_FGetFileLogLevelStr (), ERR_VGFileDontLog, ERR_VGLogPath, ERR_VGUserLogEnable, ERR_FGetUserLogLevelStr (), ERR_VGUserDontLog ); + + return (VStr); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FUserStopLog ( SInt8 Stop ) { + ERR_VGUserDontLog = Stop; + return (0); +} + +/* 10/06/2005 */ + +SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func ) { + + ERR_VGUserErrorFunc = Func; + + return (0); +} + +SInt32 ERR_FGenError ( char MsgType ) { + + static char VErrMsg[ERR_TOT_MSG_SZ]; + + ERR_VGLastErrMsg = VErrMsg; + + /* ERR_VGLogLevel */ + /* == ERR_LOG_LVL_NONE => No log */ + /* == ERR_LOG_LVL_ALL => Log 'T', 'W', 'E' */ + /* == ERR_LOG_LVL_WARINGS_ERRORS => Log 'W', 'E' */ + /* == ERR_LOG_LVL_ERRORS => Log 'E' */ + + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_NONE) && (ERR_VGUserLogLevel == ERR_LOG_LVL_NONE) ) { + return (0); + } + + sprintf ( VErrMsg, "%s%s \n", ERR_VGStrLocationMsg , ERR_OUT ); + + /* File log handling */ + + while (1) { + + if ( ERR_VGFileLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Write error message to file */ + + if ( ERR_VGLogClosed && (ERR_VGLogFile != stdout) && (ERR_VGLogFile != stderr) ) { + ERR_VGLogClosed = 0; + // + // 29/10/10 => Don't open log file in append mode but overwrite it + // + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); + } + + if ( (ERR_VGFileDontLog == 0) && (ERR_VGLogFile != NULL) ) { + fprintf ( ERR_VGLogFile, VErrMsg ); + fflush ( ERR_VGLogFile ); + } + + break; + } + + /* User log handling */ + + while (1) { + + if ( ERR_VGUserLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Call user error function */ + + if ( (ERR_VGUserDontLog == 0) && (ERR_VGUserErrorFunc != NULL) ) { + ERR_VGUserErrorFunc ( MsgType, ERR_VGStrLocationMsg , ERR_OUT, VErrMsg ); + } + + break; + } + + + + + + + return (0); +} + + + +char* ERR_FGetLastErrMsg () { + + return (ERR_VGLastErrMsg); + +} + + + +void FPrint ( void ) +{ + printf ( "%s \n", VGOut ); +} + +//========================================================================================= + + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.1.0/errors.def b/include/pxi_daq_lib_v.1.0/errors.def new file mode 100755 index 0000000..40969a2 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/errors.def @@ -0,0 +1,153 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.def +Goal : Macros definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef ERRORS_DEF +#define ERRORS_DEF + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + + +#ifdef CC_APP_WINDOWS + + #ifndef __FUNCTION__ + + #ifdef CC_COMPILER_CPPB_4 + #define __FUNCTION__ "? Not available" + #endif + + #ifdef CC_COMPILER_CPPB_6 + #define __FUNCTION__ __FUNC__ + #endif + + #endif + +#endif +// ms 24 11 2009 changed size from 100 to 256 +#define ERR_USR_MSG_SZ 256 +#define ERR_SYS_MSG_SZ 256 +#define ERR_TOT_MSG_SZ (ERR_USR_MSG_SZ + ERR_SYS_MSG_SZ) + + +/* 07/04/2007 ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ +/* #define ERR_OUT ERR_VGStrUserMsg */ + + +/* 07/04/2007 - Use a local variable in each function because __FUNCTION__ IS NOT handled by CNT ... */ +/* __LINE__ is replaced by 0 because __LINE__ because ... __LINE__ is not handled file by file ... */ + +#ifdef APP_ROOT + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,VFuncName, 0 /* __LINE__ */ );} +#else + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,__FUNCTION__,__LINE__ );} +#endif + + + +#define ERR_WARNING(Msg) { sprintf Msg; ERR_LOCATION ('W'); ERR_FGenError ('W'); } + +#define ERR_ERROR(Msg) { sprintf Msg; ERR_LOCATION ('E'); ERR_FGenError ('E'); } + +#define ERR_TRACE(Msg) { sprintf Msg; ERR_LOCATION ('T'); ERR_FGenError ('T'); } + + +#define ERR_RET(Code,MsgOk,MsgFail) { \ + if ((Code)<0) ERR_ERROR (MsgFail) \ + else ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_RET_FAIL(Code,MsgFail) { \ + if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (Code); } \ + } + + + +#define ERR_RET_FAIL_NULL(Code,MsgFail) { \ +if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (NULL); } \ + } + + + +#define ERR_RET_NULL(Ptr,MsgFail) { \ +if ((void*)(Ptr)==NULL) { ERR_ERROR (MsgFail) return (-1); } \ + } + + + +#define ERR_RET_OK(MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (0); \ + } + + + +#define ERR_RET_VAL(Code,MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_TYPE_ID(Id) ( 0x5A00 | Id ) + +#define ERR_TYPE_CHK(Pt,TypeId) { \ +if ( *( (UInt16*) (Pt) ) != ERR_TYPE_ID(TypeId) ) { \ + err_retfail ( -1, (ERR_OUT,"Bad type used Type Id = %x MUST be %x => Check the function call parameters in your source code", *( (UInt8*) (Pt) ) , TypeId ) ); \ + } \ + } + + +#define err_trace(Msg) ERR_TRACE(Msg) +#define err_tracel(Lvl,Msg) ERR_TRACE(Msg) +#define err_warning(Msg) ERR_WARNING(Msg) +#define err_error(Msg) ERR_ERROR(Msg) + +#define err_ret(Code,MsgOk,MsgFail) ERR_RET(Code,MsgOk,MsgFail) +#define err_retok(MsgOk) ERR_RET_OK(MsgOk) +#define err_retval(Code,MsgOk) ERR_RET_VAL(Code,MsgOk) +#define err_retfail(Code,MsgFail) ERR_RET_FAIL(Code,MsgFail) +#define err_retfailnull(Code,MsgFail) ERR_RET_FAIL_NULL(Code,MsgFail) +#define err_retnull(Ptr,MsgFail) ERR_RET_NULL(Ptr,MsgFail) + +#define err_typechk(Pt,TypeId) ERR_TYPE_CHK(Pt,TypeId) + +#define PRINT(msg) { sprintf (VGOut, "%s",msg); FPrint (); } +#define RETURN_ERROR(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (FALSE); } +#define RETURN_ERROR_2(msg1,msg2) { sprintf (VGOut, "%s %s",msg1,msg2); FPrint (); return (FALSE); } + +#define RETURN_ERROR_NULL(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (NULL); } +#define RETURN_OK { return (TRUE);} + + + + +#endif + + +// trace (( ERR_OUT, "", par )); +// retfail ( Code, (ERR_OUT,"MsgFail",par) ); +// retnull ( Code, (ERR_OUT,"MsgFail",par) ); // Pointer == NULL => Ret -1 +// error (( ERR_OUT, "", par )); + + diff --git a/include/pxi_daq_lib_v.1.0/errors.typ b/include/pxi_daq_lib_v.1.0/errors.typ new file mode 100755 index 0000000..983ef79 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/errors.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.typ +Goal : Types definition if error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_TYP +#define ERRORS_TYP + +typedef SInt32 (*ERR_TUserErrorFunc) ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ); + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/errors.var b/include/pxi_daq_lib_v.1.0/errors.var new file mode 100755 index 0000000..d36cd82 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/errors.var @@ -0,0 +1,79 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.var +Goal : Variables definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_VAR +#define ERRORS_VAR + + +/* + +EXTERN VAR_STATIC SInt8 ERR_VGLogClosed VAR_INIT (0); // Set to 1 to allow error loggin +EXTERN VAR_STATIC SInt8 ERR_VGFileDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogLevel VAR_INIT (ERR_LOG_LVL_ALL); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogLevel VAR_INIT (ERR_LOG_LVL_ALL); + +EXTERN VAR_STATIC char ERR_VGLogPath[GLB_FILE_PATH_SZ] VAR_INIT ("/dd/tmp/pc/errors.txt"); +EXTERN VAR_STATIC FILE *ERR_VGLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC FILE *ERR_VGTmpLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC SInt32 ERR_VGMsgCnt VAR_INIT (0); +EXTERN VAR_STATIC ERR_TUserErrorFunc ERR_VGUserErrorFunc VAR_INIT (NULL); +EXTERN VAR_STATIC char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ]; +EXTERN VAR_STATIC char ERR_VGStrUserMsg[ERR_TOT_MSG_SZ]; + +EXTERN VAR_STATIC char VGOut[255]; + +*/ + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_VGLogPath[GLB_FILE_PATH_SZ] , "/dd/tmp/pc/errors.txt"); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGTmpLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt32 ERR_VGMsgCnt , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, ERR_TUserErrorFunc ERR_VGUserErrorFunc , NULL); +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ] ); + +/* 07/04/2007 - ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ + +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + +VAR_DCL ( EXTERN, VAR_STATIC, char VGOut[255] ); + +// 21/12/2010 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char *ERR_VGLastErrMsg, "NULL"); + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.1.0/eudet_frio.def b/include/pxi_daq_lib_v.1.0/eudet_frio.def new file mode 100755 index 0000000..112ee47 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/eudet_frio.def @@ -0,0 +1,226 @@ + + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.def +Goal : Macros definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_DEF +#define EUDET_FRIO_DEF + + +/* ======================= */ +/* Conditional compilation */ +/* ======================= */ + +// Enable EFRIO__FRAME_TAGS_ENABLE to add tags at beginning of EFRIO__TFrame record and sub-records +// +// Each sub-record has it own tag, see list of constants at end of file +// +// EFRIO__TFrame -> EFRIO__FRAME_TAG +// EFRIO__TFrameHeader -> EFRIO__FRAME_TAG_HEADER +// EFRIO__TFrameData -> EFRIO__FRAME_TAG_DATA +// EFRIO__TTriggerRec -> EFRIO__FRAME_TAG_TRIG + +#define EFRIO__FRAME_TAGS_ENABLE + + + + +// Enable / Disable demultiplexing of Mimosa 26 data part +// +// It has NO effect if running with a single Mimosa 26 +// +// In case of multiple Mimosa 26 acquisition, Flex RIO provides multiplexed data +// +// W32[0] Mi26 No 0 , W32[0] Mi26 No 1 ... W32[0] Mi26 No 5 +// W32[1] Mi26 No 0 , W32[1] Mi26 No 1 ... W32[1] Mi26 No 5 +// W32[2] Mi26 No 0 , W32[2] Mi26 No 1 ... W32[2] Mi26 No 5 +// W32[3] Mi26 No 0 , W32[3] Mi26 No 1 ... W32[3] Mi26 No 5 +// +// Data are demultiplexed if this directive is enabled +// This processing will cost CPU time -> it may be done on EUDET SW side if needed +// that's why this processing can be disabled + +#define EFRIO__DEMUX_MI26_DATA_PART + + + + + +/* ================= */ +/* Macro */ +/* ================= */ + + +// Test if board Id is valid, if not return (-1) and lof error message + +#define EFRIO__CHK_BOARD_ID(BoardId) { if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) err_retfail ( -1, (ERR_OUT,"Abort : Bad board Id=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 ) ); } + + +/* ================= */ +/* Constants */ +/* ================= */ + + +// Maximum board number handle by the lib ( define arrays size ) + +#define EFRIO__MAX_BOARDS_NB 2 + +// Maximum ASIC nb handle by the lib ( define arrays size ) + +// #define EFRIO__MAX_ASIC_NB 6 before 21/02/2011 + +#define EFRIO__MAX_ASIC_NB 16 // Set to 16 on 21/02/2011 + + +// Maximum number of frames per acquisition ( define arrays size ) +// - One frame = one readout of MAPS +// - One acquisition = N consecutives frames acquired in one call of board readout function + +#define EFRIO__MAX_FRAME_NB_PER_ACQ 1800 + + +// ************************************************************************************************************* +// Data transfer modes +// ************************************************************************************************************* +// Few information about how the Flex RIO board acquired Mimosa 26 +// +// - Flex RIO board can acquire the data of up to 6 Mimosa 26 and deserialize them +// Each Mimosa 26 is seen as an "acquisition channel", because fw is organized / Mimosa 26 +// +// - Now the fw doesn't care about trigger to select which frame to acquire, all frames are stored and the selection +// is done on-line by DAQ sw. Because it will be more flexible to adjust & modify trigger handling by sw rather than +// by fw and for 6 Mimosa 26 it seems possible to do it on execution time point of view. +// Later, this processing will be moved in fw, for AIDA but for EUDET it should work fine by sw. +// +// - The fw counts triggers and store it's own trigger information "Mimosa 26 trigger" ( the Mimosa 26 line read when trigger occurs ) +// This trigger information is written in the zero fields of Mimosa 26 ( by overwritting them ) +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 +// +// - An extra acquisition channel can be enabled to store trigger from TLU ( it has the same size as a Mimosa 26 channel = 2304 W8 ) +// It will store two W32 informations for each trigger +// - The trigger TLU -> See record EFRIO__TTluTrigger +// - The trigger from Flex RIO ( Mimosa 26 line + frame ) -> See record EFRIO__TFlexRioTimeStamp1 +// The extra channel can store up to 288 triggers ( 288 * W32 * 2 = 2304 ) +// +// We have decided to implement 4 data transfert mode, the difference is on trigger handling and only the last one will +// be useful for EUDET => EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// +// * EFRIO__TRF_MODE_IPHC +// +// Keep compatibility with IPHC DAQ -> limited to 3 triggers + data demultiplex which cost CPU time +// +// * EFRIO__TRF_MODE_EUDET__NO_TRG_CHAN, +// +// Send all frames, store 3 first "Mimosa 26 trigger", don't store TLU trigger +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_ALL_FRAMES, +// +// Send all frames, store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// Send only frame with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG +// store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// + + +typedef enum EFRIO__TRF_MODE { + EFRIO__TRF_MODE_IPHC, + EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, + EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, + EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + +} EFRIO__TTrfMode; + + +// We use the two "zero fields" of each 32 bits at the end of Mimosa 26 data stream to store first three triggers +// It's not trigger from TLU but the trigger we used in our first BT with flex RIO = Mimosa 26 line index when trigger occurs +// +// This is the field Mi26Line of the record EFRIO__TFlexRioTimeStamp1 x 16 because unit is Mimosa 26 clock cycle +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 + + +#define EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA 3 // CAN'T be higher than 3 !!!!!!!!!! + + +// The current frame - with trigger - is not enough to build the physics event +// due to internal MAPS logic ( double memory, pipelines etc ... ) following frames must be also used +// => This is the number of frames to read after the one which contains trigger to build physics event + +#define EFRIO__FRAME_NB_TO_READ_AFTER_TRIG 3 // For Mimosa 26 it's 3 + +// Constants to define extra channel size -> Hard coded ( don't use sizeof ( xyz) ) in order to reduce execution time +// The extra channel is a MAPS acquisition channel ( it has he same size ) but used to store trigger information +// It can store up to 288 triggers / MAPS frame +// +// Now 28/10/2010 +// - Each trigger info stored in extra channel contain two fields, each one is a W32, in the following order +// -- EFRIO__TTluTrigger +// -- EFRIO__TFlexRioTimeStamp1 +// --> Total trigger info size is 2 x W32 = 8 bytes +// - The extral channel has the same size of one Mi26 frame = 2304 W8 +// --> Maximum number of trigger info which can be stored = 2304 / 8 = 288 +// --> It means one trigger each two lines of Mimosa 26 readout ... ;-) + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 288 // Maximum number of trigger info = pair of W32 fields TLU Trig + Felx RIO TS + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 576 // Maximum number of W32 fields + +#define EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ 8 // Size of the trigger info = pair of W32 fields TLU Trig + Flex RIO TS + +#define EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ 4 // Size of one W32 field + + +// Maximum number of messages / board -> define array in EFRIO__TBoardStatus + +#define EFRIO__ERROR_MSG_LIST_MAX_NB 100 + + +// Maximum number of triggers in DAQ emulation configurable by GUI +// We can emulate more triggers than EFRIO__MAX_GUI_TRIG_NB but their value is hard coded in emulation function to 0 +// +// Only the first three triggers and the last one ( if EFRIO__MAX_GUI_TRIG_NB = 4 ) are configurable from GUI + +// #define EFRIO__MAX_GUI_TRIG_NB 4 // WARNING => Redined (with same value) in C++ Builder emulation application ! + +#define EFRIO__MAX_EMUL_GUI_TRIG_NB 4 // WARNING => Redefined (with same value) in C++ Builder emulaion application ! + + +// Tags values to be added at beginning of each EFRIO__TFrame sub-record + +#define EFRIO__FRAME_TAG 0x55550000 +#define EFRIO__FRAME_TAG_HEADER 0x00000001 +#define EFRIO__FRAME_TAG_DATA 0x00000002 +#define EFRIO__FRAME_TAG_TRIG 0x00000003 + +// Maximum size of one acquisition store to disk => Used by FIL__TCStreamFile class + +#define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/eudet_frio.typ b/include/pxi_daq_lib_v.1.0/eudet_frio.typ new file mode 100755 index 0000000..fa09c63 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/eudet_frio.typ @@ -0,0 +1,792 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.typ +Goal : Types definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_TYP +#define EUDET_FRIO_TYP + + + +/* ============================================== */ +/* Board parameters configuration record */ +/* ---------------------------------------------- */ +/* Can be use to build a boards database */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// Remark for EUDET concerning trigger handling +// +// Most of the following trigger options will be useless for EUDET +// The operating mode for EUDET is : +// - The board takes data all the time regardless of trigger state +// - The fw store all triggers from TLU ( up to 288 / Mimsoa 26 frame ) are stored +// - The sw extract frames with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames after trigger + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + + char AsicName[GLB_CMT_SZ]; // The ASIC read by the board + + SInt32 AsicNb; // The number of ASICs read by the board + + SInt32 ReadoutMode; // The readout mode -> Future use + + SInt8 EmuleChannels; // Copy data of first MAPS in all channels, useful for test & debugging + // because it allows to run with one ASIC only but get data of all + + float DataClkFrequency; // Frequency of clock -> Future use, only useful in case board provide clock + + UInt32 DmaHostSz; // DMA size reserved on host CPU, must be >= size of one acquisition + + SInt32 FrameNbPerAcq; // Consecutives frames number stored during one acquisition + + SInt8 EnableExtraChannel; // Enable one more channel ( default is one channel per ASIC ) + // which can be used to store extra information -> eg : TLU trigger + + SInt32 AcqNbPerTrig; // TO BE CHECKED ! Number of consecutive acquisitions taken upon trigger detection by board + + SInt8 TriggerMode; // Trigger operating mode + + UInt32 TriggerDetectTimeWindow; // Time window during which we count triggers and decide to start acquisition if >= TriggerDetectOccurNb + + UInt32 TriggerDetectOccurNb; // Minimum trigger number during TriggerDetectTimeWindow to decide to start acquisition + + UInt32 TimeStampRes; // Resolution of time stamp + + SInt8 EnableTimeStamping; // Enable time stamping mode + + SInt8 EnableTrigCnt; // Enable trigger counter + + SInt8 TagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ ( HW line indicates that DUT has saved event ) + + UInt32 ReadTluTrigCntEachNTrig; // Period of reading TLU trigger + + +} EFRIO__TBoardConf; + + +/* ============================================== */ +/* Board status record */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + SInt8 BoardPresent; // Board present => 1, otherwise 0 + SInt8 FwLoaded; // Firmware has been loaded in board + SInt8 ConfDone; // The board has been configured by sw + + SInt32 StatusCode; // Current board status code + + char StatusStr[GLB_CMT_SZ]; // Status message associated to StatusCode + + // List of errors and last error + + char* ErrorMsgList[EFRIO__ERROR_MSG_LIST_MAX_NB]; + char LastErrorMsg[GLB_CMT_SZ]; + + // Registers read from board + + UInt32 RegDmaHostSz; // DMA host size in bytes + SInt32 RegFrameNbPerAcq; // Number of frames / acq + SInt8 RegEnableExtraChannel; // Extral channel state = enabled or not + SInt32 RegAcqNbPerTrig; // Consecutive acquisition nb per trigger + + SInt8 RegTriggerMode; // Trigger mode + UInt32 RegTriggerDetectTimeWindow; // Trigger detection window + UInt32 RegTriggerDetectOccurNb; // Number of triggers required during window to start acquisition + + UInt32 RegTimeStampRes; // Resolution of time stamp -> Check with CS if implemented ! + SInt8 RegEnableTimeStamping; // Enable time stamping mode -> Check with CS if implemented ! + + SInt8 RegEnableTrigCnt; // Enable trigger counter -> Check with CS if implemented ! + + SInt8 RegTagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ -> Check with CS if implemented ! + UInt32 RegReadTluTrigCntEachNTrig; // Period of reading TLU trigger -> Check with CS if implemented ! + + UInt64 RegTimeStamp; // Time stamp value + UInt32 RegTrigCnt; // Flex RIO rigger value + UInt32 RegTluTrigCnt; // TLU trigger value + +} EFRIO__TBoardStatus; + + + + +/* ============================================== */ +/* TLU trigger record */ +/* ---------------------------------------------- */ +/* Contains TLU trigger -> field TrigCnt */ +/* plus additional information */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 TrigCnt : 16; // Trigger counter read from TLU + UInt32 FrameIdInAcq : 11; // Index of frame in current acquisition during which trigger occurs ( 0 - 2407 ) + UInt32 EventTakenByDut : 1; // For future use : Flag at 1 if DUT has taken the event + UInt32 Reserved : 3; + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TTluTrigger; + + +/* ============================================== */ +/* Flex RIO time stamp 1 record */ +/* ---------------------------------------------- */ +/* This is the Flex RIO trigger, called */ +/* "time stamp" to avoid confusion / TLU */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Mi26Line : 10; // Line of Mi26 read during which trigger occurs + UInt32 Mi26Frame : 21; // Frame of Mi26 ( = frame counter field ) read during which trigger occurs + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TFlexRioTimeStamp1; + + +/* ============================================== */ +/* Frame header */ +/* ---------------------------------------------- */ +/* Each frame starts with a header which contains */ +/* - DAQ system info */ +/* - Mimosa 26 relevant fields */ +/* ---------------------------------------------- */ +/* Date : 22/10/2010 */ +/* Rev : 23/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_HEADER +#endif + + // New fields AcqStatus & TrigStatus 23/02/2011 + // + SInt32 AcqStatus; // Status of acquistion board for this acquisition + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + // + SInt32 TrigStatus; // No meaning now = reserved for future use + + UInt16 AcqId; // Index of acquisition containing this frame + UInt16 FrameIdInAcq; // Index of frame IN the CURRENT acquisition + + UInt16 MapsName; // MAPS name as a 16 bits code + UInt16 MapsNb; // Total number of MAPS in data + + UInt32 AMapsHeader[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 AMapsFrameCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 AMapsDataLength[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 AMapsTrailer[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + SInt16 TriggerNb; // Total triggers number during this frame + + UInt16 AMapsTrigInfo[EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA]; // First 3 "Mi26 trigger info" -> Line of Mi26 read during which trigger occurs + // if more than 3 trigger => look in trigger info block where all trigger are stored + +} EFRIO__TFrameHeader; + + +/* ============================================== */ +/* Frame data */ +/* ---------------------------------------------- */ +/* Each frame has a data part with variable size */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_DATA +#endif + UInt32 TotSz; // Total size of data bloc + UInt32 OneMapsSz; // Size of data of one MAPS + + UInt32 ADataW32[0]; // Beginning of data space + +} EFRIO__TFrameData; + + +/* ============================================== */ +/* Frame triggers list */ +/* ---------------------------------------------- */ +/* Each frame has a triggers list, up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB fields */ +/* which means up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB */ +/* trigger info */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_TRIG +#endif + UInt32 TotSz; // Total size of trigger info bloc + UInt16 TrigNb; // Total trigger nb + UInt16 TrigType; // Type of trigger info stored + + UInt32 ATrig[0]; // Beginning off triggers list + +} EFRIO__TTriggerRec; + + +/* ============================================== */ +/* Frame record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Data handling fields ( size etc ) */ +/* - The frame header */ +/* - The frame data part ( variable length ) */ +/* - Followed by the triggers info part */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new field DaqVersion */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG +#endif + SInt32 DaqVersion; // Version of DAQ - New field 21/02/2011 + SInt32 TotSz; // Total size of this frame + SInt32 TrigRecOffset; // Offset ( in bytes ) from beginning of frame to trigger info part + EFRIO__TFrameHeader Header; // Frame header + EFRIO__TFrameData Data; // Beginning of data part + + // The field EFRIO__TTriggerInfo is not defined here because "Data" has variable length + // the field BegData of Data field is used a pointer to beginning of data part + // The trigger info will be added at the end of this part but position is calculated dynamically + +} EFRIO__TFrame; + + +/* ============================================== */ +/* List of frames currently stored by lib */ +/* ---------------------------------------------- */ +/* This record stores frames list corresponding */ +/* to one acquisition */ +/* */ +/* It can be : */ +/* - frames acquired by DAQ */ +/* - frames loaded from a run file */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : */ +/* : 24/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// More information about frames storage in memory +// +// A buffer IS NOT allocated for EACH frame, a single bloc of memory is allocated for all frames of one acquisition. +// This will avoid copy frame by frame before sending them to Ethernet lib or saving them to disk. A single access +// can be done with a pointer on beginning of buffer and data size. +// +// But to process frames it's handly to have an array of pointers, each array item pointing on next frame, +// this is the goal of this list which provides : +// - The total number of frames in list +// - An array of pointers, eg : AFramePtr[2] points on third frame of acquisition +// - An array with the total size ( in bytes ) of each frame +// +// This list is built on-line while DAQ is running, or off-line via EFRIO__FBuildFrameListFromAcq (...) from +// the data of one acquisition stored in a run file. + +typedef struct { + + // New fields AcqStatus & TrigStatus 24/02/2011 + // + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + +} EFRIO__TFrameList; + + +/* ============================================== */ +/* Run configuration record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Run parameters -> Par... */ +/* - Informations built from Par etc -> Inf... */ +/* - Acquisition results ( ev cnt etc ) -> Res... */ +/* - Pointers to frames buffers */ +/* ---------------------------------------------- */ +/* This record is filled by EFRIO__FConfRun (...) */ +/* call with run parameters from GUI or Ethernet */ +/* ---------------------------------------------- */ +/* This record can be saved to disk as run config */ +/* file, but it can't be ONLY loaded from file ! */ +/* A call to EFRIO__FConfRun (...) must be done */ +/* because it allocates mem and do other tasks */ +/* -> load record from file */ +/* -> call EFRIO__FConfRun with record fields as */ +/* parameters, it will overwrite itself and all */ +/* " other tasks " will also be done */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new fields */ +/* : ParDaqVersion, ParMapsName */ +/* : - Change type of ParMi26Nb to S16 */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + +/* ============================================== */ +/* Acquisition emulation record */ +/* ---------------------------------------------- */ +/* This record contains context of DAQ emulator */ +/* application, it means : */ +/* - Parameters -> Par... */ +/* - Information, calculated from Par -> Inf... */ +/* - Results -> Res... */ +/* ---------------------------------------------- */ +/* All emulation functions are implemented in the */ +/* lib, therefore application task is only GUI. */ +/* That's why emulation context is defined here */ +/* ---------------------------------------------- */ +/* All run param for emulation are taken from */ +/* run config record -> EFRIO__TRunCont */ +/* ---------------------------------------------- */ +/* Date : 30/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqCycleMs; // Delai between two acquisitions + + SInt32 ParEmuleDRamReadMs; // Delai added to PC DRAM access to emulate Flex RIO DRAM access time + + SInt32 ParEmuleFunctNo; // Select emulation function to call -> Future use = not implemented now + + SInt8 ParRandomDataSz; // Enables random generation of data size per Mimosa 26 + // By default data size is fixed in emulation function + // Used to check if variabl length records are properly handled + + SInt8 ParSetMaxDataSzOnOneMaps; // Set maximum possible data sze on first Mi26, overwrite value set by emulation + // function, but next Mi26 keep the data size value from emulation function + // Used to check if DAQ loose frames while Mi26 provides full frames + + + UInt32 ParAHeader[EFRIO__MAX_ASIC_NB]; // Emulated header of each Mi26 + + UInt32 ParATrailer[EFRIO__MAX_ASIC_NB]; // Emulated trailer of each Mi26 + + SInt32 ParTrigNbPerFrame; // Number of trigger per frame, set the part trigger nb (B31B16) of Mi26 Zero1 field + + // In data transfer modes EUDET 2 & 3 a more complex trigger emulation is done + // We don't emulate ParTrigNbPerFrame on each frame but on N consecutives frames + // each M frames + // + SInt32 ParTrigOnOneFrameOverN; // Start emulate ParTrigNbPerFrame on one frame over M = ParTrigOnOneFrameOverN + SInt32 ParTrigOnNConsecutiveFrames; // Emulates on N consecutive frames = ParTrigOnNConsecutiveFrames + + // TLU trigger & Flex RIO trigger emulation + // Up to 288 couples TLU & Flex RIO triggers can be emulated but only EFRIO__MAX_EMUL_GUI_TRIG_NB + // are configurabbles from GUI, now EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + // - First three are configurable from GUI + // - The last one is configurable from GUI + // - Others are configured in emulation function and set to 0 + // + SInt32 ParATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated TLU trigger + SInt32 ParATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated Flex RIO trigger, called "Time stamp 1" + + // DRAM info to emulate Flex RIO readout ( we need a PC RAM bloc of same size as the board one ) + // + SInt32 InfDRamSzMb; // DRAM size in MB + SInt32 InfDRamSz; // DRAM size in bytes + UInt32* InfDRamPtr; // DRAM pointer + + SInt8 InfExtraChan; // Extra channel status ( enabled or not ) depends on data transfer mode ( -> run config ) + + char InfEmuleFuncCmt[GLB_CMT_SZ]; // A comment set by emulation function selected by ParEmuleFunctNo + // -> Future use = not implemented now + + // DAQ emulation results + // + SInt32 ResAcqCnt; // Acquisition counter + SInt32 ResEvCnt; // Events counter + // + SInt32 ResAcqFunctRetCode; // Error code returned by acquisition function + +} EFRIO__TAcqEmul; + + +/* ============================================== */ +/* Frames check record */ +/* ---------------------------------------------- */ +/* This is context of frames check functions */ +/* - EFRIO__MI26_FChkAcqIphcMode (...) */ +/* - EFRIO__MI26_FChkAcqEudetMode (...) */ +/* */ +/* They check frames integrity, can be used in */ +/* normal DAQ mode or emulation */ +/* ---------------------------------------------- */ +/* Date : 31/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqNo; // Acquisition index + + SInt32 ParFrNo; // Frame index + + SInt8 ParChkMode; // Check mode -> Allows to define a level of test + + SInt8 ParChkVerbose; // Verbose mode or not + + SInt8 ParFrPrintLevel; // Define the frame information printed in log file + // 0 -> No print + // 1 -> Print general info ( AcqId, FrameId, TrigNb ... ) + Mi26 header, frame cnt, trailer + // 2 -> Print also triggers list + + SInt8 InfMi26Nb; // Mi26 number runnig in the system + + // Values provided by DAQ to check + // They are compared to the " same fields " of EFRIO_TAcqEmul + // + UInt32 ResAHeader[EFRIO__MAX_ASIC_NB]; // Mi26 header + UInt32 ResATrailer[EFRIO__MAX_ASIC_NB]; // Mi26 trailer + UInt32 ResAFrameCnt[EFRIO__MAX_ASIC_NB]; // Mi26 frames counter + UInt32 ResADataLenght[EFRIO__MAX_ASIC_NB]; // Mi26 data part length ( in W8 not in W16 as in DataLength fields of Mi26 data stream ) + // + SInt32 ResTrigNb; // Trigger info ( couple TLU & Flex RIO trigger ) number UNDER GUI control => limited to EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + SInt32 ResATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // TLU triggers list + SInt32 ResATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Flex RIO trigegrs list + + SInt32 ResErrCnt; // Total errors counter => Information provide by DAQ <> value set in EFRIO_TAcqEmul + + +} EFRIO__TFrCheck; + +/* ============================================== */ +/* Board check record */ +/* ---------------------------------------------- */ +/* This is context of board check Vi */ +/* The board test is done by a Vi on Labview side */ +/* this record pass the parameters to the Vi */ +/* */ +/* Parameters are set via call to functions */ +/* EFRIO__FSetBoardChk... */ +/* */ +/* Parameters are read via call to functions */ +/* EFRIO__FGetBoardChk... */ +/* Theses functions are encapsulated in Vi */ +/* ---------------------------------------------- */ +/* */ +/* The test results are written in board status */ +/* record ABoardsStatus [BoardId] */ +/* */ +/* Test results are set or read functions */ +/* EFRIO__FSetBoardStatus... */ +/* EFRIO__FGetBoardStatus... */ +/* ---------------------------------------------- */ +/* Date : 22/12/2010 */ +/* Doc date : 22/12/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParBoardId; // Board to test + + SInt8 ParDoTheTest; // Set to 1 to request the test + // Reset once test has been started + + SInt32 ParTestId; // Identifier to select different tests + + SInt8 ResTestDone; // Set to 1 when test is finished + + SInt32 ResTestResult; // Test result + // < 0 => Test has failed + // = 0 => Test OK + +} EFRIO__TBoardCheck; + + +/* ============================================== */ +/* Spare W32 bloc of index file */ +/* ---------------------------------------------- */ +/* This record contains spare info for index file */ +/* ---------------------------------------------- */ +/* Date : 24/02/2011 */ +/* Doc date : 24/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + + SInt32 DiskSectorSz; // Size of disk sector + +} EFRIO__TFileSpareW32Info; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains monitoring via Eth conf */ +/* ---------------------------------------------- */ +/* Date : 15/02/2011 */ +/* Doc date : 15/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 InfFrameNbToSend; // Frame nb to send on Eth = " Frame nb per acq * % monitoring " + SInt32 InfSzToSend; // Size corresponding to InfFrameNbToSend + +} EFRIO__TMon; + + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : 07/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef struct { + + SInt8 InfInitDone; // Lib iit done or not + + EFRIO__TBoardConf ABoardsConf[EFRIO__MAX_BOARDS_NB]; // Acquisition boards config + EFRIO__TBoardStatus ABoardsStatus[EFRIO__MAX_BOARDS_NB]; // Acquisition boards status + + EFRIO__TBoardCheck BoardChk; // Reserved for future implementation + // Parameters record to check + // - Boards + // - Mimosa 26 Clk & Sync signals + + EFRIO__TAcqEmul AcqEmul; // DAQ emulation context + EFRIO__TFrCheck FrCheck; // Frames check functions context + + EFRIO__TRunCont RunCont; // Run context = parameters, memory allocated, results + + EFRIO__TMon MonCont; // Monitoring context + + EFRIO__TFrameList AAcqFrameList[1]; // Frame list of acquistion - Can be extended to more than one acq if needed + + // List of frame Id to read ( Eudet3Mode => Trigger + 2 following frames ) / acquistion - Can be extended to more than one acq if needed + + SInt16 AAAcqFrameWithTrigList[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + + EFRIO__TTriggerRec* PtTmpTrigRec; // Temporary triggers record used for internal processing + +} EFRIO__TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/eudet_frio.var b/include/pxi_daq_lib_v.1.0/eudet_frio.var new file mode 100755 index 0000000..2242f88 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/eudet_frio.var @@ -0,0 +1,39 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.var +Goal : Variables definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_VAR +#define EUDET_FRIO_VAR + + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC EFRIO__TContext EFRIO__VGContext; + +EXTERN VAR_STATIC FIL__TCStreamFile EFRIO__VGRunDataFile ( "x:\\log\\err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); +EXTERN VAR_STATIC FIL__TCBinFile EFRIO__VGRunConfFile ( "x:\\log\\err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); + +#ifdef EFRIO__INCLUDE_JTAG + EXTERN VAR_STATIC TCOMIMI26MasterConf EFRIO_VGJtagMi26; +#endif + +#endif diff --git a/include/pxi_daq_lib_v.1.0/eudet_frio_print.c b/include/pxi_daq_lib_v.1.0/eudet_frio_print.c new file mode 100755 index 0000000..3cb78e6 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/eudet_frio_print.c @@ -0,0 +1,1009 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_PRINT_C +#define EUDET_FRIO_PRINT_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert TLU trigger info record to string for print or display +: +Inputs : Trig - Source trigger record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display +: +Inputs : Ts - Source time stamp record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger / timestamp as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) + : +Goal : Print run context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Rev : 21/02/2011 + : - Print new fields ParDaqVersion, ParMapsName +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Run context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParDaqVersion = %.4d", PtRec->ParDaqVersion )); + msg (( MSG_OUT, "ParMapsName = %.4d", PtRec->ParMapsName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParMi26Nb = %.4d", PtRec->ParMi26Nb )); + msg (( MSG_OUT, "ParFrameNbPerAcq = %.4d", PtRec->ParFrameNbPerAcq )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParRunNo = %.4d", PtRec->ParRunNo )); + msg (( MSG_OUT, "ParTotEvNb = %.4d", PtRec->ParTotEvNb )); + msg (( MSG_OUT, "ParEvNbPerFile = %.4d", PtRec->ParEvNbPerFile )); + msg (( MSG_OUT, "ParDataTransferMode = %.4d", PtRec->ParDataTransferMode )); + msg (( MSG_OUT, "ParTrigMode = %.4d", PtRec->ParTrigMode )); + msg (( MSG_OUT, "ParSaveOnDisk = %.4d", PtRec->ParSaveOnDisk )); + msg (( MSG_OUT, "ParSendOnEth = %.4d", PtRec->ParSendOnEth )); + msg (( MSG_OUT, "ParSendOnEthPCent = %.4d", PtRec->ParSendOnEthPCent )); + msg (( MSG_OUT, "ParDestDir = %s" , PtRec->ParDestDir )); + msg (( MSG_OUT, "ParFileNamePrefix = %s" , PtRec->ParFileNamePrefix )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParJtagFileName = %s ", PtRec->ParJtagFileName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); +// msg (( MSG_OUT, "InfMi26FrameSzFromFlexRio = %.4d", PtRec->InfMi26FrameSzFromFlexRio )); + msg (( MSG_OUT, "InfZsFFrameRawBuffSz = %.4d", PtRec->InfZsFFrameRawBuffSz )); + msg (( MSG_OUT, "InfFrameBuffSz = %.4d", PtRec->InfFrameBuffSz )); + msg (( MSG_OUT, "InfConfFileName = %s" , PtRec->InfConfFileName )); + msg (( MSG_OUT, "InfDataFileName = %s" , PtRec->InfDataFileName )); + msg (( MSG_OUT, "InfSaveDataOnDiskRunning = %.4d", PtRec->InfSaveDataOnDiskRunning )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResFrameCnt = %.4d", PtRec->ResFrameCnt )); + msg (( MSG_OUT, "ResEventCnt = %.4d", PtRec->ResEventCnt )); + msg (( MSG_OUT, "ResDataRateMBytesPerSec = %.3f", PtRec->ResDataRateMBytesPerSec )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "PtZsFFrameRaw = %.8x", PtRec->PtZsFFrameRaw )); + msg (( MSG_OUT, "PtFrame = %.8x", PtRec->PtFrame )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunCont () + : +Goal : Print lib run context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunCont () { + + return ( EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) + : +Goal : Print board conf record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board conf record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "AsicName = %s", PtRec->AsicName )); + msg (( MSG_OUT, "AsicNb = %.4d", PtRec->AsicNb )); + msg (( MSG_OUT, "ReadoutMode = %.4d", PtRec->ReadoutMode )); + msg (( MSG_OUT, "DataClkFrequency = %2.f", PtRec->DataClkFrequency )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "DmaHostSz = %.4d", PtRec->DmaHostSz )); + msg (( MSG_OUT, "FrameNbPerAcq = %.4d", PtRec->FrameNbPerAcq )); + msg (( MSG_OUT, "EnableExtraChannel = %.4d", PtRec->EnableExtraChannel )); + msg (( MSG_OUT, "AcqNbPerTrig = %.4d", PtRec->AcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TriggerMode = %.4d", PtRec->TriggerMode )); + msg (( MSG_OUT, "TriggerDetectTimeWindow = %.4d", PtRec->TriggerDetectTimeWindow )); + msg (( MSG_OUT, "TriggerDetectOccurNb = %.4d", PtRec->TriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TimeStampRes = %.4d", PtRec->TimeStampRes )); + msg (( MSG_OUT, "EnableTimeStamping = %.4d", PtRec->EnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EnableTrigCnt = %.4d", PtRec->EnableTrigCnt )); + msg (( MSG_OUT, "TagEventsStoredByDUT = %.4d", PtRec->TagEventsStoredByDUT )); + msg (( MSG_OUT, "ReadTluTrigCntEachNTrig = %.4d", PtRec->ReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) + : +Goal : Print lib board conf record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) + : +Goal : Print board status record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board status record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "BoardPresent = %.4d", PtRec->BoardPresent )); + msg (( MSG_OUT, "FwLoaded = %.4d", PtRec->FwLoaded )); + msg (( MSG_OUT, "ConfDone = %.4d", PtRec->ConfDone )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "StatusCode = %.4d", PtRec->StatusCode )); + msg (( MSG_OUT, "StatusStr = %.4d", PtRec->StatusStr )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ErrorMsgList = %s", PtRec->ErrorMsgList )); + msg (( MSG_OUT, "LastErrorMsg = %s", PtRec->LastErrorMsg )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegDmaHostSz = %.4d", PtRec->RegDmaHostSz )); + msg (( MSG_OUT, "RegFrameNbPerAcq = %.4d", PtRec->RegFrameNbPerAcq )); + msg (( MSG_OUT, "RegEnableExtraChannel = %.4d", PtRec->RegEnableExtraChannel )); + msg (( MSG_OUT, "RegAcqNbPerTrig = %.4d", PtRec->RegAcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTriggerMode = %.4d", PtRec->RegTriggerMode )); + msg (( MSG_OUT, "RegTriggerDetectTimeWindow = %.4d", PtRec->RegTriggerDetectTimeWindow )); + msg (( MSG_OUT, "RegTriggerDetectOccurNb = %.4d", PtRec->RegTriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStampRes = %.4d", PtRec->RegTimeStampRes )); + msg (( MSG_OUT, "RegEnableTimeStamping = %.4d", PtRec->RegEnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegEnableTrigCnt = %.4d", PtRec->RegEnableTrigCnt )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTagEventsStoredByDUT = %.4d", PtRec->RegTagEventsStoredByDUT )); + msg (( MSG_OUT, "RegReadTluTrigCntEachNTrig = %.4d", PtRec->RegReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStamp = %.4d", PtRec->RegTimeStamp )); + msg (( MSG_OUT, "RegTrigCnt = %.4d", PtRec->RegTrigCnt )); + msg (( MSG_OUT, "RegTluTrigCnt = %.4d", PtRec->RegTluTrigCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) + : +Goal : Print lib board status record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) + : +Goal : Print acquisition emulation context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Acquistion emulation record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqCycleMs = %.4d", PtRec->ParAcqCycleMs )); + msg (( MSG_OUT, "ParEmuleDRamReadMs = %.4d", PtRec->ParEmuleDRamReadMs )); + msg (( MSG_OUT, "ParEmuleFunctNo = %.4d", PtRec->ParEmuleFunctNo )); + msg (( MSG_OUT, "InfEmuleFuncCmt = %s" , PtRec->InfEmuleFuncCmt )); + msg (( MSG_OUT, "ParRandomDataSz = %d" , PtRec->ParRandomDataSz )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParAHeader[0] , PtRec->ParAHeader[1] , PtRec->ParAHeader[2] , PtRec->ParAHeader[3] , PtRec->ParAHeader[4] , PtRec->ParAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParATrailer[0], PtRec->ParATrailer[1], PtRec->ParATrailer[2], PtRec->ParATrailer[3], PtRec->ParATrailer[4], PtRec->ParATrailer[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParTrigNbPerFrame = %.4d", PtRec->ParTrigNbPerFrame )); + msg (( MSG_OUT, "ParTrigOnOneFrameOverN = %.4d", PtRec->ParTrigOnOneFrameOverN )); + msg (( MSG_OUT, "ParTrigOnNConsecutiveFrames = %.4d", PtRec->ParTrigOnNConsecutiveFrames )); + msg (( MSG_OUT, "Trig [0]=%.4d [1]=%.4d [2]=%.4d [Last]=%.4d", PtRec->ParATrig[0], PtRec->ParATrig[1], PtRec->ParATrig[2], PtRec->ParATrig[3] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfDRamSzMb = %.4d", PtRec->InfDRamSzMb )); + msg (( MSG_OUT, "InfDRamSz = %.4d", PtRec->InfDRamSz )); + msg (( MSG_OUT, "InfDRamPtr = %.8x", PtRec->InfDRamPtr )); + msg (( MSG_OUT, "InfExtraChan = %.4d", PtRec->InfExtraChan )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqFunctRetCode = %.4d", PtRec->ResAcqFunctRetCode )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResEvCnt = %.4d", PtRec->ResEvCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmul () + : +Goal : Print lib acquisition emulation context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.AcqEmul = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) + : +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmul () { + + return ( EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheckRec ( EFRIO_TFrCheck* PtRec ) + : +Goal : Print frame check context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheckRec ( EFRIO__TFrCheck* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Frames check record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqNo = %.4d", PtRec->ParAcqNo )); + msg (( MSG_OUT, "ParFrNo = %.4d", PtRec->ParFrNo )); + msg (( MSG_OUT, "ParChkMode = %.4d", PtRec->ParChkMode )); + msg (( MSG_OUT, "ParFrPrintLevel = %.4d", PtRec->ParFrPrintLevel )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfMi26Nb = %.4d", PtRec->InfMi26Nb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResAHeader[0] , PtRec->ResAHeader[1] , PtRec->ResAHeader[2] , PtRec->ResAHeader[3] , PtRec->ResAHeader[4] , PtRec->ResAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResATrailer[0] , PtRec->ResATrailer[1] , PtRec->ResATrailer[2] , PtRec->ResATrailer[3] , PtRec->ResATrailer[4] , PtRec->ResATrailer[5] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResAFrameCnt[0] , PtRec->ResAFrameCnt[1] , PtRec->ResAFrameCnt[2] , PtRec->ResAFrameCnt[3] , PtRec->ResAFrameCnt[4] , PtRec->ResAFrameCnt[5] )); + msg (( MSG_OUT, "DL [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResADataLenght[0], PtRec->ResADataLenght[1], PtRec->ResADataLenght[2], PtRec->ResADataLenght[3], PtRec->ResADataLenght[4], PtRec->ResADataLenght[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResTrigNb = %.4d", PtRec->ResTrigNb )); + msg (( MSG_OUT, "TRG [0]=%.8d [1]=%.8d [3]=%.8d [Last]=%.8d", PtRec->ResATrig[0], PtRec->ResATrig[1], PtRec->ResATrig[2], PtRec->ResATrig[3] )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheck () + : +Goal : Print lib frame check context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.FrCheck = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheck () { + + return ( EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - > 0 -> print state list for each line + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 22/12/2010 +Rev : 30/12/2010 + : - Add handling of N Mimosa 26 + : +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + MI26__TStatesLine VStatesLine; + MI26__TState VState; + SInt16 ViMi26; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + char VStrState[255]; + char VStrLine[255]; + + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + + msg (( MSG_OUT, "===================================================================================" )); + msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); + msg (( MSG_OUT, "===================================================================================" )); + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + ViStatesLine = 0; + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Copy StatesLine field + + VStatesLine.W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VStatesLine.F.StateNb; + + sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf ); + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + VState.W16 = VPtSrcW16[ViSrcW16]; + + sprintf ( VStrState, "[Col %4d - %2d pixel(s)] ", VState.F.ColAddr, VState.F.HitNb + 1 ); + strcat ( VStrLine , VStrState ); + + ++ViSrcW16; + } + + if ( (PrintLevel != 0) ) { + msg (( MSG_OUT, "%s", VStrLine )); + } + + ++ViStatesLine; + + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + } // End for ( ViMi26 ) + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - 1 -> Print AcqId & FrId + : - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + : - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + : - 4 -> Print trigger list + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 06/11/2010 +Rev : 21/02/2011 + : - Print new field DaqVersion +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTriggerRec* VPtTrig; + SInt16 ViTrig; + char VStrTrig[30]; + char VStrTs [30]; + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Trigger record follows the data record which has a VARIABLE size + + VPtTrig = (EFRIO__TTriggerRec*) ( (UInt8*) PtRec + PtRec->TrigRecOffset ); + + // ------------------------------------- + // Print TFrame fields + // ------------------------------------- + + if ( PrintLevel == 1 ) { + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, "AcqId = %.4d - FrameIdInAcq = %.4d - TrigNb = %.4d - Address trig %d [D]", VPtHead->AcqId, VPtHead->FrameIdInAcq, VPtTrig->TrigNb, VPtTrig )); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + + return (0); + } + + + msg (( MSG_OUT, "==============================================" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "Tag = %.8X [H]", PtRec->Tag )); +#endif + msg (( MSG_OUT, "DaqVersion = %.4d [D]", PtRec->DaqVersion )); + msg (( MSG_OUT, "TotSz = %.4d [D]", PtRec->TotSz )); + msg (( MSG_OUT, "TrigRecOffset = %.4d [D]", PtRec->TrigRecOffset )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "H.Tag = %.8X [H]", VPtHead->Tag )); +#endif + msg (( MSG_OUT, "H.AcqStatus = %.4d [D]", VPtHead->AcqStatus )); + msg (( MSG_OUT, "H.TrigStatus = %.4d [D]", VPtHead->TrigStatus )); + msg (( MSG_OUT, "H.AcqId = %.4d [D]", VPtHead->AcqId )); + msg (( MSG_OUT, "H.FrameIdInAcq = %.4d [D]", VPtHead->FrameIdInAcq )); + msg (( MSG_OUT, "H.MapsName = %.4d [D]", VPtHead->MapsName )); + msg (( MSG_OUT, "H.MapsNb = %.4d [D]", VPtHead->MapsNb )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.Header [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X" , VPtHead->AMapsHeader[0] , VPtHead->AMapsHeader[1] , VPtHead->AMapsHeader[2] , VPtHead->AMapsHeader[3] , VPtHead->AMapsHeader[4] , VPtHead->AMapsHeader[5] )); + msg (( MSG_OUT, "H.FrCnt [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d", VPtHead->AMapsFrameCnt[0] , VPtHead->AMapsFrameCnt[1] , VPtHead->AMapsFrameCnt[2] , VPtHead->AMapsFrameCnt[3] , VPtHead->AMapsFrameCnt[4] , VPtHead->AMapsFrameCnt[5] )); + msg (( MSG_OUT, "H.DataSz [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d", VPtHead->AMapsDataLength[0], VPtHead->AMapsDataLength[1], VPtHead->AMapsDataLength[2], VPtHead->AMapsDataLength[3], VPtHead->AMapsDataLength[4], VPtHead->AMapsDataLength[5] )); + msg (( MSG_OUT, "H.Trailer [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X" , VPtHead->AMapsTrailer[0] , VPtHead->AMapsTrailer[1] , VPtHead->AMapsTrailer[2] , VPtHead->AMapsTrailer[3] , VPtHead->AMapsTrailer[4] , VPtHead->AMapsTrailer[5] )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.TriggerNb = %.4d - Address trig %d [D]", VPtHead->TriggerNb, VPtTrig )); + msg (( MSG_OUT, "H.TrigInfo [0]=%.8X [1]=%.8X [2]=%.8X ", VPtHead->AMapsTrigInfo[0], VPtHead->AMapsTrigInfo[1], VPtHead->AMapsTrigInfo[2] )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "D.Tag = %.8X [H]", VPtData->Tag )); +#endif + msg (( MSG_OUT, "D.TotSz = %.4d [D]", VPtData->TotSz )); + msg (( MSG_OUT, "D.OneMapsSz = %.4d [D]", VPtData->OneMapsSz )); + + if ( PrintLevel == 3 ) { + EFRIO__FPrintFrameData ( PtRec, PrintLevel ); + } + + if ( PrintLevel < 4 ) { + msg (( MSG_OUT, "===================================================================================" )); + return (0); + } + + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "T.Tag = %X [H]", VPtTrig->Tag )); +#endif + msg (( MSG_OUT, "T.TotSz = %.4d [D]", VPtTrig->TotSz )); + msg (( MSG_OUT, "T.TrigNb = %.4d [D]", VPtTrig->TrigNb )); + msg (( MSG_OUT, "T.TrigType = %d [D]", VPtTrig->TrigType )); + + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) + : +Goal : Print monitor context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Monitor context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "InfFrameNbToSend = %.4d", PtRec->InfFrameNbToSend )); + msg (( MSG_OUT, "InfSzToSend = %.4d", PtRec->InfSzToSend )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonCont () + : +Goal : Print lib monitor context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMoniCont () { + + return ( EFRIO__FPrintMonContRec (&EFRIO__VGContext.MonCont) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMsg ( + : SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, + : SInt8 PrintAsError, char* Msg ) + : +Goal : Print messages in msg or error log file from LabView -> A Vi encapsulets this function. + : +Inputs : DummyS32In - Dummy value used under Labview to easily " chain " function execution. + : + : To execute it after a Vi call, connect any output of this Vi to the + : DummyS32In pin and it will be automatically called after Vi end. + : To execute it before a Vi call, if this Vi has an integer parameter + : cut the wire and insert DummyS32In input and function output on it. + : + : Printing mode flags + : + : PrintAsMsg - If 1 -> Print in messages log file + : PrintAsTrace - If 1 -> Print in errors log file as a trace message + : PrintAsWarning - If 1 -> Print in errors log file as a warning message + : PrintAsError - If 1 -> Print in errors log file as an error message + : + : Msg - Message to print ( string ) + : +Ouputs : The function always returns the input parameter DummyS32In. + : +Globals : + : +Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) + : It can be used to insert this function call on an integer datapath under LabView + : + : If more than one printing mode flag is enabled therefore the same message will + : be printed in different ways. + : +Level : +Date : 09/08/2010 +Rev : 25/10/2010 + : - Implementation -> Empty function before +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", Msg )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", Msg )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", Msg )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", Msg )); + + return (DummyS32In); +} + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/files.c b/include/pxi_daq_lib_v.1.0/files.c new file mode 100755 index 0000000..e3e4d85 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/files.c @@ -0,0 +1,3744 @@ + +#ifndef FIL_C +#define FIL_C + + +#ifdef CC_UNIX + +UInt32 GetTickCount () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + + +SInt32 GetLastError () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + +#endif + +/******************************************************************************* +Prototype : SInt32 FIL_FFileExists ( char* FilePath ) +Goal : Test if the file exists. +Inputs : The file name ( full path if needed ). +Ouputs : 1 if the file exists, else 0. +Globals : +Remark : The result is not guaranted in case of multi application lock to file. +Level : This is a user level function. +Date : 17/04/2003 +Doc date : 17/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FFileExists ( char* FilePath ) { + + SInt32 VRet; + FILE* VPf; + + VPf = fopen ( FilePath, "r" ); + + if ( VPf == NULL ) { + VRet = 0; + } + + else { + fclose ( VPf ); + VRet = 1; + } + + + return (VRet); +} + +/* 13/10/2004 */ + +SInt32 FIL_FFileSize ( char* FilePath ) { + + FILE* VPf; + SInt32 VFileSz; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fopen fail !" ) )); + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fclose (VPf) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fclose fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "%d Bytes", VFileSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FCpyFile ( char* Src, char* Dest ) + : +Goal : Copy SrcFile to DestFile. + : +Inputs : Src - Source file + : Dest - Destination file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - fonction moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FCpyFile ( char* Src, char* Dest ) { + + FILE* VPfSrc; + FILE* VPfDest; + SInt8 VBuffer[512]; // Debug 02/06/2007 move storage class static to auto + SInt32 VReadBytesCnt; + SInt32 VTotBytesCnt; + SInt32 VRet; + + VPfSrc = fopen ( Src, "rb" ); + + err_retnull ( VPfSrc, (ERR_OUT,"Source file %d open failed", Src ) ); + + VPfDest = fopen ( Dest, "wb" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", VPfDest ) ); + + VTotBytesCnt = 0; + + while ( ( VReadBytesCnt = fread ( VBuffer, 1 /* byte size */ , 512 /* bytes number */, VPfSrc ) ) > 0 ) { + fwrite ( VBuffer, 1 /* byte size */, VReadBytesCnt, VPfDest ); + VTotBytesCnt += VReadBytesCnt; + } + + fclose (VPfSrc); + fclose (VPfDest); + + err_retok (( ERR_OUT, "file %s copied in %s => %d bytes", Src, Dest, VTotBytesCnt )); +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FRemoveFile ( char* FilePath ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FRemoveFile ( char* FilePath ) { + + SInt32 VRet; + char* VStrError; + + VRet = remove ( FilePath ); + + err_retfail ( VRet, (ERR_OUT,"Remove file=%s failed => %s", FilePath, _strerror ("")) ); + err_retok (( ERR_OUT, "")); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) + : +Goal : List the directory SrcDir and write the result in DestDirFile. + : +Inputs : SrcDir - The directory to list + : DestDirFile - The result file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - Function moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + + VPf = fopen ( DestDirFile, "wt" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT, "Dir file %s creation failed ", DestDirFile ) ); + } + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + ++VItemCnt; + fprintf( VPf, "%s\n", VFileInfo.ff_name); + VRet = findnext(&VFileInfo); + } + + fclose ( VPf ); + + return (0); +} + + +#endif + + +SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosDirOutFile ( SrcDir, DestDirFile ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FDosDelDir ( char* SrcDir ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : Compiled only if CC_APP_WINDOWS is defined +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosRmDirFiles ( char* SrcDir ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + char VFileToDelete[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + SInt32 VRetRemove; + SInt32 VFuncRet; + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VFuncRet = 0; + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + sprintf ( VFileToDelete, "%s\\%s", SrcDir, VFileInfo.ff_name ); + VRetRemove = FIL_FRemoveFile ( VFileToDelete ); + + if ( VRetRemove < 0 ) { + VFuncRet = -1; + err_error (( ERR_OUT, "Remove file=%s failed => %s", VFileToDelete, _strerror ("") )); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + + return (VFuncRet); +} + +#endif + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDirFiles ( char* SrcDir ) +Goal : Remove all the files in directory SrcDir but let the direcory +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDirFiles ( char* SrcDir ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosRmDirFiles (SrcDir) ); + +#else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available !", SrcDir) ); +#endif + + +} + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDir ( char* SrcDir ) +Goal : Remove the directory SrcDir if empty +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDir ( char* SrcDir ) { + + SInt32 VRet; + +#ifdef CC_APP_WINDOWS + + // VRet = _rtl_chmod( SrcDir, 1 , FA_NORMAL ); + // err_retfail ( VRet, (ERR_OUT,"Chmod failed on directory=%s", SrcDir) ); + + VRet = rmdir ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"Remove directory=%s failed => %s ", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + +#else + err_retfail ( -1, (ERR_OUT,"Function handled only under Windows") ); +#endif + +} + +/******************************************************************************* +Prototype : +Goal : Delete direcory files and directory itself +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelDir ( char* SrcDir ) { + + SInt32 VRet; + char VNewName[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + + sprintf ( VNewName, "%s.old", SrcDir ); + + VRet = rename ( SrcDir, VNewName ); + + err_retfail ( VRet, (ERR_OUT,"Rename Dir=%s to %s failed !", SrcDir, VNewName ) ); + + err_warning (( ERR_OUT, "Directory %s renamed in %s because delete is impossible !", SrcDir, VNewName )); + + err_retok (( ERR_OUT, "" )); + +/* + VRet = FIL_FRmDirFiles ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDirFiles (%s) failed ", SrcDir) ); + + VRet = FIL_FRmDir ( VNewName ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDir (%s) failed ", SrcDir) ); + + err_retok (( ERR_OUT, "" )); +*/ + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FMkDir ( char* SrcDir ) { + + SInt32 VRet; + char VStrCmd[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + #ifdef APP_DAQ + + err_retfail ( -1, (ERR_OUT,"Function NOT available under LynxOS !") ); + + #endif + + #ifdef CC_APP_LINUX + sprintf ( VStrCmd, "mkdir %s", SrcDir ); + system ( VStrCmd ); + #endif + + + #ifdef CC_APP_WINDOWS + VRet = mkdir ( SrcDir ); + + err_retfail ( VRet, (ERR_OUT,"Creation of directory=%s failed => %s", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FMkDir (SrcDir=%s) IS NOT available !", SrcDir) ); + #endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in + : the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT + : are not written in list. +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in +: the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT +: are not written in list. +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIL_FExtDosListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\%s", SrcDir, Joker ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIl_FDosListDirFiles ( SrcDir, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIL_FExtDosListDirFiles ( SrcDir, Joker, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList ) { + + SInt32 VRet; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + VFilesCnt = FIl_FListDirFiles ( VRmpDirPath, PtList ); + + return ( VFilesCnt ); +} + + + +#ifndef APP_DAQ + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Extended version which handles conf extension i,j,k +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtDelRmpFiles ( char* RmpDataPath, char ConfExt, SInt32 RunNo, SInt32 MaxFileCnt ) { + + SInt32 VRet; + SInt32 ViFile; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VInfoFilePath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VData0Filepath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + FIL_TDirFilesList VFilesList; // Debug 02/06/2007 move storage class static to auto + + + char VFileToDelete[GLB_FILE_PATH_SZ]; + + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + sprintf ( VInfoFilePath , "RUN_%d_%c.rz", RunNo, ConfExt ); + sprintf ( VData0Filepath, "RUN_%d_0.rz" , RunNo ); + + VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &VFilesList ); + + /* !!! DESY 20/09/05 !!! MUST BE CHECKED ! */ + /* previous line replaced by this one in order to be able to compile boards_db_man */ + /* VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &(VPtAFilesPath) ); */ + + err_retfail ( VFilesCnt, (ERR_OUT,"FIL_FCntRmpFiles (%s) failed Ret=%d", RmpDataPath, VFilesCnt ) ); + + if ( VFilesCnt < MaxFileCnt ) { + err_retok (( ERR_OUT, "Nothing to do VFilesCnt=%d < MaxFileCnt=%d", VFilesCnt, MaxFileCnt )); + } + + err_warning (( ERR_OUT, "%d RMP files are not deleted by monitoring => I will remove them", VFilesCnt )); + + for ( ViFile = 0; ViFile < VFilesCnt; ViFile++ ) { + + if ( strcmp ( VFilesList.AList[ViFile], VInfoFilePath ) == 0 ) { + continue; + } + + if ( strcmp ( VFilesList.AList[ViFile], VData0Filepath ) == 0 ) { + continue; + } + + sprintf ( VFileToDelete, "%s\\%s", VRmpDirPath, VFilesList.AList[ViFile] ); + + err_warning (( ERR_OUT, "FIL_FDelRmpFilesv => File = %s", VFileToDelete )); + + FIL_FRemoveFile ( VFileToDelete ); + + } + + return (0); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Creation of FIL_FExtDelRmpFiles to replace FIL_FDelRmpFiles + : - FIL_FDelRmpFiles call FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt ) { + return ( FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) ); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FFloatVectorsToTextFile ( float** SrcVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** VectorsNames, char DataSep, char* DestFile ) { + + char VFuncName[] = "FIL_FFloatVectorsToTextFile"; + + FILE* VPfDest; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + + + VPfDest = fopen ( DestFile, "wt" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", DestFile ) ); + + + if ( HeaderLine != NULL ) { + VRet = fprintf ( VPfDest, "%s \n", HeaderLine ); + } + + else { + VRet = fprintf ( VPfDest, "No header line \n", HeaderLine ); + } + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing Header line file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + + if ( VectorsNames != NULL ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + VRet = fprintf ( VPfDest, "%-21s", VectorsNames[ViVector]); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing vectors names line - Vector=%d file=%s => %s", ViVector, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + VRet = fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + } + + else { + fprintf ( VPfDest, "No vectors names line \n", HeaderLine ); + } + + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + VRet = fprintf ( VPfDest, "%.6f%c", SrcVectors[ViVector][ViLine], DataSep); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing line=%d in file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR line=%d file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + fflush (VPfDest); + fclose (VPfDest); + + err_retok (( ERR_OUT, "%d line written in file", EltNbPerVector, DestFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FTextFileToFloatVectors ( char* SrcFile, char DataSep, float** DestVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** AVectorsNames, char* StrVectorsNames ) { + + char VFuncName[] = "FIL_FTextFileToFloatVectors"; + + FILE* VPf; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + char VStrCR[2]; + char VDataSep; + + /* Check parameters */ + + err_retnull ( SrcFile , (ERR_OUT,"SrcFile == NULL" ) ); + err_retnull ( DestVectors , (ERR_OUT,"DestVectors == NULL" ) ); + err_retnull ( HeaderLine , (ERR_OUT,"HeaderLine == NULL" ) ); + err_retnull ( AVectorsNames , (ERR_OUT,"AVectorsNames == NULL" ) ); + err_retnull ( StrVectorsNames , (ERR_OUT,"StrVectorsNames == NULL" ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 1" )); + + /* Try to open file */ + + VPf = fopen ( SrcFile, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFile ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read header line */ + + VRet = (SInt32) fgets( HeaderLine, 255, VPf ); + + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read header line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + /* Read vectors names line */ + + + VRet = (SInt32) fgets( StrVectorsNames, 255, VPf ); + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read vectors names line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + sprintf ( AVectorsNames[ViVector], "" ); + }; + + + /* Read vectors */ + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + if ( ViVector == VectorsNb-1 ) { + VRet = fscanf ( VPf, "%f%c", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + else { + VRet = fscanf ( VPf, "%f%c\n", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + + if ( VRet != 2 ) { + fflush (VPf); + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s", ViLine, SrcFile, VRet, _strerror ( "System says :" ) ) ); + } + + } + + } + + + fflush (VPf); + fclose (VPf); + + err_retok (( ERR_OUT, "%d line Read in file", EltNbPerVector, SrcFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef CC_APP_WINDOWS + + SInt32 FIL_FGetAppRunDir ( char* StrRunDir, TApplication* PtApp ) { + + char* VPtStrExeName; + AnsiString VAStrExeName; + char VExeDriveLetter; + char VExeDriveId; /* 0 = default, 1 = A, 2 = B ... */ + char VStrCurDir[GLB_FILE_PATH_SZ]; + char VStrCurDirPath[GLB_FILE_PATH_SZ]; + + err_retfailnull ( StrRunDir, (ERR_OUT,"StrRunDir == NULL") ); + + VPtStrExeName = FStr2PCh ( &(PtApp->ExeName) ); + + VExeDriveLetter = toupper ( VPtStrExeName[0] ); + + switch ( VExeDriveLetter ) { + + case 'A' : { + VExeDriveId = 1; + break; } + + case 'B' : { + VExeDriveId = 2; + break; } + + case 'C' : { + VExeDriveId = 3; + break; } + + case 'D' : { + VExeDriveId = 4; + break; } + + case 'E' : { + VExeDriveId = 5; + break; } + + case 'F' : { + VExeDriveId = 6; + break; } + + case 'G' : { + VExeDriveId = 7; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown drive id=%d", VExeDriveId) ); + VExeDriveId = 0; + } + + } + + getcurdir( VExeDriveId, VStrCurDir ); + + sprintf ( VStrCurDirPath, "%c:\\%s", VExeDriveLetter, VStrCurDir ); + sprintf ( StrRunDir, "%s", VStrCurDirPath ); + + // msg (( MSG_OUT, "VStrCurDirPath = %s", VStrCurDirPath )); + + err_retok (( ERR_OUT, "" )); + } + +#else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 07/03/2011 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FGetDiskSectorSz ( char* Drive ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported under Unix !" ) ); + +#else + + DWORD VDummyW; + DWORD VBytesPerSector; + BOOL VRetBool; + + + // BOOL GetDiskFreeSpace( + // + // LPCTSTR lpRootPathName, // address of root path + // LPDWORD lpSectorsPerCluster, // address of sectors per cluster + // LPDWORD lpBytesPerSector, // address of bytes per sector + // LPDWORD lpNumberOfFreeClusters, // address of number of free clusters + // LPDWORD lpTotalNumberOfClusters // address of total number of clusters + // ); + + + VRetBool = GetDiskFreeSpace( + Drive, // address of root path + &VDummyW, // address of sectors per cluster + &VBytesPerSector, // address of bytes per sector + &VDummyW, // address of number of free clusters + &VDummyW // address of total number of clusters + ); + + if ( VRetBool == True ) { + return ( VBytesPerSector ); + } + + else { + return (-1); + } + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: ~FIL__TCBinFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + + // Variables for internal processing + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdEltId = 0; + ProCurRdSz = 0; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProPtFile = NULL; + + err_trace (( ERR_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + ProParRWBMode = RWBMode; + ProParMaxBlocSz = MaxBlocSz; + ProParBlocSz = BlocSz; + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + ProConfDone = 1; + + + // Allocate memory buffer for data read from file + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = MaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCBinFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProPtFile == NULL ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + + // Store current ( initial ) position in file + + if ( (VCurPos = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Goto end of file + + if ( fseek ( ProPtFile, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + // Get current position = END in file => it's file size + + if ( (VFileSz = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Restor initial position in file + + if ( fseek ( ProPtFile, VCurPos, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + + } // End file is already open + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFCreate () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProPtFile = fopen ( ProParDataFile, "wb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFOpen () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + ProPtFile = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz ) { + SInt8 VBlocNbWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can write to a file when RWB mode IS NOT Write !") ); + } + + ProCurWrSz = DataSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbWritten = fwrite ( PtrData, DataSz /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbWritten != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc write failed ! => System : %s", _strerror ("") ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + fflush ( ProPtFile ); + } + + ++ProCurWrEltId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", DataSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + if ( DataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > MaxDestSz=%d", DataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( DestPtr, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc read of %d bytes failed ! - VBlocNbRead = %d => System : %s", DataSzToRead, VBlocNbRead, _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + if ( DataSzToRead > ProParMaxBlocSz ) { + err_retfailnull ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > ProParMaxBlocSz=%d", DataSzToRead, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( ProPtrBuffRdData, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Bloc read failed ! => System : %s", _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGotoBloc ( SInt32 BlocNo ) { + + SInt32 VOffset; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + VOffset = BlocNo * ProParBlocSz; + + if ( fseek ( ProPtFile, VOffset, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Goto bloc %d => %d bytes from beginning failed !", BlocNo ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ) { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFFlush () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + fflush ( ProPtFile ); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFClose () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + fflush ( ProPtFile ); + } + + fclose ( ProPtFile ); + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + ProConfDone = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_WRITE, RecSz, RecSz, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFCreate (); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqWrite ( PtSrc, RecSz ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_READ, RecSz, RecSz, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFOpen(); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqRead ( PtDest, RecSz /* MaxDestSz */, RecSz /* DataSzToRead */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + + +// msg (( MSG_OUT, "Msg" )); + + + +// **************************** +// FIL__TCStreamFile +// **************************** + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl, DiskBlocSz ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: ~FIL__TCStreamFile () { + + // Free info record + + if ( ProPtRecInfFile != NULL ) { + free ( ProPtRecInfFile ); + } + +#ifndef CC_UNIX + TerminateThread ( ProThreadHnd , 0 /* Thread exit code */ ); + + DeleteCriticalSection ( &ProCsPrintMsg ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : 05/11/2010 + : - Error handling on disk access is not properly done, a message is printed + : but the error is not propagated => MUST be done. +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef CC_UNIX + +DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ) { + + FIL__TCStreamFile* VPtObj = (FIL__TCStreamFile*) lpParam; + + SInt32 VRet; + DWORD VBuffFull; + UInt32 VNbBytesToWrite; + UInt32 VNbBytesWritten; + char VStrMsg[GLB_CMT_SZ]; + + + while (1) { + + // Wait on buffer to read + + VBuffFull = WaitForSingleObject ( VPtObj->ProSemRdBuffHnd, INFINITE ); + + switch ( VBuffFull ) { + + case WAIT_OBJECT_0 : { + + + VNbBytesToWrite = VPtObj->ProParBlocSz; + + WriteFile( + VPtObj->ProFileHnd, // handle to file to write to + VPtObj->ProABuff[VPtObj->ProIndexRdBuff], // pointer to data to write to file + VNbBytesToWrite, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != VNbBytesToWrite ) { + sprintf ( VStrMsg, "ThreadDisk => Writing buff %d error !", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + else { + sprintf ( VStrMsg, "ThreadDisk => Buffer %d save to disk", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + if ( VPtObj->ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( VPtObj->ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + ++VPtObj->ProIndexRdBuff; + + err_retfail ( VPtObj->ProIndexRdBuff, (ERR_OUT,"Bad variable size => ProIndexRdBuff=%d < 0", VPtObj->ProIndexRdBuff) ); + + if ( VPtObj->ProIndexRdBuff >= FIL__TCStreamFile_MAX_BUFF_NB ) { + VPtObj->ProIndexRdBuff = 0; + } + + ReleaseSemaphore ( VPtObj->ProSemWrBuffHnd, 1, NULL ); + + + break; } + + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFull )); + break; } + + } + + + + } // End while (1) + + return 0; +} + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 05/11/2010 +Doc date : 05/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFCalcProParBlocSz ( SInt32 DataSz ) { + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VRecInfSz; + + VNotIntegerDiskBlocNb = DataSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (DataSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = DataSz; + } + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + SInt8 ViBuff; + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + ProParDiskBlocSz = DiskBlocSz; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + sprintf ( ProInfFileName, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + ProParFixedBlocSzMode = 1; + + // Variables for internal processing + + ProUseThread = 0; + + ProFileHnd = INVALID_HANDLE_VALUE; + ProPtInfFile = NULL; + +#ifndef CC_UNIX + InitializeCriticalSection ( &ProCsPrintMsg ); +#endif + + ProThreadHnd = INVALID_HANDLE_VALUE; + ProThreadId = 0; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProABuff[ViBuff] = NULL; + } + + ProSemWrBuffHnd = INVALID_HANDLE_VALUE; + ProSemRdBuffHnd = INVALID_HANDLE_VALUE; + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + ProBuffSz = 0; + + ProPtRecInfFile = NULL; + ProRecInfSz = 0; + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdBlocId = 0; + ProCurRdSz = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetDiskSectorSz ( SInt32 DiskBlocSz ) { + + ProParDiskBlocSz = DiskBlocSz; + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetDiskSectorSz () { + + return (ProParDiskBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void FIL__TCStreamFile :: PubFPrintMsg ( char* Msg ) { + +#ifndef CC_UNIX + EnterCriticalSection( &ProCsPrintMsg ); +#endif + err_trace (( ERR_OUT, "%s", Msg )); + +#ifndef CC_UNIX + LeaveCriticalSection( &ProCsPrintMsg ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt8 ViBuff; + SInt32 VNotIntegerDiskBlocNb; +#ifndef CC_UNIX + TDateTime VODateTime; +#endif + + + + // ------------------------------------------------------- + // Set class parameters from PubFConf parameters list + // ------------------------------------------------------- + + err_retnull ( PtMyself, (ERR_OUT,"PtMyself == NULL") ); + + PriPtMyself = PtMyself; + + ProUseThread = UseThread; + + sprintf ( ProParDataFile, "%s", DataFile ); + + sprintf ( ProInfFileName, "%s.inf", ProParDataFile ); + + ProParRWBMode = RWBMode; + + ProParFixedBlocSzMode = FixedBlocSzMode; + + ProParRequestedBlocSz = BlocSz; + + VNotIntegerDiskBlocNb = ProParRequestedBlocSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (ProParRequestedBlocSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = ProParRequestedBlocSz; + } + + err_trace (( ERR_OUT, "RequestedBlocSz=%d - BlocSz=%d", ProParRequestedBlocSz, ProParBlocSz )); + + + ProParRequestedMaxBlocSz = MaxBlocSz; + + if ( ProParRequestedMaxBlocSz >= ProParBlocSz ) { + ProParMaxBlocSz = ProParRequestedMaxBlocSz; + } + + else { + err_warning (( ERR_OUT, "ProParMaxBlocSz=%d must be adjusted -> Set to ProParBlocSz=%d", ProParMaxBlocSz, ProParBlocSz )); + ProParMaxBlocSz = ProParBlocSz; + } + + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + // ------------------------------------------------------- + // Alloc information file record + // ------------------------------------------------------- + + if ( ProParFixedBlocSzMode == 1 ) { + ProRecInfSz = sizeof (FIL__TCStreamFile_Old_TRecInfFile); + } + + else { + + // BUG ? + + // ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (UInt64) ); + + ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (FIL__TCStreamFile_TBlocInf) ); + + } + + ProPtRecInfFile = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFile, (ERR_OUT,"Allocation of info record failed !") ); + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // ------------------------------------------------------- + // Create or open information file + // ------------------------------------------------------- + + // Write mode => Create info file + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProPtRecInfFile->Version = 1; + ProPtRecInfFile->FixedBlocSz = ProParFixedBlocSzMode; + ProPtRecInfFile->MaxBlocSz = ProParMaxBlocSz; + ProPtRecInfFile->BlocSz = ProParBlocSz; + ProPtRecInfFile->BlocNb = 0; + ProPtRecInfFile->ABlocInf[0].Offset = 0; + ProPtRecInfFile->ABlocInf[0].Sz = 0; + +#ifndef CC_UNIX + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateCreate = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeCreate = TIME__FConvDateTime2Time ( VODateTime ); +#else + ProPtRecInfFile->DateCreate.W32 = 0; + ProPtRecInfFile->TimeCreate.W32 = 0; +#endif + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Creation of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + err_trace (( ERR_OUT, "Info file=%s created", ProInfFileName )); + } + + // Read mode => Open info file + + else { + + ProPtInfFile = fopen ( ProInfFileName, "rb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Open info file %s failed => system : %s", ProInfFileName, _strerror ( "" ) )); + err_trace (( ERR_OUT, "Info file=%s read", ProInfFileName )); + + if ( fread ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Read info file %s failed => system : %s", ProInfFileName, _strerror ( "" )) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + // Print info file + + PubFPrintInfFile (); + + // Set bloc size + + ProParBlocSz = ProPtRecInfFile->BlocSz; + + if ( ProParRequestedBlocSz != ProParBlocSz ) { + err_warning (( ERR_OUT, "Requested bloc sz=%d <> Info file bloc sz=%d => Use Info file bloc sz", ProParRequestedBlocSz, ProParBlocSz )); + } + + } + + + // ------------------------------------------------------------- + // Write mode => Allocate buffers, create semaphores and thread + // ------------------------------------------------------------- + + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + if ( FIL__TCStreamFile_MAX_BUFF_NB > 4 ) { + err_retfail ( -1, (ERR_OUT,"FIL__TCStreamFile_MAX_BUFF_NB = %d ! Handling of more than 4 buffers is NOT implemented !", FIL__TCStreamFile_MAX_BUFF_NB) ); + } + + // Allocate buffers + + ProBuffSz = ProParMaxBlocSz; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + // If already allocated => Free + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + } + + // Allocate + + ProABuff[ViBuff] = (UInt8*) malloc ( ProBuffSz ); + + err_retnull ( ProABuff[ViBuff], (ERR_OUT,"Allocation buffer[%d] of %d bytes failed !", ViBuff, ProBuffSz ) ); + err_trace (( ERR_OUT, "Buffer[%d] of %d bytes allocated", ViBuff, ProBuffSz )); + + // Reset content with $FF + + memset ( ProABuff[ViBuff], 0xFF, ProBuffSz ); + } + + // Create & init semaphores + + #ifndef CC_UNIX + ProSemWrBuffHnd = CreateSemaphore( NULL, FIL__TCStreamFile_MAX_BUFF_NB, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = Max = Max buff nb + + err_retnull ( ProSemWrBuffHnd, (ERR_OUT,"Create SemWrBuff failed ! - LastError=%d", GetLastError ()) ); + + ProSemRdBuffHnd = CreateSemaphore( NULL, 0, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = 0, Max = Max buff nb + + err_retnull ( ProSemRdBuffHnd, (ERR_OUT,"Create SemRdBuff failed ! - LastError=%d", GetLastError ()) ); + #endif + + // Init buffers index + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + // Create thread + + #ifndef CC_UNIX + ProThreadHnd = CreateThread ( NULL, 0, FIL__TCStreamFile_FThread, (void*) PriPtMyself /* Param */ , 0, &ProThreadId ); + err_retnull ( ProThreadHnd, (ERR_OUT,"Thread creation failed ! LastError=%d", GetLastError ()) ); + #endif + + } + + // ------------------------------------------------------------- + // Read mode => Allocate memory buffer for data read from file + // ------------------------------------------------------------- + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = ProParMaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 20/05/2010 +Doc date : 20/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFile () { + + SInt32 ViBloc; + SInt16 ViSpareW32Info; + + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record " )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Version = %d", ProPtRecInfFile->Version )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Date create = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateCreate, NULL, 0 ) )); + msg (( MSG_OUT, "Time create = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeCreate, NULL, 0 ) )); + msg (( MSG_OUT, "Date close = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateClose , NULL, 0 ) )); + msg (( MSG_OUT, "Time close = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeClose , NULL, 0 ) )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "FixedBlocSz = %d", ProPtRecInfFile->FixedBlocSz )); + msg (( MSG_OUT, "MaxBlocSz = %d", ProPtRecInfFile->MaxBlocSz )); + msg (( MSG_OUT, "BlocSz = %d", ProPtRecInfFile->BlocSz )); + msg (( MSG_OUT, "BlocNb = %d", ProPtRecInfFile->BlocNb )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "ABlocInf[0].Offset = %Lu", ProPtRecInfFile->ABlocInf[0].Offset )); + msg (( MSG_OUT, "ABlocInf[0].Sz = %d ", ProPtRecInfFile->ABlocInf[0].Sz )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoFormat = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoFormat )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoNb = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb )); + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb; ViSpareW32Info++ ) { + msg (( MSG_OUT, "ABlocInf[0].ASpareW32Info[%.2d] = %d ", ViSpareW32Info, ProPtRecInfFile->ABlocInf[0].ASpareW32Info[ViSpareW32Info] )); + } + + + if ( ProPtRecInfFile->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < ProPtRecInfFile->BlocNb; ViBloc++ ) { + msg (( MSG_OUT, "Bloc[%.4d] : Offset=%.12Lu - Sz=%.8d [Bytes] - ASpare [0]=%.4d [1]=%.4d [2]=%.4d [3]=%.4d", ViBloc, ProPtRecInfFile->ABlocInf[ViBloc].Offset, ProPtRecInfFile->ABlocInf[ViBloc].Sz, ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[0], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[1], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[2], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[3] )); + } + + } + + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + err_retfail ( -1, (ERR_OUT,"File is opened => Get file size not coded in this state (TOB ...)") ); + } + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 + : - Calculation => file size / block size +Rev : 20/05/2010 + : - Read from info file field BlocNb + : +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + +/* Before 20/05/2010 + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + +*/ + + VBlocNb = ProPtRecInfFile->BlocNb; + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFCreate () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_WRITE | GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFOpen () { + +#ifdef CC_UNIX + + ProFilePtUx = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProFilePtUx, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#endif +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation + : + : 24/02/2011 + : - Handle SpareW32Info as an array now => New parameters + : +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + SInt16 ViSpareW32Info; + DWORD VBuffFree; + UInt32 VNbBytesWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + err_retnull ( PtSpareW32Info, (ERR_OUT,"PtSpareW32Info == NULL") ); + + if ( SpareW32InfoNb > FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"SpareW32InfoNb=%d > Max=%d", SpareW32InfoNb, FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Cant write to a file when RWB mode IS NOT Write !") ); + } + + // If variable bloc sz mode => Test max nb of blocs allowed & Adjust ProParBlocSz + + if ( ProParFixedBlocSzMode == 0 ) { + + if ( ProPtRecInfFile->BlocNb >= FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE ) { + err_retfail ( -1, (ERR_OUT,"Max bloc nb = %d reached in variable bloc sz mode !", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE) ); + } + + ProFCalcProParBlocSz ( DataSz ); + } + + // err_error (( ERR_OUT, "DataSz=%d - ProParBlocSz=%d bytes", DataSz, ProParBlocSz )); + + ProCurWrSz = ProParBlocSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + // Let thread write data to disk in background task + + if ( ProUseThread == 1 ) { + + // Wait on buffer to write + + VBuffFree = WaitForSingleObject ( ProSemWrBuffHnd, 1 /* ms */ ); + + switch ( VBuffFree ) { + + case WAIT_TIMEOUT : { + ++ProResWrBlocFailCnt; + err_retfail ( -1, (ERR_OUT,"Write failed for the %d time -> No buffer available - DbgCallPar=%d !", ProResWrBlocFailCnt, DbgCallPar ) ); + break; } + + case WAIT_OBJECT_0 : { + + memcpy ( ProABuff[ProIndexWrBuff], PtrData, DataSz ); + + // PubFPrintMsg ( "Thread => Buffer %d filled", ProIndexWrBuff ); + err_trace (( ERR_OUT, "Thread => Buffer %d filled - DbgCallPar=%d", ProIndexWrBuff, DbgCallPar )); + + ++ProIndexWrBuff; + + err_retfail ( ProIndexWrBuff, (ERR_OUT,"Bad variable size => ProIndexWrBuff=%d < 0", ProIndexWrBuff) ); + + if ( ProIndexWrBuff >= FIL__TCStreamFile_MAX_BUFF_NB) { + ProIndexWrBuff = 0; + } + + ReleaseSemaphore ( ProSemRdBuffHnd, 1, NULL ); + break; } + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFree )); + break; } + + } + + } + + // Write NOW data to disk + + else { + + // Copy to buffer -> "Automatically" add padding bytes + + memcpy ( ProABuff[0], PtrData, DataSz ); + + // Warning => Write ProParBlocSz bytes AND NOT the value passed via parameter DataSz + // because non buffered I/O functions MUST write multiple of DISK bloc size + + WriteFile( + ProFileHnd, // handle to file to write to + ProABuff[0], // pointer to data to write to file + ProParBlocSz, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != ProParBlocSz ) { + err_retfail ( VRet, (ERR_OUT,"Writing block %d failed %d bytes written - %d bytes requested ! - %s", ProCurWrBlocId, VNbBytesWritten, ProParBlocSz, strerror ( errno ) ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + } + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + + if ( ProUseThread == 1 ) { + err_trace (( ERR_OUT, "Copy bloc of %d bytes done in %d [ms]", DataSz, ProTimeExec )); + } + + else { + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", VNbBytesWritten, ProTimeExec )); + } + + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + +#ifdef CC_UNIX + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + SInt32 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VBlocNbRead = fread ( DestPtr, VDataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProFilePtUx ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed of %d bytes ! - %s", ProCurRdBlocId, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#else + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + UInt32 VNbBytesRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + ReadFile( + ProFileHnd, // handle of file to read + DestPtr, // address of buffer that receives data + VDataSzToRead, // number of bytes to read + &VNbBytesRead, // address of number of bytes read + NULL // address of structure for data + ); + + if ( VNbBytesRead != VDataSzToRead ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed : %d bytes read - %d bytes requested ! - %s", ProCurRdBlocId, VNbBytesRead, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( ProPtrBuffRdData, ProSzBuffRdData, DataSzToRead ); + + err_retfailnull ( VRet, (ERR_OUT,"PubFSeqRead failed !") ); + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : Limited to 4 GB files + : +Rev : 09/05/2010 + : - Use W64 offset => Not limited to 4 GB file +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGotoBloc ( SInt32 BlocNo ) { + +#ifdef CC_UNIX + + SInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = fseeko ( ProFilePtUx, (off_t) VOffsetW64, SEEK_SET ); + + err_retfail ( VRet, (ERR_OUT,"Bloc %d read failed ! => System : %s", BlocNo, _strerror ("") ) ); + + err_retok (( ERR_OUT, "" )); + +#else + + UInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = SetFilePointer ( + ProFileHnd, // handle of file + *VPtOffsetLow32, // number of bytes to move file pointer + (SInt32*) VPtOffsetHigh32, // address of high-order word of distance to move + // lpDistanceToMoveHigh = 0 => Limited to 4 GB + FILE_BEGIN // how to move + ); + + + if ( VRet == 0xFFFFFFFF ) { + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &VMsgBuf, + 0, + NULL + ); + + err_retfail ( -1, (ERR_OUT,"Goto bloc %d failed => %s", BlocNo, VMsgBuf ) ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 24/02/2011 + : - Handle SpareW32Info as and array ASpareW32Info now => New parameters + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ) { + + SInt32 VRet; + SInt16 ViSpareW32Info; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + + if ( (PtSpareW32InfoFormat != NULL) && (PtSpareW32Info != NULL) && (ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb <= MaxSpareW32InfoNb) ) { + + *PtSpareW32InfoFormat = ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoFormat; + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb; ViSpareW32Info++ ) { + PtSpareW32Info[ViSpareW32Info] = ProPtRecInfFile->ABlocInf[BlocNo].ASpareW32Info[ViSpareW32Info]; + } + + } + + else { + err_warning (( ERR_OUT, "ASpareInfo bloc not updated ! Pointer NULL or Dest size too small ?" )); + } + + } + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + return (ProParBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + } + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFFlush () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFClose () { + + SInt32 VRet; + SInt8 ViBuff; +#ifndef CC_UNIX + TDateTime VODateTime; +#endif + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + PubFFlush (); + } + + ProConfDone = 0; + +#ifndef CC_UNIX + CloseHandle ( ProFileHnd ); +#endif + + // Free read buffers + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + // Free write buffers + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + ProABuff[ViBuff] = NULL; + } + + } + + + // Get close date & time + +#ifndef CC_UNIX + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateClose = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeClose = TIME__FConvDateTime2Time ( VODateTime ); +#else + ProPtRecInfFile->DateClose.W32 = 0; + ProPtRecInfFile->TimeClose.W32 = 0; +#endif + + + if ( ProReadyToWrite == 1 ) { + + // Overwrite info file with update close time & date + bloc nb + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Overwrite of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file failed => System : %s", strerror ( errno ) ) ); + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.0/files.def b/include/pxi_daq_lib_v.1.0/files.def new file mode 100755 index 0000000..535b3fc --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/files.def @@ -0,0 +1,33 @@ +/* 24/02/05 */ + + +#ifndef FIL_DEF +#define FIL_DEF + +#define FIL_DIR_FILES_LIST_MAX_CNT 100 + +#define FIL__TCBinFile_MEAS_TIME +#define FIL__TCStreamFile_MEAS_TIME + +#define FIL__TCBinFile_RWB_MODE_WRITE 0 +#define FIL__TCBinFile_RWB_MODE_READ 1 +#define FIL__TCBinFile_RWB_MODE_BOTH 2 + +// 07/03/2009 +// Macro removed because they are not supported under ROOT ... +// => Macro "calls" had been replaced by the macro code below in files.c +// => For new implementations : a copy paste of the macro code below must be done for each "flag test" +// +// #define FIL__TCBinFile_CHK_CONF_DONE {err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_WR {err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_RD {err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );} + + +#define FIL__TCStreamFile_MAX_BUFF_NB 4 +#define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 // Maximum number of blocs in variable bloc size mode +#define FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB 20 + + + +#endif + diff --git a/include/pxi_daq_lib_v.1.0/files.typ b/include/pxi_daq_lib_v.1.0/files.typ new file mode 100755 index 0000000..0a20dce --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/files.typ @@ -0,0 +1,279 @@ +/* 24/02/05 */ + + +#ifndef FIL_TYP +#define FIL_TYP + +/* char FIL_TADirFilesList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; */ + + +typedef struct { + char AList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; +} FIL_TDirFilesList; + + +// 30/01/2009 + +class FIL__TCBinFile { + + + private : + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + // Parameters from conf + + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParMaxBlocSz; + SInt32 ProParBlocSz; + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + + SInt32 ProCurRdEltId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrEltId; + UInt64 ProCurWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + UInt64 ProTotWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + FILE* ProPtFile; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + + + public : + + FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~FIL__TCBinFile (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + SInt32 PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz ); + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + +// 01/05/2010 + +typedef struct { + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + UInt32 ABlocSz[1]; + +} FIL__TCStreamFile_Old_TRecInfFile; + +// 05/11/10 + +typedef struct { + + UInt64 Offset; + UInt32 Sz; + + SInt32 SpareW32InfoFormat; // Number which identifies the meaning ASpareW32Info + SInt32 SpareW32InfoNb; // Number of spare parameters + SInt32 ASpareW32Info[FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB]; // Array for user parameters + + UInt32 Dummy; // For alignment + +} FIL__TCStreamFile_TBlocInf; + + +// 05/11/10 + +typedef struct { + + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + + UInt32 Dummy; // For alignment + + FIL__TCStreamFile_TBlocInf ABlocInf[1]; + + +} FIL__TCStreamFile_TRecInfFile; + + +class FIL__TCStreamFile { + + + private : + + FIL__TCStreamFile* PriPtMyself; + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + SInt32 ProParDiskBlocSz; + SInt8 ProParFixedBlocSzMode; + + // Parameters from conf + + SInt8 ProUseThread; + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParRequestedMaxBlocSz; // Bloc size value asked by user + SInt32 ProParMaxBlocSz; // Adjusted depending on ProParBlocSz + + SInt32 ProParRequestedBlocSz; // Bloc size value asked by user + SInt32 ProParBlocSz; // Bloc size value used ( multiple of disk bloc size ) + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + HANDLE ProFileHnd; + +#ifdef CC_UNIX + FILE* ProFilePtUx; // Pointer to data file for Linux / Unix +#endif + + char ProInfFileName[GLB_FILE_PATH_SZ]; + FILE* ProPtInfFile; + + FIL__TCStreamFile_TRecInfFile* ProPtRecInfFile; + SInt32 ProRecInfSz; + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + +#ifndef CC_UNIX + CRITICAL_SECTION ProCsPrintMsg; +#endif + + HANDLE ProThreadHnd; + DWORD ProThreadId; + + HANDLE ProSemWrBuffHnd; + HANDLE ProSemRdBuffHnd; + + SInt16 ProIndexWrBuff; + SInt16 ProIndexRdBuff; + + UInt8* ProABuff[FIL__TCStreamFile_MAX_BUFF_NB]; + SInt32 ProBuffSz; + + + SInt32 ProCurRdBlocId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrBlocId; + SInt32 ProCurWrSz; + SInt64 ProTotWrSz; + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + // Results + + SInt32 ProResWrBlocFailCnt; + + SInt32 ProFCalcProParBlocSz ( SInt32 DataSz ); + + public : + + FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + ~FIL__TCStreamFile (); + + friend DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + SInt32 PubFSetDiskSectorSz ( SInt32 DiskBlocSz ); + SInt32 PubFGetDiskSectorSz (); + + void PubFPrintMsg ( char* Msg ); + SInt32 PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFPrintInfFile (); + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + // SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 SpareInfo ); + + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ); + + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.0/files.var b/include/pxi_daq_lib_v.1.0/files.var new file mode 100755 index 0000000..7f38a20 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/files.var @@ -0,0 +1,18 @@ +/* 24/02/05 */ + + +#ifndef FIL_VAR +#define FIL_VAR + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +// Examples +// +// VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +// VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.0/globals.def b/include/pxi_daq_lib_v.1.0/globals.def new file mode 100755 index 0000000..296f090 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/globals.def @@ -0,0 +1,39 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_DEF +#define GLOBALS_DEF + +#ifndef CC_UNIX + #include "y:/dd/sdev/src/com/c/com/include/globals_root.def" +#endif + +#ifndef ROOT_ROOT + #define GLB_READ_CR { while ( getchar () != '\n' ); }; +#endif + + +#ifndef ROOT_ROOT + #define GLB_KEYB_CR { while ( getchar () != '\n' ); } +#endif + + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/globals_root.def b/include/pxi_daq_lib_v.1.0/globals_root.def new file mode 100755 index 0000000..26466d2 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/globals_root.def @@ -0,0 +1,44 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_ROOT_DEF +#define GLOBALS_ROOT_DEF + +/* CONDITIONNAL COMPILATION */ + +#define GLB_GC_CASCADE +#define GLB_FIRST_REC_FORMAT + +/* MACROS */ + +#define GLB_FILE_PATH_SZ 256 +#define GLB_CMT_SZ 256 +#define GLB_HOST_NAME_SZ 50 + +#define GLB_SEQ 0 + +#define GLB_RMP_FILE_PATH "/common/rmp/RMP" +#define GLB_RMPS_FILE_PATH "/common/rmp/RUN" + + +#define GLB_DEF_BYTE_SEX 0x3615ABCD + + +// #define GLB_DESY_VME_A32_BASE 0xd0000000 /* By default it's LEPSI config base address 0xd0000000*/ + + + + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/maps.def b/include/pxi_daq_lib_v.1.0/maps.def new file mode 100755 index 0000000..7a798eb --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/maps.def @@ -0,0 +1,49 @@ +/******************************************************************************* +File : x:\lib\com\maps\maps.def +Goal : Macros definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_DEF +#define MAPS_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define MAPS__TCDigTelMon_MAX_EV_NB 300 +#define MAPS__TCDigTelMon_MAX_PLANE_NB 6 +#define MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB 10000 +#define MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE 1000 + +#define MAPS__TCDigTelMon_CHK_PLANE_ID(Id) { if ( (Id < 0) || (Id >= MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + +#define MAPS__TCDigTelMon_CHK_PLANE_NB(Nb) { if ( (Nb <= 0) || (Nb > MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Nb, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + + +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME 0 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL 1 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS 2 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR 3 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS 4 + +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES 0 +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE 1 + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/maps.typ b/include/pxi_daq_lib_v.1.0/maps.typ new file mode 100755 index 0000000..63e1342 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/maps.typ @@ -0,0 +1,383 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.typ +Goal : Types definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_TYP +#define MAPS_TYP + + +#ifdef ROOT_ROOT + typedef UInt32 MAPS__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor MAPS__TColor; +#endif + + + +// 17/07/2009 + +typedef struct { + + SInt32 MaxBuffEvNb; + + // Hard coded parameters in next classes + + SInt8 MapsNb; // Nb of MAPS acquired by DAQ + SInt8 MapsName; + SInt8 PlaneNb; + + // Parameters from GUI + + SInt8 MonEnabled; + + SInt32 AcqFrNb; // Nb of frame in current acq to process + + SInt8 ProcOneAcq; // 1 => Process current ONLY acq + // 0 => Process ProcEvNb coming from GUI + // It can be more or less than one acq + + SInt32 ProcEvNb; // Ev nb to process, either + // - if ProcOneAcq = 1 => ev nb of one acq + // - if ProcOneAcq = 0 => from GUI + + SInt8 ProcOnlyFrWithHitOnAllPlanes; + + SInt8 ListHitAllPlanesMode; + + SInt8 ProcOnlyFrWithTrig; // Process only frames with hit + SInt8 HandleTrigPos; // Use trigger position to extract events + SInt8 StopAtEndOfProc; // Stop at end of processing, no automatic processing of next acq + SInt8 StoreEvents; // Store events + + SInt8 DispFrNbWithTrigOrFrNbWithHit; // Display in PubPt_ADispFrNbWithTrigOrHit & PubPt_ADispFrPCentWithTrigOrHit trig or hit nb + // 0 => Display frame nb & % with trigger + // 1 => Display frame nb & % with at least one hit + + SInt8 DispFullMatrix; // 0 => Display 1/2 scale matrix + // 1 => Display full matrix + + SInt8 ProcMode; // Processing mode + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + + SInt8 CumPlotGrayOrBlueLevels; // Cumul plot + // 0 => in gray levels + // 1 => in blue levels + + SInt8 CumPlotHitOrHitCnt; // Cumul plot + // 0 => binary display : count > 0 => set pixel in black / blue + // 1 => gray or blue levels display + + + SInt32 GotoRawFrNo; // Plot raw data of frame No + +} MAPS__TDigTelPar; + + +// 17/07/2009 + +typedef struct { + + SInt8 RunInProgress; + SInt8 LastPlaneSelForCoin; // Index of last plane selected for coincidence + + SInt32 CurEvNo; // Index of last event buffered + SInt32 FirstEvToProc; // Index of first event to process + SInt32 LastEvToProc; // Index of last event to process + SInt32 CurEvToProc; // Index of event to process + SInt32 EvNbToProc; // Ev nb to process + +} MAPS__TDigTelInf; + + +// 17/07/2009 + +typedef struct { + + SInt32 AcqFrNb; // Frame nb received from current acq + SInt32 ProFrNo; // Index of currently processed frame + SInt32 ProTimeMs; // Processing time + +} MAPS__TDigTelRes; + + +// 17/07/2009 + +typedef struct { + + SInt8 MapsId; // Id of the MAPS + MAPS__TColor PlotColor; + + SInt8 Process; // Process data of this plane + SInt8 RevertXDir; // Revert numbering of X direction ( columns ) in case planes are mounted back to back + SInt8 PlotCum; // Plot cumulated hit count over N events + SInt8 PlotCoin; // Plot coincidence + SInt8 PlotFrame; // Plot frame raw data + +} MAPS__TDigTelPlanePar; + + +// 22/07/2009 + +typedef struct { + + SInt8 PrevProcState; // Not used on 22/07/2009 + SInt8 CurProcState; // Not used on 22/07/2009 + + +} MAPS__TDigPlaneInf; + + +// 17/07/2009 + +typedef struct { + + void* AEvPt[MAPS__TCDigTelMon_MAX_EV_NB]; + void* CurEvPt; + +} MAPS__TDigTelPlaneData; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add CumTotTrigNb & CumFrameTrigNb + +typedef struct { + + void* PtMatDiscriBit; // Flat view of matrix X col x Y lines + void* PtMatCumTotHitCnt; // Hit count of each pixel over all events + + SInt32 FrameNbWithTrig; // Nb of frame with trigger + float FramePCentWithTrig; // % of frame with trigger + SInt32 CumTotTrigNb; // Total number of triggers + float CumFrameTrigNb; // Cumul MEAN trigger nb on frames WITH trigger + + SInt32 FrameNbWithHit; // Nb of frame with at least one hit + float FramePCentWithHit; // % of frame with at least one hit + SInt32 CumTotHitNb; // Total cumul hit nb over ALL frames ( with and without hit ) + float CumFrHitNb; // Cumul MEAN hit nb on frames WITH hit + +} MAPS__TDigTelPlaneRes; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add PubPt_ADispCumFrTrigNb + +#ifndef ROOT_ROOT + +class MAPS__TCDigTelMon { + + private: + + SInt8 PrivGuiConnected; + SInt8 PrivSetGuiParDontRead; + + SInt32 PrivFInit (); + + SInt32 PrivChkPlaneId ( SInt8 Id ); + + SInt32 PrivFSetGuiLabelsDispFrNbWithTrigOrFrNbWithHit (); + + protected: + + SInt8 ProRequestPlot; // Request plot from sw external to object + + MAPS__TDigTelPar ProPar; + MAPS__TDigTelInf ProInf; + MAPS__TDigTelRes ProRes; + MAPS__TDigTelPlanePar ProAPlanePar[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigPlaneInf ProAPlaneInf[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneData ProAPlaneData[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneRes ProAPlaneRes[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + public: + + // ---------------------------------- + // Fields to connect GUI components + // ---------------------------------- + + // Group + + TGroupBox* PubPt_GrpTelMon; + + // Label + + TLabel* PubPt_LbFrNbWithTrigOrHit; + TLabel* PubPt_LbFrPCentWithTrigOrHit; + + // Controls + + TCheckBox* PubPt_ChkEnableMonitor; + + TCheckBox* PubPt_AChkProc[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkRevertXDir[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TCheckBox* PubPt_ChkProcOneAcq; + TEdit* PubPt_EdFrNbToProc; + TCheckBox* PubPt_ChkProcOnlyFrWithTrig; + + TComboBox* PubPt_CbListHitAllPlanesMode; + + TCheckBox* PubPt_ChkTrigPosHanling; + TCheckBox* PubPt_ChkStopAtEndOfProc; + TCheckBox* PubPt_ChkStoreFr; + + TCheckBox* PubPt_ChkDispFrNbWithTrigOrFrNbWithHit; + TCheckBox* PubPt_ChkDispFullMatrix; + + TComboBox* PubPt_CbProcMode; + TCheckBox* PubPt_ChkCumPlotGrayOrBlueLevels; + TCheckBox* PubPt_ChkCumPlotHitOrHitCnt; + + TEdit* PubPt_EdGotoFr; + + TLabel* PubPt_ALbPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TRadioButton* PubPt_ARbPlotCum[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkPlotCoin[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TRadioButton* PubPt_ARdPlotFr[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // Indicators + + TEdit* PubPt_DispAcqFrNb; + TEdit* PubPt_DispCurProcFr; + + TEdit* PubPt_ADispFrNbWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispFrPCentWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_ADispCumFrTrigNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumTotHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumFrHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_DispProFrNo; + TEdit* PubPt_DispProcTimeMs; + + // Display + + TImage* PubPt_ImgMiniMatrix; + TImage* PubPt_ImgFullMatrix; + + + // ------------- + // Methods + // ------------- + + + MAPS__TCDigTelMon (); + ~MAPS__TCDigTelMon (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGuiEnablePlane ( SInt8 Id, SInt8 Enable ); + + SInt32 PubFSetGuiPar (); + SInt32 PubFSetGuiParGotoFr (); + + SInt32 PubFGetGuiPar (); + SInt32 PubFOnGuiParDispModeChangeFrNbWithTrigOrFrNbWithHit (); // Specific GUI behaviour + SInt32 PubFSetGuiStatus (); + SInt32 PubFSetGuiRes (); + + + // Set parameters + + SInt32 PubFSetPar ( MAPS__TDigTelPar* Pt ); + SInt32 PubFSetPlanePar ( SInt8 Id, MAPS__TDigTelPlanePar* Pt ); + + // Get parameters + + MAPS__TDigTelPar* PubFGetPar (); + MAPS__TDigTelPlanePar* PubFGetPlanePar ( SInt8 Id ); + MAPS__TDigTelPlaneData* PubFGetPlaneData ( SInt8 Id ); + + // Disable all planes processing + + SInt32 PubFDisAllPlanesProcessing (); + + // Disable group + + SInt32 PubFDisCumPlot (); + SInt32 PubFDisCoinPlot (); + SInt32 PubFDisFramePlot (); + + // Set results + + MAPS__TDigTelPlaneRes* PubFSetPlaneRes ( SInt8 Id ); + + // Poll plot request + + SInt32 PubFGetPlotRqStatus (); + SInt32 PubFResetPlotRqStatus (); + + SInt8* PubFGetPtPlotRq (); + SInt8* PubFGetPtMonEnabled (); + + + // Debug print + + SInt32 PubFPrintPar (); + SInt32 PubFPrintInf (); + + SInt32 PubFPrintPlanePar ( SInt8 Id ); + SInt32 PubFPrintAllPlanesPar (); + + SInt32 PubFPrintPlaneInf ( SInt8 Id ); + SInt32 PubFPrintAllPlanesInf (); + + SInt32 PubFPrintPlaneData ( SInt8 Id ); + SInt32 PubFPrintAllPlanesData (); + + SInt32 PubFPrintPlaneRes ( SInt8 Id ); + SInt32 PubFPrintAllPlanesRes (); + + +}; + +#endif + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 17/07/2009 */ +/* ============================= */ + +typedef struct { + + SInt8 Dummy; + +} MAPS__TContext; + + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/maps.var b/include/pxi_daq_lib_v.1.0/maps.var new file mode 100755 index 0000000..cd0d91a --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/maps.var @@ -0,0 +1,33 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.var +Goal : Variables definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_VAR +#define MAPS_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC MAPS__TContext MAPS__VGContext; + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/mi26_usr.def b/include/pxi_daq_lib_v.1.0/mi26_usr.def new file mode 100755 index 0000000..7771c7f --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/mi26_usr.def @@ -0,0 +1,75 @@ +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.def +Goal : Macros definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_DEF +#define MI26_USR_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ 1152 + +#define MI26__ZS_FFRAME_RAW_MAX_W8 2280 +#define MI26__ZS_FFRAME_RAW_MAX_W16 1140 // 1142 +#define MI26__ZS_FFRAME_RAW_MAX_W32 570 +#define MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 + + +#define MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 +#define MI26__ZS_FFRAME_MAX_STATES_REC 576 // one per line + +// ====================================== +// For MI26 discri analysis tools +// ====================================== + +// Submatrices number + +#define MI26__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define MI26__REG_BIAS_NB 19 + +#define MI26__REG_BIAS_ICLPDISC 0 +#define MI26__REG_BIAS_IPWRSW 1 +#define MI26__REG_BIAS_IBUF 2 +#define MI26__REG_BIAS_ID1PWRS 3 +#define MI26__REG_BIAS_ID2PWRS 4 +#define MI26__REG_BIAS_ILVDSTX 5 +#define MI26__REG_BIAS_ILVDS 6 +#define MI26__REG_BIAS_IVTST1 7 +#define MI26__REG_BIAS_IVTST2 8 +#define MI26__REG_BIAS_IANABUF 9 +#define MI26__REG_BIAS_IVDREF1D 10 +#define MI26__REG_BIAS_IVDREF1C 11 +#define MI26__REG_BIAS_IVDREF1B 12 +#define MI26__REG_BIAS_IVDREF1A 13 +#define MI26__REG_BIAS_IVDREF2 14 +#define MI26__REG_BIAS_IDIS1 15 +#define MI26__REG_BIAS_IDIS2 16 +#define MI26__REG_BIAS_IPXI 17 +#define MI26__REG_BIAS_IKIMO 18 + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/mi26_usr.typ b/include/pxi_daq_lib_v.1.0/mi26_usr.typ new file mode 100755 index 0000000..006161a --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/mi26_usr.typ @@ -0,0 +1,193 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.typ +Goal : Types definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_TYP +#define MI26_USR_TYP + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} MI26__TContext; + + +/* ======================================================= */ +/* Frame provided by Mi26 DAQ, it's independent of output */ +/* mode BUT data are not organized as in MI26__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by MI26__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + UInt32 Header; // Header of Mimosa 26 frame + UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 Trailer; // Trailer of Mimosa 26 frame + + UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + UInt16 ADataW16[MI26__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} MI26__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} MI26__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} MI26__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + MI26__TStatesLine StatesLine; + MI26__TState AStates[MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} MI26__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by Mi26, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a MI26 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + MI26__TZsFStatesRec AStatesRec[MI26__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} MI26__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/msg.c b/include/pxi_daq_lib_v.1.0/msg.c new file mode 100755 index 0000000..7dd5585 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/msg.c @@ -0,0 +1,230 @@ + +/******************************************************************************* +File : x:\lib\com\msg\msg.c +Goal : Implement user messages print ( screen ) or log ( file ) functions. + : It's usefull to send debug messages. + : +Remark : The way it works is controlled by 3 globals variables + : MSG_VGLogClosed = 0 ( disable ) / 1 ( enable ) user messages + : MSG_VGLogPath = '/msg/msg.txt' = path of messages logfile + : MSG_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : There is the same variables with RMSG_ instead of MSG_ they are + : used for on-line remote monitoring messages. + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_C +#define MSG_C + + +SInt32 MSG_FGenEnableLog ( SInt8 Chan, SInt8 Enable ) { + MSG_VGALogClosed[Chan] = Enable; + MSG_VGALogEnabled[Chan] = Enable; + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGenGetLogEnabled ( SInt8 Chan ) { + return (MSG_VGALogEnabled[Chan]); +} + + +SInt32 MSG_FGenSetLogFilePath ( SInt8 Chan, char* LogFilePath ) { + sprintf ( MSG_VGALogPath[Chan], "%s", LogFilePath ); + return (0); +} + +char* MSG_FGenGetLogFilePath ( SInt8 Chan ) { + return ( MSG_VGALogPath[Chan] ); +} + +SInt32 MSG_FGenStopLog ( SInt8 Chan, SInt8 Stop ) { + MSG_VGADontLog[Chan] = Stop; + return (0); +} + + +SInt32 MSG_FGenBegin ( SInt8 Chan, SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( Chan, Enable ); + MSG_FGenSetLogFilePath ( Chan, FilePath ); + + return (0); +} + +SInt32 MSG_FBegin ( SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable ); + MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, FilePath ); + + return (0); +} + + +SInt32 MSG_FEnd () { + + return (0); +} + + +SInt32 MSG_FEnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt32 MSG_EnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt8 MSG_FGetLogEnabled () { + return ( MSG_FGenGetLogEnabled ( MSG_CHAN_MSG ) ); +} + +SInt32 MSG_FSetLogFilePath ( char* LogFilePath ) { + return ( MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, LogFilePath ) ); +} + +/* 11/06/2005 */ + +SInt32 MSG_FSetFileLogLevel ( SInt8 Level ) { + + MSG_VGFileLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_GSetFileLogLevel () { + return (MSG_VGFileLogLevel); +} + + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserLogLevel ( SInt8 Level ) { + + MSG_VGUserLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGetUserLogLevel () { + return (MSG_VGUserLogLevel); +} + +char* MSG_FGetLogFilePath ( void ) { + return ( MSG_FGenGetLogFilePath ( MSG_CHAN_MSG ) ); +} + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserMsgFunc ( TUserMsgFunc Func ) { + + MSG_VGUserMsgFunc = Func; + + return (0); +} + + +/* 07/04/2007 */ + +char* MSG_FGenGetMsgLogConfStr ( SInt8 Chan ) { + + static char VStr[MSG_CMT_SZ+1]; + + sprintf ( VStr, "Messages log configuration \n\n - Log enabled = %d \n - Stop log = %d \n - File log level = %d \n - Log file name = %s \n - User log level = %d \n\n ", MSG_VGALogEnabled[Chan], MSG_VGADontLog[Chan], MSG_VGFileLogLevel, MSG_VGALogPath[Chan], MSG_VGUserLogLevel ); + + return (VStr); +} + +/* 07/04/2007 */ + +char* MSG_FGetMsgLogConfStr () { + return ( MSG_FGenGetMsgLogConfStr (MSG_CHAN_MSG) ); +} + +SInt32 MSG_FGenMsg ( SInt8 Chan, SInt8 Level ) { + + static char VMsg[256 /* MSG_CMT_SZ include file not visble from ROOT => must be solved */]; + + if ( (MSG_VGFileLogLevel == 0) && (MSG_VGUserLogLevel == 0) ) { + return (0); + } + + sprintf ( VMsg, "MSG %.7d => %s \n", MSG_VGAMsgCnt[Chan]++, MSG_VGAStrMsg[Chan]); + + if ( (MSG_VGFileLogLevel != 0) && (MSG_VGFileLogLevel >= Level) ) { + + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + + // 29/10/2010 => Alway overwrite log file + + // if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + // MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + // } + + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "%s", VMsg ); + fflush ( MSG_VGALogFile[Chan] ); + } + + } /* End if ( Level >= MSG_VGFileLogLevel ) */ + + if ( (MSG_VGUserLogLevel != 0) && (MSG_VGUserLogLevel >= Level) ) { + + if ( MSG_VGUserMsgFunc != NULL ) { + MSG_VGUserMsgFunc ( VMsg ); + } + + } /* End if ( Level >= MSG_VGUserLogLevel ) */ + + + return (0); + +/* + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + } + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "MSG %.4d =>", MSG_VGAMsgCnt[Chan]++ ); + fprintf ( MSG_VGALogFile[Chan], MSG_VGAStrMsg[Chan] ); + fprintf ( MSG_VGALogFile[Chan], "\n" ); + fflush ( MSG_VGALogFile[Chan] ); + } + + return (0); + +*/ + +} + + +#endif + diff --git a/include/pxi_daq_lib_v.1.0/msg.def b/include/pxi_daq_lib_v.1.0/msg.def new file mode 100755 index 0000000..c709cc1 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/msg.def @@ -0,0 +1,63 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.def +Goal : Macros definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_DEF +#define MSG_DEF + + + +#define MSG_CMT_SZ 1024 + +#define MSG_CHAN_NB 2 +#define MSG_CHAN_MSG 0 +#define MSG_CHAN_RMSG 1 + + +/* Must be after variables definition, instead CINT will be unable to handle these macros */ + +#define MSG_VGLogFile MSG_VGALogFile[MSG_CHAN_MSG] +#define MSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_MSG] +#define MSG_VGDontLog MSG_VGADontLog[MSG_CHAN_MSG] +#define MSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_MSG] +#define MSG_VGLogPath MSG_VGALogPath[MSG_CHAN_MSG] + +#define RMSG_VGLogFile MSG_VGALogFile[MSG_CHAN_RMSG] +#define RMSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_RMSG] +#define RMSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_RMSG] +#define RMSG_VGLogPath MSG_VGALogPath[MSG_CHAN_RMSG] + +/* 07/04/2007 MSG_VGAStrMsg identifier replaced by MSG_OUT because of ROOT CINT macros limitations */ +/* #define MSG_OUT MSG_VGAStrMsg[MSG_CHAN_MSG] */ + +#define RMSG_OUT MSG_VGAStrMsg[MSG_CHAN_RMSG] + +#define MSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,127);} +#define msg(Msg) MSG_PRINTF(Msg) + +#define MSG_PRINTF_LVL(Msg,Lvl) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,Lvl); } +#define msgl(Msg,Lvl) MSG_PRINTF_LVL(Msg,Lvl) + + +#define RMSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_RMSG,127); } +#define msgr(Msg) RMSG_PRINTF(Msg) +#define rmsg(Msg) RMSG_PRINTF(Msg) + + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/msg.typ b/include/pxi_daq_lib_v.1.0/msg.typ new file mode 100755 index 0000000..0f62f1d --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/msg.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.typ +Goal : Types definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef MSG_TYP +#define MSG_TYP + +typedef SInt32 (*TUserMsgFunc) ( char* Msg ); + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/msg.var b/include/pxi_daq_lib_v.1.0/msg.var new file mode 100755 index 0000000..2e8fc8b --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/msg.var @@ -0,0 +1,59 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.var +Goal : Variables definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_VAR +#define MSG_VAR + +/* + +EXTERN VAR_STATIC FILE* MSG_VGALogFile[MSG_CHAN_NB] VAR_INIT_A2(NULL,NULL); +EXTERN VAR_STATIC SInt8 MSG_VGALogClosed[MSG_CHAN_NB] VAR_INIT_A2(1,1); +EXTERN VAR_STATIC SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt8 MSG_VGADontLog[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ] VAR_INIT_A2("/dd/tmp/pc/msg.txt","/dev/rmsg"); +EXTERN VAR_STATIC char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ]; +EXTERN VAR_STATIC SInt8 MSG_VGFileLogLevel VAR_INIT (0); +EXTERN VAR_STATIC SInt8 MSG_VGUserLogLevel VAR_INIT (0); +EXTERN VAR_STATIC TUserMsgFunc MSG_VGUserMsgFunc VAR_INIT (NULL); + +*/ + +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, FILE* MSG_VGALogFile[MSG_CHAN_NB] , NULL, NULL ); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogClosed[MSG_CHAN_NB] , 1, 1); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGADontLog[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ], "/dd/tmp/pc/msg.txt","/dev/rmsg" ); + + +VAR_DCL ( EXTERN, VAR_STATIC, char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ] ); + +/* 07/04/2007 Replace macro MSG_OUT by a variable which points to MSG_VGAStrMsg[MSG_CHAN_MSG] because of ROOT CINT macros limitations */ + + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char* MSG_OUT , MSG_VGAStrMsg[MSG_CHAN_MSG] ); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGFileLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGUserLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, TUserMsgFunc MSG_VGUserMsgFunc , NULL); + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.0/pxi_daq_lib_v.1.0.c b/include/pxi_daq_lib_v.1.0/pxi_daq_lib_v.1.0.c new file mode 100755 index 0000000..a7b7c2c --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/pxi_daq_lib_v.1.0.c @@ -0,0 +1,754 @@ +// -------------------------------------------------------------------------------------- +// Includes required by DAQ library +// imported directly from Gilles Claus +// all the .def, .typ, .var or .c files are located in the include dir +// JB 2011/03/14 + +#define _FILE_OFFSET_BITS 64 // Mandatory for large files ( > 2 GB ) handling +// MUST be set before standard C header files + +#include +#include +#include // types +#include +#include + +/* ========================================= */ +/* Conditional compilation for DAQ sources */ +/* ========================================= */ + +#define ROOT_ROOT // Disable code parts which can't compile under ROOT +#define CC_UNIX // Specify operating system + +/* ========================================= */ +/* DAQ commun files -> types & constants */ +/* ========================================= */ + + +#include "globals.def" +#include "globals_root.def" +#include "types.typ" + +/* ================================================================ */ +/* Definition of WIndows types & constant not available under Linux */ +/* ---------------------------------------------------------------- */ +/* Work like this now = allow to compile program, but should be */ +/* done in a better way later !!!!!!!!! */ +/* ================================================================ */ + +#define HANDLE UInt32 +#define DWORD UInt32 +#define WINAPI +#define LPVOID void* +#define INVALID_HANDLE_VALUE 0xFFFFFFFF + + +/* ========================================= */ +/* Macros needed to compile DAQ sources */ +/* ========================================= */ + +#define EXTERN +#define VAR_STATIC +#define VAR_INIT(x) =x +#define VAR_INIT_A2(x,y) ={x,y} +#define VAR_DCL(Extern,Static,Var) Extern Static Var +#define VAR_DCL_INIT(Extern,Static,Var,Init) Extern Static Var VAR_INIT (Init) +#define VAR_DCL_INIT_A2(Extern,Static,Var,Init0,Init1) Extern Static Var VAR_INIT_A2 (Init0,Init1) + + +/* ========================================= */ +/* Includes DAQ source files */ +/* ========================================= */ + +// Errors messages logging library interface + +#include "errors.def" +#include "errors.typ" +#include "errors.var" + +// General messages logging library interface + +#include "msg.def" +#include "msg.typ" +#include "msg.var" + +// ASIC library interface + +#include "asic.def" +#include "asic.typ" +#include "asic.var" + +// MAPS library interface + +#include "maps.def" +#include "maps.typ" +#include "maps.var" + +// Time library interface + +#include "time.def" +#include "time.typ" +#include "time.var" + +// Files library interface + +#include "files.def" +#include "files.typ" +#include "files.var" + +// Mimosa 26 library interface + +#include "mi26_usr.def" +#include "mi26_usr.typ" + +// Eudet flex rio DAQ library interface + +#include "eudet_frio.def" +#include "eudet_frio.typ" +#include "eudet_frio.var" + + +// Libraries C source files + +#include "errors.c" +#include "msg.c" +#include "time.c" +#include "files.c" + +#include "eudet_frio_print.c" + + + +/* ========================== */ +/* Application constants */ +/* ========================== */ + +#define APP_ERR_LOG_FILE "./Results/errors.txt" +#define APP_MSG_LOG_FILE "./Results/msg.txt" + +/* ========================== */ +/* Application macros */ +/* ========================== */ + +#define APP__READ_CR { while ( getchar () != '\n' ); }; + +/* ============================= */ +/* Application context type */ +/* ============================= */ + + +typedef struct { + + // Parameters + + char ParRunDir[GLB_FILE_PATH_SZ]; // Run directory + char ParFileNamePrefix[20]; // Run file prefix, eg : RUN_666 => RUN_ is the prefix + SInt32 ParRunNo; + + SInt32 ParFrameNbPerAcq; // Nb of frame in the acquisition ( get from run file ) + SInt32 ParAcqNo; // Index of acquisition to select ( get from GUI ) + SInt32 ParFrameNo; // Index of frame to get + + // Intermediate variables + + char InfRunParFile[GLB_FILE_PATH_SZ]; // File which contains run parameters *.par + char InfRunDataFile[GLB_FILE_PATH_SZ]; // File which contains run data *.bin + SInt32 InfMaxFrameSz; // Maximal size of one frame = total size for N Mimosa 26 + + // Results + + SInt8 ResRunLoaded; // Flag indicates run state : -1 not loaded, +1 loaded + + EFRIO__TRunCont ResRunCont; // Run context record = run parameter + additional info + // Loaded from file RUN*.par + + EFRIO__TFrameList ResFramesList; // List of frames + +} APP__TContext; + +/* ============================= */ +/* Application global variables */ +/* ============================= */ + + +// Error messages logging level ( file errors.txt ) , can be +// - ERR_LOG_LVL_NONE +// - ERR_LOG_LVL_ALL +// - ERR_LOG_LVL_WARNINGS_ERRORS +// - ERR_LOG_LVL_ERRORS + + +SInt32 APP_VGErrFileLogLvl = ERR_LOG_LVL_ALL; // Log level for log file +SInt32 APP_VGErrUserLogLvl = ERR_LOG_LVL_ALL; // Log level for user print function => not used + +// General messages logging level ( file msg.txt ), 127 => log all messages + +SInt32 APP_VGMsgFileLogLvl = 127; // Log level for log file +SInt32 APP_VGMsgUserLogLvl = 127; // Log level for user print function => not used + +// Class to read run file +// - APP__VGRunConfFile for run conf file = RUN*.par +// - APP__VGRunDataFile for run data file = RUN*.bin (data) and RUN*.bin.inf (index file) + +FIL__TCBinFile APP__VGRunConfFile ( "./err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); +FIL__TCStreamFile APP__VGRunDataFile ( "./err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); + + +// Application context record +// - Contains all global variables needed => easier to move to an object +// - Should also include errors and messages log variables ( APP_VGErrFileLogLvl, etc ... ), not done now + +APP__TContext APP__VGContext; // generic pointer to the DAQ information +//APP__TContext* VPtCont = &APP__VGContext; + +SInt32 VAcqNo; // current acquisition number +SInt32 VFrNo; // current frame number +EFRIO__TFrame* VPtFrame; // pointer to the current frame + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : + : + Inputs : + : + Ouputs : + : + Globals : + : + Remark : + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FIsLittleEndian () + : + Goal : Test is CPU is little endian, return 1 in this case, 0 otherwise. + : + Inputs : None + : + Ouputs : The function returns + : 0 - CPU is not little endian + : 1 - CPU is little endian + : + Globals : None + : + Remark : One + : + Level : + Date : 19/02/2011 + Doc date : 19/02/2011 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FIsLittleEndian () { + + SInt32 VTest = 0x11223344; + char* VPt; + + VPt = (char*) &VTest; + + if ( (VPt[0] == 0x11) && (VPt[1] == 0x22) && (VPt[2] == 0x33) && (VPt[3] == 0x44) ) { + return (0); + } + + else { + return (1); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : + : + Inputs : + : + Ouputs : + : + Globals : + : + Remark : + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FPrintRecSzChkAlign ( char* Os ) { + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "= Print records size for alignment checking Windows / Unix =" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "= System = %s ", Os )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "" )); + + msg (( MSG_OUT, "FIL__TCStreamFile_TBlocInf = %d ", sizeof (FIL__TCStreamFile_TBlocInf) )); + msg (( MSG_OUT, "FIL__TCStreamFile_TRecInfFile = %d ", sizeof (FIL__TCStreamFile_TRecInfFile) )); + msg (( MSG_OUT, "EFRIO__TRunCont = %d ", sizeof (EFRIO__TRunCont) )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EFRIO__TFrame = %d ", sizeof (EFRIO__TFrame) )); + msg (( MSG_OUT, "EFRIO__TFrameHeader = %d ", sizeof (EFRIO__TFrameHeader) )); + msg (( MSG_OUT, "EFRIO__TFrameData = %d ", sizeof (EFRIO__TFrameData) )); + msg (( MSG_OUT, "EFRIO__TTriggerRec = %d ", sizeof (EFRIO__TTriggerRec) )); + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) + : + Goal : Load a run file = configure lib for this run but the run is not loaded + : in memory. + : + Inputs : RunDir - Run directory without \ at end + : RunPrefix - Run file prefix, eg : "RUN_" + : RunNo - Run no + : + Ouputs : The function returns + : Number of acquisitions in run file + : -1 if an error occurs + : + Globals : Update APP__VGContext fields + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : 19/02/2011 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqNb; + SInt32 VRet; + + + // ----------------------------- + // Reset run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = -1; + + // ----------------------------- + // Set run parameters + // ----------------------------- + + sprintf ( VPtCont->ParRunDir , "%s", RunDir ); + sprintf ( VPtCont->ParFileNamePrefix, "%s", RunPrefix ); + + VPtCont->ParRunNo = RunNo; + + // Calculate run par file & run data file names + + sprintf ( VPtCont->InfRunDataFile, "%s/%s%d.bin", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + sprintf ( VPtCont->InfRunParFile , "%s/%s%d.par", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + + // Print run par file & run data file names for debugging + + msg (( MSG_OUT, "Run data file name = %s", VPtCont->InfRunDataFile )); + msg (( MSG_OUT, "Run par file name = %s", VPtCont->InfRunParFile )); + + + // ----------------------------- + // Read run param file + // ----------------------------- + + // Init & conf TCBinFile class to do the job + + //printf("pxi_daq: Opening .par file %s with RWBmode %d, MaxBlocSz %d, BlocSz %d\n", VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont)); + + VRet = VRet | APP__VGRunConfFile.PubFConf ( VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont), 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + //printf("pxi_daq: return after PubFConf %d\n", VRet); + VRet = VRet | APP__VGRunConfFile.PubFOpen (); + //printf("pxi_daq: return after PubFOpen %d\n", VRet); + VRet = VRet | APP__VGRunConfFile.PubFSeqRead ( &VPtCont->ResRunCont, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont) ); + //printf("pxi_daq: return after PubFSeqRead %d\n", VRet); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Load run parameter file = %s failed !", VPtCont->InfRunParFile ) ); + + // ----------------------------- + // Open run data file + // ----------------------------- + + // Init & conf TCStreamFile class to do the job + + VRet = VRet | APP__VGRunDataFile.PubFConf ( &APP__VGRunDataFile, 0 /* UseThread */, VPtCont->InfRunDataFile, FIL__TCBinFile_RWB_MODE_READ, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunDataFile.PubFOpen (); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Open run data file %s failed !", VPtCont->InfRunDataFile ) ); + + + // ----------------------------- + // Set run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = 1; + + // ----------------------------- + // Return number of acq in file + // ----------------------------- + + VAcqNb = APP__VGRunDataFile.PubFGetBlocNb (); + + err_retval ( VAcqNb, ( ERR_OUT, "Run %d loaded => Contains %d acquistions", RunNo, VAcqNb ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FAllocAcqBuffer ( ) + : + Goal : Allocates the buffer for one acqusition. + : + Inputs : None + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read informations from APP__VGContext and set pointer to buffer. + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FAllocAcqBuffer () { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + + // ---------------------- + // Calculates sizes + // ---------------------- + + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + VPtCont->ResRunCont.InfFrameBuffSz = VPtCont->ResRunCont.ParFrameNbPerAcq * VPtCont->InfMaxFrameSz; + + // ---------------------- + // Print results + // ---------------------- + + msg (( MSG_OUT, "==========================================" )); + msg (( MSG_OUT, "InfMaxFrameSz = %d", VPtCont->InfMaxFrameSz )); + msg (( MSG_OUT, "ResRunCont.InfFrameBuffSz = %d", VPtCont->ResRunCont.InfFrameBuffSz )); + msg (( MSG_OUT, "==========================================" )); + + // ---------------------- + // Allocate acq buffer + // ---------------------- + + // Free if already allocated + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + } + + // Try to allocate + + VPtCont->ResRunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->ResRunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->ResRunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->ResRunCont.ParFrameNbPerAcq) ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FFreeAcqBuffer () + : + Goal : Free acquisition buffer + : + Inputs : None + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read informations from APP__VGContext and set buffer pointer to NULL. + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FFreeAcqBuffer ( ) { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Free buffer + // ------------------------------- + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + VPtCont->ResRunCont.PtFrame = NULL; + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : + Goal : Build the frame list for one acquisition + : + Inputs : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : + : + Remark : This function is the copy of EFRIO__FBuildFrameListFromAcq for application + : program demo. + : + : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : + Level : + Date : 06/11/2010 + Rev : 19/02/2011 + : - Moved from eudet_fio.c + : + Doc date : 07/11/2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) + : + Goal : Load AcqNo in memory + : + Inputs : AcqNo - No of acquisition to load + : PtFrameNb - Pointer to a variable which will be set with frames nb in AcqNo + : - Set it to NULL if you don't need it + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read information from APP__VGContext. + : + Remark : None. + : + Level : + Date : 19/02/2011 + Rev : 07/03/2011 + : - New " spare W32 info " format + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqInfFormat; + EFRIO__TFileSpareW32Info VAcqInf; + SInt32 VRet; + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + // ----------------------------------- + // Load acquisition in memory + // ----------------------------------- + + // Load from run file + + // Before 07/03/2011 + // VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VFrameNb ); + + VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VAcqInfFormat, sizeof (VAcqInf) / 4 /* MaxSpareW32InfoNb */, (SInt32*) &VAcqInf ); + + err_retfail ( VRet, (ERR_OUT, "Goto acquisition No %d failed !", AcqNo ) ); + + // Build frame list = array of pointer to access frames one by one + + VRet = APP__FBuildFrameListFromAcq ( VAcqInf.TotFrameNb, VPtCont->ResRunCont.PtFrame, &VPtCont->ResFramesList ); + + err_retfail ( VRet, (ERR_OUT,"Build frames list for acquisition No %d failed !", AcqNo ) ); + + // ----------------------------------- + // Update frame nb parameter + // ----------------------------------- + + if ( PtFrameNb != NULL ) { + *PtFrameNb = VAcqInf.TotFrameNb; + } + + err_retok (( ERR_OUT, "Acquisiton No %d loaded in memory - Contains %d frames", AcqNo, VAcqInf.TotFrameNb )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) + : + Goal : Return a pointer to one frame of the acquisition which is loaded in memory. + : + Inputs : FrameIdInAcq - The no of the frame + : + Ouputs : The function returns + : A valid pointer to the frame + : A NULL pointer if the operation failed + : + Globals : Read information from APP__VGContext. + : + Remark : None + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) { + + APP__TContext* VPtCont = &APP__VGContext; + EFRIO__TRunCont* VPtRunCont = &VPtCont->ResRunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->ResFramesList; + + + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"No frame=%d in list => Pointer NULL", FrameIdInAcq) ); + } + + return ( VPtFrList->AFramePtr[FrameIdInAcq] ); +} + diff --git a/include/pxi_daq_lib_v.1.0/time.c b/include/pxi_daq_lib_v.1.0/time.c new file mode 100755 index 0000000..1e98424 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/time.c @@ -0,0 +1,623 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.c +Goal : Functions of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_C +#define TIME_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateL TIME_FConvDateS2DateL ( TIME__TUDateS DateS ) { + + TIME__TUDateL VDateL; + + VDateL.Date.Day = DateS.Date.Day; + VDateL.Date.Month = DateS.Date.Month; + VDateL.Date.Year = 2000 + DateS.Date.Year; + + return (VDateL); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateS TIME_FConvDateL2DateS ( TIME__TUDateL DateL ) { + + TIME__TUDateS VDateS; + + VDateS.Date.Day = DateL.Date.Day; + VDateS.Date.Month = DateL.Date.Month; + VDateS.Date.Year = DateL.Date.Year % 2000; + + return (VDateS); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 23/05/2010 +Doc date : 23/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateS2Str ( TIME__TUDateS Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.2d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( UInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( SInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = (UInt32) Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ + : +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FDateL2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2Str ( TIME__TUDateL Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.4d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 06/03/2010 +Doc date : 06/03/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2StrExt ( TIME__TUDateL Date, char SepChar, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d%c%.2d%c%.4d", Date.Date.Day, SepChar, Date.Date.Month, SepChar, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FConvDateTime2DateL ( TDateTime Src ) { + + TIME__TUDateL VDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + Src.DecodeDate ( &VYear, &VMonth, &VDay ); + + VDate.Date.Year = VYear; + VDate.Date.Month = VMonth; + VDate.Date.Day = VDay; + + return (VDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FGetDateLOfNextDay ( TIME__TUDateL Cur ) { + + TDateTime VCurDate ( Cur.Date.Year, Cur.Date.Month, Cur.Date.Day ); + TIME__TUDateL VNextDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + ++VCurDate; + + VCurDate.DecodeDate ( &VYear, &VMonth, &VDay ); + + VNextDate.Date.Year = VYear; + VNextDate.Date.Month = VMonth; + VNextDate.Date.Day = VDay; + + return (VNextDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +WARNING : If return pointer to list is used, a copy of LIST ( not pointer ) must be done + : after each TIME__FFillListDatesLOfWeek () call otherwise the list content will be + : the one of last call because all pointers will point to last list stored in local + : variable of function. + : + : +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef ROOT_ROOT + +TIME__TListDatesLOfWeek* TIME__FFillListDatesLOfWeek ( TIME__TUDateL MondayDate, TIME__TListDatesLOfWeek* PtList ) { + + static TIME__TListDatesLOfWeek VList; + TIME__TUDateL VDayDate; + SInt8 ViDay; + + + VDayDate = MondayDate; + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + VList.ADates[ViDay] = VDayDate; + VDayDate = TIME__FGetDateLOfNextDay ( VDayDate ); + } + + if ( PtList != NULL ) { + *PtList = VList; + } + + return (&VList); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 TIME__FPrintListDatesLOfWeek ( TIME__TListDatesLOfWeek* PtList ) { + + SInt8 ViDay; + + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + msg (( MSG_OUT, "Date : %s", TIME__FDateL2Str ( PtList->ADates[ViDay], NULL /* PtDestStr */, 0 /* DestStrSz */ ) )); + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +WARNING : A copy of return STRING ( not pointer ) must be done after each TIME_FGetDayName call + : otherwise the string content will be the one of last call because all pointers will + : point to last string stored in local variable of function. +: +Level : +Date : 27/02/2010 +Doc date : 27/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME_FGetDayName ( UInt8 DayIndex, SInt8 Language ) { + + static char* VAStrDayNameFr[8] = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche" }; + static char* VAStrDayNameEn[8] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + + if ( DayIndex > 7 ) { + err_error (( ERR_OUT, "Bad day index = %d out of rnage 0..7", DayIndex )); + return ( "?" ); + } + + switch ( Language ) { + + case TIME__LANG_FRENCH : { + return ( VAStrDayNameFr[DayIndex] ); + break; } + + case TIME__LANG_ENGLISH : { + return ( VAStrDayNameEn[DayIndex] ); + break; } + + + default : { + err_error (( ERR_OUT, "Bad language = %d out of range", Language )); + return ( "?"); + } + + } + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUTime TIME__FConvDateTime2Time ( TDateTime Src ) { + + TIME__TUTime VTime; + unsigned short VHour; + unsigned short VMin; + unsigned short VSec; + unsigned short VMSec; + + Src.DecodeTime ( &VHour, &VMin, &VSec, &VMSec ); + + VTime.Time.Hour = VHour; + VTime.Time.Min = VMin; + VTime.Time.Sec = VSec; + VTime.Time.Cent = VMSec / 10; + + return (VTime); +} + +#endif + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FTime2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FTime2Str ( TIME__TUTime Time, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrTime[TIME__STR_TIME_SZ]; + + sprintf ( VStrTime, "%.2d:%.2d:%.2d|%.2d", Time.Time.Hour, Time.Time.Min, Time.Time.Sec, Time.Time.Cent ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_TIME_SZ) ) { + sprintf ( PtDestStr, "%s", VStrTime ); + } + + return (VStrTime); +} + + +// 23/05/2010 + +char* TIME__FTime2Str ( UInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + +// 23/05/2010 + +char* TIME__FTime2Str ( SInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = (UInt32) Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +#endif + diff --git a/include/pxi_daq_lib_v.1.0/time.def b/include/pxi_daq_lib_v.1.0/time.def new file mode 100755 index 0000000..a4ec9f1 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/time.def @@ -0,0 +1,40 @@ + + +/******************************************************************************* +File : x:\lib\com\time\time.def +Goal : Macros definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_DEF +#define TIME_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define TIME__STR_DATE_SZ 11 +#define TIME__STR_TIME_SZ 11 + +#define TIME__LANG_FRENCH 0 +#define TIME__LANG_ENGLISH 1 + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/time.typ b/include/pxi_daq_lib_v.1.0/time.typ new file mode 100755 index 0000000..3d88f0e --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/time.typ @@ -0,0 +1,140 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.typ +Goal : Types definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_TYP +#define TIME_TYP + + +/* =========================== */ +/* Date S => Short date format */ +/* Eg : 01/01/10 */ +/* =========================== */ + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aa in W32 + // B31B24 B23B16 B15B08 B07B00 + // 00 Day Month Year + + SInt8 Year; + SInt8 Month; + SInt8 Day; + SInt8 NotUsed; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateS; + + +typedef union { + + UInt32 W32; + + TIME__TSDateS Date; + +} TIME__TUDateS; + + + +/* ========================== */ +/* Date L => Long date format */ +/* Eg : 01/01/2010 */ +/* ========================== */ + + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aaaa in W32 + // B31B24 B23B16 B15B00 + // Day Month Year + + SInt16 Year; + SInt8 Month; + SInt8 Day; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateL; + + +typedef union { + + UInt32 W32; + + TIME__TSDateL Date; + +} TIME__TUDateL; + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + TIME__TUDateL ADates[7]; + +} TIME__TListDatesLOfWeek; + + +/* =============================== */ +/* Time : Hour - Min - Sec - 1/100 */ +/* Eg : 21/05/2010 */ +/* =============================== */ + + +typedef struct { + + // Fields order MUST be Hour - Min - Sec - 1/100 -> Don't modify it + // B31B24 B23B16 B15B08 B07B00 + // Hour Min Sec Cent + + SInt8 Cent; + SInt8 Sec; + SInt8 Min; + SInt8 Hour; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSTime; + + +typedef union { + + UInt32 W32; + + TIME__TSTime Time; + +} TIME__TUTime; + + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/time.var b/include/pxi_daq_lib_v.1.0/time.var new file mode 100755 index 0000000..3b0fee6 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/time.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.var +Goal : Variables definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_VAR +#define TIME_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN SInt8 TIME_VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.0/types.typ b/include/pxi_daq_lib_v.1.0/types.typ new file mode 100755 index 0000000..7c7b655 --- /dev/null +++ b/include/pxi_daq_lib_v.1.0/types.typ @@ -0,0 +1,164 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.typ +Goal : Common basic types definitions. + : I never use default C types names ( char, int ... ) + : i redefined them here ( SInt8, UInt32 ... ). + : + : If something go wong on you'r plateform with C types + : definition you need to update this file. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +/*H**************************************************************************** +FILE : Types.Typ +BUT : Define types. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_TYP +#define TYPES_TYP + + // typedef enum ELang { ELang_FRENCH, ELang_ENGLISH, ELang_GERMAN, ELang_LANG_NB } TLang; + +#ifndef NODEFTYPCHAR + +/* +17/11/04 GC + +BCPPB declares an identfier with the same name " Char " +this problem happens while compiling Mimo* JTAG application (MP). +This Char identifier is used in SpinEdit object. + +MP used conditionnal compilation, i decided to remove this Char +type definition, because i believe i never use it. +Wait and see ... + +*/ + +/* typedef unsigned char Char; */ + +#endif + +#ifndef UInt8 + typedef unsigned char UInt8; +#endif + +#ifndef UByte + typedef UInt8 UByte; +#endif + +#ifndef SInt8 + typedef char SInt8; +#endif + +#ifndef SByte + typedef SInt8 SByte; +#endif + +#ifndef UInt16 + typedef unsigned short UInt16; +#endif + +#ifndef UWord + typedef UInt16 UWord; +#endif + +#ifndef SInt16 + typedef short SInt16; +#endif + +#ifndef SWord + typedef SInt16 SWord; +#endif + +#ifndef UInt32 + typedef unsigned long int UInt32; +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + typedef long int SInt32; +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif + + +#ifdef CC_UNIX + +#ifndef UInt64 + typedef int64_t UInt64; +#endif + +#ifndef SInt64 + typedef uint64_t SInt64; +#endif + +#else + +#ifndef UInt64 + typedef unsigned __int64 UInt64; +#endif + +#ifndef SInt64 + typedef __int64 SInt64; +#endif + + +#endif + + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/asic.def b/include/pxi_daq_lib_v.1.1/asic.def new file mode 100755 index 0000000..a191e22 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/asic.def @@ -0,0 +1,92 @@ + + +/******************************************************************************* +File : x:\lib\com\asic\asic.def +Goal : Macros definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_DEF +#define ASIC_DEF + + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef enum { + + ASIC__NONE, + ASIC__MI26, + ASIC__ULT1 + +} ASIC__TEAsicName; + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__MI26_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__MI26_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__MI26_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__MI26_TRIG_TOT_NB // Total number of triggers + +} ASIC__MI26_TETrigRes; + + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__ULT1_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__ULT1_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__ULT1_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__ULT1_TRIG_TOT_NB // Total number of triggers + +} ASIC__ULT1_TETrigRes; + + +#define ASIC__ENUM_TRIG_RES_NB 4 + + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/asic.typ b/include/pxi_daq_lib_v.1.1/asic.typ new file mode 100755 index 0000000..51d7703 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/asic.typ @@ -0,0 +1,51 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.typ +Goal : Types definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_TYP +#define ASIC_TYP + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + SInt8 AsicNo; // Index of Asic <0..N-1> in case more than one is acquired + SInt32 AcqNo; // Index of current acquisition + SInt32 FrameNoInAcq; // Index of frame in acquisition <0..AcqFrameNb-1> + SInt32 FrameNoInRun; // Index of frame in run <0..TotEventNb-1> + + SInt32 HitCnt; // Counter of hits in frame + // Used for monitoring, may be not set, therefore HitCnt = -1 + + + SInt32 ATrigRes[ASIC__ENUM_TRIG_RES_NB]; // Information about trigger, see ASIC__MI26_TETrigRes in asic.def + // Parameters list index is + // ASIC__MI26_TRIG_RES__SIG_LINE + // ASIC__MI26_TRIG_RES__SIG_CLK + // ASIC__MI26_TRIG_RES__LINE + // ASIC__MI26_TRIG_TOT_NB + +} ASIC__TFrameStatus; + + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/asic.var b/include/pxi_daq_lib_v.1.1/asic.var new file mode 100755 index 0000000..452512e --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/asic.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.var +Goal : Variables definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_VAR +#define ASIC_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN VAR_STATIC SInt8 ASIC__VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/daq_lib.c b/include/pxi_daq_lib_v.1.1/daq_lib.c new file mode 100755 index 0000000..ea80716 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/daq_lib.c @@ -0,0 +1,645 @@ +#include "daq_lib.h" + +#include "errors.c" +#include "msg.c" +#include "time.c" +#include "files.c" +#include "eudet_frio_print.c" + +/* ========================== */ +/* Application constants */ +/* ========================== */ + +#define APP_ERR_LOG_FILE "./Results/errors.txt" +#define APP_MSG_LOG_FILE "./Results/msg.txt" + +/* ========================== */ +/* Application macros */ +/* ========================== */ + +#define APP__READ_CR { while ( getchar () != '\n' ); }; + +/* ============================= */ +/* Application context type */ +/* ============================= */ + + +typedef struct { + + // Parameters + + char ParRunDir[GLB_FILE_PATH_SZ]; // Run directory + char ParFileNamePrefix[20]; // Run file prefix, eg : RUN_666 => RUN_ is the prefix + SInt32 ParRunNo; + + SInt32 ParFrameNbPerAcq; // Nb of frame in the acquisition ( get from run file ) + SInt32 ParAcqNo; // Index of acquisition to select ( get from GUI ) + SInt32 ParFrameNo; // Index of frame to get + + // Intermediate variables + + char InfRunParFile[GLB_FILE_PATH_SZ]; // File which contains run parameters *.par + char InfRunDataFile[GLB_FILE_PATH_SZ]; // File which contains run data *.bin + SInt32 InfMaxFrameSz; // Maximal size of one frame = total size for N Mimosa 26 + + // Results + + SInt8 ResRunLoaded; // Flag indicates run state : -1 not loaded, +1 loaded + + EFRIO__TRunCont ResRunCont; // Run context record = run parameter + additional info + // Loaded from file RUN*.par + + EFRIO__TFrameList ResFramesList; // List of frames + +} APP__TContext; + +/* ============================= */ +/* Application global variables */ +/* ============================= */ + + +// Error messages logging level ( file errors.txt ) , can be +// - ERR_LOG_LVL_NONE +// - ERR_LOG_LVL_ALL +// - ERR_LOG_LVL_WARNINGS_ERRORS +// - ERR_LOG_LVL_ERRORS + + +SInt32 APP_VGErrFileLogLvl = ERR_LOG_LVL_ALL; // Log level for log file +SInt32 APP_VGErrUserLogLvl = ERR_LOG_LVL_ALL; // Log level for user print function => not used + +// General messages logging level ( file msg.txt ), 127 => log all messages + +SInt32 APP_VGMsgFileLogLvl = 127; // Log level for log file +SInt32 APP_VGMsgUserLogLvl = 127; // Log level for user print function => not used + +// Class to read run file +// - APP__VGRunConfFile for run conf file = RUN*.par +// - APP__VGRunDataFile for run data file = RUN*.bin (data) and RUN*.bin.inf (index file) + +FIL__TCBinFile APP__VGRunConfFile ( "./err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); +FIL__TCStreamFile APP__VGRunDataFile ( "./err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); + + +// Application context record +// - Contains all global variables needed => easier to move to an object +// - Should also include errors and messages log variables ( APP_VGErrFileLogLvl, etc ... ), not done now + +APP__TContext APP__VGContext; // generic pointer to the DAQ information +//APP__TContext* VPtCont = &APP__VGContext; + +SInt32 VAcqNo; // current acquisition number +SInt32 VFrNo; // current frame number +EFRIO__TFrame* VPtFrame; // pointer to the current frame + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : + : + Inputs : + : + Ouputs : + : + Globals : + : + Remark : + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FIsLittleEndian () + : + Goal : Test is CPU is little endian, return 1 in this case, 0 otherwise. + : + Inputs : None + : + Ouputs : The function returns + : 0 - CPU is not little endian + : 1 - CPU is little endian + : + Globals : None + : + Remark : One + : + Level : + Date : 19/02/2011 + Doc date : 19/02/2011 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FIsLittleEndian () { + + SInt32 VTest = 0x11223344; + char* VPt; + + VPt = (char*) &VTest; + + if ( (VPt[0] == 0x11) && (VPt[1] == 0x22) && (VPt[2] == 0x33) && (VPt[3] == 0x44) ) { + return (0); + } + + else { + return (1); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : + : + Inputs : + : + Ouputs : + : + Globals : + : + Remark : + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FPrintRecSzChkAlign ( char* Os ) { + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "= Print records size for alignment checking Windows / Unix =" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "= System = %s ", Os )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "" )); + + msg (( MSG_OUT, "FIL__TCStreamFile_TBlocInf = %d ", sizeof (FIL__TCStreamFile_TBlocInf) )); + msg (( MSG_OUT, "FIL__TCStreamFile_TRecInfFile = %d ", sizeof (FIL__TCStreamFile_TRecInfFile) )); + msg (( MSG_OUT, "EFRIO__TRunCont = %d ", sizeof (EFRIO__TRunCont) )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EFRIO__TFrame = %d ", sizeof (EFRIO__TFrame) )); + msg (( MSG_OUT, "EFRIO__TFrameHeader = %d ", sizeof (EFRIO__TFrameHeader) )); + msg (( MSG_OUT, "EFRIO__TFrameData = %d ", sizeof (EFRIO__TFrameData) )); + msg (( MSG_OUT, "EFRIO__TTriggerRec = %d ", sizeof (EFRIO__TTriggerRec) )); + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) + : + Goal : Load a run file = configure lib for this run but the run is not loaded + : in memory. + : + Inputs : RunDir - Run directory without \ at end + : RunPrefix - Run file prefix, eg : "RUN_" + : RunNo - Run no + : + Ouputs : The function returns + : Number of acquisitions in run file + : -1 if an error occurs + : + Globals : Update APP__VGContext fields + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : 19/02/2011 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqNb; + SInt32 VRet=0; // init necessary, JB 2011/06/30 + + + // ----------------------------- + // Reset run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = -1; + + // ----------------------------- + // Set run parameters + // ----------------------------- + + sprintf ( VPtCont->ParRunDir , "%s", RunDir ); + sprintf ( VPtCont->ParFileNamePrefix, "%s", RunPrefix ); + + VPtCont->ParRunNo = RunNo; + + // Calculate run par file & run data file names + + sprintf ( VPtCont->InfRunDataFile, "%s/%s%d.bin", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + sprintf ( VPtCont->InfRunParFile , "%s/%s%d.par", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + + // Print run par file & run data file names for debugging + + msg (( MSG_OUT, "Run data file name = %s", VPtCont->InfRunDataFile )); + msg (( MSG_OUT, "Run par file name = %s", VPtCont->InfRunParFile )); + + + // ----------------------------- + // Read run param file + // ----------------------------- + + // Init & conf TCBinFile class to do the job + + //printf("pxi_daq: Opening .par file %s with RWBmode %d, MaxBlocSz %d, BlocSz %d\n", VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont)); + + // Fix to adapt the structure size from 32 to 64 bits machine + // Data are taken on a 32 bits processor with sizeof (EFRIO__TRunCont) = 1372 + // However on 64 bits processor, sizeof (EFRIO__TRunCont) = 1384 + // JB 2012/03/08 + SInt32 sizeof_EFRIO__TRunCont = 1372; + + VRet = VRet | APP__VGRunConfFile.PubFConf ( VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof_EFRIO__TRunCont, sizeof_EFRIO__TRunCont, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunConfFile.PubFOpen (); + VRet = VRet | APP__VGRunConfFile.PubFSeqRead ( &VPtCont->ResRunCont, sizeof_EFRIO__TRunCont, sizeof_EFRIO__TRunCont ); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Load run parameter file = %s failed !", VPtCont->InfRunParFile ) ); + + // ----------------------------- + // Open run data file + // ----------------------------- + + // Init & conf TCStreamFile class to do the job + + VRet = VRet | APP__VGRunDataFile.PubFConf ( &APP__VGRunDataFile, 0 /* UseThread */, VPtCont->InfRunDataFile, FIL__TCBinFile_RWB_MODE_READ, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunDataFile.PubFOpen (); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Open run data file %s failed !", VPtCont->InfRunDataFile ) ); + + + // ----------------------------- + // Set run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = 1; + + // ----------------------------- + // Return number of acq in file + // ----------------------------- + + VAcqNb = APP__VGRunDataFile.PubFGetBlocNb (); + + err_retval ( VAcqNb, ( ERR_OUT, "Run %d loaded => Contains %d acquistions", RunNo, VAcqNb ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FAllocAcqBuffer ( ) + : + Goal : Allocates the buffer for one acqusition. + : + Inputs : None + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read informations from APP__VGContext and set pointer to buffer. + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FAllocAcqBuffer () { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + + // ---------------------- + // Calculates sizes + // ---------------------- + + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + VPtCont->ResRunCont.InfFrameBuffSz = VPtCont->ResRunCont.ParFrameNbPerAcq * VPtCont->InfMaxFrameSz; + + // ---------------------- + // Print results + // ---------------------- + + msg (( MSG_OUT, "==========================================" )); + msg (( MSG_OUT, "InfMaxFrameSz = %d", VPtCont->InfMaxFrameSz )); + msg (( MSG_OUT, "ResRunCont.InfFrameBuffSz = %d", VPtCont->ResRunCont.InfFrameBuffSz )); + msg (( MSG_OUT, "==========================================" )); + + // ---------------------- + // Allocate acq buffer + // ---------------------- + + // Free if already allocated + // removed because provokes crash when other BoardReader used in combination + // SS 2012/08 + + //if ( VPtCont->ResRunCont.PtFrame != NULL ) { + // free ( VPtCont->ResRunCont.PtFrame ); + //} + + // Try to allocate + + VPtCont->ResRunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->ResRunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->ResRunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->ResRunCont.ParFrameNbPerAcq) ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FFreeAcqBuffer () + : + Goal : Free acquisition buffer + : + Inputs : None + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read informations from APP__VGContext and set buffer pointer to NULL. + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FFreeAcqBuffer ( ) { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Free buffer + // ------------------------------- + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + VPtCont->ResRunCont.PtFrame = NULL; + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : + Goal : Build the frame list for one acquisition + : + Inputs : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : + : + Remark : This function is the copy of EFRIO__FBuildFrameListFromAcq for application + : program demo. + : + : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : + Level : + Date : 06/11/2010 + Rev : 19/02/2011 + : - Moved from eudet_fio.c + : + Doc date : 07/11/2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) + : + Goal : Load AcqNo in memory + : + Inputs : AcqNo - No of acquisition to load + : PtFrameNb - Pointer to a variable which will be set with frames nb in AcqNo + : - Set it to NULL if you don't need it + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read information from APP__VGContext. + : + Remark : None. + : + Level : + Date : 19/02/2011 + Rev : 07/03/2011 + : - New " spare W32 info " format + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqInfFormat; + EFRIO__TFileSpareW32Info VAcqInf; + SInt32 VRet; + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + // ----------------------------------- + // Load acquisition in memory + // ----------------------------------- + + // Load from run file + + // Before 07/03/2011 + // VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VFrameNb ); + + VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VAcqInfFormat, sizeof (VAcqInf) / 4 /* MaxSpareW32InfoNb */, (SInt32*) &VAcqInf ); + + err_retfail ( VRet, (ERR_OUT, "Goto acquisition No %d failed !", AcqNo ) ); + + // Build frame list = array of pointer to access frames one by one + + VRet = APP__FBuildFrameListFromAcq ( VAcqInf.TotFrameNb, VPtCont->ResRunCont.PtFrame, &VPtCont->ResFramesList ); + + err_retfail ( VRet, (ERR_OUT,"Build frames list for acquisition No %d failed !", AcqNo ) ); + + // ----------------------------------- + // Update frame nb parameter + // ----------------------------------- + + if ( PtFrameNb != NULL ) { + *PtFrameNb = VAcqInf.TotFrameNb; + } + + err_retok (( ERR_OUT, "Acquisiton No %d loaded in memory - Contains %d frames", AcqNo, VAcqInf.TotFrameNb )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) + : + Goal : Return a pointer to one frame of the acquisition which is loaded in memory. + : + Inputs : FrameIdInAcq - The no of the frame + : + Ouputs : The function returns + : A valid pointer to the frame + : A NULL pointer if the operation failed + : + Globals : Read information from APP__VGContext. + : + Remark : None + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) { + + APP__TContext* VPtCont = &APP__VGContext; + EFRIO__TRunCont* VPtRunCont = &VPtCont->ResRunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->ResFramesList; + + + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"No frame=%d in list => Pointer NULL", FrameIdInAcq) ); + } + + return ( VPtFrList->AFramePtr[FrameIdInAcq] ); +} diff --git a/include/pxi_daq_lib_v.1.1/daq_lib.h b/include/pxi_daq_lib_v.1.1/daq_lib.h new file mode 100755 index 0000000..34248a0 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/daq_lib.h @@ -0,0 +1,115 @@ +// -------------------------------------------------------------------------------------- +// Includes required by DAQ library +// imported directly from Gilles Claus +// all the .def, .typ, .var or .c files are located in the include dir +// JB 2011/03/14 +// Modified: JB 2012/07/19 to include sync_index_rec + +#ifndef DAQ_LIB_INCLUDE +#define DAQ_LIB_INCLUDE + +#define _FILE_OFFSET_BITS 64 // Mandatory for large files ( > 2 GB ) handling +// MUST be set before standard C header files + +#include +#include +#include // types +#include +#include + +/* ========================================= */ +/* Conditional compilation for DAQ sources */ +/* ========================================= */ + +#define ROOT_ROOT // Disable code parts which can't compile under ROOT +#define CC_UNIX // Specify operating system + +/* ========================================= */ +/* DAQ commun files -> types & constants */ +/* ========================================= */ + + +#include "globals.def" +#include "globals_root.def" +#include "types.typ" + +/* ================================================================ */ +/* Definition of WIndows types & constant not available under Linux */ +/* ---------------------------------------------------------------- */ +/* Work like this now = allow to compile program, but should be */ +/* done in a better way later !!!!!!!!! */ +/* ================================================================ */ + +#define HANDLE UInt32 +#define DWORD UInt32 +#define WINAPI +#define LPVOID void* +#define INVALID_HANDLE_VALUE 0xFFFFFFFF + + +/* ========================================= */ +/* Macros needed to compile DAQ sources */ +/* ========================================= */ + +#define EXTERN +#define VAR_STATIC +#define VAR_INIT(x) =x +#define VAR_INIT_A2(x,y) ={x,y} +#define VAR_DCL(Extern,Static,Var) Extern Static Var +#define VAR_DCL_INIT(Extern,Static,Var,Init) Extern Static Var VAR_INIT (Init) +#define VAR_DCL_INIT_A2(Extern,Static,Var,Init0,Init1) Extern Static Var VAR_INIT_A2 (Init0,Init1) + + +/* ========================================= */ +/* Includes DAQ source files */ +/* ========================================= */ + +// Errors messages logging library interface + +#include "errors.def" +#include "errors.typ" +#include "errors.var" + +// General messages logging library interface + +#include "msg.def" +#include "msg.typ" +#include "msg.var" + +// Time library interface + +#include "time.def" +#include "time.typ" +#include "time.var" + +// Files library interface + +#include "files.def" +#include "files.typ" +#include "files.var" + +// ASIC library interface + +#include "asic.def" +#include "asic.typ" +#include "asic.var" + +// MAPS library interface + +#include "maps.def" +#include "maps.typ" +#include "maps.var" + +// Mimosa 26 library interface + +#include "mi26_usr.def" +#include "mi26_usr.typ" + +// Eudet flex rio DAQ library interface + +#include "eudet_frio.def" +#include "eudet_frio.typ" +#include "eudet_frio.var" + +#endif + diff --git a/include/pxi_daq_lib_v.1.1/errors.c b/include/pxi_daq_lib_v.1.1/errors.c new file mode 100755 index 0000000..a263280 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/errors.c @@ -0,0 +1,336 @@ + +/******************************************************************************* +File : x:\lib\com\errors\errors.c +Goal : Implement errors messages print ( screen ) or log ( file ) functions. + : Each function use " errors macros " to log errors and return code. + : +Remark : The way it works is controlled by 3 globals variables + : ERR_VGLogClosed = 0 ( disable ) / 1 ( enable ) errors messages + : ERR_VGLogPath = '/tmp/errors.txt' = path of error logfile + : ERR_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_C +#define ERRORS_C + + +#ifdef CC_APP_OS9 + +char* strerror ( SInt32 errno ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + sprintf ( VMsgStr, "Not avalibale under OS9" ); + + return (VMsgStr); +} + +#endif + +#ifndef CC_APP_WINDOWS + + +char *_strerror ( char* UsrStr ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + #ifdef APP_ROOT + sprintf ( VMsgStr, "%s : No errno str because not supported by ROOT", UsrStr ); + #else + strncpy ( VMsgStr, UsrStr, ERR_USR_MSG_SZ-10 ); + strcat ( VMsgStr, " : " ); + strncat ( VMsgStr, strerror ( errno ), ERR_SYS_MSG_SZ-10 ); + #endif + + + return (VMsgStr); +} + + +#endif + +SInt32 ERR_FEnableLog ( SInt8 Enable ) { + + ERR_VGLogClosed = Enable; + ERR_VGFileLogEnable = Enable; + ERR_VGUserLogEnable = Enable; + + return (0); +} + +SInt32 ERR_EnableLog ( SInt8 Enable ) { + return ( ERR_FEnableLog ( Enable) ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetFileLogEnabled () { + return ( ERR_VGFileLogEnable ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetUserLogEnabled () { + return ( ERR_VGUserLogEnable ); +} + + +SInt32 ERR_FSetLogFilePath ( char* LogFilePath ) { + sprintf ( ERR_VGLogPath, "%s", LogFilePath ); + return (0); +} + +char* ERR_FGetLogFilePath () { + return ( ERR_VGLogPath ); +} + +SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath ) { + ERR_FEnableLog ( Enable ); + ERR_FSetLogFilePath ( FilePath ); + + return (0); +} + + +SInt32 ERR_FEnd () { + return (0); +} + + +SInt32 ERR_FStopLog ( SInt8 Stop ) { + ERR_VGFileDontLog = Stop; + return (0); +} + +/* 11/06/2005 */ + +SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel ) { + ERR_VGFileLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetFileLogLevel () { + return ( ERR_VGFileLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FLogLevel2Str ( SInt8 Lvl ) { + + static char VStr[GLB_CMT_SZ+1]; + + switch ( Lvl ) { + + case ERR_LOG_LVL_NONE : { + sprintf ( VStr, "ERR_LOG_LVL_NONE" ); + break; } + + case ERR_LOG_LVL_ALL : { + sprintf ( VStr, "ERR_LOG_LVL_ALL" ); + break; } + + case ERR_LOG_LVL_WARINGS_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_WARINGS_ERRORS" ); + break; } + + case ERR_LOG_LVL_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_ERRORS" ); + break; } + + default : { + sprintf ( VStr, "Unknow error level = %d", Lvl ); + break; } + + } + + return ( VStr ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetFileLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGFileLogLevel ) ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel ) { + ERR_VGUserLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetUserLogLevel () { + return ( ERR_VGUserLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FGetUserLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGUserLogLevel ) ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetErrLogConfStr () { + + static char VStr[GLB_CMT_SZ+1]; + + sprintf ( VStr, "Error log configuration \n\n - File log enabled = %d \n - File log level = %s \n - File stop log =%d \n - Log file name = %s \n - User log enabled = %d \n - User log level = %s \n - User stop log =%d \n\n", ERR_VGFileLogEnable, ERR_FGetFileLogLevelStr (), ERR_VGFileDontLog, ERR_VGLogPath, ERR_VGUserLogEnable, ERR_FGetUserLogLevelStr (), ERR_VGUserDontLog ); + + return (VStr); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FUserStopLog ( SInt8 Stop ) { + ERR_VGUserDontLog = Stop; + return (0); +} + +/* 10/06/2005 */ + +SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func ) { + + ERR_VGUserErrorFunc = Func; + + return (0); +} + +SInt32 ERR_FGenError ( char MsgType ) { + + static char VErrMsg[ERR_TOT_MSG_SZ]; + + ERR_VGLastErrMsg = VErrMsg; + + /* ERR_VGLogLevel */ + /* == ERR_LOG_LVL_NONE => No log */ + /* == ERR_LOG_LVL_ALL => Log 'T', 'W', 'E' */ + /* == ERR_LOG_LVL_WARINGS_ERRORS => Log 'W', 'E' */ + /* == ERR_LOG_LVL_ERRORS => Log 'E' */ + + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_NONE) && (ERR_VGUserLogLevel == ERR_LOG_LVL_NONE) ) { + return (0); + } + + sprintf ( VErrMsg, "%s%s \n", ERR_VGStrLocationMsg , ERR_OUT ); + + /* File log handling */ + + while (1) { + + if ( ERR_VGFileLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Write error message to file */ + + if ( ERR_VGLogClosed && (ERR_VGLogFile != stdout) && (ERR_VGLogFile != stderr) ) { + ERR_VGLogClosed = 0; + // + // 29/10/10 => Don't open log file in append mode but overwrite it + // + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); + } + + if ( (ERR_VGFileDontLog == 0) && (ERR_VGLogFile != NULL) ) { + fprintf ( ERR_VGLogFile, VErrMsg ); + fflush ( ERR_VGLogFile ); + } + + break; + } + + /* User log handling */ + + while (1) { + + if ( ERR_VGUserLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Call user error function */ + + if ( (ERR_VGUserDontLog == 0) && (ERR_VGUserErrorFunc != NULL) ) { + ERR_VGUserErrorFunc ( MsgType, ERR_VGStrLocationMsg , ERR_OUT, VErrMsg ); + } + + break; + } + + + + + + + return (0); +} + + + +char* ERR_FGetLastErrMsg () { + + return (ERR_VGLastErrMsg); + +} + + + +void FPrint ( void ) +{ + printf ( "%s \n", VGOut ); +} + +//========================================================================================= + + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.1.1/errors.def b/include/pxi_daq_lib_v.1.1/errors.def new file mode 100755 index 0000000..40969a2 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/errors.def @@ -0,0 +1,153 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.def +Goal : Macros definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef ERRORS_DEF +#define ERRORS_DEF + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + + +#ifdef CC_APP_WINDOWS + + #ifndef __FUNCTION__ + + #ifdef CC_COMPILER_CPPB_4 + #define __FUNCTION__ "? Not available" + #endif + + #ifdef CC_COMPILER_CPPB_6 + #define __FUNCTION__ __FUNC__ + #endif + + #endif + +#endif +// ms 24 11 2009 changed size from 100 to 256 +#define ERR_USR_MSG_SZ 256 +#define ERR_SYS_MSG_SZ 256 +#define ERR_TOT_MSG_SZ (ERR_USR_MSG_SZ + ERR_SYS_MSG_SZ) + + +/* 07/04/2007 ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ +/* #define ERR_OUT ERR_VGStrUserMsg */ + + +/* 07/04/2007 - Use a local variable in each function because __FUNCTION__ IS NOT handled by CNT ... */ +/* __LINE__ is replaced by 0 because __LINE__ because ... __LINE__ is not handled file by file ... */ + +#ifdef APP_ROOT + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,VFuncName, 0 /* __LINE__ */ );} +#else + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,__FUNCTION__,__LINE__ );} +#endif + + + +#define ERR_WARNING(Msg) { sprintf Msg; ERR_LOCATION ('W'); ERR_FGenError ('W'); } + +#define ERR_ERROR(Msg) { sprintf Msg; ERR_LOCATION ('E'); ERR_FGenError ('E'); } + +#define ERR_TRACE(Msg) { sprintf Msg; ERR_LOCATION ('T'); ERR_FGenError ('T'); } + + +#define ERR_RET(Code,MsgOk,MsgFail) { \ + if ((Code)<0) ERR_ERROR (MsgFail) \ + else ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_RET_FAIL(Code,MsgFail) { \ + if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (Code); } \ + } + + + +#define ERR_RET_FAIL_NULL(Code,MsgFail) { \ +if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (NULL); } \ + } + + + +#define ERR_RET_NULL(Ptr,MsgFail) { \ +if ((void*)(Ptr)==NULL) { ERR_ERROR (MsgFail) return (-1); } \ + } + + + +#define ERR_RET_OK(MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (0); \ + } + + + +#define ERR_RET_VAL(Code,MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_TYPE_ID(Id) ( 0x5A00 | Id ) + +#define ERR_TYPE_CHK(Pt,TypeId) { \ +if ( *( (UInt16*) (Pt) ) != ERR_TYPE_ID(TypeId) ) { \ + err_retfail ( -1, (ERR_OUT,"Bad type used Type Id = %x MUST be %x => Check the function call parameters in your source code", *( (UInt8*) (Pt) ) , TypeId ) ); \ + } \ + } + + +#define err_trace(Msg) ERR_TRACE(Msg) +#define err_tracel(Lvl,Msg) ERR_TRACE(Msg) +#define err_warning(Msg) ERR_WARNING(Msg) +#define err_error(Msg) ERR_ERROR(Msg) + +#define err_ret(Code,MsgOk,MsgFail) ERR_RET(Code,MsgOk,MsgFail) +#define err_retok(MsgOk) ERR_RET_OK(MsgOk) +#define err_retval(Code,MsgOk) ERR_RET_VAL(Code,MsgOk) +#define err_retfail(Code,MsgFail) ERR_RET_FAIL(Code,MsgFail) +#define err_retfailnull(Code,MsgFail) ERR_RET_FAIL_NULL(Code,MsgFail) +#define err_retnull(Ptr,MsgFail) ERR_RET_NULL(Ptr,MsgFail) + +#define err_typechk(Pt,TypeId) ERR_TYPE_CHK(Pt,TypeId) + +#define PRINT(msg) { sprintf (VGOut, "%s",msg); FPrint (); } +#define RETURN_ERROR(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (FALSE); } +#define RETURN_ERROR_2(msg1,msg2) { sprintf (VGOut, "%s %s",msg1,msg2); FPrint (); return (FALSE); } + +#define RETURN_ERROR_NULL(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (NULL); } +#define RETURN_OK { return (TRUE);} + + + + +#endif + + +// trace (( ERR_OUT, "", par )); +// retfail ( Code, (ERR_OUT,"MsgFail",par) ); +// retnull ( Code, (ERR_OUT,"MsgFail",par) ); // Pointer == NULL => Ret -1 +// error (( ERR_OUT, "", par )); + + diff --git a/include/pxi_daq_lib_v.1.1/errors.typ b/include/pxi_daq_lib_v.1.1/errors.typ new file mode 100755 index 0000000..983ef79 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/errors.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.typ +Goal : Types definition if error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_TYP +#define ERRORS_TYP + +typedef SInt32 (*ERR_TUserErrorFunc) ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ); + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/errors.var b/include/pxi_daq_lib_v.1.1/errors.var new file mode 100755 index 0000000..d36cd82 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/errors.var @@ -0,0 +1,79 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.var +Goal : Variables definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_VAR +#define ERRORS_VAR + + +/* + +EXTERN VAR_STATIC SInt8 ERR_VGLogClosed VAR_INIT (0); // Set to 1 to allow error loggin +EXTERN VAR_STATIC SInt8 ERR_VGFileDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogLevel VAR_INIT (ERR_LOG_LVL_ALL); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogLevel VAR_INIT (ERR_LOG_LVL_ALL); + +EXTERN VAR_STATIC char ERR_VGLogPath[GLB_FILE_PATH_SZ] VAR_INIT ("/dd/tmp/pc/errors.txt"); +EXTERN VAR_STATIC FILE *ERR_VGLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC FILE *ERR_VGTmpLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC SInt32 ERR_VGMsgCnt VAR_INIT (0); +EXTERN VAR_STATIC ERR_TUserErrorFunc ERR_VGUserErrorFunc VAR_INIT (NULL); +EXTERN VAR_STATIC char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ]; +EXTERN VAR_STATIC char ERR_VGStrUserMsg[ERR_TOT_MSG_SZ]; + +EXTERN VAR_STATIC char VGOut[255]; + +*/ + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_VGLogPath[GLB_FILE_PATH_SZ] , "/dd/tmp/pc/errors.txt"); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGTmpLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt32 ERR_VGMsgCnt , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, ERR_TUserErrorFunc ERR_VGUserErrorFunc , NULL); +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ] ); + +/* 07/04/2007 - ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ + +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + +VAR_DCL ( EXTERN, VAR_STATIC, char VGOut[255] ); + +// 21/12/2010 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char *ERR_VGLastErrMsg, "NULL"); + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.1.1/eudet_frio.def b/include/pxi_daq_lib_v.1.1/eudet_frio.def new file mode 100755 index 0000000..0e2b029 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/eudet_frio.def @@ -0,0 +1,233 @@ + + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.def +Goal : Macros definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_DEF +#define EUDET_FRIO_DEF + + +/* ======================= */ +/* Conditional compilation */ +/* ======================= */ + +// Enable EFRIO__FRAME_TAGS_ENABLE to add tags at beginning of EFRIO__TFrame record and sub-records +// +// Each sub-record has it own tag, see list of constants at end of file +// +// EFRIO__TFrame -> EFRIO__FRAME_TAG +// EFRIO__TFrameHeader -> EFRIO__FRAME_TAG_HEADER +// EFRIO__TFrameData -> EFRIO__FRAME_TAG_DATA +// EFRIO__TTriggerRec -> EFRIO__FRAME_TAG_TRIG + +#define EFRIO__FRAME_TAGS_ENABLE + + + + +// Enable / Disable demultiplexing of Mimosa 26 data part +// +// It has NO effect if running with a single Mimosa 26 +// +// In case of multiple Mimosa 26 acquisition, Flex RIO provides multiplexed data +// +// W32[0] Mi26 No 0 , W32[0] Mi26 No 1 ... W32[0] Mi26 No 5 +// W32[1] Mi26 No 0 , W32[1] Mi26 No 1 ... W32[1] Mi26 No 5 +// W32[2] Mi26 No 0 , W32[2] Mi26 No 1 ... W32[2] Mi26 No 5 +// W32[3] Mi26 No 0 , W32[3] Mi26 No 1 ... W32[3] Mi26 No 5 +// +// Data are demultiplexed if this directive is enabled +// This processing will cost CPU time -> it may be done on EUDET SW side if needed +// that's why this processing can be disabled + +#define EFRIO__DEMUX_MI26_DATA_PART + + + + + +/* ================= */ +/* Macro */ +/* ================= */ + + +// Test if board Id is valid, if not return (-1) and lof error message + +#define EFRIO__CHK_BOARD_ID(BoardId) { if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) err_retfail ( -1, (ERR_OUT,"Abort : Bad board Id=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 ) ); } + + +/* ================= */ +/* Constants */ +/* ================= */ + + +// Maximum board number handle by the lib ( define arrays size ) + +#define EFRIO__MAX_BOARDS_NB 2 + +// Maximum ASIC nb handle by the lib ( define arrays size ) + +// #define EFRIO__MAX_ASIC_NB 6 before 21/02/2011 + +#define EFRIO__MAX_ASIC_NB 16 // Set to 16 on 21/02/2011 + + +// Maximum number of frames per acquisition ( define arrays size ) +// - One frame = one readout of MAPS +// - One acquisition = N consecutives frames acquired in one call of board readout function + +#define EFRIO__MAX_FRAME_NB_PER_ACQ 1800 + + +// ************************************************************************************************************* +// Data transfer modes +// ************************************************************************************************************* +// Few information about how the Flex RIO board acquired Mimosa 26 +// +// - Flex RIO board can acquire the data of up to 6 Mimosa 26 and deserialize them +// Each Mimosa 26 is seen as an "acquisition channel", because fw is organized / Mimosa 26 +// +// - Now the fw doesn't care about trigger to select which frame to acquire, all frames are stored and the selection +// is done on-line by DAQ sw. Because it will be more flexible to adjust & modify trigger handling by sw rather than +// by fw and for 6 Mimosa 26 it seems possible to do it on execution time point of view. +// Later, this processing will be moved in fw, for AIDA but for EUDET it should work fine by sw. +// +// - The fw counts triggers and store it's own trigger information "Mimosa 26 trigger" ( the Mimosa 26 line read when trigger occurs ) +// This trigger information is written in the zero fields of Mimosa 26 ( by overwritting them ) +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 +// +// - An extra acquisition channel can be enabled to store trigger from TLU ( it has the same size as a Mimosa 26 channel = 2304 W8 ) +// It will store two W32 informations for each trigger +// - The trigger TLU -> See record EFRIO__TTluTrigger +// - The trigger from Flex RIO ( Mimosa 26 line + frame ) -> See record EFRIO__TFlexRioTimeStamp1 +// The extra channel can store up to 288 triggers ( 288 * W32 * 2 = 2304 ) +// +// We have decided to implement 4 data transfert mode, the difference is on trigger handling and only the last one will +// be useful for EUDET => EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// +// * EFRIO__TRF_MODE_IPHC +// +// Keep compatibility with IPHC DAQ -> limited to 3 triggers + data demultiplex which cost CPU time +// +// * EFRIO__TRF_MODE_EUDET__NO_TRG_CHAN, +// +// Send all frames, store 3 first "Mimosa 26 trigger", don't store TLU trigger +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_ALL_FRAMES, +// +// Send all frames, store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// Send only frame with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG +// store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// + + +typedef enum EFRIO__TRF_MODE { + EFRIO__TRF_MODE_IPHC, + EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, + EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, + EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + +} EFRIO__TTrfMode; + + +// We use the two "zero fields" of each 32 bits at the end of Mimosa 26 data stream to store first three triggers +// It's not trigger from TLU but the trigger we used in our first BT with flex RIO = Mimosa 26 line index when trigger occurs +// +// This is the field Mi26Line of the record EFRIO__TFlexRioTimeStamp1 x 16 because unit is Mimosa 26 clock cycle +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 + + +#define EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA 3 // CAN'T be higher than 3 !!!!!!!!!! + + +// The current frame - with trigger - is not enough to build the physics event +// due to internal MAPS logic ( double memory, pipelines etc ... ) following frames must be also used +// => This is the number of frames to read after the one which contains trigger to build physics event + +#define EFRIO__FRAME_NB_TO_READ_AFTER_TRIG 3 // For Mimosa 26 it's 3 + +// Constants to define extra channel size -> Hard coded ( don't use sizeof ( xyz) ) in order to reduce execution time +// The extra channel is a MAPS acquisition channel ( it has he same size ) but used to store trigger information +// It can store up to 288 triggers / MAPS frame +// +// Now 28/10/2010 +// - Each trigger info stored in extra channel contain two fields, each one is a W32, in the following order +// -- EFRIO__TTluTrigger +// -- EFRIO__TFlexRioTimeStamp1 +// --> Total trigger info size is 2 x W32 = 8 bytes +// - The extral channel has the same size of one Mi26 frame = 2304 W8 +// --> Maximum number of trigger info which can be stored = 2304 / 8 = 288 +// --> It means one trigger each two lines of Mimosa 26 readout ... ;-) + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 288 // Maximum number of trigger info = pair of W32 fields TLU Trig + Felx RIO TS + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 576 // Maximum number of W32 fields + +#define EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ 8 // Size of the trigger info = pair of W32 fields TLU Trig + Flex RIO TS + +#define EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ 4 // Size of one W32 field + + +// Maximum number of messages / board -> define array in EFRIO__TBoardStatus + +#define EFRIO__ERROR_MSG_LIST_MAX_NB 100 + + +// Maximum number of triggers in DAQ emulation configurable by GUI +// We can emulate more triggers than EFRIO__MAX_GUI_TRIG_NB but their value is hard coded in emulation function to 0 +// +// Only the first three triggers and the last one ( if EFRIO__MAX_GUI_TRIG_NB = 4 ) are configurable from GUI + +// #define EFRIO__MAX_GUI_TRIG_NB 4 // WARNING => Redined (with same value) in C++ Builder emulation application ! + +#define EFRIO__MAX_EMUL_GUI_TRIG_NB 4 // WARNING => Redefined (with same value) in C++ Builder emulaion application ! + + +// Tags values to be added at beginning of each EFRIO__TFrame sub-record + +#define EFRIO__FRAME_TAG 0x55550000 +#define EFRIO__FRAME_TAG_HEADER 0x00000001 +#define EFRIO__FRAME_TAG_DATA 0x00000002 +#define EFRIO__FRAME_TAG_TRIG 0x00000003 + +// Maximum size of one acquisition store to disk => Used by FIL__TCStreamFile class + +//#define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +// Bug fixed by GC, 2011/07/06 + +#ifdef CC_UNIX + #define ULT1__ZS_FFRAME_RAW_MAX_W8 7400 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 + #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +#else + #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +#endif + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/eudet_frio.typ b/include/pxi_daq_lib_v.1.1/eudet_frio.typ new file mode 100755 index 0000000..fa09c63 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/eudet_frio.typ @@ -0,0 +1,792 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.typ +Goal : Types definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_TYP +#define EUDET_FRIO_TYP + + + +/* ============================================== */ +/* Board parameters configuration record */ +/* ---------------------------------------------- */ +/* Can be use to build a boards database */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// Remark for EUDET concerning trigger handling +// +// Most of the following trigger options will be useless for EUDET +// The operating mode for EUDET is : +// - The board takes data all the time regardless of trigger state +// - The fw store all triggers from TLU ( up to 288 / Mimsoa 26 frame ) are stored +// - The sw extract frames with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames after trigger + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + + char AsicName[GLB_CMT_SZ]; // The ASIC read by the board + + SInt32 AsicNb; // The number of ASICs read by the board + + SInt32 ReadoutMode; // The readout mode -> Future use + + SInt8 EmuleChannels; // Copy data of first MAPS in all channels, useful for test & debugging + // because it allows to run with one ASIC only but get data of all + + float DataClkFrequency; // Frequency of clock -> Future use, only useful in case board provide clock + + UInt32 DmaHostSz; // DMA size reserved on host CPU, must be >= size of one acquisition + + SInt32 FrameNbPerAcq; // Consecutives frames number stored during one acquisition + + SInt8 EnableExtraChannel; // Enable one more channel ( default is one channel per ASIC ) + // which can be used to store extra information -> eg : TLU trigger + + SInt32 AcqNbPerTrig; // TO BE CHECKED ! Number of consecutive acquisitions taken upon trigger detection by board + + SInt8 TriggerMode; // Trigger operating mode + + UInt32 TriggerDetectTimeWindow; // Time window during which we count triggers and decide to start acquisition if >= TriggerDetectOccurNb + + UInt32 TriggerDetectOccurNb; // Minimum trigger number during TriggerDetectTimeWindow to decide to start acquisition + + UInt32 TimeStampRes; // Resolution of time stamp + + SInt8 EnableTimeStamping; // Enable time stamping mode + + SInt8 EnableTrigCnt; // Enable trigger counter + + SInt8 TagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ ( HW line indicates that DUT has saved event ) + + UInt32 ReadTluTrigCntEachNTrig; // Period of reading TLU trigger + + +} EFRIO__TBoardConf; + + +/* ============================================== */ +/* Board status record */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + SInt8 BoardPresent; // Board present => 1, otherwise 0 + SInt8 FwLoaded; // Firmware has been loaded in board + SInt8 ConfDone; // The board has been configured by sw + + SInt32 StatusCode; // Current board status code + + char StatusStr[GLB_CMT_SZ]; // Status message associated to StatusCode + + // List of errors and last error + + char* ErrorMsgList[EFRIO__ERROR_MSG_LIST_MAX_NB]; + char LastErrorMsg[GLB_CMT_SZ]; + + // Registers read from board + + UInt32 RegDmaHostSz; // DMA host size in bytes + SInt32 RegFrameNbPerAcq; // Number of frames / acq + SInt8 RegEnableExtraChannel; // Extral channel state = enabled or not + SInt32 RegAcqNbPerTrig; // Consecutive acquisition nb per trigger + + SInt8 RegTriggerMode; // Trigger mode + UInt32 RegTriggerDetectTimeWindow; // Trigger detection window + UInt32 RegTriggerDetectOccurNb; // Number of triggers required during window to start acquisition + + UInt32 RegTimeStampRes; // Resolution of time stamp -> Check with CS if implemented ! + SInt8 RegEnableTimeStamping; // Enable time stamping mode -> Check with CS if implemented ! + + SInt8 RegEnableTrigCnt; // Enable trigger counter -> Check with CS if implemented ! + + SInt8 RegTagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ -> Check with CS if implemented ! + UInt32 RegReadTluTrigCntEachNTrig; // Period of reading TLU trigger -> Check with CS if implemented ! + + UInt64 RegTimeStamp; // Time stamp value + UInt32 RegTrigCnt; // Flex RIO rigger value + UInt32 RegTluTrigCnt; // TLU trigger value + +} EFRIO__TBoardStatus; + + + + +/* ============================================== */ +/* TLU trigger record */ +/* ---------------------------------------------- */ +/* Contains TLU trigger -> field TrigCnt */ +/* plus additional information */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 TrigCnt : 16; // Trigger counter read from TLU + UInt32 FrameIdInAcq : 11; // Index of frame in current acquisition during which trigger occurs ( 0 - 2407 ) + UInt32 EventTakenByDut : 1; // For future use : Flag at 1 if DUT has taken the event + UInt32 Reserved : 3; + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TTluTrigger; + + +/* ============================================== */ +/* Flex RIO time stamp 1 record */ +/* ---------------------------------------------- */ +/* This is the Flex RIO trigger, called */ +/* "time stamp" to avoid confusion / TLU */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Mi26Line : 10; // Line of Mi26 read during which trigger occurs + UInt32 Mi26Frame : 21; // Frame of Mi26 ( = frame counter field ) read during which trigger occurs + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TFlexRioTimeStamp1; + + +/* ============================================== */ +/* Frame header */ +/* ---------------------------------------------- */ +/* Each frame starts with a header which contains */ +/* - DAQ system info */ +/* - Mimosa 26 relevant fields */ +/* ---------------------------------------------- */ +/* Date : 22/10/2010 */ +/* Rev : 23/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_HEADER +#endif + + // New fields AcqStatus & TrigStatus 23/02/2011 + // + SInt32 AcqStatus; // Status of acquistion board for this acquisition + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + // + SInt32 TrigStatus; // No meaning now = reserved for future use + + UInt16 AcqId; // Index of acquisition containing this frame + UInt16 FrameIdInAcq; // Index of frame IN the CURRENT acquisition + + UInt16 MapsName; // MAPS name as a 16 bits code + UInt16 MapsNb; // Total number of MAPS in data + + UInt32 AMapsHeader[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 AMapsFrameCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 AMapsDataLength[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 AMapsTrailer[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + SInt16 TriggerNb; // Total triggers number during this frame + + UInt16 AMapsTrigInfo[EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA]; // First 3 "Mi26 trigger info" -> Line of Mi26 read during which trigger occurs + // if more than 3 trigger => look in trigger info block where all trigger are stored + +} EFRIO__TFrameHeader; + + +/* ============================================== */ +/* Frame data */ +/* ---------------------------------------------- */ +/* Each frame has a data part with variable size */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_DATA +#endif + UInt32 TotSz; // Total size of data bloc + UInt32 OneMapsSz; // Size of data of one MAPS + + UInt32 ADataW32[0]; // Beginning of data space + +} EFRIO__TFrameData; + + +/* ============================================== */ +/* Frame triggers list */ +/* ---------------------------------------------- */ +/* Each frame has a triggers list, up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB fields */ +/* which means up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB */ +/* trigger info */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_TRIG +#endif + UInt32 TotSz; // Total size of trigger info bloc + UInt16 TrigNb; // Total trigger nb + UInt16 TrigType; // Type of trigger info stored + + UInt32 ATrig[0]; // Beginning off triggers list + +} EFRIO__TTriggerRec; + + +/* ============================================== */ +/* Frame record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Data handling fields ( size etc ) */ +/* - The frame header */ +/* - The frame data part ( variable length ) */ +/* - Followed by the triggers info part */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new field DaqVersion */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG +#endif + SInt32 DaqVersion; // Version of DAQ - New field 21/02/2011 + SInt32 TotSz; // Total size of this frame + SInt32 TrigRecOffset; // Offset ( in bytes ) from beginning of frame to trigger info part + EFRIO__TFrameHeader Header; // Frame header + EFRIO__TFrameData Data; // Beginning of data part + + // The field EFRIO__TTriggerInfo is not defined here because "Data" has variable length + // the field BegData of Data field is used a pointer to beginning of data part + // The trigger info will be added at the end of this part but position is calculated dynamically + +} EFRIO__TFrame; + + +/* ============================================== */ +/* List of frames currently stored by lib */ +/* ---------------------------------------------- */ +/* This record stores frames list corresponding */ +/* to one acquisition */ +/* */ +/* It can be : */ +/* - frames acquired by DAQ */ +/* - frames loaded from a run file */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : */ +/* : 24/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// More information about frames storage in memory +// +// A buffer IS NOT allocated for EACH frame, a single bloc of memory is allocated for all frames of one acquisition. +// This will avoid copy frame by frame before sending them to Ethernet lib or saving them to disk. A single access +// can be done with a pointer on beginning of buffer and data size. +// +// But to process frames it's handly to have an array of pointers, each array item pointing on next frame, +// this is the goal of this list which provides : +// - The total number of frames in list +// - An array of pointers, eg : AFramePtr[2] points on third frame of acquisition +// - An array with the total size ( in bytes ) of each frame +// +// This list is built on-line while DAQ is running, or off-line via EFRIO__FBuildFrameListFromAcq (...) from +// the data of one acquisition stored in a run file. + +typedef struct { + + // New fields AcqStatus & TrigStatus 24/02/2011 + // + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + +} EFRIO__TFrameList; + + +/* ============================================== */ +/* Run configuration record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Run parameters -> Par... */ +/* - Informations built from Par etc -> Inf... */ +/* - Acquisition results ( ev cnt etc ) -> Res... */ +/* - Pointers to frames buffers */ +/* ---------------------------------------------- */ +/* This record is filled by EFRIO__FConfRun (...) */ +/* call with run parameters from GUI or Ethernet */ +/* ---------------------------------------------- */ +/* This record can be saved to disk as run config */ +/* file, but it can't be ONLY loaded from file ! */ +/* A call to EFRIO__FConfRun (...) must be done */ +/* because it allocates mem and do other tasks */ +/* -> load record from file */ +/* -> call EFRIO__FConfRun with record fields as */ +/* parameters, it will overwrite itself and all */ +/* " other tasks " will also be done */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new fields */ +/* : ParDaqVersion, ParMapsName */ +/* : - Change type of ParMi26Nb to S16 */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + +/* ============================================== */ +/* Acquisition emulation record */ +/* ---------------------------------------------- */ +/* This record contains context of DAQ emulator */ +/* application, it means : */ +/* - Parameters -> Par... */ +/* - Information, calculated from Par -> Inf... */ +/* - Results -> Res... */ +/* ---------------------------------------------- */ +/* All emulation functions are implemented in the */ +/* lib, therefore application task is only GUI. */ +/* That's why emulation context is defined here */ +/* ---------------------------------------------- */ +/* All run param for emulation are taken from */ +/* run config record -> EFRIO__TRunCont */ +/* ---------------------------------------------- */ +/* Date : 30/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqCycleMs; // Delai between two acquisitions + + SInt32 ParEmuleDRamReadMs; // Delai added to PC DRAM access to emulate Flex RIO DRAM access time + + SInt32 ParEmuleFunctNo; // Select emulation function to call -> Future use = not implemented now + + SInt8 ParRandomDataSz; // Enables random generation of data size per Mimosa 26 + // By default data size is fixed in emulation function + // Used to check if variabl length records are properly handled + + SInt8 ParSetMaxDataSzOnOneMaps; // Set maximum possible data sze on first Mi26, overwrite value set by emulation + // function, but next Mi26 keep the data size value from emulation function + // Used to check if DAQ loose frames while Mi26 provides full frames + + + UInt32 ParAHeader[EFRIO__MAX_ASIC_NB]; // Emulated header of each Mi26 + + UInt32 ParATrailer[EFRIO__MAX_ASIC_NB]; // Emulated trailer of each Mi26 + + SInt32 ParTrigNbPerFrame; // Number of trigger per frame, set the part trigger nb (B31B16) of Mi26 Zero1 field + + // In data transfer modes EUDET 2 & 3 a more complex trigger emulation is done + // We don't emulate ParTrigNbPerFrame on each frame but on N consecutives frames + // each M frames + // + SInt32 ParTrigOnOneFrameOverN; // Start emulate ParTrigNbPerFrame on one frame over M = ParTrigOnOneFrameOverN + SInt32 ParTrigOnNConsecutiveFrames; // Emulates on N consecutive frames = ParTrigOnNConsecutiveFrames + + // TLU trigger & Flex RIO trigger emulation + // Up to 288 couples TLU & Flex RIO triggers can be emulated but only EFRIO__MAX_EMUL_GUI_TRIG_NB + // are configurabbles from GUI, now EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + // - First three are configurable from GUI + // - The last one is configurable from GUI + // - Others are configured in emulation function and set to 0 + // + SInt32 ParATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated TLU trigger + SInt32 ParATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated Flex RIO trigger, called "Time stamp 1" + + // DRAM info to emulate Flex RIO readout ( we need a PC RAM bloc of same size as the board one ) + // + SInt32 InfDRamSzMb; // DRAM size in MB + SInt32 InfDRamSz; // DRAM size in bytes + UInt32* InfDRamPtr; // DRAM pointer + + SInt8 InfExtraChan; // Extra channel status ( enabled or not ) depends on data transfer mode ( -> run config ) + + char InfEmuleFuncCmt[GLB_CMT_SZ]; // A comment set by emulation function selected by ParEmuleFunctNo + // -> Future use = not implemented now + + // DAQ emulation results + // + SInt32 ResAcqCnt; // Acquisition counter + SInt32 ResEvCnt; // Events counter + // + SInt32 ResAcqFunctRetCode; // Error code returned by acquisition function + +} EFRIO__TAcqEmul; + + +/* ============================================== */ +/* Frames check record */ +/* ---------------------------------------------- */ +/* This is context of frames check functions */ +/* - EFRIO__MI26_FChkAcqIphcMode (...) */ +/* - EFRIO__MI26_FChkAcqEudetMode (...) */ +/* */ +/* They check frames integrity, can be used in */ +/* normal DAQ mode or emulation */ +/* ---------------------------------------------- */ +/* Date : 31/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqNo; // Acquisition index + + SInt32 ParFrNo; // Frame index + + SInt8 ParChkMode; // Check mode -> Allows to define a level of test + + SInt8 ParChkVerbose; // Verbose mode or not + + SInt8 ParFrPrintLevel; // Define the frame information printed in log file + // 0 -> No print + // 1 -> Print general info ( AcqId, FrameId, TrigNb ... ) + Mi26 header, frame cnt, trailer + // 2 -> Print also triggers list + + SInt8 InfMi26Nb; // Mi26 number runnig in the system + + // Values provided by DAQ to check + // They are compared to the " same fields " of EFRIO_TAcqEmul + // + UInt32 ResAHeader[EFRIO__MAX_ASIC_NB]; // Mi26 header + UInt32 ResATrailer[EFRIO__MAX_ASIC_NB]; // Mi26 trailer + UInt32 ResAFrameCnt[EFRIO__MAX_ASIC_NB]; // Mi26 frames counter + UInt32 ResADataLenght[EFRIO__MAX_ASIC_NB]; // Mi26 data part length ( in W8 not in W16 as in DataLength fields of Mi26 data stream ) + // + SInt32 ResTrigNb; // Trigger info ( couple TLU & Flex RIO trigger ) number UNDER GUI control => limited to EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + SInt32 ResATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // TLU triggers list + SInt32 ResATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Flex RIO trigegrs list + + SInt32 ResErrCnt; // Total errors counter => Information provide by DAQ <> value set in EFRIO_TAcqEmul + + +} EFRIO__TFrCheck; + +/* ============================================== */ +/* Board check record */ +/* ---------------------------------------------- */ +/* This is context of board check Vi */ +/* The board test is done by a Vi on Labview side */ +/* this record pass the parameters to the Vi */ +/* */ +/* Parameters are set via call to functions */ +/* EFRIO__FSetBoardChk... */ +/* */ +/* Parameters are read via call to functions */ +/* EFRIO__FGetBoardChk... */ +/* Theses functions are encapsulated in Vi */ +/* ---------------------------------------------- */ +/* */ +/* The test results are written in board status */ +/* record ABoardsStatus [BoardId] */ +/* */ +/* Test results are set or read functions */ +/* EFRIO__FSetBoardStatus... */ +/* EFRIO__FGetBoardStatus... */ +/* ---------------------------------------------- */ +/* Date : 22/12/2010 */ +/* Doc date : 22/12/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParBoardId; // Board to test + + SInt8 ParDoTheTest; // Set to 1 to request the test + // Reset once test has been started + + SInt32 ParTestId; // Identifier to select different tests + + SInt8 ResTestDone; // Set to 1 when test is finished + + SInt32 ResTestResult; // Test result + // < 0 => Test has failed + // = 0 => Test OK + +} EFRIO__TBoardCheck; + + +/* ============================================== */ +/* Spare W32 bloc of index file */ +/* ---------------------------------------------- */ +/* This record contains spare info for index file */ +/* ---------------------------------------------- */ +/* Date : 24/02/2011 */ +/* Doc date : 24/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + + SInt32 DiskSectorSz; // Size of disk sector + +} EFRIO__TFileSpareW32Info; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains monitoring via Eth conf */ +/* ---------------------------------------------- */ +/* Date : 15/02/2011 */ +/* Doc date : 15/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 InfFrameNbToSend; // Frame nb to send on Eth = " Frame nb per acq * % monitoring " + SInt32 InfSzToSend; // Size corresponding to InfFrameNbToSend + +} EFRIO__TMon; + + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : 07/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef struct { + + SInt8 InfInitDone; // Lib iit done or not + + EFRIO__TBoardConf ABoardsConf[EFRIO__MAX_BOARDS_NB]; // Acquisition boards config + EFRIO__TBoardStatus ABoardsStatus[EFRIO__MAX_BOARDS_NB]; // Acquisition boards status + + EFRIO__TBoardCheck BoardChk; // Reserved for future implementation + // Parameters record to check + // - Boards + // - Mimosa 26 Clk & Sync signals + + EFRIO__TAcqEmul AcqEmul; // DAQ emulation context + EFRIO__TFrCheck FrCheck; // Frames check functions context + + EFRIO__TRunCont RunCont; // Run context = parameters, memory allocated, results + + EFRIO__TMon MonCont; // Monitoring context + + EFRIO__TFrameList AAcqFrameList[1]; // Frame list of acquistion - Can be extended to more than one acq if needed + + // List of frame Id to read ( Eudet3Mode => Trigger + 2 following frames ) / acquistion - Can be extended to more than one acq if needed + + SInt16 AAAcqFrameWithTrigList[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + + EFRIO__TTriggerRec* PtTmpTrigRec; // Temporary triggers record used for internal processing + +} EFRIO__TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/eudet_frio.var b/include/pxi_daq_lib_v.1.1/eudet_frio.var new file mode 100755 index 0000000..2242f88 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/eudet_frio.var @@ -0,0 +1,39 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.var +Goal : Variables definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_VAR +#define EUDET_FRIO_VAR + + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC EFRIO__TContext EFRIO__VGContext; + +EXTERN VAR_STATIC FIL__TCStreamFile EFRIO__VGRunDataFile ( "x:\\log\\err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); +EXTERN VAR_STATIC FIL__TCBinFile EFRIO__VGRunConfFile ( "x:\\log\\err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); + +#ifdef EFRIO__INCLUDE_JTAG + EXTERN VAR_STATIC TCOMIMI26MasterConf EFRIO_VGJtagMi26; +#endif + +#endif diff --git a/include/pxi_daq_lib_v.1.1/eudet_frio_print.c b/include/pxi_daq_lib_v.1.1/eudet_frio_print.c new file mode 100755 index 0000000..3cb78e6 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/eudet_frio_print.c @@ -0,0 +1,1009 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_PRINT_C +#define EUDET_FRIO_PRINT_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert TLU trigger info record to string for print or display +: +Inputs : Trig - Source trigger record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display +: +Inputs : Ts - Source time stamp record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger / timestamp as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) + : +Goal : Print run context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Rev : 21/02/2011 + : - Print new fields ParDaqVersion, ParMapsName +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Run context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParDaqVersion = %.4d", PtRec->ParDaqVersion )); + msg (( MSG_OUT, "ParMapsName = %.4d", PtRec->ParMapsName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParMi26Nb = %.4d", PtRec->ParMi26Nb )); + msg (( MSG_OUT, "ParFrameNbPerAcq = %.4d", PtRec->ParFrameNbPerAcq )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParRunNo = %.4d", PtRec->ParRunNo )); + msg (( MSG_OUT, "ParTotEvNb = %.4d", PtRec->ParTotEvNb )); + msg (( MSG_OUT, "ParEvNbPerFile = %.4d", PtRec->ParEvNbPerFile )); + msg (( MSG_OUT, "ParDataTransferMode = %.4d", PtRec->ParDataTransferMode )); + msg (( MSG_OUT, "ParTrigMode = %.4d", PtRec->ParTrigMode )); + msg (( MSG_OUT, "ParSaveOnDisk = %.4d", PtRec->ParSaveOnDisk )); + msg (( MSG_OUT, "ParSendOnEth = %.4d", PtRec->ParSendOnEth )); + msg (( MSG_OUT, "ParSendOnEthPCent = %.4d", PtRec->ParSendOnEthPCent )); + msg (( MSG_OUT, "ParDestDir = %s" , PtRec->ParDestDir )); + msg (( MSG_OUT, "ParFileNamePrefix = %s" , PtRec->ParFileNamePrefix )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParJtagFileName = %s ", PtRec->ParJtagFileName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); +// msg (( MSG_OUT, "InfMi26FrameSzFromFlexRio = %.4d", PtRec->InfMi26FrameSzFromFlexRio )); + msg (( MSG_OUT, "InfZsFFrameRawBuffSz = %.4d", PtRec->InfZsFFrameRawBuffSz )); + msg (( MSG_OUT, "InfFrameBuffSz = %.4d", PtRec->InfFrameBuffSz )); + msg (( MSG_OUT, "InfConfFileName = %s" , PtRec->InfConfFileName )); + msg (( MSG_OUT, "InfDataFileName = %s" , PtRec->InfDataFileName )); + msg (( MSG_OUT, "InfSaveDataOnDiskRunning = %.4d", PtRec->InfSaveDataOnDiskRunning )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResFrameCnt = %.4d", PtRec->ResFrameCnt )); + msg (( MSG_OUT, "ResEventCnt = %.4d", PtRec->ResEventCnt )); + msg (( MSG_OUT, "ResDataRateMBytesPerSec = %.3f", PtRec->ResDataRateMBytesPerSec )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "PtZsFFrameRaw = %.8x", PtRec->PtZsFFrameRaw )); + msg (( MSG_OUT, "PtFrame = %.8x", PtRec->PtFrame )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunCont () + : +Goal : Print lib run context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunCont () { + + return ( EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) + : +Goal : Print board conf record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board conf record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "AsicName = %s", PtRec->AsicName )); + msg (( MSG_OUT, "AsicNb = %.4d", PtRec->AsicNb )); + msg (( MSG_OUT, "ReadoutMode = %.4d", PtRec->ReadoutMode )); + msg (( MSG_OUT, "DataClkFrequency = %2.f", PtRec->DataClkFrequency )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "DmaHostSz = %.4d", PtRec->DmaHostSz )); + msg (( MSG_OUT, "FrameNbPerAcq = %.4d", PtRec->FrameNbPerAcq )); + msg (( MSG_OUT, "EnableExtraChannel = %.4d", PtRec->EnableExtraChannel )); + msg (( MSG_OUT, "AcqNbPerTrig = %.4d", PtRec->AcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TriggerMode = %.4d", PtRec->TriggerMode )); + msg (( MSG_OUT, "TriggerDetectTimeWindow = %.4d", PtRec->TriggerDetectTimeWindow )); + msg (( MSG_OUT, "TriggerDetectOccurNb = %.4d", PtRec->TriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TimeStampRes = %.4d", PtRec->TimeStampRes )); + msg (( MSG_OUT, "EnableTimeStamping = %.4d", PtRec->EnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EnableTrigCnt = %.4d", PtRec->EnableTrigCnt )); + msg (( MSG_OUT, "TagEventsStoredByDUT = %.4d", PtRec->TagEventsStoredByDUT )); + msg (( MSG_OUT, "ReadTluTrigCntEachNTrig = %.4d", PtRec->ReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) + : +Goal : Print lib board conf record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) + : +Goal : Print board status record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board status record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "BoardPresent = %.4d", PtRec->BoardPresent )); + msg (( MSG_OUT, "FwLoaded = %.4d", PtRec->FwLoaded )); + msg (( MSG_OUT, "ConfDone = %.4d", PtRec->ConfDone )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "StatusCode = %.4d", PtRec->StatusCode )); + msg (( MSG_OUT, "StatusStr = %.4d", PtRec->StatusStr )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ErrorMsgList = %s", PtRec->ErrorMsgList )); + msg (( MSG_OUT, "LastErrorMsg = %s", PtRec->LastErrorMsg )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegDmaHostSz = %.4d", PtRec->RegDmaHostSz )); + msg (( MSG_OUT, "RegFrameNbPerAcq = %.4d", PtRec->RegFrameNbPerAcq )); + msg (( MSG_OUT, "RegEnableExtraChannel = %.4d", PtRec->RegEnableExtraChannel )); + msg (( MSG_OUT, "RegAcqNbPerTrig = %.4d", PtRec->RegAcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTriggerMode = %.4d", PtRec->RegTriggerMode )); + msg (( MSG_OUT, "RegTriggerDetectTimeWindow = %.4d", PtRec->RegTriggerDetectTimeWindow )); + msg (( MSG_OUT, "RegTriggerDetectOccurNb = %.4d", PtRec->RegTriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStampRes = %.4d", PtRec->RegTimeStampRes )); + msg (( MSG_OUT, "RegEnableTimeStamping = %.4d", PtRec->RegEnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegEnableTrigCnt = %.4d", PtRec->RegEnableTrigCnt )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTagEventsStoredByDUT = %.4d", PtRec->RegTagEventsStoredByDUT )); + msg (( MSG_OUT, "RegReadTluTrigCntEachNTrig = %.4d", PtRec->RegReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStamp = %.4d", PtRec->RegTimeStamp )); + msg (( MSG_OUT, "RegTrigCnt = %.4d", PtRec->RegTrigCnt )); + msg (( MSG_OUT, "RegTluTrigCnt = %.4d", PtRec->RegTluTrigCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) + : +Goal : Print lib board status record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) + : +Goal : Print acquisition emulation context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Acquistion emulation record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqCycleMs = %.4d", PtRec->ParAcqCycleMs )); + msg (( MSG_OUT, "ParEmuleDRamReadMs = %.4d", PtRec->ParEmuleDRamReadMs )); + msg (( MSG_OUT, "ParEmuleFunctNo = %.4d", PtRec->ParEmuleFunctNo )); + msg (( MSG_OUT, "InfEmuleFuncCmt = %s" , PtRec->InfEmuleFuncCmt )); + msg (( MSG_OUT, "ParRandomDataSz = %d" , PtRec->ParRandomDataSz )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParAHeader[0] , PtRec->ParAHeader[1] , PtRec->ParAHeader[2] , PtRec->ParAHeader[3] , PtRec->ParAHeader[4] , PtRec->ParAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParATrailer[0], PtRec->ParATrailer[1], PtRec->ParATrailer[2], PtRec->ParATrailer[3], PtRec->ParATrailer[4], PtRec->ParATrailer[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParTrigNbPerFrame = %.4d", PtRec->ParTrigNbPerFrame )); + msg (( MSG_OUT, "ParTrigOnOneFrameOverN = %.4d", PtRec->ParTrigOnOneFrameOverN )); + msg (( MSG_OUT, "ParTrigOnNConsecutiveFrames = %.4d", PtRec->ParTrigOnNConsecutiveFrames )); + msg (( MSG_OUT, "Trig [0]=%.4d [1]=%.4d [2]=%.4d [Last]=%.4d", PtRec->ParATrig[0], PtRec->ParATrig[1], PtRec->ParATrig[2], PtRec->ParATrig[3] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfDRamSzMb = %.4d", PtRec->InfDRamSzMb )); + msg (( MSG_OUT, "InfDRamSz = %.4d", PtRec->InfDRamSz )); + msg (( MSG_OUT, "InfDRamPtr = %.8x", PtRec->InfDRamPtr )); + msg (( MSG_OUT, "InfExtraChan = %.4d", PtRec->InfExtraChan )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqFunctRetCode = %.4d", PtRec->ResAcqFunctRetCode )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResEvCnt = %.4d", PtRec->ResEvCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmul () + : +Goal : Print lib acquisition emulation context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.AcqEmul = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) + : +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmul () { + + return ( EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheckRec ( EFRIO_TFrCheck* PtRec ) + : +Goal : Print frame check context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheckRec ( EFRIO__TFrCheck* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Frames check record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqNo = %.4d", PtRec->ParAcqNo )); + msg (( MSG_OUT, "ParFrNo = %.4d", PtRec->ParFrNo )); + msg (( MSG_OUT, "ParChkMode = %.4d", PtRec->ParChkMode )); + msg (( MSG_OUT, "ParFrPrintLevel = %.4d", PtRec->ParFrPrintLevel )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfMi26Nb = %.4d", PtRec->InfMi26Nb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResAHeader[0] , PtRec->ResAHeader[1] , PtRec->ResAHeader[2] , PtRec->ResAHeader[3] , PtRec->ResAHeader[4] , PtRec->ResAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResATrailer[0] , PtRec->ResATrailer[1] , PtRec->ResATrailer[2] , PtRec->ResATrailer[3] , PtRec->ResATrailer[4] , PtRec->ResATrailer[5] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResAFrameCnt[0] , PtRec->ResAFrameCnt[1] , PtRec->ResAFrameCnt[2] , PtRec->ResAFrameCnt[3] , PtRec->ResAFrameCnt[4] , PtRec->ResAFrameCnt[5] )); + msg (( MSG_OUT, "DL [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResADataLenght[0], PtRec->ResADataLenght[1], PtRec->ResADataLenght[2], PtRec->ResADataLenght[3], PtRec->ResADataLenght[4], PtRec->ResADataLenght[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResTrigNb = %.4d", PtRec->ResTrigNb )); + msg (( MSG_OUT, "TRG [0]=%.8d [1]=%.8d [3]=%.8d [Last]=%.8d", PtRec->ResATrig[0], PtRec->ResATrig[1], PtRec->ResATrig[2], PtRec->ResATrig[3] )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheck () + : +Goal : Print lib frame check context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.FrCheck = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheck () { + + return ( EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - > 0 -> print state list for each line + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 22/12/2010 +Rev : 30/12/2010 + : - Add handling of N Mimosa 26 + : +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + MI26__TStatesLine VStatesLine; + MI26__TState VState; + SInt16 ViMi26; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + char VStrState[255]; + char VStrLine[255]; + + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + + msg (( MSG_OUT, "===================================================================================" )); + msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); + msg (( MSG_OUT, "===================================================================================" )); + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + ViStatesLine = 0; + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Copy StatesLine field + + VStatesLine.W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VStatesLine.F.StateNb; + + sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf ); + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + VState.W16 = VPtSrcW16[ViSrcW16]; + + sprintf ( VStrState, "[Col %4d - %2d pixel(s)] ", VState.F.ColAddr, VState.F.HitNb + 1 ); + strcat ( VStrLine , VStrState ); + + ++ViSrcW16; + } + + if ( (PrintLevel != 0) ) { + msg (( MSG_OUT, "%s", VStrLine )); + } + + ++ViStatesLine; + + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + } // End for ( ViMi26 ) + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - 1 -> Print AcqId & FrId + : - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + : - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + : - 4 -> Print trigger list + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 06/11/2010 +Rev : 21/02/2011 + : - Print new field DaqVersion +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTriggerRec* VPtTrig; + SInt16 ViTrig; + char VStrTrig[30]; + char VStrTs [30]; + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Trigger record follows the data record which has a VARIABLE size + + VPtTrig = (EFRIO__TTriggerRec*) ( (UInt8*) PtRec + PtRec->TrigRecOffset ); + + // ------------------------------------- + // Print TFrame fields + // ------------------------------------- + + if ( PrintLevel == 1 ) { + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, "AcqId = %.4d - FrameIdInAcq = %.4d - TrigNb = %.4d - Address trig %d [D]", VPtHead->AcqId, VPtHead->FrameIdInAcq, VPtTrig->TrigNb, VPtTrig )); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + + return (0); + } + + + msg (( MSG_OUT, "==============================================" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "Tag = %.8X [H]", PtRec->Tag )); +#endif + msg (( MSG_OUT, "DaqVersion = %.4d [D]", PtRec->DaqVersion )); + msg (( MSG_OUT, "TotSz = %.4d [D]", PtRec->TotSz )); + msg (( MSG_OUT, "TrigRecOffset = %.4d [D]", PtRec->TrigRecOffset )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "H.Tag = %.8X [H]", VPtHead->Tag )); +#endif + msg (( MSG_OUT, "H.AcqStatus = %.4d [D]", VPtHead->AcqStatus )); + msg (( MSG_OUT, "H.TrigStatus = %.4d [D]", VPtHead->TrigStatus )); + msg (( MSG_OUT, "H.AcqId = %.4d [D]", VPtHead->AcqId )); + msg (( MSG_OUT, "H.FrameIdInAcq = %.4d [D]", VPtHead->FrameIdInAcq )); + msg (( MSG_OUT, "H.MapsName = %.4d [D]", VPtHead->MapsName )); + msg (( MSG_OUT, "H.MapsNb = %.4d [D]", VPtHead->MapsNb )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.Header [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X" , VPtHead->AMapsHeader[0] , VPtHead->AMapsHeader[1] , VPtHead->AMapsHeader[2] , VPtHead->AMapsHeader[3] , VPtHead->AMapsHeader[4] , VPtHead->AMapsHeader[5] )); + msg (( MSG_OUT, "H.FrCnt [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d", VPtHead->AMapsFrameCnt[0] , VPtHead->AMapsFrameCnt[1] , VPtHead->AMapsFrameCnt[2] , VPtHead->AMapsFrameCnt[3] , VPtHead->AMapsFrameCnt[4] , VPtHead->AMapsFrameCnt[5] )); + msg (( MSG_OUT, "H.DataSz [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d", VPtHead->AMapsDataLength[0], VPtHead->AMapsDataLength[1], VPtHead->AMapsDataLength[2], VPtHead->AMapsDataLength[3], VPtHead->AMapsDataLength[4], VPtHead->AMapsDataLength[5] )); + msg (( MSG_OUT, "H.Trailer [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X" , VPtHead->AMapsTrailer[0] , VPtHead->AMapsTrailer[1] , VPtHead->AMapsTrailer[2] , VPtHead->AMapsTrailer[3] , VPtHead->AMapsTrailer[4] , VPtHead->AMapsTrailer[5] )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.TriggerNb = %.4d - Address trig %d [D]", VPtHead->TriggerNb, VPtTrig )); + msg (( MSG_OUT, "H.TrigInfo [0]=%.8X [1]=%.8X [2]=%.8X ", VPtHead->AMapsTrigInfo[0], VPtHead->AMapsTrigInfo[1], VPtHead->AMapsTrigInfo[2] )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "D.Tag = %.8X [H]", VPtData->Tag )); +#endif + msg (( MSG_OUT, "D.TotSz = %.4d [D]", VPtData->TotSz )); + msg (( MSG_OUT, "D.OneMapsSz = %.4d [D]", VPtData->OneMapsSz )); + + if ( PrintLevel == 3 ) { + EFRIO__FPrintFrameData ( PtRec, PrintLevel ); + } + + if ( PrintLevel < 4 ) { + msg (( MSG_OUT, "===================================================================================" )); + return (0); + } + + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "T.Tag = %X [H]", VPtTrig->Tag )); +#endif + msg (( MSG_OUT, "T.TotSz = %.4d [D]", VPtTrig->TotSz )); + msg (( MSG_OUT, "T.TrigNb = %.4d [D]", VPtTrig->TrigNb )); + msg (( MSG_OUT, "T.TrigType = %d [D]", VPtTrig->TrigType )); + + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) + : +Goal : Print monitor context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Monitor context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "InfFrameNbToSend = %.4d", PtRec->InfFrameNbToSend )); + msg (( MSG_OUT, "InfSzToSend = %.4d", PtRec->InfSzToSend )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonCont () + : +Goal : Print lib monitor context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMoniCont () { + + return ( EFRIO__FPrintMonContRec (&EFRIO__VGContext.MonCont) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMsg ( + : SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, + : SInt8 PrintAsError, char* Msg ) + : +Goal : Print messages in msg or error log file from LabView -> A Vi encapsulets this function. + : +Inputs : DummyS32In - Dummy value used under Labview to easily " chain " function execution. + : + : To execute it after a Vi call, connect any output of this Vi to the + : DummyS32In pin and it will be automatically called after Vi end. + : To execute it before a Vi call, if this Vi has an integer parameter + : cut the wire and insert DummyS32In input and function output on it. + : + : Printing mode flags + : + : PrintAsMsg - If 1 -> Print in messages log file + : PrintAsTrace - If 1 -> Print in errors log file as a trace message + : PrintAsWarning - If 1 -> Print in errors log file as a warning message + : PrintAsError - If 1 -> Print in errors log file as an error message + : + : Msg - Message to print ( string ) + : +Ouputs : The function always returns the input parameter DummyS32In. + : +Globals : + : +Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) + : It can be used to insert this function call on an integer datapath under LabView + : + : If more than one printing mode flag is enabled therefore the same message will + : be printed in different ways. + : +Level : +Date : 09/08/2010 +Rev : 25/10/2010 + : - Implementation -> Empty function before +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", Msg )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", Msg )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", Msg )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", Msg )); + + return (DummyS32In); +} + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/files.c b/include/pxi_daq_lib_v.1.1/files.c new file mode 100755 index 0000000..94c26df --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/files.c @@ -0,0 +1,3772 @@ + +#ifndef FIL_C +#define FIL_C + + +#ifdef CC_UNIX + +UInt32 GetTickCount () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + + +SInt32 GetLastError () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + +#endif + +/******************************************************************************* +Prototype : SInt32 FIL_FFileExists ( char* FilePath ) +Goal : Test if the file exists. +Inputs : The file name ( full path if needed ). +Ouputs : 1 if the file exists, else 0. +Globals : +Remark : The result is not guaranted in case of multi application lock to file. +Level : This is a user level function. +Date : 17/04/2003 +Doc date : 17/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FFileExists ( char* FilePath ) { + + SInt32 VRet; + FILE* VPf; + + VPf = fopen ( FilePath, "r" ); + + if ( VPf == NULL ) { + VRet = 0; + } + + else { + fclose ( VPf ); + VRet = 1; + } + + + return (VRet); +} + +/* 13/10/2004 */ + +SInt32 FIL_FFileSize ( char* FilePath ) { + + FILE* VPf; + SInt32 VFileSz; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fopen fail !" ) )); + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fclose (VPf) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fclose fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "%d Bytes", VFileSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FCpyFile ( char* Src, char* Dest ) + : +Goal : Copy SrcFile to DestFile. + : +Inputs : Src - Source file + : Dest - Destination file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - fonction moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FCpyFile ( char* Src, char* Dest ) { + + FILE* VPfSrc; + FILE* VPfDest; + SInt8 VBuffer[512]; // Debug 02/06/2007 move storage class static to auto + SInt32 VReadBytesCnt; + SInt32 VTotBytesCnt; + SInt32 VRet; + + VPfSrc = fopen ( Src, "rb" ); + + err_retnull ( VPfSrc, (ERR_OUT,"Source file %d open failed", Src ) ); + + VPfDest = fopen ( Dest, "wb" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", VPfDest ) ); + + VTotBytesCnt = 0; + + while ( ( VReadBytesCnt = fread ( VBuffer, 1 /* byte size */ , 512 /* bytes number */, VPfSrc ) ) > 0 ) { + fwrite ( VBuffer, 1 /* byte size */, VReadBytesCnt, VPfDest ); + VTotBytesCnt += VReadBytesCnt; + } + + fclose (VPfSrc); + fclose (VPfDest); + + err_retok (( ERR_OUT, "file %s copied in %s => %d bytes", Src, Dest, VTotBytesCnt )); +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FRemoveFile ( char* FilePath ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FRemoveFile ( char* FilePath ) { + + SInt32 VRet; + char* VStrError; + + VRet = remove ( FilePath ); + + err_retfail ( VRet, (ERR_OUT,"Remove file=%s failed => %s", FilePath, _strerror ("")) ); + err_retok (( ERR_OUT, "")); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) + : +Goal : List the directory SrcDir and write the result in DestDirFile. + : +Inputs : SrcDir - The directory to list + : DestDirFile - The result file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - Function moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + + VPf = fopen ( DestDirFile, "wt" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT, "Dir file %s creation failed ", DestDirFile ) ); + } + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + ++VItemCnt; + fprintf( VPf, "%s\n", VFileInfo.ff_name); + VRet = findnext(&VFileInfo); + } + + fclose ( VPf ); + + return (0); +} + + +#endif + + +SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosDirOutFile ( SrcDir, DestDirFile ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FDosDelDir ( char* SrcDir ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : Compiled only if CC_APP_WINDOWS is defined +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosRmDirFiles ( char* SrcDir ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + char VFileToDelete[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + SInt32 VRetRemove; + SInt32 VFuncRet; + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VFuncRet = 0; + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + sprintf ( VFileToDelete, "%s\\%s", SrcDir, VFileInfo.ff_name ); + VRetRemove = FIL_FRemoveFile ( VFileToDelete ); + + if ( VRetRemove < 0 ) { + VFuncRet = -1; + err_error (( ERR_OUT, "Remove file=%s failed => %s", VFileToDelete, _strerror ("") )); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + + return (VFuncRet); +} + +#endif + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDirFiles ( char* SrcDir ) +Goal : Remove all the files in directory SrcDir but let the direcory +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDirFiles ( char* SrcDir ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosRmDirFiles (SrcDir) ); + +#else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available !", SrcDir) ); +#endif + + +} + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDir ( char* SrcDir ) +Goal : Remove the directory SrcDir if empty +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDir ( char* SrcDir ) { + + SInt32 VRet; + +#ifdef CC_APP_WINDOWS + + // VRet = _rtl_chmod( SrcDir, 1 , FA_NORMAL ); + // err_retfail ( VRet, (ERR_OUT,"Chmod failed on directory=%s", SrcDir) ); + + VRet = rmdir ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"Remove directory=%s failed => %s ", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + +#else + err_retfail ( -1, (ERR_OUT,"Function handled only under Windows") ); +#endif + +} + +/******************************************************************************* +Prototype : +Goal : Delete direcory files and directory itself +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelDir ( char* SrcDir ) { + + SInt32 VRet; + char VNewName[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + + sprintf ( VNewName, "%s.old", SrcDir ); + + VRet = rename ( SrcDir, VNewName ); + + err_retfail ( VRet, (ERR_OUT,"Rename Dir=%s to %s failed !", SrcDir, VNewName ) ); + + err_warning (( ERR_OUT, "Directory %s renamed in %s because delete is impossible !", SrcDir, VNewName )); + + err_retok (( ERR_OUT, "" )); + +/* + VRet = FIL_FRmDirFiles ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDirFiles (%s) failed ", SrcDir) ); + + VRet = FIL_FRmDir ( VNewName ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDir (%s) failed ", SrcDir) ); + + err_retok (( ERR_OUT, "" )); +*/ + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FMkDir ( char* SrcDir ) { + + SInt32 VRet; + char VStrCmd[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + #ifdef APP_DAQ + + err_retfail ( -1, (ERR_OUT,"Function NOT available under LynxOS !") ); + + #endif + + #ifdef CC_APP_LINUX + sprintf ( VStrCmd, "mkdir %s", SrcDir ); + system ( VStrCmd ); + #endif + + + #ifdef CC_APP_WINDOWS + VRet = mkdir ( SrcDir ); + + err_retfail ( VRet, (ERR_OUT,"Creation of directory=%s failed => %s", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FMkDir (SrcDir=%s) IS NOT available !", SrcDir) ); + #endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in + : the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT + : are not written in list. +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in +: the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT +: are not written in list. +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIL_FExtDosListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\%s", SrcDir, Joker ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIl_FDosListDirFiles ( SrcDir, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIL_FExtDosListDirFiles ( SrcDir, Joker, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList ) { + + SInt32 VRet; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + VFilesCnt = FIl_FListDirFiles ( VRmpDirPath, PtList ); + + return ( VFilesCnt ); +} + + + +#ifndef APP_DAQ + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Extended version which handles conf extension i,j,k +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtDelRmpFiles ( char* RmpDataPath, char ConfExt, SInt32 RunNo, SInt32 MaxFileCnt ) { + + SInt32 VRet; + SInt32 ViFile; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VInfoFilePath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VData0Filepath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + FIL_TDirFilesList VFilesList; // Debug 02/06/2007 move storage class static to auto + + + char VFileToDelete[GLB_FILE_PATH_SZ]; + + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + sprintf ( VInfoFilePath , "RUN_%d_%c.rz", RunNo, ConfExt ); + sprintf ( VData0Filepath, "RUN_%d_0.rz" , RunNo ); + + VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &VFilesList ); + + /* !!! DESY 20/09/05 !!! MUST BE CHECKED ! */ + /* previous line replaced by this one in order to be able to compile boards_db_man */ + /* VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &(VPtAFilesPath) ); */ + + err_retfail ( VFilesCnt, (ERR_OUT,"FIL_FCntRmpFiles (%s) failed Ret=%d", RmpDataPath, VFilesCnt ) ); + + if ( VFilesCnt < MaxFileCnt ) { + err_retok (( ERR_OUT, "Nothing to do VFilesCnt=%d < MaxFileCnt=%d", VFilesCnt, MaxFileCnt )); + } + + err_warning (( ERR_OUT, "%d RMP files are not deleted by monitoring => I will remove them", VFilesCnt )); + + for ( ViFile = 0; ViFile < VFilesCnt; ViFile++ ) { + + if ( strcmp ( VFilesList.AList[ViFile], VInfoFilePath ) == 0 ) { + continue; + } + + if ( strcmp ( VFilesList.AList[ViFile], VData0Filepath ) == 0 ) { + continue; + } + + sprintf ( VFileToDelete, "%s\\%s", VRmpDirPath, VFilesList.AList[ViFile] ); + + err_warning (( ERR_OUT, "FIL_FDelRmpFilesv => File = %s", VFileToDelete )); + + FIL_FRemoveFile ( VFileToDelete ); + + } + + return (0); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Creation of FIL_FExtDelRmpFiles to replace FIL_FDelRmpFiles + : - FIL_FDelRmpFiles call FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt ) { + return ( FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) ); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FFloatVectorsToTextFile ( float** SrcVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** VectorsNames, char DataSep, char* DestFile ) { + + char VFuncName[] = "FIL_FFloatVectorsToTextFile"; + + FILE* VPfDest; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + + + VPfDest = fopen ( DestFile, "wt" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", DestFile ) ); + + + if ( HeaderLine != NULL ) { + VRet = fprintf ( VPfDest, "%s \n", HeaderLine ); + } + + else { + VRet = fprintf ( VPfDest, "No header line \n", HeaderLine ); + } + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing Header line file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + + if ( VectorsNames != NULL ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + VRet = fprintf ( VPfDest, "%-21s", VectorsNames[ViVector]); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing vectors names line - Vector=%d file=%s => %s", ViVector, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + VRet = fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + } + + else { + fprintf ( VPfDest, "No vectors names line \n", HeaderLine ); + } + + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + VRet = fprintf ( VPfDest, "%.6f%c", SrcVectors[ViVector][ViLine], DataSep); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing line=%d in file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR line=%d file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + fflush (VPfDest); + fclose (VPfDest); + + err_retok (( ERR_OUT, "%d line written in file", EltNbPerVector, DestFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#undef CC_FIL + +#ifdef CC_FIL + +SInt32 FIL_FTextFileToFloatVectors ( char* SrcFile, char DataSep, float** DestVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** AVectorsNames, char* StrVectorsNames ) { + + char VFuncName[] = "FIL_FTextFileToFloatVectors"; + + FILE* VPf; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + char VStrCR[2]; + char VDataSep; + + /* Check parameters */ + + err_retnull ( SrcFile , (ERR_OUT,"SrcFile == NULL" ) ); + err_retnull ( DestVectors , (ERR_OUT,"DestVectors == NULL" ) ); + err_retnull ( HeaderLine , (ERR_OUT,"HeaderLine == NULL" ) ); + err_retnull ( AVectorsNames , (ERR_OUT,"AVectorsNames == NULL" ) ); + err_retnull ( StrVectorsNames , (ERR_OUT,"StrVectorsNames == NULL" ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 1" )); + + /* Try to open file */ + + VPf = fopen ( SrcFile, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFile ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read header line */ + + VRet = (SInt32) fgets( HeaderLine, 255, VPf ); + + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read header line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + /* Read vectors names line */ + + + VRet = (SInt32) fgets( StrVectorsNames, 255, VPf ); + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read vectors names line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + sprintf ( AVectorsNames[ViVector], "" ); + }; + + + /* Read vectors */ + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + if ( ViVector == VectorsNb-1 ) { + VRet = fscanf ( VPf, "%f%c", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + else { + VRet = fscanf ( VPf, "%f%c\n", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + + if ( VRet != 2 ) { + fflush (VPf); + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s", ViLine, SrcFile, VRet, _strerror ( "System says :" ) ) ); + } + + } + + } + + + fflush (VPf); + fclose (VPf); + + err_retok (( ERR_OUT, "%d line Read in file", EltNbPerVector, SrcFile )); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef CC_APP_WINDOWS + + SInt32 FIL_FGetAppRunDir ( char* StrRunDir, TApplication* PtApp ) { + + char* VPtStrExeName; + AnsiString VAStrExeName; + char VExeDriveLetter; + char VExeDriveId; /* 0 = default, 1 = A, 2 = B ... */ + char VStrCurDir[GLB_FILE_PATH_SZ]; + char VStrCurDirPath[GLB_FILE_PATH_SZ]; + + err_retfailnull ( StrRunDir, (ERR_OUT,"StrRunDir == NULL") ); + + VPtStrExeName = FStr2PCh ( &(PtApp->ExeName) ); + + VExeDriveLetter = toupper ( VPtStrExeName[0] ); + + switch ( VExeDriveLetter ) { + + case 'A' : { + VExeDriveId = 1; + break; } + + case 'B' : { + VExeDriveId = 2; + break; } + + case 'C' : { + VExeDriveId = 3; + break; } + + case 'D' : { + VExeDriveId = 4; + break; } + + case 'E' : { + VExeDriveId = 5; + break; } + + case 'F' : { + VExeDriveId = 6; + break; } + + case 'G' : { + VExeDriveId = 7; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown drive id=%d", VExeDriveId) ); + VExeDriveId = 0; + } + + } + + getcurdir( VExeDriveId, VStrCurDir ); + + sprintf ( VStrCurDirPath, "%c:\\%s", VExeDriveLetter, VStrCurDir ); + sprintf ( StrRunDir, "%s", VStrCurDirPath ); + + // msg (( MSG_OUT, "VStrCurDirPath = %s", VStrCurDirPath )); + + err_retok (( ERR_OUT, "" )); + } + +#else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 07/03/2011 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FGetDiskSectorSz ( char* Drive ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported under Unix !" ) ); + +#else + + DWORD VDummyW; + DWORD VBytesPerSector; + BOOL VRetBool; + + + // BOOL GetDiskFreeSpace( + // + // LPCTSTR lpRootPathName, // address of root path + // LPDWORD lpSectorsPerCluster, // address of sectors per cluster + // LPDWORD lpBytesPerSector, // address of bytes per sector + // LPDWORD lpNumberOfFreeClusters, // address of number of free clusters + // LPDWORD lpTotalNumberOfClusters // address of total number of clusters + // ); + + + VRetBool = GetDiskFreeSpace( + Drive, // address of root path + &VDummyW, // address of sectors per cluster + &VBytesPerSector, // address of bytes per sector + &VDummyW, // address of number of free clusters + &VDummyW // address of total number of clusters + ); + + if ( VRetBool == True ) { + return ( VBytesPerSector ); + } + + else { + return (-1); + } + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: ~FIL__TCBinFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + + // Variables for internal processing + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdEltId = 0; + ProCurRdSz = 0; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProPtFile = NULL; + + err_trace (( ERR_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + ProParRWBMode = RWBMode; + ProParMaxBlocSz = MaxBlocSz; + ProParBlocSz = BlocSz; + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + ProConfDone = 1; + + + // Allocate memory buffer for data read from file + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = MaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCBinFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProPtFile == NULL ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + + // Store current ( initial ) position in file + + if ( (VCurPos = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Goto end of file + + if ( fseek ( ProPtFile, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + // Get current position = END in file => it's file size + + if ( (VFileSz = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Restor initial position in file + + if ( fseek ( ProPtFile, VCurPos, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + + } // End file is already open + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFCreate () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProPtFile = fopen ( ProParDataFile, "wb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFOpen () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + ProPtFile = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz ) { + SInt8 VBlocNbWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can write to a file when RWB mode IS NOT Write !") ); + } + + ProCurWrSz = DataSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbWritten = fwrite ( PtrData, DataSz /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbWritten != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc write failed ! => System : %s", _strerror ("") ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + fflush ( ProPtFile ); + } + + ++ProCurWrEltId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", DataSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + if ( DataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > MaxDestSz=%d", DataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( DestPtr, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc read of %d bytes failed ! - VBlocNbRead = %d => System : %s", DataSzToRead, VBlocNbRead, _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + if ( DataSzToRead > ProParMaxBlocSz ) { + err_retfailnull ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > ProParMaxBlocSz=%d", DataSzToRead, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( ProPtrBuffRdData, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Bloc read failed ! => System : %s", _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGotoBloc ( SInt32 BlocNo ) { + + SInt32 VOffset; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + VOffset = BlocNo * ProParBlocSz; + + if ( fseek ( ProPtFile, VOffset, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Goto bloc %d => %d bytes from beginning failed !", BlocNo ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ) { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFFlush () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + fflush ( ProPtFile ); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFClose () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + fflush ( ProPtFile ); + } + + fclose ( ProPtFile ); + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + ProConfDone = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_WRITE, RecSz, RecSz, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFCreate (); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqWrite ( PtSrc, RecSz ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_READ, RecSz, RecSz, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFOpen(); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqRead ( PtDest, RecSz /* MaxDestSz */, RecSz /* DataSzToRead */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + + +// msg (( MSG_OUT, "Msg" )); + + + +// **************************** +// FIL__TCStreamFile +// **************************** + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl, DiskBlocSz ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: ~FIL__TCStreamFile () { + + // Free info record + + if ( ProPtRecInfFile != NULL ) { + free ( ProPtRecInfFile ); + } + +#ifndef CC_UNIX + TerminateThread ( ProThreadHnd , 0 /* Thread exit code */ ); + + DeleteCriticalSection ( &ProCsPrintMsg ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : 05/11/2010 + : - Error handling on disk access is not properly done, a message is printed + : but the error is not propagated => MUST be done. +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef CC_UNIX + +DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ) { + + FIL__TCStreamFile* VPtObj = (FIL__TCStreamFile*) lpParam; + + SInt32 VRet; + DWORD VBuffFull; + UInt32 VNbBytesToWrite; + UInt32 VNbBytesWritten; + char VStrMsg[GLB_CMT_SZ]; + + + while (1) { + + // Wait on buffer to read + + VBuffFull = WaitForSingleObject ( VPtObj->ProSemRdBuffHnd, INFINITE ); + + switch ( VBuffFull ) { + + case WAIT_OBJECT_0 : { + + + VNbBytesToWrite = VPtObj->ProParBlocSz; + + WriteFile( + VPtObj->ProFileHnd, // handle to file to write to + VPtObj->ProABuff[VPtObj->ProIndexRdBuff], // pointer to data to write to file + VNbBytesToWrite, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != VNbBytesToWrite ) { + sprintf ( VStrMsg, "ThreadDisk => Writing buff %d error !", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + else { + sprintf ( VStrMsg, "ThreadDisk => Buffer %d save to disk", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + if ( VPtObj->ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( VPtObj->ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + ++VPtObj->ProIndexRdBuff; + + err_retfail ( VPtObj->ProIndexRdBuff, (ERR_OUT,"Bad variable size => ProIndexRdBuff=%d < 0", VPtObj->ProIndexRdBuff) ); + + if ( VPtObj->ProIndexRdBuff >= FIL__TCStreamFile_MAX_BUFF_NB ) { + VPtObj->ProIndexRdBuff = 0; + } + + ReleaseSemaphore ( VPtObj->ProSemWrBuffHnd, 1, NULL ); + + + break; } + + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFull )); + break; } + + } + + + + } // End while (1) + + return 0; +} + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 05/11/2010 +Doc date : 05/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFCalcProParBlocSz ( SInt32 DataSz ) { + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VRecInfSz; + + VNotIntegerDiskBlocNb = DataSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (DataSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = DataSz; + } + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + SInt8 ViBuff; + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + ProParDiskBlocSz = DiskBlocSz; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + sprintf ( ProInfFileName, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + ProParFixedBlocSzMode = 1; + + // Variables for internal processing + + ProUseThread = 0; + + ProFileHnd = INVALID_HANDLE_VALUE; + ProPtInfFile = NULL; + +#ifndef CC_UNIX + InitializeCriticalSection ( &ProCsPrintMsg ); +#endif + + ProThreadHnd = INVALID_HANDLE_VALUE; + ProThreadId = 0; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProABuff[ViBuff] = NULL; + } + + ProSemWrBuffHnd = INVALID_HANDLE_VALUE; + ProSemRdBuffHnd = INVALID_HANDLE_VALUE; + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + ProBuffSz = 0; + + ProPtRecInfFile = NULL; + ProRecInfSz = 0; + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdBlocId = 0; + ProCurRdSz = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetDiskSectorSz ( SInt32 DiskBlocSz ) { + + ProParDiskBlocSz = DiskBlocSz; + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetDiskSectorSz () { + + return (ProParDiskBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void FIL__TCStreamFile :: PubFPrintMsg ( char* Msg ) { + +#ifndef CC_UNIX + EnterCriticalSection( &ProCsPrintMsg ); +#endif + err_trace (( ERR_OUT, "%s", Msg )); + +#ifndef CC_UNIX + LeaveCriticalSection( &ProCsPrintMsg ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt8 ViBuff; + SInt32 VNotIntegerDiskBlocNb; +#ifndef CC_UNIX + TDateTime VODateTime; +#endif + + + + // ------------------------------------------------------- + // Set class parameters from PubFConf parameters list + // ------------------------------------------------------- + + err_retnull ( PtMyself, (ERR_OUT,"PtMyself == NULL") ); + + PriPtMyself = PtMyself; + + ProUseThread = UseThread; + + sprintf ( ProParDataFile, "%s", DataFile ); + + sprintf ( ProInfFileName, "%s.inf", ProParDataFile ); + + ProParRWBMode = RWBMode; + + ProParFixedBlocSzMode = FixedBlocSzMode; + + ProParRequestedBlocSz = BlocSz; + + VNotIntegerDiskBlocNb = ProParRequestedBlocSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (ProParRequestedBlocSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = ProParRequestedBlocSz; + } + + err_trace (( ERR_OUT, "RequestedBlocSz=%d - BlocSz=%d", ProParRequestedBlocSz, ProParBlocSz )); + + + ProParRequestedMaxBlocSz = MaxBlocSz; + + if ( ProParRequestedMaxBlocSz >= ProParBlocSz ) { + ProParMaxBlocSz = ProParRequestedMaxBlocSz; + } + + else { + err_warning (( ERR_OUT, "ProParMaxBlocSz=%d must be adjusted -> Set to ProParBlocSz=%d", ProParMaxBlocSz, ProParBlocSz )); + ProParMaxBlocSz = ProParBlocSz; + } + + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + // ------------------------------------------------------- + // Alloc information file record + // ------------------------------------------------------- + + if ( ProParFixedBlocSzMode == 1 ) { + ProRecInfSz = sizeof (FIL__TCStreamFile_Old_TRecInfFile); + } + + else { + + // BUG ? + + // ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (UInt64) ); + + ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (FIL__TCStreamFile_TBlocInf) ); + + } + + ProPtRecInfFile = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFile, (ERR_OUT,"Allocation of info record failed !") ); + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // ------------------------------------------------------- + // Create or open information file + // ------------------------------------------------------- + + // Write mode => Create info file + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProPtRecInfFile->Version = 1; + ProPtRecInfFile->FixedBlocSz = ProParFixedBlocSzMode; + ProPtRecInfFile->MaxBlocSz = ProParMaxBlocSz; + ProPtRecInfFile->BlocSz = ProParBlocSz; + ProPtRecInfFile->BlocNb = 0; + ProPtRecInfFile->ABlocInf[0].Offset = 0; + ProPtRecInfFile->ABlocInf[0].Sz = 0; + +#ifndef CC_UNIX + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateCreate = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeCreate = TIME__FConvDateTime2Time ( VODateTime ); +#else + ProPtRecInfFile->DateCreate.W32 = 0; + ProPtRecInfFile->TimeCreate.W32 = 0; +#endif + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Creation of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + err_trace (( ERR_OUT, "Info file=%s created", ProInfFileName )); + } + + // Read mode => Open info file + + else { + + ProPtInfFile = fopen ( ProInfFileName, "rb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Open info file %s failed => system : %s", ProInfFileName, _strerror ( "" ) )); + err_trace (( ERR_OUT, "Info file=%s read", ProInfFileName )); + + if ( fread ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Read info file %s failed => system : %s", ProInfFileName, _strerror ( "" )) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + // Print info file + + PubFPrintInfFile (); + + // Set bloc size + + ProParBlocSz = ProPtRecInfFile->BlocSz; + + if ( ProParRequestedBlocSz != ProParBlocSz ) { + err_warning (( ERR_OUT, "Requested bloc sz=%d <> Info file bloc sz=%d => Use Info file bloc sz", ProParRequestedBlocSz, ProParBlocSz )); + } + + } + + + // ------------------------------------------------------------- + // Write mode => Allocate buffers, create semaphores and thread + // ------------------------------------------------------------- + + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + if ( FIL__TCStreamFile_MAX_BUFF_NB > 4 ) { + err_retfail ( -1, (ERR_OUT,"FIL__TCStreamFile_MAX_BUFF_NB = %d ! Handling of more than 4 buffers is NOT implemented !", FIL__TCStreamFile_MAX_BUFF_NB) ); + } + + // Allocate buffers + + ProBuffSz = ProParMaxBlocSz; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + // If already allocated => Free + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + } + + // Allocate + + ProABuff[ViBuff] = (UInt8*) malloc ( ProBuffSz ); + + err_retnull ( ProABuff[ViBuff], (ERR_OUT,"Allocation buffer[%d] of %d bytes failed !", ViBuff, ProBuffSz ) ); + err_trace (( ERR_OUT, "Buffer[%d] of %d bytes allocated", ViBuff, ProBuffSz )); + + // Reset content with $FF + + memset ( ProABuff[ViBuff], 0xFF, ProBuffSz ); + } + + // Create & init semaphores + + #ifndef CC_UNIX + ProSemWrBuffHnd = CreateSemaphore( NULL, FIL__TCStreamFile_MAX_BUFF_NB, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = Max = Max buff nb + + err_retnull ( ProSemWrBuffHnd, (ERR_OUT,"Create SemWrBuff failed ! - LastError=%d", GetLastError ()) ); + + ProSemRdBuffHnd = CreateSemaphore( NULL, 0, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = 0, Max = Max buff nb + + err_retnull ( ProSemRdBuffHnd, (ERR_OUT,"Create SemRdBuff failed ! - LastError=%d", GetLastError ()) ); + #endif + + // Init buffers index + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + // Create thread + + #ifndef CC_UNIX + ProThreadHnd = CreateThread ( NULL, 0, FIL__TCStreamFile_FThread, (void*) PriPtMyself /* Param */ , 0, &ProThreadId ); + err_retnull ( ProThreadHnd, (ERR_OUT,"Thread creation failed ! LastError=%d", GetLastError ()) ); + #endif + + } + + // ------------------------------------------------------------- + // Read mode => Allocate memory buffer for data read from file + // ------------------------------------------------------------- + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = ProParMaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 20/05/2010 +Doc date : 20/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFile () { + + SInt32 ViBloc; + SInt16 ViSpareW32Info; + + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record " )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Version = %d", ProPtRecInfFile->Version )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Date create = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateCreate, NULL, 0 ) )); + msg (( MSG_OUT, "Time create = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeCreate, NULL, 0 ) )); + msg (( MSG_OUT, "Date close = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateClose , NULL, 0 ) )); + msg (( MSG_OUT, "Time close = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeClose , NULL, 0 ) )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "FixedBlocSz = %d", ProPtRecInfFile->FixedBlocSz )); + msg (( MSG_OUT, "MaxBlocSz = %d", ProPtRecInfFile->MaxBlocSz )); + msg (( MSG_OUT, "BlocSz = %d", ProPtRecInfFile->BlocSz )); + msg (( MSG_OUT, "BlocNb = %d", ProPtRecInfFile->BlocNb )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "ABlocInf[0].Offset = %Lu", ProPtRecInfFile->ABlocInf[0].Offset )); + msg (( MSG_OUT, "ABlocInf[0].Sz = %d ", ProPtRecInfFile->ABlocInf[0].Sz )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoFormat = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoFormat )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoNb = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb )); + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb; ViSpareW32Info++ ) { + msg (( MSG_OUT, "ABlocInf[0].ASpareW32Info[%.2d] = %d ", ViSpareW32Info, ProPtRecInfFile->ABlocInf[0].ASpareW32Info[ViSpareW32Info] )); + } + + + if ( ProPtRecInfFile->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < ProPtRecInfFile->BlocNb; ViBloc++ ) { + msg (( MSG_OUT, "Bloc[%.4d] : Offset=%.12Lu - Sz=%.8d [Bytes] - ASpare [0]=%.4d [1]=%.4d [2]=%.4d [3]=%.4d", ViBloc, ProPtRecInfFile->ABlocInf[ViBloc].Offset, ProPtRecInfFile->ABlocInf[ViBloc].Sz, ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[0], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[1], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[2], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[3] )); + } + + } + + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + err_retfail ( -1, (ERR_OUT,"File is opened => Get file size not coded in this state (TOB ...)") ); + } + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 + : - Calculation => file size / block size +Rev : 20/05/2010 + : - Read from info file field BlocNb + : +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + +/* Before 20/05/2010 + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + +*/ + + VBlocNb = ProPtRecInfFile->BlocNb; + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFCreate () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_WRITE | GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFOpen () { + +#ifdef CC_UNIX + + ProFilePtUx = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProFilePtUx, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#endif +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation + : + : 24/02/2011 + : - Handle SpareW32Info as an array now => New parameters + : +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + SInt16 ViSpareW32Info; + DWORD VBuffFree; + UInt32 VNbBytesWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + err_retnull ( PtSpareW32Info, (ERR_OUT,"PtSpareW32Info == NULL") ); + + if ( SpareW32InfoNb > FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"SpareW32InfoNb=%d > Max=%d", SpareW32InfoNb, FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Cant write to a file when RWB mode IS NOT Write !") ); + } + + // If variable bloc sz mode => Test max nb of blocs allowed & Adjust ProParBlocSz + + if ( ProParFixedBlocSzMode == 0 ) { + + if ( ProPtRecInfFile->BlocNb >= FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE ) { + err_retfail ( -1, (ERR_OUT,"Max bloc nb = %d reached in variable bloc sz mode !", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE) ); + } + + ProFCalcProParBlocSz ( DataSz ); + } + + // err_error (( ERR_OUT, "DataSz=%d - ProParBlocSz=%d bytes", DataSz, ProParBlocSz )); + + ProCurWrSz = ProParBlocSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + // Let thread write data to disk in background task + + if ( ProUseThread == 1 ) { + + // Wait on buffer to write + + VBuffFree = WaitForSingleObject ( ProSemWrBuffHnd, 1 /* ms */ ); + + switch ( VBuffFree ) { + + case WAIT_TIMEOUT : { + ++ProResWrBlocFailCnt; + err_retfail ( -1, (ERR_OUT,"Write failed for the %d time -> No buffer available - DbgCallPar=%d !", ProResWrBlocFailCnt, DbgCallPar ) ); + break; } + + case WAIT_OBJECT_0 : { + + memcpy ( ProABuff[ProIndexWrBuff], PtrData, DataSz ); + + // PubFPrintMsg ( "Thread => Buffer %d filled", ProIndexWrBuff ); + err_trace (( ERR_OUT, "Thread => Buffer %d filled - DbgCallPar=%d", ProIndexWrBuff, DbgCallPar )); + + ++ProIndexWrBuff; + + err_retfail ( ProIndexWrBuff, (ERR_OUT,"Bad variable size => ProIndexWrBuff=%d < 0", ProIndexWrBuff) ); + + if ( ProIndexWrBuff >= FIL__TCStreamFile_MAX_BUFF_NB) { + ProIndexWrBuff = 0; + } + + ReleaseSemaphore ( ProSemRdBuffHnd, 1, NULL ); + break; } + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFree )); + break; } + + } + + } + + // Write NOW data to disk + + else { + + // Copy to buffer -> "Automatically" add padding bytes + + memcpy ( ProABuff[0], PtrData, DataSz ); + + // Warning => Write ProParBlocSz bytes AND NOT the value passed via parameter DataSz + // because non buffered I/O functions MUST write multiple of DISK bloc size + + WriteFile( + ProFileHnd, // handle to file to write to + ProABuff[0], // pointer to data to write to file + ProParBlocSz, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != ProParBlocSz ) { + err_retfail ( VRet, (ERR_OUT,"Writing block %d failed %d bytes written - %d bytes requested ! - %s", ProCurWrBlocId, VNbBytesWritten, ProParBlocSz, strerror ( errno ) ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + } + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + + if ( ProUseThread == 1 ) { + err_trace (( ERR_OUT, "Copy bloc of %d bytes done in %d [ms]", DataSz, ProTimeExec )); + } + + else { + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", VNbBytesWritten, ProTimeExec )); + } + + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + +#ifdef CC_UNIX + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + SInt32 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VBlocNbRead = fread ( DestPtr, VDataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProFilePtUx ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed of %d bytes ! - %s", ProCurRdBlocId, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#else + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + UInt32 VNbBytesRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + ReadFile( + ProFileHnd, // handle of file to read + DestPtr, // address of buffer that receives data + VDataSzToRead, // number of bytes to read + &VNbBytesRead, // address of number of bytes read + NULL // address of structure for data + ); + + if ( VNbBytesRead != VDataSzToRead ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed : %d bytes read - %d bytes requested ! - %s", ProCurRdBlocId, VNbBytesRead, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( ProPtrBuffRdData, ProSzBuffRdData, DataSzToRead ); + + err_retfailnull ( VRet, (ERR_OUT,"PubFSeqRead failed !") ); + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : Limited to 4 GB files + : +Rev : 09/05/2010 + : - Use W64 offset => Not limited to 4 GB file +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGotoBloc ( SInt32 BlocNo ) { + +#ifdef CC_UNIX + + SInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = fseeko ( ProFilePtUx, (off_t) VOffsetW64, SEEK_SET ); + + err_retfail ( VRet, (ERR_OUT,"Bloc %d read failed ! => System : %s", BlocNo, _strerror ("") ) ); + + err_retok (( ERR_OUT, "" )); + +#else + + UInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = SetFilePointer ( + ProFileHnd, // handle of file + *VPtOffsetLow32, // number of bytes to move file pointer + (SInt32*) VPtOffsetHigh32, // address of high-order word of distance to move + // lpDistanceToMoveHigh = 0 => Limited to 4 GB + FILE_BEGIN // how to move + ); + + + if ( VRet == 0xFFFFFFFF ) { + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &VMsgBuf, + 0, + NULL + ); + + err_retfail ( -1, (ERR_OUT,"Goto bloc %d failed => %s", BlocNo, VMsgBuf ) ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 24/02/2011 + : - Handle SpareW32Info as and array ASpareW32Info now => New parameters + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ) { + + SInt32 VRet; + SInt16 ViSpareW32Info; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + + if ( (PtSpareW32InfoFormat != NULL) && (PtSpareW32Info != NULL) && (ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb <= MaxSpareW32InfoNb) ) { + + *PtSpareW32InfoFormat = ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoFormat; + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb; ViSpareW32Info++ ) { + PtSpareW32Info[ViSpareW32Info] = ProPtRecInfFile->ABlocInf[BlocNo].ASpareW32Info[ViSpareW32Info]; + } + + } + + else { + err_warning (( ERR_OUT, "ASpareInfo bloc not updated ! Pointer NULL or Dest size too small ?" )); + } + + } + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + return (ProParBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + } + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFFlush () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFClose () { + + SInt32 VRet; + SInt8 ViBuff; +#ifndef CC_UNIX + TDateTime VODateTime; +#endif + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + PubFFlush (); + } + + ProConfDone = 0; + +#ifndef CC_UNIX + CloseHandle ( ProFileHnd ); +#endif + + // Free read buffers + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + // Free write buffers + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + ProABuff[ViBuff] = NULL; + } + + } + + + // Get close date & time + +#ifndef CC_UNIX + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateClose = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeClose = TIME__FConvDateTime2Time ( VODateTime ); +#else + ProPtRecInfFile->DateClose.W32 = 0; + ProPtRecInfFile->TimeClose.W32 = 0; +#endif + + + if ( ProReadyToWrite == 1 ) { + + // Overwrite info file with update close time & date + bloc nb + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Overwrite of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file failed => System : %s", strerror ( errno ) ) ); + } + + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* + Prototype : + Goal : returns the start run time in the day in seconds + Inputs : + Ouputs : + Globals : + Remark : + Level : + Date : 11/05/2012 + Doc date : 11/05/2012 + Author : Jerome BAUDOT + E-mail : baudot@in2p3.fr + Labo : IPHC */ +/******************************************************************************/ + +int FIL__TCStreamFile :: GetTime () { + + TIME__TSTime aTime = (ProPtRecInfFile->TimeCreate).Time; + + return aTime.Hour*60*60 + aTime.Min*60 + aTime.Sec; + +} + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.1/files.def b/include/pxi_daq_lib_v.1.1/files.def new file mode 100755 index 0000000..183addd --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/files.def @@ -0,0 +1,42 @@ +/* 24/02/05 */ +// Modified: VR 2014/03/21 Configuration of FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE is now made in the "pxi_daq_lib_config.h" file + +#ifndef FIL_DEF +#define FIL_DEF + +#define FIL_DIR_FILES_LIST_MAX_CNT 100 + +#define FIL__TCBinFile_MEAS_TIME +#define FIL__TCStreamFile_MEAS_TIME + +#define FIL__TCBinFile_RWB_MODE_WRITE 0 +#define FIL__TCBinFile_RWB_MODE_READ 1 +#define FIL__TCBinFile_RWB_MODE_BOTH 2 + +// 07/03/2009 +// Macro removed because they are not supported under ROOT ... +// => Macro "calls" had been replaced by the macro code below in files.c +// => For new implementations : a copy paste of the macro code below must be done for each "flag test" +// +// #define FIL__TCBinFile_CHK_CONF_DONE {err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_WR {err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_RD {err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );} + + +#define FIL__TCStreamFile_MAX_BUFF_NB 4 +#define FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB 20 + +// 21/03/2014 (VR) +// Configuration of FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE variable (Maximum number of blocs in variable bloc size mode) +// is set in the "pxi_daq_lib_config.h" file : // #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 + +#include "pxi_daq_lib_config.h" + +// TEST to check if configuration in "pxi_daq_lib_config.h" is well done +#ifndef FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE + #error in pxi_daq_lib_v.1.1 (files.def) : bad configuration in file include/pxi_daq_lib_config.h +#endif + + +#endif + diff --git a/include/pxi_daq_lib_v.1.1/files.typ b/include/pxi_daq_lib_v.1.1/files.typ new file mode 100755 index 0000000..ff6a400 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/files.typ @@ -0,0 +1,281 @@ +/* 24/02/05 */ + + +#ifndef FIL_TYP +#define FIL_TYP + +/* char FIL_TADirFilesList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; */ + + +typedef struct { + char AList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; +} FIL_TDirFilesList; + + +// 30/01/2009 + +class FIL__TCBinFile { + + + private : + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + // Parameters from conf + + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParMaxBlocSz; + SInt32 ProParBlocSz; + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + + SInt32 ProCurRdEltId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrEltId; + UInt64 ProCurWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + UInt64 ProTotWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + FILE* ProPtFile; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + + + public : + + FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~FIL__TCBinFile (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + SInt32 PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz ); + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + +// 01/05/2010 + +typedef struct { + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + UInt32 ABlocSz[1]; + +} FIL__TCStreamFile_Old_TRecInfFile; + +// 05/11/10 + +typedef struct { + + UInt64 Offset; + UInt32 Sz; + + SInt32 SpareW32InfoFormat; // Number which identifies the meaning ASpareW32Info + SInt32 SpareW32InfoNb; // Number of spare parameters + SInt32 ASpareW32Info[FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB]; // Array for user parameters + + UInt32 Dummy; // For alignment + +} FIL__TCStreamFile_TBlocInf; + + +// 05/11/10 + +typedef struct { + + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + + UInt32 Dummy; // For alignment + + FIL__TCStreamFile_TBlocInf ABlocInf[1]; + + +} FIL__TCStreamFile_TRecInfFile; + + +class FIL__TCStreamFile { + + + private : + + FIL__TCStreamFile* PriPtMyself; + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + SInt32 ProParDiskBlocSz; + SInt8 ProParFixedBlocSzMode; + + // Parameters from conf + + SInt8 ProUseThread; + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParRequestedMaxBlocSz; // Bloc size value asked by user + SInt32 ProParMaxBlocSz; // Adjusted depending on ProParBlocSz + + SInt32 ProParRequestedBlocSz; // Bloc size value asked by user + SInt32 ProParBlocSz; // Bloc size value used ( multiple of disk bloc size ) + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + HANDLE ProFileHnd; + +#ifdef CC_UNIX + FILE* ProFilePtUx; // Pointer to data file for Linux / Unix +#endif + + char ProInfFileName[GLB_FILE_PATH_SZ]; + FILE* ProPtInfFile; + + FIL__TCStreamFile_TRecInfFile* ProPtRecInfFile; + SInt32 ProRecInfSz; + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + +#ifndef CC_UNIX + CRITICAL_SECTION ProCsPrintMsg; +#endif + + HANDLE ProThreadHnd; + DWORD ProThreadId; + + HANDLE ProSemWrBuffHnd; + HANDLE ProSemRdBuffHnd; + + SInt16 ProIndexWrBuff; + SInt16 ProIndexRdBuff; + + UInt8* ProABuff[FIL__TCStreamFile_MAX_BUFF_NB]; + SInt32 ProBuffSz; + + + SInt32 ProCurRdBlocId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrBlocId; + SInt32 ProCurWrSz; + SInt64 ProTotWrSz; + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + // Results + + SInt32 ProResWrBlocFailCnt; + + SInt32 ProFCalcProParBlocSz ( SInt32 DataSz ); + + public : + + FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + ~FIL__TCStreamFile (); + + friend DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + SInt32 PubFSetDiskSectorSz ( SInt32 DiskBlocSz ); + SInt32 PubFGetDiskSectorSz (); + + void PubFPrintMsg ( char* Msg ); + SInt32 PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFPrintInfFile (); + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + // SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 SpareInfo ); + + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ); + + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + + int GetTime (); + +}; + + + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.1/files.var b/include/pxi_daq_lib_v.1.1/files.var new file mode 100755 index 0000000..7f38a20 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/files.var @@ -0,0 +1,18 @@ +/* 24/02/05 */ + + +#ifndef FIL_VAR +#define FIL_VAR + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +// Examples +// +// VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +// VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.1/globals.def b/include/pxi_daq_lib_v.1.1/globals.def new file mode 100755 index 0000000..296f090 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/globals.def @@ -0,0 +1,39 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_DEF +#define GLOBALS_DEF + +#ifndef CC_UNIX + #include "y:/dd/sdev/src/com/c/com/include/globals_root.def" +#endif + +#ifndef ROOT_ROOT + #define GLB_READ_CR { while ( getchar () != '\n' ); }; +#endif + + +#ifndef ROOT_ROOT + #define GLB_KEYB_CR { while ( getchar () != '\n' ); } +#endif + + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/globals_root.def b/include/pxi_daq_lib_v.1.1/globals_root.def new file mode 100755 index 0000000..26466d2 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/globals_root.def @@ -0,0 +1,44 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_ROOT_DEF +#define GLOBALS_ROOT_DEF + +/* CONDITIONNAL COMPILATION */ + +#define GLB_GC_CASCADE +#define GLB_FIRST_REC_FORMAT + +/* MACROS */ + +#define GLB_FILE_PATH_SZ 256 +#define GLB_CMT_SZ 256 +#define GLB_HOST_NAME_SZ 50 + +#define GLB_SEQ 0 + +#define GLB_RMP_FILE_PATH "/common/rmp/RMP" +#define GLB_RMPS_FILE_PATH "/common/rmp/RUN" + + +#define GLB_DEF_BYTE_SEX 0x3615ABCD + + +// #define GLB_DESY_VME_A32_BASE 0xd0000000 /* By default it's LEPSI config base address 0xd0000000*/ + + + + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/maps.def b/include/pxi_daq_lib_v.1.1/maps.def new file mode 100755 index 0000000..7a798eb --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/maps.def @@ -0,0 +1,49 @@ +/******************************************************************************* +File : x:\lib\com\maps\maps.def +Goal : Macros definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_DEF +#define MAPS_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define MAPS__TCDigTelMon_MAX_EV_NB 300 +#define MAPS__TCDigTelMon_MAX_PLANE_NB 6 +#define MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB 10000 +#define MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE 1000 + +#define MAPS__TCDigTelMon_CHK_PLANE_ID(Id) { if ( (Id < 0) || (Id >= MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + +#define MAPS__TCDigTelMon_CHK_PLANE_NB(Nb) { if ( (Nb <= 0) || (Nb > MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Nb, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + + +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME 0 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL 1 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS 2 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR 3 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS 4 + +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES 0 +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE 1 + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/maps.typ b/include/pxi_daq_lib_v.1.1/maps.typ new file mode 100755 index 0000000..63e1342 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/maps.typ @@ -0,0 +1,383 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.typ +Goal : Types definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_TYP +#define MAPS_TYP + + +#ifdef ROOT_ROOT + typedef UInt32 MAPS__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor MAPS__TColor; +#endif + + + +// 17/07/2009 + +typedef struct { + + SInt32 MaxBuffEvNb; + + // Hard coded parameters in next classes + + SInt8 MapsNb; // Nb of MAPS acquired by DAQ + SInt8 MapsName; + SInt8 PlaneNb; + + // Parameters from GUI + + SInt8 MonEnabled; + + SInt32 AcqFrNb; // Nb of frame in current acq to process + + SInt8 ProcOneAcq; // 1 => Process current ONLY acq + // 0 => Process ProcEvNb coming from GUI + // It can be more or less than one acq + + SInt32 ProcEvNb; // Ev nb to process, either + // - if ProcOneAcq = 1 => ev nb of one acq + // - if ProcOneAcq = 0 => from GUI + + SInt8 ProcOnlyFrWithHitOnAllPlanes; + + SInt8 ListHitAllPlanesMode; + + SInt8 ProcOnlyFrWithTrig; // Process only frames with hit + SInt8 HandleTrigPos; // Use trigger position to extract events + SInt8 StopAtEndOfProc; // Stop at end of processing, no automatic processing of next acq + SInt8 StoreEvents; // Store events + + SInt8 DispFrNbWithTrigOrFrNbWithHit; // Display in PubPt_ADispFrNbWithTrigOrHit & PubPt_ADispFrPCentWithTrigOrHit trig or hit nb + // 0 => Display frame nb & % with trigger + // 1 => Display frame nb & % with at least one hit + + SInt8 DispFullMatrix; // 0 => Display 1/2 scale matrix + // 1 => Display full matrix + + SInt8 ProcMode; // Processing mode + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + + SInt8 CumPlotGrayOrBlueLevels; // Cumul plot + // 0 => in gray levels + // 1 => in blue levels + + SInt8 CumPlotHitOrHitCnt; // Cumul plot + // 0 => binary display : count > 0 => set pixel in black / blue + // 1 => gray or blue levels display + + + SInt32 GotoRawFrNo; // Plot raw data of frame No + +} MAPS__TDigTelPar; + + +// 17/07/2009 + +typedef struct { + + SInt8 RunInProgress; + SInt8 LastPlaneSelForCoin; // Index of last plane selected for coincidence + + SInt32 CurEvNo; // Index of last event buffered + SInt32 FirstEvToProc; // Index of first event to process + SInt32 LastEvToProc; // Index of last event to process + SInt32 CurEvToProc; // Index of event to process + SInt32 EvNbToProc; // Ev nb to process + +} MAPS__TDigTelInf; + + +// 17/07/2009 + +typedef struct { + + SInt32 AcqFrNb; // Frame nb received from current acq + SInt32 ProFrNo; // Index of currently processed frame + SInt32 ProTimeMs; // Processing time + +} MAPS__TDigTelRes; + + +// 17/07/2009 + +typedef struct { + + SInt8 MapsId; // Id of the MAPS + MAPS__TColor PlotColor; + + SInt8 Process; // Process data of this plane + SInt8 RevertXDir; // Revert numbering of X direction ( columns ) in case planes are mounted back to back + SInt8 PlotCum; // Plot cumulated hit count over N events + SInt8 PlotCoin; // Plot coincidence + SInt8 PlotFrame; // Plot frame raw data + +} MAPS__TDigTelPlanePar; + + +// 22/07/2009 + +typedef struct { + + SInt8 PrevProcState; // Not used on 22/07/2009 + SInt8 CurProcState; // Not used on 22/07/2009 + + +} MAPS__TDigPlaneInf; + + +// 17/07/2009 + +typedef struct { + + void* AEvPt[MAPS__TCDigTelMon_MAX_EV_NB]; + void* CurEvPt; + +} MAPS__TDigTelPlaneData; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add CumTotTrigNb & CumFrameTrigNb + +typedef struct { + + void* PtMatDiscriBit; // Flat view of matrix X col x Y lines + void* PtMatCumTotHitCnt; // Hit count of each pixel over all events + + SInt32 FrameNbWithTrig; // Nb of frame with trigger + float FramePCentWithTrig; // % of frame with trigger + SInt32 CumTotTrigNb; // Total number of triggers + float CumFrameTrigNb; // Cumul MEAN trigger nb on frames WITH trigger + + SInt32 FrameNbWithHit; // Nb of frame with at least one hit + float FramePCentWithHit; // % of frame with at least one hit + SInt32 CumTotHitNb; // Total cumul hit nb over ALL frames ( with and without hit ) + float CumFrHitNb; // Cumul MEAN hit nb on frames WITH hit + +} MAPS__TDigTelPlaneRes; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add PubPt_ADispCumFrTrigNb + +#ifndef ROOT_ROOT + +class MAPS__TCDigTelMon { + + private: + + SInt8 PrivGuiConnected; + SInt8 PrivSetGuiParDontRead; + + SInt32 PrivFInit (); + + SInt32 PrivChkPlaneId ( SInt8 Id ); + + SInt32 PrivFSetGuiLabelsDispFrNbWithTrigOrFrNbWithHit (); + + protected: + + SInt8 ProRequestPlot; // Request plot from sw external to object + + MAPS__TDigTelPar ProPar; + MAPS__TDigTelInf ProInf; + MAPS__TDigTelRes ProRes; + MAPS__TDigTelPlanePar ProAPlanePar[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigPlaneInf ProAPlaneInf[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneData ProAPlaneData[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneRes ProAPlaneRes[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + public: + + // ---------------------------------- + // Fields to connect GUI components + // ---------------------------------- + + // Group + + TGroupBox* PubPt_GrpTelMon; + + // Label + + TLabel* PubPt_LbFrNbWithTrigOrHit; + TLabel* PubPt_LbFrPCentWithTrigOrHit; + + // Controls + + TCheckBox* PubPt_ChkEnableMonitor; + + TCheckBox* PubPt_AChkProc[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkRevertXDir[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TCheckBox* PubPt_ChkProcOneAcq; + TEdit* PubPt_EdFrNbToProc; + TCheckBox* PubPt_ChkProcOnlyFrWithTrig; + + TComboBox* PubPt_CbListHitAllPlanesMode; + + TCheckBox* PubPt_ChkTrigPosHanling; + TCheckBox* PubPt_ChkStopAtEndOfProc; + TCheckBox* PubPt_ChkStoreFr; + + TCheckBox* PubPt_ChkDispFrNbWithTrigOrFrNbWithHit; + TCheckBox* PubPt_ChkDispFullMatrix; + + TComboBox* PubPt_CbProcMode; + TCheckBox* PubPt_ChkCumPlotGrayOrBlueLevels; + TCheckBox* PubPt_ChkCumPlotHitOrHitCnt; + + TEdit* PubPt_EdGotoFr; + + TLabel* PubPt_ALbPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TRadioButton* PubPt_ARbPlotCum[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkPlotCoin[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TRadioButton* PubPt_ARdPlotFr[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // Indicators + + TEdit* PubPt_DispAcqFrNb; + TEdit* PubPt_DispCurProcFr; + + TEdit* PubPt_ADispFrNbWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispFrPCentWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_ADispCumFrTrigNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumTotHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumFrHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_DispProFrNo; + TEdit* PubPt_DispProcTimeMs; + + // Display + + TImage* PubPt_ImgMiniMatrix; + TImage* PubPt_ImgFullMatrix; + + + // ------------- + // Methods + // ------------- + + + MAPS__TCDigTelMon (); + ~MAPS__TCDigTelMon (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGuiEnablePlane ( SInt8 Id, SInt8 Enable ); + + SInt32 PubFSetGuiPar (); + SInt32 PubFSetGuiParGotoFr (); + + SInt32 PubFGetGuiPar (); + SInt32 PubFOnGuiParDispModeChangeFrNbWithTrigOrFrNbWithHit (); // Specific GUI behaviour + SInt32 PubFSetGuiStatus (); + SInt32 PubFSetGuiRes (); + + + // Set parameters + + SInt32 PubFSetPar ( MAPS__TDigTelPar* Pt ); + SInt32 PubFSetPlanePar ( SInt8 Id, MAPS__TDigTelPlanePar* Pt ); + + // Get parameters + + MAPS__TDigTelPar* PubFGetPar (); + MAPS__TDigTelPlanePar* PubFGetPlanePar ( SInt8 Id ); + MAPS__TDigTelPlaneData* PubFGetPlaneData ( SInt8 Id ); + + // Disable all planes processing + + SInt32 PubFDisAllPlanesProcessing (); + + // Disable group + + SInt32 PubFDisCumPlot (); + SInt32 PubFDisCoinPlot (); + SInt32 PubFDisFramePlot (); + + // Set results + + MAPS__TDigTelPlaneRes* PubFSetPlaneRes ( SInt8 Id ); + + // Poll plot request + + SInt32 PubFGetPlotRqStatus (); + SInt32 PubFResetPlotRqStatus (); + + SInt8* PubFGetPtPlotRq (); + SInt8* PubFGetPtMonEnabled (); + + + // Debug print + + SInt32 PubFPrintPar (); + SInt32 PubFPrintInf (); + + SInt32 PubFPrintPlanePar ( SInt8 Id ); + SInt32 PubFPrintAllPlanesPar (); + + SInt32 PubFPrintPlaneInf ( SInt8 Id ); + SInt32 PubFPrintAllPlanesInf (); + + SInt32 PubFPrintPlaneData ( SInt8 Id ); + SInt32 PubFPrintAllPlanesData (); + + SInt32 PubFPrintPlaneRes ( SInt8 Id ); + SInt32 PubFPrintAllPlanesRes (); + + +}; + +#endif + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 17/07/2009 */ +/* ============================= */ + +typedef struct { + + SInt8 Dummy; + +} MAPS__TContext; + + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/maps.var b/include/pxi_daq_lib_v.1.1/maps.var new file mode 100755 index 0000000..cd0d91a --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/maps.var @@ -0,0 +1,33 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.var +Goal : Variables definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_VAR +#define MAPS_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC MAPS__TContext MAPS__VGContext; + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/mi26_usr.def b/include/pxi_daq_lib_v.1.1/mi26_usr.def new file mode 100755 index 0000000..7771c7f --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/mi26_usr.def @@ -0,0 +1,75 @@ +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.def +Goal : Macros definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_DEF +#define MI26_USR_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ 1152 + +#define MI26__ZS_FFRAME_RAW_MAX_W8 2280 +#define MI26__ZS_FFRAME_RAW_MAX_W16 1140 // 1142 +#define MI26__ZS_FFRAME_RAW_MAX_W32 570 +#define MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 + + +#define MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 +#define MI26__ZS_FFRAME_MAX_STATES_REC 576 // one per line + +// ====================================== +// For MI26 discri analysis tools +// ====================================== + +// Submatrices number + +#define MI26__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define MI26__REG_BIAS_NB 19 + +#define MI26__REG_BIAS_ICLPDISC 0 +#define MI26__REG_BIAS_IPWRSW 1 +#define MI26__REG_BIAS_IBUF 2 +#define MI26__REG_BIAS_ID1PWRS 3 +#define MI26__REG_BIAS_ID2PWRS 4 +#define MI26__REG_BIAS_ILVDSTX 5 +#define MI26__REG_BIAS_ILVDS 6 +#define MI26__REG_BIAS_IVTST1 7 +#define MI26__REG_BIAS_IVTST2 8 +#define MI26__REG_BIAS_IANABUF 9 +#define MI26__REG_BIAS_IVDREF1D 10 +#define MI26__REG_BIAS_IVDREF1C 11 +#define MI26__REG_BIAS_IVDREF1B 12 +#define MI26__REG_BIAS_IVDREF1A 13 +#define MI26__REG_BIAS_IVDREF2 14 +#define MI26__REG_BIAS_IDIS1 15 +#define MI26__REG_BIAS_IDIS2 16 +#define MI26__REG_BIAS_IPXI 17 +#define MI26__REG_BIAS_IKIMO 18 + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/mi26_usr.typ b/include/pxi_daq_lib_v.1.1/mi26_usr.typ new file mode 100755 index 0000000..006161a --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/mi26_usr.typ @@ -0,0 +1,193 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.typ +Goal : Types definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_TYP +#define MI26_USR_TYP + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} MI26__TContext; + + +/* ======================================================= */ +/* Frame provided by Mi26 DAQ, it's independent of output */ +/* mode BUT data are not organized as in MI26__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by MI26__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + UInt32 Header; // Header of Mimosa 26 frame + UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 Trailer; // Trailer of Mimosa 26 frame + + UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + UInt16 ADataW16[MI26__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} MI26__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} MI26__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} MI26__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + MI26__TStatesLine StatesLine; + MI26__TState AStates[MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} MI26__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by Mi26, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a MI26 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + MI26__TZsFStatesRec AStatesRec[MI26__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} MI26__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/msg.c b/include/pxi_daq_lib_v.1.1/msg.c new file mode 100755 index 0000000..7dd5585 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/msg.c @@ -0,0 +1,230 @@ + +/******************************************************************************* +File : x:\lib\com\msg\msg.c +Goal : Implement user messages print ( screen ) or log ( file ) functions. + : It's usefull to send debug messages. + : +Remark : The way it works is controlled by 3 globals variables + : MSG_VGLogClosed = 0 ( disable ) / 1 ( enable ) user messages + : MSG_VGLogPath = '/msg/msg.txt' = path of messages logfile + : MSG_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : There is the same variables with RMSG_ instead of MSG_ they are + : used for on-line remote monitoring messages. + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_C +#define MSG_C + + +SInt32 MSG_FGenEnableLog ( SInt8 Chan, SInt8 Enable ) { + MSG_VGALogClosed[Chan] = Enable; + MSG_VGALogEnabled[Chan] = Enable; + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGenGetLogEnabled ( SInt8 Chan ) { + return (MSG_VGALogEnabled[Chan]); +} + + +SInt32 MSG_FGenSetLogFilePath ( SInt8 Chan, char* LogFilePath ) { + sprintf ( MSG_VGALogPath[Chan], "%s", LogFilePath ); + return (0); +} + +char* MSG_FGenGetLogFilePath ( SInt8 Chan ) { + return ( MSG_VGALogPath[Chan] ); +} + +SInt32 MSG_FGenStopLog ( SInt8 Chan, SInt8 Stop ) { + MSG_VGADontLog[Chan] = Stop; + return (0); +} + + +SInt32 MSG_FGenBegin ( SInt8 Chan, SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( Chan, Enable ); + MSG_FGenSetLogFilePath ( Chan, FilePath ); + + return (0); +} + +SInt32 MSG_FBegin ( SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable ); + MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, FilePath ); + + return (0); +} + + +SInt32 MSG_FEnd () { + + return (0); +} + + +SInt32 MSG_FEnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt32 MSG_EnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt8 MSG_FGetLogEnabled () { + return ( MSG_FGenGetLogEnabled ( MSG_CHAN_MSG ) ); +} + +SInt32 MSG_FSetLogFilePath ( char* LogFilePath ) { + return ( MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, LogFilePath ) ); +} + +/* 11/06/2005 */ + +SInt32 MSG_FSetFileLogLevel ( SInt8 Level ) { + + MSG_VGFileLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_GSetFileLogLevel () { + return (MSG_VGFileLogLevel); +} + + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserLogLevel ( SInt8 Level ) { + + MSG_VGUserLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGetUserLogLevel () { + return (MSG_VGUserLogLevel); +} + +char* MSG_FGetLogFilePath ( void ) { + return ( MSG_FGenGetLogFilePath ( MSG_CHAN_MSG ) ); +} + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserMsgFunc ( TUserMsgFunc Func ) { + + MSG_VGUserMsgFunc = Func; + + return (0); +} + + +/* 07/04/2007 */ + +char* MSG_FGenGetMsgLogConfStr ( SInt8 Chan ) { + + static char VStr[MSG_CMT_SZ+1]; + + sprintf ( VStr, "Messages log configuration \n\n - Log enabled = %d \n - Stop log = %d \n - File log level = %d \n - Log file name = %s \n - User log level = %d \n\n ", MSG_VGALogEnabled[Chan], MSG_VGADontLog[Chan], MSG_VGFileLogLevel, MSG_VGALogPath[Chan], MSG_VGUserLogLevel ); + + return (VStr); +} + +/* 07/04/2007 */ + +char* MSG_FGetMsgLogConfStr () { + return ( MSG_FGenGetMsgLogConfStr (MSG_CHAN_MSG) ); +} + +SInt32 MSG_FGenMsg ( SInt8 Chan, SInt8 Level ) { + + static char VMsg[256 /* MSG_CMT_SZ include file not visble from ROOT => must be solved */]; + + if ( (MSG_VGFileLogLevel == 0) && (MSG_VGUserLogLevel == 0) ) { + return (0); + } + + sprintf ( VMsg, "MSG %.7d => %s \n", MSG_VGAMsgCnt[Chan]++, MSG_VGAStrMsg[Chan]); + + if ( (MSG_VGFileLogLevel != 0) && (MSG_VGFileLogLevel >= Level) ) { + + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + + // 29/10/2010 => Alway overwrite log file + + // if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + // MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + // } + + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "%s", VMsg ); + fflush ( MSG_VGALogFile[Chan] ); + } + + } /* End if ( Level >= MSG_VGFileLogLevel ) */ + + if ( (MSG_VGUserLogLevel != 0) && (MSG_VGUserLogLevel >= Level) ) { + + if ( MSG_VGUserMsgFunc != NULL ) { + MSG_VGUserMsgFunc ( VMsg ); + } + + } /* End if ( Level >= MSG_VGUserLogLevel ) */ + + + return (0); + +/* + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + } + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "MSG %.4d =>", MSG_VGAMsgCnt[Chan]++ ); + fprintf ( MSG_VGALogFile[Chan], MSG_VGAStrMsg[Chan] ); + fprintf ( MSG_VGALogFile[Chan], "\n" ); + fflush ( MSG_VGALogFile[Chan] ); + } + + return (0); + +*/ + +} + + +#endif + diff --git a/include/pxi_daq_lib_v.1.1/msg.def b/include/pxi_daq_lib_v.1.1/msg.def new file mode 100755 index 0000000..c709cc1 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/msg.def @@ -0,0 +1,63 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.def +Goal : Macros definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_DEF +#define MSG_DEF + + + +#define MSG_CMT_SZ 1024 + +#define MSG_CHAN_NB 2 +#define MSG_CHAN_MSG 0 +#define MSG_CHAN_RMSG 1 + + +/* Must be after variables definition, instead CINT will be unable to handle these macros */ + +#define MSG_VGLogFile MSG_VGALogFile[MSG_CHAN_MSG] +#define MSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_MSG] +#define MSG_VGDontLog MSG_VGADontLog[MSG_CHAN_MSG] +#define MSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_MSG] +#define MSG_VGLogPath MSG_VGALogPath[MSG_CHAN_MSG] + +#define RMSG_VGLogFile MSG_VGALogFile[MSG_CHAN_RMSG] +#define RMSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_RMSG] +#define RMSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_RMSG] +#define RMSG_VGLogPath MSG_VGALogPath[MSG_CHAN_RMSG] + +/* 07/04/2007 MSG_VGAStrMsg identifier replaced by MSG_OUT because of ROOT CINT macros limitations */ +/* #define MSG_OUT MSG_VGAStrMsg[MSG_CHAN_MSG] */ + +#define RMSG_OUT MSG_VGAStrMsg[MSG_CHAN_RMSG] + +#define MSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,127);} +#define msg(Msg) MSG_PRINTF(Msg) + +#define MSG_PRINTF_LVL(Msg,Lvl) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,Lvl); } +#define msgl(Msg,Lvl) MSG_PRINTF_LVL(Msg,Lvl) + + +#define RMSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_RMSG,127); } +#define msgr(Msg) RMSG_PRINTF(Msg) +#define rmsg(Msg) RMSG_PRINTF(Msg) + + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/msg.typ b/include/pxi_daq_lib_v.1.1/msg.typ new file mode 100755 index 0000000..0f62f1d --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/msg.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.typ +Goal : Types definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef MSG_TYP +#define MSG_TYP + +typedef SInt32 (*TUserMsgFunc) ( char* Msg ); + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/msg.var b/include/pxi_daq_lib_v.1.1/msg.var new file mode 100755 index 0000000..2e8fc8b --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/msg.var @@ -0,0 +1,59 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.var +Goal : Variables definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_VAR +#define MSG_VAR + +/* + +EXTERN VAR_STATIC FILE* MSG_VGALogFile[MSG_CHAN_NB] VAR_INIT_A2(NULL,NULL); +EXTERN VAR_STATIC SInt8 MSG_VGALogClosed[MSG_CHAN_NB] VAR_INIT_A2(1,1); +EXTERN VAR_STATIC SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt8 MSG_VGADontLog[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ] VAR_INIT_A2("/dd/tmp/pc/msg.txt","/dev/rmsg"); +EXTERN VAR_STATIC char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ]; +EXTERN VAR_STATIC SInt8 MSG_VGFileLogLevel VAR_INIT (0); +EXTERN VAR_STATIC SInt8 MSG_VGUserLogLevel VAR_INIT (0); +EXTERN VAR_STATIC TUserMsgFunc MSG_VGUserMsgFunc VAR_INIT (NULL); + +*/ + +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, FILE* MSG_VGALogFile[MSG_CHAN_NB] , NULL, NULL ); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogClosed[MSG_CHAN_NB] , 1, 1); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGADontLog[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ], "/dd/tmp/pc/msg.txt","/dev/rmsg" ); + + +VAR_DCL ( EXTERN, VAR_STATIC, char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ] ); + +/* 07/04/2007 Replace macro MSG_OUT by a variable which points to MSG_VGAStrMsg[MSG_CHAN_MSG] because of ROOT CINT macros limitations */ + + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char* MSG_OUT , MSG_VGAStrMsg[MSG_CHAN_MSG] ); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGFileLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGUserLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, TUserMsgFunc MSG_VGUserMsgFunc , NULL); + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.1/pxi_daq_lib_v.1.1.c b/include/pxi_daq_lib_v.1.1/pxi_daq_lib_v.1.1.c new file mode 100755 index 0000000..71f2b4c --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/pxi_daq_lib_v.1.1.c @@ -0,0 +1,758 @@ +// -------------------------------------------------------------------------------------- +// Includes required by DAQ library +// imported directly from Gilles Claus +// all the .def, .typ, .var or .c files are located in the include dir +// JB 2011/03/14 +// Modified: JB 2011/06/30 APP__FLoadRun + +#define _FILE_OFFSET_BITS 64 // Mandatory for large files ( > 2 GB ) handling +// MUST be set before standard C header files + +#include +#include +#include // types +#include +#include + +/* ========================================= */ +/* Conditional compilation for DAQ sources */ +/* ========================================= */ + +#define ROOT_ROOT // Disable code parts which can't compile under ROOT +#define CC_UNIX // Specify operating system + +/* ========================================= */ +/* DAQ commun files -> types & constants */ +/* ========================================= */ + + +#include "globals.def" +#include "globals_root.def" +#include "types.typ" + +/* ================================================================ */ +/* Definition of WIndows types & constant not available under Linux */ +/* ---------------------------------------------------------------- */ +/* Work like this now = allow to compile program, but should be */ +/* done in a better way later !!!!!!!!! */ +/* ================================================================ */ + +#define HANDLE UInt32 +#define DWORD UInt32 +#define WINAPI +#define LPVOID void* +#define INVALID_HANDLE_VALUE 0xFFFFFFFF + + +/* ========================================= */ +/* Macros needed to compile DAQ sources */ +/* ========================================= */ + +#define EXTERN +#define VAR_STATIC +#define VAR_INIT(x) =x +#define VAR_INIT_A2(x,y) ={x,y} +#define VAR_DCL(Extern,Static,Var) Extern Static Var +#define VAR_DCL_INIT(Extern,Static,Var,Init) Extern Static Var VAR_INIT (Init) +#define VAR_DCL_INIT_A2(Extern,Static,Var,Init0,Init1) Extern Static Var VAR_INIT_A2 (Init0,Init1) + + +/* ========================================= */ +/* Includes DAQ source files */ +/* ========================================= */ + +// Errors messages logging library interface + +#include "errors.def" +#include "errors.typ" +#include "errors.var" + +// General messages logging library interface + +#include "msg.def" +#include "msg.typ" +#include "msg.var" + +// ASIC library interface + +#include "asic.def" +#include "asic.typ" +#include "asic.var" + +// MAPS library interface + +#include "maps.def" +#include "maps.typ" +#include "maps.var" + +// Time library interface + +#include "time.def" +#include "time.typ" +#include "time.var" + +// Files library interface + +#include "files.def" +#include "files.typ" +#include "files.var" + +// Mimosa 26 library interface + +#include "mi26_usr.def" +#include "mi26_usr.typ" + +// Eudet flex rio DAQ library interface + +#include "eudet_frio.def" +#include "eudet_frio.typ" +#include "eudet_frio.var" + + +// Libraries C source files + +#include "errors.c" +#include "msg.c" +#include "time.c" +#include "files.c" + +#include "eudet_frio_print.c" + + + +/* ========================== */ +/* Application constants */ +/* ========================== */ + +#define APP_ERR_LOG_FILE "./Results/errors.txt" +#define APP_MSG_LOG_FILE "./Results/msg.txt" + +/* ========================== */ +/* Application macros */ +/* ========================== */ + +#define APP__READ_CR { while ( getchar () != '\n' ); }; + +/* ============================= */ +/* Application context type */ +/* ============================= */ + + +typedef struct { + + // Parameters + + char ParRunDir[GLB_FILE_PATH_SZ]; // Run directory + char ParFileNamePrefix[20]; // Run file prefix, eg : RUN_666 => RUN_ is the prefix + SInt32 ParRunNo; + + SInt32 ParFrameNbPerAcq; // Nb of frame in the acquisition ( get from run file ) + SInt32 ParAcqNo; // Index of acquisition to select ( get from GUI ) + SInt32 ParFrameNo; // Index of frame to get + + // Intermediate variables + + char InfRunParFile[GLB_FILE_PATH_SZ]; // File which contains run parameters *.par + char InfRunDataFile[GLB_FILE_PATH_SZ]; // File which contains run data *.bin + SInt32 InfMaxFrameSz; // Maximal size of one frame = total size for N Mimosa 26 + + // Results + + SInt8 ResRunLoaded; // Flag indicates run state : -1 not loaded, +1 loaded + + EFRIO__TRunCont ResRunCont; // Run context record = run parameter + additional info + // Loaded from file RUN*.par + + EFRIO__TFrameList ResFramesList; // List of frames + +} APP__TContext; + +/* ============================= */ +/* Application global variables */ +/* ============================= */ + + +// Error messages logging level ( file errors.txt ) , can be +// - ERR_LOG_LVL_NONE +// - ERR_LOG_LVL_ALL +// - ERR_LOG_LVL_WARNINGS_ERRORS +// - ERR_LOG_LVL_ERRORS + + +SInt32 APP_VGErrFileLogLvl = ERR_LOG_LVL_ALL; // Log level for log file +SInt32 APP_VGErrUserLogLvl = ERR_LOG_LVL_ALL; // Log level for user print function => not used + +// General messages logging level ( file msg.txt ), 127 => log all messages + +SInt32 APP_VGMsgFileLogLvl = 127; // Log level for log file +SInt32 APP_VGMsgUserLogLvl = 127; // Log level for user print function => not used + +// Class to read run file +// - APP__VGRunConfFile for run conf file = RUN*.par +// - APP__VGRunDataFile for run data file = RUN*.bin (data) and RUN*.bin.inf (index file) + +FIL__TCBinFile APP__VGRunConfFile ( "./err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); +FIL__TCStreamFile APP__VGRunDataFile ( "./err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); + + +// Application context record +// - Contains all global variables needed => easier to move to an object +// - Should also include errors and messages log variables ( APP_VGErrFileLogLvl, etc ... ), not done now + +APP__TContext APP__VGContext; // generic pointer to the DAQ information +//APP__TContext* VPtCont = &APP__VGContext; + +SInt32 VAcqNo; // current acquisition number +SInt32 VFrNo; // current frame number +EFRIO__TFrame* VPtFrame; // pointer to the current frame + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : + : + Inputs : + : + Ouputs : + : + Globals : + : + Remark : + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FIsLittleEndian () + : + Goal : Test is CPU is little endian, return 1 in this case, 0 otherwise. + : + Inputs : None + : + Ouputs : The function returns + : 0 - CPU is not little endian + : 1 - CPU is little endian + : + Globals : None + : + Remark : One + : + Level : + Date : 19/02/2011 + Doc date : 19/02/2011 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FIsLittleEndian () { + + SInt32 VTest = 0x11223344; + char* VPt; + + VPt = (char*) &VTest; + + if ( (VPt[0] == 0x11) && (VPt[1] == 0x22) && (VPt[2] == 0x33) && (VPt[3] == 0x44) ) { + return (0); + } + + else { + return (1); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : + : + Inputs : + : + Ouputs : + : + Globals : + : + Remark : + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FPrintRecSzChkAlign ( char* Os ) { + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "= Print records size for alignment checking Windows / Unix =" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "= System = %s ", Os )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "" )); + + msg (( MSG_OUT, "FIL__TCStreamFile_TBlocInf = %d ", sizeof (FIL__TCStreamFile_TBlocInf) )); + msg (( MSG_OUT, "FIL__TCStreamFile_TRecInfFile = %d ", sizeof (FIL__TCStreamFile_TRecInfFile) )); + msg (( MSG_OUT, "EFRIO__TRunCont = %d ", sizeof (EFRIO__TRunCont) )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EFRIO__TFrame = %d ", sizeof (EFRIO__TFrame) )); + msg (( MSG_OUT, "EFRIO__TFrameHeader = %d ", sizeof (EFRIO__TFrameHeader) )); + msg (( MSG_OUT, "EFRIO__TFrameData = %d ", sizeof (EFRIO__TFrameData) )); + msg (( MSG_OUT, "EFRIO__TTriggerRec = %d ", sizeof (EFRIO__TTriggerRec) )); + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) + : + Goal : Load a run file = configure lib for this run but the run is not loaded + : in memory. + : + Inputs : RunDir - Run directory without \ at end + : RunPrefix - Run file prefix, eg : "RUN_" + : RunNo - Run no + : + Ouputs : The function returns + : Number of acquisitions in run file + : -1 if an error occurs + : + Globals : Update APP__VGContext fields + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : 19/02/2011 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqNb; + SInt32 VRet=0; // init necessary, JB 2011/06/30 + + + // ----------------------------- + // Reset run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = -1; + + // ----------------------------- + // Set run parameters + // ----------------------------- + + sprintf ( VPtCont->ParRunDir , "%s", RunDir ); + sprintf ( VPtCont->ParFileNamePrefix, "%s", RunPrefix ); + + VPtCont->ParRunNo = RunNo; + + // Calculate run par file & run data file names + + sprintf ( VPtCont->InfRunDataFile, "%s/%s%d.bin", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + sprintf ( VPtCont->InfRunParFile , "%s/%s%d.par", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + + // Print run par file & run data file names for debugging + + msg (( MSG_OUT, "Run data file name = %s", VPtCont->InfRunDataFile )); + msg (( MSG_OUT, "Run par file name = %s", VPtCont->InfRunParFile )); + + + // ----------------------------- + // Read run param file + // ----------------------------- + + // Init & conf TCBinFile class to do the job + + //printf("pxi_daq: Opening .par file %s with RWBmode %d, MaxBlocSz %d, BlocSz %d\n", VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont)); + + // Fix to adapt the structure size from 32 to 64 bits machine + // Data are taken on a 32 bits processor with sizeof (EFRIO__TRunCont) = 1372 + // However on 64 bits processor, sizeof (EFRIO__TRunCont) = 1384 + // JB 2012/03/08 + SInt32 sizeof_EFRIO__TRunCont = 1372; + + VRet = VRet | APP__VGRunConfFile.PubFConf ( VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof_EFRIO__TRunCont, sizeof_EFRIO__TRunCont, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunConfFile.PubFOpen (); + VRet = VRet | APP__VGRunConfFile.PubFSeqRead ( &VPtCont->ResRunCont, sizeof_EFRIO__TRunCont, sizeof_EFRIO__TRunCont ); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Load run parameter file = %s failed !", VPtCont->InfRunParFile ) ); + + // ----------------------------- + // Open run data file + // ----------------------------- + + // Init & conf TCStreamFile class to do the job + + VRet = VRet | APP__VGRunDataFile.PubFConf ( &APP__VGRunDataFile, 0 /* UseThread */, VPtCont->InfRunDataFile, FIL__TCBinFile_RWB_MODE_READ, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunDataFile.PubFOpen (); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Open run data file %s failed !", VPtCont->InfRunDataFile ) ); + + + // ----------------------------- + // Set run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = 1; + + // ----------------------------- + // Return number of acq in file + // ----------------------------- + + VAcqNb = APP__VGRunDataFile.PubFGetBlocNb (); + + err_retval ( VAcqNb, ( ERR_OUT, "Run %d loaded => Contains %d acquistions", RunNo, VAcqNb ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FAllocAcqBuffer ( ) + : + Goal : Allocates the buffer for one acqusition. + : + Inputs : None + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read informations from APP__VGContext and set pointer to buffer. + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FAllocAcqBuffer () { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + + // ---------------------- + // Calculates sizes + // ---------------------- + + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + VPtCont->ResRunCont.InfFrameBuffSz = VPtCont->ResRunCont.ParFrameNbPerAcq * VPtCont->InfMaxFrameSz; + + // ---------------------- + // Print results + // ---------------------- + + msg (( MSG_OUT, "==========================================" )); + msg (( MSG_OUT, "InfMaxFrameSz = %d", VPtCont->InfMaxFrameSz )); + msg (( MSG_OUT, "ResRunCont.InfFrameBuffSz = %d", VPtCont->ResRunCont.InfFrameBuffSz )); + msg (( MSG_OUT, "==========================================" )); + + // ---------------------- + // Allocate acq buffer + // ---------------------- + + // Free if already allocated + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + } + + // Try to allocate + + VPtCont->ResRunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->ResRunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->ResRunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->ResRunCont.ParFrameNbPerAcq) ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FFreeAcqBuffer () + : + Goal : Free acquisition buffer + : + Inputs : None + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read informations from APP__VGContext and set buffer pointer to NULL. + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FFreeAcqBuffer ( ) { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Free buffer + // ------------------------------- + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + VPtCont->ResRunCont.PtFrame = NULL; + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : + Goal : Build the frame list for one acquisition + : + Inputs : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : + : + Remark : This function is the copy of EFRIO__FBuildFrameListFromAcq for application + : program demo. + : + : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : + Level : + Date : 06/11/2010 + Rev : 19/02/2011 + : - Moved from eudet_fio.c + : + Doc date : 07/11/2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) + : + Goal : Load AcqNo in memory + : + Inputs : AcqNo - No of acquisition to load + : PtFrameNb - Pointer to a variable which will be set with frames nb in AcqNo + : - Set it to NULL if you don't need it + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read information from APP__VGContext. + : + Remark : None. + : + Level : + Date : 19/02/2011 + Rev : 07/03/2011 + : - New " spare W32 info " format + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqInfFormat; + EFRIO__TFileSpareW32Info VAcqInf; + SInt32 VRet; + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + // ----------------------------------- + // Load acquisition in memory + // ----------------------------------- + + // Load from run file + + // Before 07/03/2011 + // VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VFrameNb ); + + VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VAcqInfFormat, sizeof (VAcqInf) / 4 /* MaxSpareW32InfoNb */, (SInt32*) &VAcqInf ); + + err_retfail ( VRet, (ERR_OUT, "Goto acquisition No %d failed !", AcqNo ) ); + + // Build frame list = array of pointer to access frames one by one + + VRet = APP__FBuildFrameListFromAcq ( VAcqInf.TotFrameNb, VPtCont->ResRunCont.PtFrame, &VPtCont->ResFramesList ); + + err_retfail ( VRet, (ERR_OUT,"Build frames list for acquisition No %d failed !", AcqNo ) ); + + // ----------------------------------- + // Update frame nb parameter + // ----------------------------------- + + if ( PtFrameNb != NULL ) { + *PtFrameNb = VAcqInf.TotFrameNb; + } + + err_retok (( ERR_OUT, "Acquisiton No %d loaded in memory - Contains %d frames", AcqNo, VAcqInf.TotFrameNb )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) + : + Goal : Return a pointer to one frame of the acquisition which is loaded in memory. + : + Inputs : FrameIdInAcq - The no of the frame + : + Ouputs : The function returns + : A valid pointer to the frame + : A NULL pointer if the operation failed + : + Globals : Read information from APP__VGContext. + : + Remark : None + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) { + + APP__TContext* VPtCont = &APP__VGContext; + EFRIO__TRunCont* VPtRunCont = &VPtCont->ResRunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->ResFramesList; + + + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"No frame=%d in list => Pointer NULL", FrameIdInAcq) ); + } + + return ( VPtFrList->AFramePtr[FrameIdInAcq] ); +} + diff --git a/include/pxi_daq_lib_v.1.1/sync_index_rec.c b/include/pxi_daq_lib_v.1.1/sync_index_rec.c new file mode 100755 index 0000000..9ae3f53 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/sync_index_rec.c @@ -0,0 +1,163 @@ +/******************************************************************************* +File : sync_index_rec.c +Goal : Functions to synchronized two DAQ files +Prj date : 18/07/2012 +File date : 18/07/2012 +Doc date : 18/07/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef SYNC_INDEX_REC_C +#define SYNC_INDEX_REC_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Return file size or negative value upon failure. + Author : Gilles CLAUS +*/ + /* =================================================================================== */ +/* DOC_FUNC_END */ +int GetFileSize ( char* FilePath ) { + + FILE* VPf; + int VFileSz = 0; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + printf( "GetFileSize: fopen fail !\n" ); + return -1; + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + printf( "GetFileSize: fseek SEEK_SET fail !\n" ); + return -1; + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + printf( "GetFileSize: fseek SEEK_END fail !\n" ); + return -1; + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + printf( "GetFileSize: ftell fail !" ); + return -1; + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + printf( "GetFileSize: fseek SEEK_SET fail !"); + return -1; + } + + if ( fclose (VPf) != 0 ) { + printf( "GetFileSize: fclose fail !" ); + return -1; + } + + return VFileSz; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : Read the file containing the synchronization information + : between two boards, each with its data file. + : For instance a board reading binary sensors + : and another board reading analog sensors. + : + Inputs : + : + : + Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : + Globals : None + : + Remark : None + : + Level : This is a user level function. + Date : 10/07/2012 + Doc date : + Modif : + Author : Gilles CLAUS + E-mail : claus@lepsi.in2p3.fr + Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +int GetSyncPointer ( char* FilePath, unsigned char* PtDest, int DestSz ) { + + int VRet; + FILE* VPfDest; + int VFileSz; + + + // Check param + + if( PtDest==NULL ) { + printf( "GetSyncPointer: PtDest == NULL !\n"); + return -1; + } + + // Measure file size + + VFileSz = GetFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + printf( "GetSyncPointer: Buffer size=%d < File size=%d.\n", DestSz, VFileSz ); + return -1; + } + + printf( "GetSyncPointer: TRACE => FileSize=%d\n", VFileSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + if( VPfDest == NULL ) { + printf( "GetSyncPointer: Source file %s open failed.\n", FilePath ); + return -1; + } + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + printf("SYNC Version is %d\n", ((APP__TSyncIndexRec*)PtDest)->Version); + + if ( VRet != 1 ) { + printf( "GetSyncPointer: Error reading source file %s.\n", FilePath ); + return -1; + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + printf( "GetSyncPointer: Error fclose source file %s.\n", FilePath ); + return -1; + } + + + // Return record nb + + return ( VFileSz / sizeof (APP__TSyncIndexRec) ); + +} + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.1.1/sync_index_rec.typ b/include/pxi_daq_lib_v.1.1/sync_index_rec.typ new file mode 100755 index 0000000..bd3bcd8 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/sync_index_rec.typ @@ -0,0 +1,57 @@ +/* ============== */ +/* 10/07/2012 */ +/* -------------- */ +/* Doc 18/07/2012 */ +/* ============== */ + +#ifndef SYNC_INDEX_REC_TYP +#define SYNC_INDEX_REC_TYP + +#define CC_UNIX // Specify operating system +#include "types.typ" + +typedef struct { + + // The fields needed to synchronize DUT & Telescope run are marked with a * + // The other fields are extra information, which may be use to make cross-check + + UInt32 Version; // Record version + + // DUT events information + + UInt32 DutEvId; // * Event identifier from 0 to NbMaxEventsInRun - 1 + UInt32 DutEvTag; // Event tag = Mi26 sync signal pulses count = Mi26 frames counter + UInt32 DutTrigLine; // Line read by DAQ when trigger has occurred + UInt32 DutTrigFrame; // Frame read by DAQ when trigger has occurred + UInt32 DutTrigNbTot; // Total number of triggers seen by DAQ since beginning of run + UInt32 DutTrigNbAccepted; // Number of triggers accepted by DAQ since beginning of run = number of events taken by DAQ + UInt32 DutSpareU32; // Reserved + + // Telescope information + + UInt32 TelBegEvFrId; // * First frame corresponding to DUT event + + // Frame which contains trigger info + // + UInt32 TelTrigFrId; // Frame id since begining of run => 0 .. NbMaxFramesInRun - 1 + UInt32 TelTrigAcqId; // Acquisition id since begining of run + UInt32 TelTrigFrIdInAcq; // Frame id in current acquisition => 0 .. NbMaxFramesPerAcq + UInt32 TelTrigEvTag; // Event tag = Mi26 frames counter + + // Three first triggers of the frame (TelTrigFrId) + // Unit is Mi26 clock TS => divide by 16 to get trigger line + // + UInt32 TelTrig0; // First trigger + UInt32 TelTrig1; // Second trigger + UInt32 TelTrig2; // Third trigger + + UInt32 TelFrTrigNb; // Total number of trigger of the frame (TelTrigFrId) + + UInt32 TelTrigSpareU32; // Reserved + + UInt32 TelEndEvFrId; // * Last frame corresponding to DUT event + +} APP__TSyncIndexRec; + +#endif + diff --git a/include/pxi_daq_lib_v.1.1/time.c b/include/pxi_daq_lib_v.1.1/time.c new file mode 100755 index 0000000..1e98424 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/time.c @@ -0,0 +1,623 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.c +Goal : Functions of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_C +#define TIME_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateL TIME_FConvDateS2DateL ( TIME__TUDateS DateS ) { + + TIME__TUDateL VDateL; + + VDateL.Date.Day = DateS.Date.Day; + VDateL.Date.Month = DateS.Date.Month; + VDateL.Date.Year = 2000 + DateS.Date.Year; + + return (VDateL); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateS TIME_FConvDateL2DateS ( TIME__TUDateL DateL ) { + + TIME__TUDateS VDateS; + + VDateS.Date.Day = DateL.Date.Day; + VDateS.Date.Month = DateL.Date.Month; + VDateS.Date.Year = DateL.Date.Year % 2000; + + return (VDateS); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 23/05/2010 +Doc date : 23/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateS2Str ( TIME__TUDateS Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.2d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( UInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( SInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = (UInt32) Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ + : +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FDateL2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2Str ( TIME__TUDateL Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.4d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 06/03/2010 +Doc date : 06/03/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2StrExt ( TIME__TUDateL Date, char SepChar, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d%c%.2d%c%.4d", Date.Date.Day, SepChar, Date.Date.Month, SepChar, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FConvDateTime2DateL ( TDateTime Src ) { + + TIME__TUDateL VDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + Src.DecodeDate ( &VYear, &VMonth, &VDay ); + + VDate.Date.Year = VYear; + VDate.Date.Month = VMonth; + VDate.Date.Day = VDay; + + return (VDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FGetDateLOfNextDay ( TIME__TUDateL Cur ) { + + TDateTime VCurDate ( Cur.Date.Year, Cur.Date.Month, Cur.Date.Day ); + TIME__TUDateL VNextDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + ++VCurDate; + + VCurDate.DecodeDate ( &VYear, &VMonth, &VDay ); + + VNextDate.Date.Year = VYear; + VNextDate.Date.Month = VMonth; + VNextDate.Date.Day = VDay; + + return (VNextDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +WARNING : If return pointer to list is used, a copy of LIST ( not pointer ) must be done + : after each TIME__FFillListDatesLOfWeek () call otherwise the list content will be + : the one of last call because all pointers will point to last list stored in local + : variable of function. + : + : +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef ROOT_ROOT + +TIME__TListDatesLOfWeek* TIME__FFillListDatesLOfWeek ( TIME__TUDateL MondayDate, TIME__TListDatesLOfWeek* PtList ) { + + static TIME__TListDatesLOfWeek VList; + TIME__TUDateL VDayDate; + SInt8 ViDay; + + + VDayDate = MondayDate; + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + VList.ADates[ViDay] = VDayDate; + VDayDate = TIME__FGetDateLOfNextDay ( VDayDate ); + } + + if ( PtList != NULL ) { + *PtList = VList; + } + + return (&VList); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 TIME__FPrintListDatesLOfWeek ( TIME__TListDatesLOfWeek* PtList ) { + + SInt8 ViDay; + + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + msg (( MSG_OUT, "Date : %s", TIME__FDateL2Str ( PtList->ADates[ViDay], NULL /* PtDestStr */, 0 /* DestStrSz */ ) )); + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +WARNING : A copy of return STRING ( not pointer ) must be done after each TIME_FGetDayName call + : otherwise the string content will be the one of last call because all pointers will + : point to last string stored in local variable of function. +: +Level : +Date : 27/02/2010 +Doc date : 27/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME_FGetDayName ( UInt8 DayIndex, SInt8 Language ) { + + static char* VAStrDayNameFr[8] = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche" }; + static char* VAStrDayNameEn[8] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + + if ( DayIndex > 7 ) { + err_error (( ERR_OUT, "Bad day index = %d out of rnage 0..7", DayIndex )); + return ( "?" ); + } + + switch ( Language ) { + + case TIME__LANG_FRENCH : { + return ( VAStrDayNameFr[DayIndex] ); + break; } + + case TIME__LANG_ENGLISH : { + return ( VAStrDayNameEn[DayIndex] ); + break; } + + + default : { + err_error (( ERR_OUT, "Bad language = %d out of range", Language )); + return ( "?"); + } + + } + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUTime TIME__FConvDateTime2Time ( TDateTime Src ) { + + TIME__TUTime VTime; + unsigned short VHour; + unsigned short VMin; + unsigned short VSec; + unsigned short VMSec; + + Src.DecodeTime ( &VHour, &VMin, &VSec, &VMSec ); + + VTime.Time.Hour = VHour; + VTime.Time.Min = VMin; + VTime.Time.Sec = VSec; + VTime.Time.Cent = VMSec / 10; + + return (VTime); +} + +#endif + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FTime2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FTime2Str ( TIME__TUTime Time, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrTime[TIME__STR_TIME_SZ]; + + sprintf ( VStrTime, "%.2d:%.2d:%.2d|%.2d", Time.Time.Hour, Time.Time.Min, Time.Time.Sec, Time.Time.Cent ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_TIME_SZ) ) { + sprintf ( PtDestStr, "%s", VStrTime ); + } + + return (VStrTime); +} + + +// 23/05/2010 + +char* TIME__FTime2Str ( UInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + +// 23/05/2010 + +char* TIME__FTime2Str ( SInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = (UInt32) Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +#endif + diff --git a/include/pxi_daq_lib_v.1.1/time.def b/include/pxi_daq_lib_v.1.1/time.def new file mode 100755 index 0000000..a4ec9f1 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/time.def @@ -0,0 +1,40 @@ + + +/******************************************************************************* +File : x:\lib\com\time\time.def +Goal : Macros definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_DEF +#define TIME_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define TIME__STR_DATE_SZ 11 +#define TIME__STR_TIME_SZ 11 + +#define TIME__LANG_FRENCH 0 +#define TIME__LANG_ENGLISH 1 + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/time.typ b/include/pxi_daq_lib_v.1.1/time.typ new file mode 100755 index 0000000..3d88f0e --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/time.typ @@ -0,0 +1,140 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.typ +Goal : Types definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_TYP +#define TIME_TYP + + +/* =========================== */ +/* Date S => Short date format */ +/* Eg : 01/01/10 */ +/* =========================== */ + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aa in W32 + // B31B24 B23B16 B15B08 B07B00 + // 00 Day Month Year + + SInt8 Year; + SInt8 Month; + SInt8 Day; + SInt8 NotUsed; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateS; + + +typedef union { + + UInt32 W32; + + TIME__TSDateS Date; + +} TIME__TUDateS; + + + +/* ========================== */ +/* Date L => Long date format */ +/* Eg : 01/01/2010 */ +/* ========================== */ + + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aaaa in W32 + // B31B24 B23B16 B15B00 + // Day Month Year + + SInt16 Year; + SInt8 Month; + SInt8 Day; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateL; + + +typedef union { + + UInt32 W32; + + TIME__TSDateL Date; + +} TIME__TUDateL; + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + TIME__TUDateL ADates[7]; + +} TIME__TListDatesLOfWeek; + + +/* =============================== */ +/* Time : Hour - Min - Sec - 1/100 */ +/* Eg : 21/05/2010 */ +/* =============================== */ + + +typedef struct { + + // Fields order MUST be Hour - Min - Sec - 1/100 -> Don't modify it + // B31B24 B23B16 B15B08 B07B00 + // Hour Min Sec Cent + + SInt8 Cent; + SInt8 Sec; + SInt8 Min; + SInt8 Hour; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSTime; + + +typedef union { + + UInt32 W32; + + TIME__TSTime Time; + +} TIME__TUTime; + + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/time.var b/include/pxi_daq_lib_v.1.1/time.var new file mode 100755 index 0000000..3b0fee6 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/time.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.var +Goal : Variables definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_VAR +#define TIME_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN SInt8 TIME_VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.1/types.typ b/include/pxi_daq_lib_v.1.1/types.typ new file mode 100755 index 0000000..6945d52 --- /dev/null +++ b/include/pxi_daq_lib_v.1.1/types.typ @@ -0,0 +1,167 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.typ +Goal : Common basic types definitions. + : I never use default C types names ( char, int ... ) + : i redefined them here ( SInt8, UInt32 ... ). + : + : If something go wong on you'r plateform with C types + : definition you need to update this file. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + +#include "stdint.h" // added, JB 2013/02/11 + +/*H**************************************************************************** +FILE : Types.Typ +BUT : Define types. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_TYP +#define TYPES_TYP + + // typedef enum ELang { ELang_FRENCH, ELang_ENGLISH, ELang_GERMAN, ELang_LANG_NB } TLang; + +#ifndef NODEFTYPCHAR + +/* +17/11/04 GC + +BCPPB declares an identfier with the same name " Char " +this problem happens while compiling Mimo* JTAG application (MP). +This Char identifier is used in SpinEdit object. + +MP used conditionnal compilation, i decided to remove this Char +type definition, because i believe i never use it. +Wait and see ... + +*/ + +/* typedef unsigned char Char; */ + +#endif + +#ifndef UInt8 + typedef unsigned char UInt8; +#endif + +#ifndef UByte + typedef UInt8 UByte; +#endif + +#ifndef SInt8 + typedef char SInt8; +#endif + +#ifndef SByte + typedef SInt8 SByte; +#endif + +#ifndef UInt16 + typedef unsigned short UInt16; +#endif + +#ifndef UWord + typedef UInt16 UWord; +#endif + +#ifndef SInt16 + typedef short SInt16; +#endif + +#ifndef SWord + typedef SInt16 SWord; +#endif + +#ifndef UInt32 + //typedef unsigned long int UInt32; + typedef unsigned int UInt32; // correction for 64bits, JB 2011/10/28 +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + //typedef long int SInt32; + typedef int SInt32; // correction for 64bits, JB 2011/10/28 +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif + + +#ifdef CC_UNIX + +#ifndef UInt64 + typedef int64_t UInt64; +#endif + +#ifndef SInt64 + typedef uint64_t SInt64; +#endif + +#else + +#ifndef UInt64 + typedef unsigned __int64 UInt64; +#endif + +#ifndef SInt64 + typedef __int64 SInt64; +#endif + + +#endif + + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/asic.def b/include/pxi_daq_lib_v.1.2/asic.def new file mode 100755 index 0000000..a191e22 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/asic.def @@ -0,0 +1,92 @@ + + +/******************************************************************************* +File : x:\lib\com\asic\asic.def +Goal : Macros definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_DEF +#define ASIC_DEF + + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef enum { + + ASIC__NONE, + ASIC__MI26, + ASIC__ULT1 + +} ASIC__TEAsicName; + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__MI26_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__MI26_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__MI26_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__MI26_TRIG_TOT_NB // Total number of triggers + +} ASIC__MI26_TETrigRes; + + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__ULT1_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__ULT1_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__ULT1_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__ULT1_TRIG_TOT_NB // Total number of triggers + +} ASIC__ULT1_TETrigRes; + + +#define ASIC__ENUM_TRIG_RES_NB 4 + + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/asic.typ b/include/pxi_daq_lib_v.1.2/asic.typ new file mode 100755 index 0000000..51d7703 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/asic.typ @@ -0,0 +1,51 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.typ +Goal : Types definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_TYP +#define ASIC_TYP + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + SInt8 AsicNo; // Index of Asic <0..N-1> in case more than one is acquired + SInt32 AcqNo; // Index of current acquisition + SInt32 FrameNoInAcq; // Index of frame in acquisition <0..AcqFrameNb-1> + SInt32 FrameNoInRun; // Index of frame in run <0..TotEventNb-1> + + SInt32 HitCnt; // Counter of hits in frame + // Used for monitoring, may be not set, therefore HitCnt = -1 + + + SInt32 ATrigRes[ASIC__ENUM_TRIG_RES_NB]; // Information about trigger, see ASIC__MI26_TETrigRes in asic.def + // Parameters list index is + // ASIC__MI26_TRIG_RES__SIG_LINE + // ASIC__MI26_TRIG_RES__SIG_CLK + // ASIC__MI26_TRIG_RES__LINE + // ASIC__MI26_TRIG_TOT_NB + +} ASIC__TFrameStatus; + + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/asic.var b/include/pxi_daq_lib_v.1.2/asic.var new file mode 100755 index 0000000..452512e --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/asic.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.var +Goal : Variables definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_VAR +#define ASIC_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN VAR_STATIC SInt8 ASIC__VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/daq_lib.c b/include/pxi_daq_lib_v.1.2/daq_lib.c new file mode 100644 index 0000000..de1654e --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/daq_lib.c @@ -0,0 +1,647 @@ +#include "daq_lib.h" + +#include "errors.c" +#include "msg.c" +#include "time.c" +#include "files.c" +#include "eudet_frio_print.c" + +/* ========================== */ +/* Application constants */ +/* ========================== */ + +#define APP_ERR_LOG_FILE "./Results/errors.txt" +#define APP_MSG_LOG_FILE "./Results/msg.txt" + +/* ========================== */ +/* Application macros */ +/* ========================== */ + +#define APP__READ_CR { while ( getchar () != '\n' ); }; + +/* ============================= */ +/* Application context type */ +/* ============================= */ + + +typedef struct { + + // Parameters + + char ParRunDir[GLB_FILE_PATH_SZ]; // Run directory + char ParFileNamePrefix[20]; // Run file prefix, eg : RUN_666 => RUN_ is the prefix + SInt32 ParRunNo; + + SInt32 ParFrameNbPerAcq; // Nb of frame in the acquisition ( get from run file ) + SInt32 ParAcqNo; // Index of acquisition to select ( get from GUI ) + SInt32 ParFrameNo; // Index of frame to get + + // Intermediate variables + + char InfRunParFile[GLB_FILE_PATH_SZ]; // File which contains run parameters *.par + char InfRunDataFile[GLB_FILE_PATH_SZ]; // File which contains run data *.bin + SInt32 InfMaxFrameSz; // Maximal size of one frame = total size for N Mimosa 26 + + // Results + + SInt8 ResRunLoaded; // Flag indicates run state : -1 not loaded, +1 loaded + + EFRIO__TRunCont ResRunCont; // Run context record = run parameter + additional info + // Loaded from file RUN*.par + + EFRIO__TFrameList ResFramesList; // List of frames + +} APP__TContext; + +/* ============================= */ +/* Application global variables */ +/* ============================= */ + + +// Error messages logging level ( file errors.txt ) , can be +// - ERR_LOG_LVL_NONE +// - ERR_LOG_LVL_ALL +// - ERR_LOG_LVL_WARNINGS_ERRORS +// - ERR_LOG_LVL_ERRORS + + +SInt32 APP_VGErrFileLogLvl = ERR_LOG_LVL_ALL; // Log level for log file +SInt32 APP_VGErrUserLogLvl = ERR_LOG_LVL_ALL; // Log level for user print function => not used + +// General messages logging level ( file msg.txt ), 127 => log all messages + +SInt32 APP_VGMsgFileLogLvl = 127; // Log level for log file +SInt32 APP_VGMsgUserLogLvl = 127; // Log level for user print function => not used + +// Class to read run file +// - APP__VGRunConfFile for run conf file = RUN*.par +// - APP__VGRunDataFile for run data file = RUN*.bin (data) and RUN*.bin.inf (index file) + +FIL__TCBinFile APP__VGRunConfFile ( (char*)"./err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); +FIL__TCStreamFile APP__VGRunDataFile ( (char*)"./err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); + + +// Application context record +// - Contains all global variables needed => easier to move to an object +// - Should also include errors and messages log variables ( APP_VGErrFileLogLvl, etc ... ), not done now + +APP__TContext APP__VGContext; // generic pointer to the DAQ information +//APP__TContext* VPtCont = &APP__VGContext; + +SInt32 VAcqNo; // current acquisition number +SInt32 VFrNo; // current frame number +EFRIO__TFrame* VPtFrame; // pointer to the current frame + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : + : + Inputs : + : + Ouputs : + : + Globals : + : + Remark : + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FIsLittleEndian () + : + Goal : Test is CPU is little endian, return 1 in this case, 0 otherwise. + : + Inputs : None + : + Ouputs : The function returns + : 0 - CPU is not little endian + : 1 - CPU is little endian + : + Globals : None + : + Remark : One + : + Level : + Date : 19/02/2011 + Doc date : 19/02/2011 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FIsLittleEndian () { + + SInt32 VTest = 0x11223344; + char* VPt; + + VPt = (char*) &VTest; + + if ( (VPt[0] == 0x11) && (VPt[1] == 0x22) && (VPt[2] == 0x33) && (VPt[3] == 0x44) ) { + return (0); + } + + else { + return (1); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : + : + Inputs : + : + Ouputs : + : + Globals : + : + Remark : + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FPrintRecSzChkAlign ( char* Os ) { + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "= Print records size for alignment checking Windows / Unix =" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "= System = %s ", Os )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "" )); + + msg (( MSG_OUT, "FIL__TCStreamFile_TBlocInf = %lu ", sizeof (FIL__TCStreamFile_TBlocInf) )); + msg (( MSG_OUT, "FIL__TCStreamFile_TRecInfFile = %lu ", sizeof (FIL__TCStreamFile_TRecInfFile) )); + msg (( MSG_OUT, "EFRIO__TRunCont = %lu ", sizeof (EFRIO__TRunCont) )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EFRIO__TFrame = %lu ", sizeof (EFRIO__TFrame) )); + msg (( MSG_OUT, "EFRIO__TFrameHeader = %lu ", sizeof (EFRIO__TFrameHeader) )); + msg (( MSG_OUT, "EFRIO__TFrameData = %lu ", sizeof (EFRIO__TFrameData) )); + msg (( MSG_OUT, "EFRIO__TTriggerRec = %lu ", sizeof (EFRIO__TTriggerRec) )); + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) + : + Goal : Load a run file = configure lib for this run but the run is not loaded + : in memory. + : + Inputs : RunDir - Run directory without \ at end + : RunPrefix - Run file prefix, eg : "RUN_" + : RunNo - Run no + : + Ouputs : The function returns + : Number of acquisitions in run file + : -1 if an error occurs + : + Globals : Update APP__VGContext fields + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : 19/02/2011 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqNb; + SInt32 VRet=0; // init necessary, JB 2011/06/30 + + + // ----------------------------- + // Reset run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = -1; + + // ----------------------------- + // Set run parameters + // ----------------------------- + + sprintf ( VPtCont->ParRunDir , "%s", RunDir ); + sprintf ( VPtCont->ParFileNamePrefix, "%s", RunPrefix ); + + VPtCont->ParRunNo = RunNo; + + // Calculate run par file & run data file names + + sprintf ( VPtCont->InfRunDataFile, "%s/%s%d.bin", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + sprintf ( VPtCont->InfRunParFile , "%s/%s%d.par", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + + // Print run par file & run data file names for debugging + + msg (( MSG_OUT, "Run data file name = %s", VPtCont->InfRunDataFile )); + msg (( MSG_OUT, "Run par file name = %s", VPtCont->InfRunParFile )); + + + // ----------------------------- + // Read run param file + // ----------------------------- + + // Init & conf TCBinFile class to do the job + + //printf("pxi_daq: Opening .par file %s with RWBmode %d, MaxBlocSz %d, BlocSz %d\n", VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont)); + + // Fix to adapt the structure size from 32 to 64 bits machine + // Data are taken on a 32 bits processor with sizeof (EFRIO__TRunCont) = 1372 + // However on 64 bits processor, sizeof (EFRIO__TRunCont) = 1384 + // JB 2012/03/08 + SInt32 sizeof_EFRIO__TRunCont = 1372; + //SInt32 sizeof_EFRIO__TRunCont = sizeof (EFRIO__TRunCont); + + VRet = VRet | APP__VGRunConfFile.PubFConf ( VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof_EFRIO__TRunCont, sizeof_EFRIO__TRunCont, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunConfFile.PubFOpen (); + VRet = VRet | APP__VGRunConfFile.PubFSeqRead ( &VPtCont->ResRunCont, sizeof_EFRIO__TRunCont, sizeof_EFRIO__TRunCont ); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Load run parameter file = %s failed !", VPtCont->InfRunParFile ) ); + + // ----------------------------- + // Open run data file + // ----------------------------- + + // Init & conf TCStreamFile class to do the job + + VRet = VRet | APP__VGRunDataFile.PubFConf ( &APP__VGRunDataFile, 0 /* UseThread */, VPtCont->InfRunDataFile, FIL__TCBinFile_RWB_MODE_READ, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunDataFile.PubFOpen (); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Open run data file %s failed !", VPtCont->InfRunDataFile ) ); + + + // ----------------------------- + // Set run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = 1; + + // ----------------------------- + // Return number of acq in file + // ----------------------------- + + VAcqNb = APP__VGRunDataFile.PubFGetBlocNb (); + + err_retval ( VAcqNb, ( ERR_OUT, "Run %d loaded => Contains %d acquistions", RunNo, VAcqNb ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FAllocAcqBuffer ( ) + : + Goal : Allocates the buffer for one acqusition. + : + Inputs : None + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read informations from APP__VGContext and set pointer to buffer. + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FAllocAcqBuffer () { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + + // ---------------------- + // Calculates sizes + // ---------------------- + + // MI26__ZS_FFRAME_RAW_MAX_W8 replaced by ULT1__ZS_FFRAME_RAW_MAX_W8, JB+GC 2014/02/07 + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + VPtCont->ResRunCont.InfFrameBuffSz = VPtCont->ResRunCont.ParFrameNbPerAcq * VPtCont->InfMaxFrameSz; + + // ---------------------- + // Print results + // ---------------------- + + msg (( MSG_OUT, "==========================================" )); + msg (( MSG_OUT, "InfMaxFrameSz = %d", VPtCont->InfMaxFrameSz )); + msg (( MSG_OUT, "ResRunCont.InfFrameBuffSz = %d", VPtCont->ResRunCont.InfFrameBuffSz )); + msg (( MSG_OUT, "==========================================" )); + + // ---------------------- + // Allocate acq buffer + // ---------------------- + + // Free if already allocated + // removed because provokes crash when other BoardReader used in combination + // SS 2012/08 + + //if ( VPtCont->ResRunCont.PtFrame != NULL ) { + // free ( VPtCont->ResRunCont.PtFrame ); + //} + + // Try to allocate + + VPtCont->ResRunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->ResRunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->ResRunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->ResRunCont.ParFrameNbPerAcq) ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FFreeAcqBuffer () + : + Goal : Free acquisition buffer + : + Inputs : None + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read informations from APP__VGContext and set buffer pointer to NULL. + : + Remark : None + : + Level : + Date : 19/02/2011 + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FFreeAcqBuffer ( ) { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Free buffer + // ------------------------------- + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + VPtCont->ResRunCont.PtFrame = NULL; + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : + Goal : Build the frame list for one acquisition + : + Inputs : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : + : + Remark : This function is the copy of EFRIO__FBuildFrameListFromAcq for application + : program demo. + : + : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : + Level : + Date : 06/11/2010 + Rev : 19/02/2011 + : - Moved from eudet_fio.c + : + Doc date : 07/11/2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) + : + Goal : Load AcqNo in memory + : + Inputs : AcqNo - No of acquisition to load + : PtFrameNb - Pointer to a variable which will be set with frames nb in AcqNo + : - Set it to NULL if you don't need it + : + Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : + Globals : Read information from APP__VGContext. + : + Remark : None. + : + Level : + Date : 19/02/2011 + Rev : 07/03/2011 + : - New " spare W32 info " format + Doc date : /2010 + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqInfFormat; + EFRIO__TFileSpareW32Info VAcqInf; + SInt32 VRet; + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + // ----------------------------------- + // Load acquisition in memory + // ----------------------------------- + + // Load from run file + + // Before 07/03/2011 + // VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VFrameNb ); + + VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VAcqInfFormat, sizeof (VAcqInf) / 4 /* MaxSpareW32InfoNb */, (SInt32*) &VAcqInf ); + + err_retfail ( VRet, (ERR_OUT, "Goto acquisition No %d failed !", AcqNo ) ); + + // Build frame list = array of pointer to access frames one by one + + VRet = APP__FBuildFrameListFromAcq ( VAcqInf.TotFrameNb, VPtCont->ResRunCont.PtFrame, &VPtCont->ResFramesList ); + + err_retfail ( VRet, (ERR_OUT,"Build frames list for acquisition No %d failed !", AcqNo ) ); + + // ----------------------------------- + // Update frame nb parameter + // ----------------------------------- + + if ( PtFrameNb != NULL ) { + *PtFrameNb = VAcqInf.TotFrameNb; + } + + err_retok (( ERR_OUT, "Acquisiton No %d loaded in memory - Contains %d frames", AcqNo, VAcqInf.TotFrameNb )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) + : + Goal : Return a pointer to one frame of the acquisition which is loaded in memory. + : + Inputs : FrameIdInAcq - The no of the frame + : + Ouputs : The function returns + : A valid pointer to the frame + : A NULL pointer if the operation failed + : + Globals : Read information from APP__VGContext. + : + Remark : None + : + Level : + Date : 19/02/2011 + Rev : + Doc date : + Author : Gilles CLAUS + E-mail : gilles.claus@ires.in2p3.fr + Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) { + + APP__TContext* VPtCont = &APP__VGContext; + EFRIO__TRunCont* VPtRunCont = &VPtCont->ResRunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->ResFramesList; + + + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"No frame=%d in list => Pointer NULL", FrameIdInAcq) ); + } + + return ( VPtFrList->AFramePtr[FrameIdInAcq] ); +} diff --git a/include/pxi_daq_lib_v.1.2/daq_lib.h b/include/pxi_daq_lib_v.1.2/daq_lib.h new file mode 100755 index 0000000..91666e8 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/daq_lib.h @@ -0,0 +1,141 @@ +// -------------------------------------------------------------------------------------- +// Includes required by DAQ library +// imported directly from Gilles Claus +// all the .def, .typ, .var or .c files are located in the include dir +// JB 2011/03/14 +// Modified: JB 2012/07/19 to include sync_index_rec +// Modified: VR 2014/03/21 Configuration of APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_ CC1 and CC2 is now made in the "pxi_daq_lib_config.h" file + +#ifndef DAQ_LIB_INCLUDE +#define DAQ_LIB_INCLUDE + +#define _FILE_OFFSET_BITS 64 // Mandatory for large files ( > 2 GB ) handling +// MUST be set before standard C header files + +#include +#include +#include // types +#include +#include + + +/* ========================================= */ +/* Conditional compilation for DAQ sources */ +/* ========================================= */ + +#define ROOT_ROOT // Disable code parts which can't compile under ROOT +#define CC_UNIX // Specify operating system + +//********************************** +// LIB CONFIGURATION +//********************************** +// Made in the "pxi_daq_lib_config.h" file +//********************************** +#include "pxi_daq_lib_config.h" +// test to check if configuration in "pxi_daq_lib_config.h" is well done +// (is one of the APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1 variable defined ?) +#ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + #error in pxi_daq_lib_v.1.2 (daq_lib.h) : bad configuration for DATA_FORMAT_CC1 in file include/pxi_daq_lib_config.h + #endif + #endif +#endif + +#ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + #error in pxi_daq_lib_v.1.2 (daq_lib.h) : bad configuration for DATA_FORMAT_CC2 in file include/pxi_daq_lib_config.h + #endif +#endif + +//********************************** + +/* ========================================= */ +/* DAQ commun files -> types & constants */ +/* ========================================= */ + + +#include "globals.def" +#include "globals_root.def" +#include "types.typ" + +/* ================================================================ */ +/* Definition of WIndows types & constant not available under Linux */ +/* ---------------------------------------------------------------- */ +/* Work like this now = allow to compile program, but should be */ +/* done in a better way later !!!!!!!!! */ +/* ================================================================ */ + +#define HANDLE UInt32 +#define DWORD UInt32 +#define WINAPI +#define LPVOID void* +#define INVALID_HANDLE_VALUE 0xFFFFFFFF + + +/* ========================================= */ +/* Macros needed to compile DAQ sources */ +/* ========================================= */ + +#define EXTERN +#define VAR_STATIC +#define VAR_INIT(x) =x +#define VAR_INIT_A2(x,y) ={x,y} +#define VAR_DCL(Extern,Static,Var) Extern Static Var +#define VAR_DCL_INIT(Extern,Static,Var,Init) Extern Static Var VAR_INIT (Init) +#define VAR_DCL_INIT_A2(Extern,Static,Var,Init0,Init1) Extern Static Var VAR_INIT_A2 (Init0,Init1) + + +/* ========================================= */ +/* Includes DAQ source files */ +/* ========================================= */ + +// Errors messages logging library interface + +#include "errors.def" +#include "errors.typ" +#include "errors.var" + +// General messages logging library interface + +#include "msg.def" +#include "msg.typ" +#include "msg.var" + +// Time library interface + +#include "time.def" +#include "time.typ" +#include "time.var" + +// Files library interface + +#include "files.def" +#include "files.typ" +#include "files.var" + +// ASIC library interface + +#include "asic.def" +#include "asic.typ" +#include "asic.var" + +// MAPS library interface + +#include "maps.def" +#include "maps.typ" +#include "maps.var" + +// Mimosa 26 library interface + +#include "mi26_usr.def" +#include "mi26_usr.typ" + +// Eudet flex rio DAQ library interface + +#include "eudet_frio.def" +#include "eudet_frio.typ" +#include "eudet_frio.var" + +#endif + diff --git a/include/pxi_daq_lib_v.1.2/errors.c b/include/pxi_daq_lib_v.1.2/errors.c new file mode 100755 index 0000000..a263280 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/errors.c @@ -0,0 +1,336 @@ + +/******************************************************************************* +File : x:\lib\com\errors\errors.c +Goal : Implement errors messages print ( screen ) or log ( file ) functions. + : Each function use " errors macros " to log errors and return code. + : +Remark : The way it works is controlled by 3 globals variables + : ERR_VGLogClosed = 0 ( disable ) / 1 ( enable ) errors messages + : ERR_VGLogPath = '/tmp/errors.txt' = path of error logfile + : ERR_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_C +#define ERRORS_C + + +#ifdef CC_APP_OS9 + +char* strerror ( SInt32 errno ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + sprintf ( VMsgStr, "Not avalibale under OS9" ); + + return (VMsgStr); +} + +#endif + +#ifndef CC_APP_WINDOWS + + +char *_strerror ( char* UsrStr ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + #ifdef APP_ROOT + sprintf ( VMsgStr, "%s : No errno str because not supported by ROOT", UsrStr ); + #else + strncpy ( VMsgStr, UsrStr, ERR_USR_MSG_SZ-10 ); + strcat ( VMsgStr, " : " ); + strncat ( VMsgStr, strerror ( errno ), ERR_SYS_MSG_SZ-10 ); + #endif + + + return (VMsgStr); +} + + +#endif + +SInt32 ERR_FEnableLog ( SInt8 Enable ) { + + ERR_VGLogClosed = Enable; + ERR_VGFileLogEnable = Enable; + ERR_VGUserLogEnable = Enable; + + return (0); +} + +SInt32 ERR_EnableLog ( SInt8 Enable ) { + return ( ERR_FEnableLog ( Enable) ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetFileLogEnabled () { + return ( ERR_VGFileLogEnable ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetUserLogEnabled () { + return ( ERR_VGUserLogEnable ); +} + + +SInt32 ERR_FSetLogFilePath ( char* LogFilePath ) { + sprintf ( ERR_VGLogPath, "%s", LogFilePath ); + return (0); +} + +char* ERR_FGetLogFilePath () { + return ( ERR_VGLogPath ); +} + +SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath ) { + ERR_FEnableLog ( Enable ); + ERR_FSetLogFilePath ( FilePath ); + + return (0); +} + + +SInt32 ERR_FEnd () { + return (0); +} + + +SInt32 ERR_FStopLog ( SInt8 Stop ) { + ERR_VGFileDontLog = Stop; + return (0); +} + +/* 11/06/2005 */ + +SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel ) { + ERR_VGFileLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetFileLogLevel () { + return ( ERR_VGFileLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FLogLevel2Str ( SInt8 Lvl ) { + + static char VStr[GLB_CMT_SZ+1]; + + switch ( Lvl ) { + + case ERR_LOG_LVL_NONE : { + sprintf ( VStr, "ERR_LOG_LVL_NONE" ); + break; } + + case ERR_LOG_LVL_ALL : { + sprintf ( VStr, "ERR_LOG_LVL_ALL" ); + break; } + + case ERR_LOG_LVL_WARINGS_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_WARINGS_ERRORS" ); + break; } + + case ERR_LOG_LVL_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_ERRORS" ); + break; } + + default : { + sprintf ( VStr, "Unknow error level = %d", Lvl ); + break; } + + } + + return ( VStr ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetFileLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGFileLogLevel ) ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel ) { + ERR_VGUserLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetUserLogLevel () { + return ( ERR_VGUserLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FGetUserLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGUserLogLevel ) ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetErrLogConfStr () { + + static char VStr[GLB_CMT_SZ+1]; + + sprintf ( VStr, "Error log configuration \n\n - File log enabled = %d \n - File log level = %s \n - File stop log =%d \n - Log file name = %s \n - User log enabled = %d \n - User log level = %s \n - User stop log =%d \n\n", ERR_VGFileLogEnable, ERR_FGetFileLogLevelStr (), ERR_VGFileDontLog, ERR_VGLogPath, ERR_VGUserLogEnable, ERR_FGetUserLogLevelStr (), ERR_VGUserDontLog ); + + return (VStr); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FUserStopLog ( SInt8 Stop ) { + ERR_VGUserDontLog = Stop; + return (0); +} + +/* 10/06/2005 */ + +SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func ) { + + ERR_VGUserErrorFunc = Func; + + return (0); +} + +SInt32 ERR_FGenError ( char MsgType ) { + + static char VErrMsg[ERR_TOT_MSG_SZ]; + + ERR_VGLastErrMsg = VErrMsg; + + /* ERR_VGLogLevel */ + /* == ERR_LOG_LVL_NONE => No log */ + /* == ERR_LOG_LVL_ALL => Log 'T', 'W', 'E' */ + /* == ERR_LOG_LVL_WARINGS_ERRORS => Log 'W', 'E' */ + /* == ERR_LOG_LVL_ERRORS => Log 'E' */ + + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_NONE) && (ERR_VGUserLogLevel == ERR_LOG_LVL_NONE) ) { + return (0); + } + + sprintf ( VErrMsg, "%s%s \n", ERR_VGStrLocationMsg , ERR_OUT ); + + /* File log handling */ + + while (1) { + + if ( ERR_VGFileLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Write error message to file */ + + if ( ERR_VGLogClosed && (ERR_VGLogFile != stdout) && (ERR_VGLogFile != stderr) ) { + ERR_VGLogClosed = 0; + // + // 29/10/10 => Don't open log file in append mode but overwrite it + // + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); + } + + if ( (ERR_VGFileDontLog == 0) && (ERR_VGLogFile != NULL) ) { + fprintf ( ERR_VGLogFile, VErrMsg ); + fflush ( ERR_VGLogFile ); + } + + break; + } + + /* User log handling */ + + while (1) { + + if ( ERR_VGUserLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Call user error function */ + + if ( (ERR_VGUserDontLog == 0) && (ERR_VGUserErrorFunc != NULL) ) { + ERR_VGUserErrorFunc ( MsgType, ERR_VGStrLocationMsg , ERR_OUT, VErrMsg ); + } + + break; + } + + + + + + + return (0); +} + + + +char* ERR_FGetLastErrMsg () { + + return (ERR_VGLastErrMsg); + +} + + + +void FPrint ( void ) +{ + printf ( "%s \n", VGOut ); +} + +//========================================================================================= + + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.1.2/errors.def b/include/pxi_daq_lib_v.1.2/errors.def new file mode 100755 index 0000000..40969a2 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/errors.def @@ -0,0 +1,153 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.def +Goal : Macros definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef ERRORS_DEF +#define ERRORS_DEF + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + + +#ifdef CC_APP_WINDOWS + + #ifndef __FUNCTION__ + + #ifdef CC_COMPILER_CPPB_4 + #define __FUNCTION__ "? Not available" + #endif + + #ifdef CC_COMPILER_CPPB_6 + #define __FUNCTION__ __FUNC__ + #endif + + #endif + +#endif +// ms 24 11 2009 changed size from 100 to 256 +#define ERR_USR_MSG_SZ 256 +#define ERR_SYS_MSG_SZ 256 +#define ERR_TOT_MSG_SZ (ERR_USR_MSG_SZ + ERR_SYS_MSG_SZ) + + +/* 07/04/2007 ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ +/* #define ERR_OUT ERR_VGStrUserMsg */ + + +/* 07/04/2007 - Use a local variable in each function because __FUNCTION__ IS NOT handled by CNT ... */ +/* __LINE__ is replaced by 0 because __LINE__ because ... __LINE__ is not handled file by file ... */ + +#ifdef APP_ROOT + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,VFuncName, 0 /* __LINE__ */ );} +#else + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,__FUNCTION__,__LINE__ );} +#endif + + + +#define ERR_WARNING(Msg) { sprintf Msg; ERR_LOCATION ('W'); ERR_FGenError ('W'); } + +#define ERR_ERROR(Msg) { sprintf Msg; ERR_LOCATION ('E'); ERR_FGenError ('E'); } + +#define ERR_TRACE(Msg) { sprintf Msg; ERR_LOCATION ('T'); ERR_FGenError ('T'); } + + +#define ERR_RET(Code,MsgOk,MsgFail) { \ + if ((Code)<0) ERR_ERROR (MsgFail) \ + else ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_RET_FAIL(Code,MsgFail) { \ + if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (Code); } \ + } + + + +#define ERR_RET_FAIL_NULL(Code,MsgFail) { \ +if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (NULL); } \ + } + + + +#define ERR_RET_NULL(Ptr,MsgFail) { \ +if ((void*)(Ptr)==NULL) { ERR_ERROR (MsgFail) return (-1); } \ + } + + + +#define ERR_RET_OK(MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (0); \ + } + + + +#define ERR_RET_VAL(Code,MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_TYPE_ID(Id) ( 0x5A00 | Id ) + +#define ERR_TYPE_CHK(Pt,TypeId) { \ +if ( *( (UInt16*) (Pt) ) != ERR_TYPE_ID(TypeId) ) { \ + err_retfail ( -1, (ERR_OUT,"Bad type used Type Id = %x MUST be %x => Check the function call parameters in your source code", *( (UInt8*) (Pt) ) , TypeId ) ); \ + } \ + } + + +#define err_trace(Msg) ERR_TRACE(Msg) +#define err_tracel(Lvl,Msg) ERR_TRACE(Msg) +#define err_warning(Msg) ERR_WARNING(Msg) +#define err_error(Msg) ERR_ERROR(Msg) + +#define err_ret(Code,MsgOk,MsgFail) ERR_RET(Code,MsgOk,MsgFail) +#define err_retok(MsgOk) ERR_RET_OK(MsgOk) +#define err_retval(Code,MsgOk) ERR_RET_VAL(Code,MsgOk) +#define err_retfail(Code,MsgFail) ERR_RET_FAIL(Code,MsgFail) +#define err_retfailnull(Code,MsgFail) ERR_RET_FAIL_NULL(Code,MsgFail) +#define err_retnull(Ptr,MsgFail) ERR_RET_NULL(Ptr,MsgFail) + +#define err_typechk(Pt,TypeId) ERR_TYPE_CHK(Pt,TypeId) + +#define PRINT(msg) { sprintf (VGOut, "%s",msg); FPrint (); } +#define RETURN_ERROR(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (FALSE); } +#define RETURN_ERROR_2(msg1,msg2) { sprintf (VGOut, "%s %s",msg1,msg2); FPrint (); return (FALSE); } + +#define RETURN_ERROR_NULL(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (NULL); } +#define RETURN_OK { return (TRUE);} + + + + +#endif + + +// trace (( ERR_OUT, "", par )); +// retfail ( Code, (ERR_OUT,"MsgFail",par) ); +// retnull ( Code, (ERR_OUT,"MsgFail",par) ); // Pointer == NULL => Ret -1 +// error (( ERR_OUT, "", par )); + + diff --git a/include/pxi_daq_lib_v.1.2/errors.typ b/include/pxi_daq_lib_v.1.2/errors.typ new file mode 100755 index 0000000..983ef79 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/errors.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.typ +Goal : Types definition if error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_TYP +#define ERRORS_TYP + +typedef SInt32 (*ERR_TUserErrorFunc) ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ); + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/errors.var b/include/pxi_daq_lib_v.1.2/errors.var new file mode 100755 index 0000000..d36cd82 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/errors.var @@ -0,0 +1,79 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.var +Goal : Variables definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_VAR +#define ERRORS_VAR + + +/* + +EXTERN VAR_STATIC SInt8 ERR_VGLogClosed VAR_INIT (0); // Set to 1 to allow error loggin +EXTERN VAR_STATIC SInt8 ERR_VGFileDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogLevel VAR_INIT (ERR_LOG_LVL_ALL); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogLevel VAR_INIT (ERR_LOG_LVL_ALL); + +EXTERN VAR_STATIC char ERR_VGLogPath[GLB_FILE_PATH_SZ] VAR_INIT ("/dd/tmp/pc/errors.txt"); +EXTERN VAR_STATIC FILE *ERR_VGLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC FILE *ERR_VGTmpLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC SInt32 ERR_VGMsgCnt VAR_INIT (0); +EXTERN VAR_STATIC ERR_TUserErrorFunc ERR_VGUserErrorFunc VAR_INIT (NULL); +EXTERN VAR_STATIC char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ]; +EXTERN VAR_STATIC char ERR_VGStrUserMsg[ERR_TOT_MSG_SZ]; + +EXTERN VAR_STATIC char VGOut[255]; + +*/ + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_VGLogPath[GLB_FILE_PATH_SZ] , "/dd/tmp/pc/errors.txt"); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGTmpLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt32 ERR_VGMsgCnt , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, ERR_TUserErrorFunc ERR_VGUserErrorFunc , NULL); +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ] ); + +/* 07/04/2007 - ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ + +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + +VAR_DCL ( EXTERN, VAR_STATIC, char VGOut[255] ); + +// 21/12/2010 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char *ERR_VGLastErrMsg, "NULL"); + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.1.2/eudet_frio.c b/include/pxi_daq_lib_v.1.2/eudet_frio.c new file mode 100755 index 0000000..2ee7a3d --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/eudet_frio.c @@ -0,0 +1,8455 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr + +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_C +#define EUDET_FRIO_C + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: Acquisition size if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 15/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FCpyAcq ( UInt8* PtDest, SInt32 MaxDestSz, SInt32 AcqSz ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + UInt32* VPtDest; + SInt32 VTotSz; + + // Check destination buffer + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + // Calculate total size + // = AcqSz + 4 because first W32 is used to store size of acquistion + + VTotSz = AcqSz + 4; + + // Test buffer size + + if ( VTotSz > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Destination buffer is too small => VTotSz=%d > MaxDestSz=%d", VTotSz, MaxDestSz ) ); + } + + // ----------------------------------------------- + // Copy data + // ----------------------------------------------- + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Add size on first elt + + VPtDest = (UInt32*) PtDest; + + *VPtDest = VTotSz; + + ++VPtDest; + + // Copy + + memcpy ( VPtDest, VPtRun->PtFrame, AcqSz ); + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotSz); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : MapsName - Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 +Rev : 11/05/2011 + : - Handle version information -> majour, minor, comment + : + : 12/05/2011 + : - JTAG version Mi26 / Ult1 handling + : + : 19/05/2011 + : - Dma host size calculated for Ultimate because we don't know at this step which + : MAPS will be used and memory size for Ultimate is > the one for Mimosa 26 + : + : 25/05/2011 + : - Renamed in EFRIO__FBeginExt + : - Add parameter MapsName + : - Create a new EFRIO__FBegin (...) which call EFRIO__FBeginExt ( ASIC__MI26, ... ) + : This will keep compatibility with previous sw (EUDET), because EFRIO__FBegin call + : will configure Mimosa 26 as ASIC as it was done for first version of EUDET library. + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + SInt32 VRet; + SInt8 VEnableErrLog; + SInt8 VEnableMsgLog; + WideString VWsJtagStatus; + +#ifdef EFRIO__INCLUDE_PARA_PORT + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + // Select JTAG Mi26 or Ultimate + + switch ( MapsName ) { + + case ASIC__MI26 : { + EFRIO__VGJtagMi26Ult1 = 0; // 0 => Mi26, 1 => Ultimate + break; } + + case ASIC__ULT1 : { + EFRIO__VGJtagMi26Ult1 = 1; // 0 => Mi26, 1 => Ultimate + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + + // Reset lib context record => Set all field to 0 + // BUT ! Set CmdRun to -1 + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + VPtCont->RunCont.CmdRun = -1; + + // Set version information ( only for version >= 2.0 ) + + #ifdef EFRIO__V20_AND_LATER + + #ifdef EFRIO__V20 + VPtCont->VersionMajor = 2; + VPtCont->VersionMinor = 0; + + sprintf ( VPtCont->VersionCmt, "Extension of V1.0 to Ultimate 1" ); + #endif + + #endif + + + // Conf errors logging + + VEnableErrLog = ( ErrorLogLvl != 0 ); + + VRet = ERR_FBegin ( VEnableErrLog, ErrorLogFile ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FBegin failed !" ) ); + + VRet = ERR_FSetFileLogLevel ( ErrorLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FSetFileLogLevel failed !" ) ); + + // Conf messages logging + + VEnableMsgLog = ( MsgLogLvl != 0 ); + + VRet = MSG_FBegin ( VEnableMsgLog, MsgLogFile ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FBegin failed !" ) ); + + VRet = MSG_FSetFileLogLevel ( MsgLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FSetFileLogLevel failed !" ) ); + + // Init // port + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FBegin ( VEnableErrLog, ErrorLogFile ); + PPO_FOpen ( 0x378 /* BaseAdr */, 0 /* Id */ ); + PPO_FEnableReadDataOutPortBeforeWrite ( 0 /* Id */, 1 /* Enable */ ); + #endif + + // Set default values to first board conf in order to get DmaHostSize initialized BEFORE fw loading + + VPtBoard->AsicNb = EFRIO__MAX_ASIC_NB; // Max possible number + VPtBoard->FrameNbPerAcq = EFRIO__MAX_FRAME_NB_PER_ACQ; // "Nominal" value + + // DMA host size is the memory size allocated for DMA on CPU side + // It must be equal AT LEAST to the size of one acquisition and higher value are not useful + // VPtBoard->AsicNb + 1 => + 1 for extra channel + + // 25/05/2011 => Calculate DMA host size in function of ASIC name + + switch ( MapsName ) { + + case ASIC__MI26 : { + VPtBoard->DmaHostSz = ((MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + + case ASIC__ULT1 : { + VPtBoard->DmaHostSz = ((ULT1__ZS_FFRAME_MODE_2X160MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + + + // Set default values of Header & Trailer for DQ emulation + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x8000800; + + VPtAcqEmul->ParATrailer[0] = 0xAAAAAAAA; + VPtAcqEmul->ParATrailer[1] = 0xBBBBBBBB; + VPtAcqEmul->ParATrailer[2] = 0xCCCCCCCC; + VPtAcqEmul->ParATrailer[3] = 0xDDDDDDDD; + VPtAcqEmul->ParATrailer[4] = 0xEEEEEEEE; + VPtAcqEmul->ParATrailer[5] = 0xFFFFFFFF; + + +#ifdef EFRIO__INCLUDE_JTAG + + +#ifdef OLD_COM_JTAG_CODE + + // Init JTAG + + if( ! EFRIO_VGJtagMi26.IsBound()) { + OleCheck(CoMI26MasterConf::Create(EFRIO_VGJtagMi26)); + } + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + // Init JTAG end + + +#else + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + + // JTAG Mi26 + + if ( EFRIO__VGJtagMi26Ult1 == 0 ) { + + VHrComErr = CoMI26MasterConf::Create( EFRIO_VGJtagMi26 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + } + + // JTAG Ult1 + + else { + + VHrComErr = CoMI28COM::Create( EFRIO_VGJtagUlt1 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI28COM::Create failed !" ) ); + } + + if ( EFRIO_VGJtagUlt1.IsBound () ) { + OleCheck ( EFRIO_VGJtagUlt1.Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + } + + + // Init JTAG end + +#endif + + + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + VPtCont->InfInitDone = 0; + + +#ifndef EFRIO__V20_AND_LATER + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "EUDET Flex RIO DLL compiled on %s at %s", __DATE__, __TIME__ )); + err_error (( ERR_OUT, "******************************************************************" )); + +#else + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "EUDET Flex RIO DLL V%d.%d compiled on %s at %s", VPtCont->VersionMajor, VPtCont->VersionMinor, __DATE__, __TIME__ )); + err_error (( ERR_OUT, "------------------------------------------------------------------" )); + err_error (( ERR_OUT, "%s", VPtCont->VersionCmt )); + err_error (( ERR_OUT, "******************************************************************" )); + +#endif + + err_retok (( ERR_OUT, "end" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 +Rev : 11/05/2011 + : - Handle version information -> majour, minor, comment + : + : 12/05/2011 + : - JTAG version Mi26 / Ult1 handling + : + : 19/05/2011 + : - Dma host size calculated for Ultimate because we don't know at this step which + : MAPS will be used and memory size for Ultimate is > the one for Mimosa 26 + : + : 25/05/2011 + : - Body of function is " empty " => it has been moved in EFRIO__FBeginExt (...) + : - Call EFRIO__FBeginExt ( ASIC__MI26, ... ) + : - EFRIO__FBeginExt (...) handles MapsName parameter ( Mi26 / Ultimate / ... ) + : EFRIO__FBegin still configure Mimosa 26 as it was done in first version of lib. + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + return ( EFRIO__FBeginExt ( ASIC__MI26, ErrorLogLvl, ErrorLogFile, MsgLogLvl, MsgLogFile ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEnd () + : +Goal : Terminate lib + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 05/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEnd () { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FEnd (); + #endif + + // Close JTAG COM classe + // Avoid "assertion message" when LabView is stop and then restarted + + err_error (( ERR_OUT, "1" )); + +#ifdef EFRIO__INCLUDE_JTAG + + + // JTAG Mi26 + + if ( EFRIO__VGJtagMi26Ult1 == 0 ) { + EFRIO_VGJtagMi26.Unbind(); + } + + else { + EFRIO_VGJtagUlt1.Unbind(); + } + + +#endif + + // Free frames buffer if allocated + + err_error (( ERR_OUT, "2" )); + + if ( VPtCont->RunCont.PtZsFFrameRaw !=NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + // Reset context record + + err_error (( ERR_OUT, "3" )); + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : +Goal : Build the frame list for one acquisition + : +Inputs : AcqStatus - ACquisition status ( < 0 -> HW error, 0 -> OK, > 0 -> Frame nb lost ) + : TrigStatus - No meaning now, reserved for future use + : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : +Level : +Date : 06/11/2010 +Rev : 24/02/2011 + : - Add parameters AcqStatus, TrigStatus to field new fields of EFRIO__TFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->AcqStatus = AcqStatus; + PtList->TrigStatus = TrigStatus; + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill followinf elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) + : +Goal : Init DAQ emulation either in standalone DAQ emulation application ( without + : HW ) or in LabView DAQ application. Selection done by RunInLabview parameter. + : +Inputs : RunInLabview = 0 => Run in C++ Builder DAQ emulation application + : = 1 => Run in Labview DAQ + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : If emulation is running under Labview ( RunInLabview = 1 ), frames emulation + : function overwite memory already allocated for Flew RIO board. In case emulation + : is runing in a standalone application ( RunInLabview = 0 ), this function allocates + : memory in PC DRAM to emulate Flex RIO RAM. + : + : This function sets default values of DAQ emulation parameters. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// RunInLabview = 0 => Run in C++ Builder DAQ emulation application +// RunInLabview = 1 => Run in Labview DAQ + +SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + // Reset context records + + memset ( VPtAcqEmul, 0, sizeof (EFRIO__TAcqEmul) ); + + memset ( VPtFrChk , 0, sizeof (EFRIO__TFrCheck) ); + + // Set default value of DAQ emulation parameters => Mainly for Labview which will not control all of them + + VPtAcqEmul->ParAcqCycleMs = 200; + VPtAcqEmul->ParEmuleDRamReadMs = 0; + VPtAcqEmul->ParEmuleFunctNo = 0; + VPtAcqEmul->ParRandomDataSz = 0; + VPtAcqEmul->ParSetMaxDataSzOnOneMaps = 1; + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x80008006; + + VPtAcqEmul->ParATrailer[0] = 0xAAAA0001; + VPtAcqEmul->ParATrailer[1] = 0xAAAA0002; + VPtAcqEmul->ParATrailer[2] = 0xAAAA0003; + VPtAcqEmul->ParATrailer[3] = 0xAAAA0004; + VPtAcqEmul->ParATrailer[4] = 0xAAAA0005; + VPtAcqEmul->ParATrailer[5] = 0xAAAA0006; + + VPtAcqEmul->ParTrigNbPerFrame = 0; + VPtAcqEmul->ParTrigOnOneFrameOverN = 1; + VPtAcqEmul->ParTrigOnNConsecutiveFrames = 1; + + VPtAcqEmul->ParATrig[0] = 10; + VPtAcqEmul->ParATrig[1] = 20; + VPtAcqEmul->ParATrig[2] = 30; + VPtAcqEmul->ParATrig[3] = 40; + + VPtAcqEmul->ParATS[0] = 100; + VPtAcqEmul->ParATS[1] = 200; + VPtAcqEmul->ParATS[2] = 300; + VPtAcqEmul->ParATS[3] = 400; + + + // Set Mi26 nb + + VPtFrChk->InfMi26Nb = VPtRunCont->ParMi26Nb; + + // Extra channel or not ? + + if ( (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtAcqEmul->InfExtraChan = 1; + } + + else { + VPtAcqEmul->InfExtraChan = 0; + } + + if ( RunInLabview == 0 ) { + + // Calculate DRAM size + + VPtAcqEmul->InfDRamSz = (VPtRunCont->ParMi26Nb + VPtAcqEmul->InfExtraChan) * VPtRunCont->ParFrameNbPerAcq * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 4; + + VPtAcqEmul->InfDRamSzMb = VPtAcqEmul->InfDRamSz / (1024 * 1024); + + // Alloc RAM to emulate Flex RIO DRAM + + VPtAcqEmul->InfDRamPtr = (UInt32*) malloc ( VPtAcqEmul->InfDRamSz ); + + err_retnull ( VPtAcqEmul->InfDRamPtr, (ERR_OUT,"Allocation of %d bytes for Flex RIO DRAM emulation failed !", VPtAcqEmul->InfDRamSz) ); + + } // End if ( RunInLabview == 0 ) + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleEnd ( ) + : +Goal : Terminate DAQ emulation + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Free DRAM if allocated in PC to emulate Flex RIO DRAM. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEmuleEnd ( ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + if ( VPtAcqEmul->InfDRamPtr != NULL ) { + free ( VPtAcqEmul->InfDRamPtr ); + } + + err_retok (( ERR_OUT, "" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) + : +Goal : Emulate Flex RIO DRAM read + : +Inputs : Cmd - 0 => Do nothing + : - 1 => Fill memory with zero + : +Ouputs : A pointer to DRAM or NULL if not allocated + : +Globals : + : +Remark : A delay should also be added here later to emulate Flex RIO DRAM access time + : configured by field ParEmuleDRamReadMs of EFRIO__TAcqEmul. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + + + if ( Cmd == 1 ) { + memset ( VPtAcqEmul->InfDRamPtr, 0, VPtAcqEmul->InfDRamSz ); + } + + Sleep ( VPtAcqEmul->ParEmuleDRamReadMs ); + + return ( VPtAcqEmul->InfDRamPtr ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) + : +Goal : Used for DAQ emulation. + : Set the FrameId fields ( TLU & Flex RIO triggers ) of all triggers info in + : the record used to emulate triggers + : +Inputs : FrameId - The value of frame id to set in all triggers info + : TrigNb - The number of trigger info to set in record + : PtRec - Pointer to destination record + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : The field set are + : - for TLU trigger => F.FrameIdInAcq ( see record EFRIO__TTluTrigger in *.typ ) + : - for Flex RIO trigger => F.Mi26Frame ( see record EFRIO__TFlexRioTimeStamp1 in *.typ ) + : +Level : +Date : 03/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) { + + SInt32 ViTrig; + EFRIO__TTluTrigger* VPtTrig; + EFRIO__TFlexRioTimeStamp1* VPtTs; + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + if ( TrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"TrigNb=%d > Max=%d", TrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) ); + } + + for ( ViTrig=0; ViTrig < TrigNb; ViTrig++ ) { + + VPtTrig = (EFRIO__TTluTrigger*) &PtRec->ATrig[2 * ViTrig]; + VPtTs = (EFRIO__TFlexRioTimeStamp1*) &PtRec->ATrig[(2 * ViTrig)+1]; + + VPtTrig->F.FrameIdInAcq = FrameId; + VPtTs->F.Mi26Frame = FrameId; + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) + : +Goal : Function used to avoid data copy while transfering data from one Vi to + : another under Labview. Because sometimes, it seems that Labview use pointers + : but it's not the case, a copy of data is done, and execution time is lost ... + : +Inputs : CmdGetPtrCpyAlloc = 0 => return buffer pointer + : = 1 => store PtSrcW32 but NO copy of data + : = 2 => copy src to buffer + : = 3 => alloc buffer + : + : AllocW32Sz - Memory size to alloc in W32 ( if CmdGetPtrCpyAlloc = 3 ) + : PtSrcW32 - Pointer to source data to copy to buffer + : SrcW32Sz - Size of source data to copy to buffer + : +Ouputs : A pointer on the buffer or NULL if not allocated. + : +Globals : + : +Remark : It's mainly used to passe a pointer on board DRAM to DLL ( CmdGetPtrCpyAlloc = 1 ) + : +Level : +Date : 07/09/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) { + + static UInt32* VPtBuff = NULL; + static UInt32 VAllocW32Sz = 0; + UInt32 VAllocSz; + SInt32 Vi; + + // Get pointer request + + if ( CmdGetPtrCpyAlloc == 0 ) { + return (VPtBuff); + } + + // Store pointer request + + if ( CmdGetPtrCpyAlloc == 1 ) { + VPtBuff = PtSrcW32; + return (VPtBuff); + } + + // Copy request + + if ( CmdGetPtrCpyAlloc == 2 ) { + + if ( (VPtBuff == NULL) || (SrcW32Sz > VAllocW32Sz) ) { + err_error (( ERR_OUT, "VPtBuff = %x = NULL ? / SrcW32Sz=%d > VAllocW32Sz=%d", VPtBuff, SrcW32Sz, VAllocW32Sz )); + return (NULL); + } + + for ( Vi=0; Vi < SrcW32Sz; Vi++ ) { + VPtBuff[Vi] = PtSrcW32[Vi]; + } + + return (VPtBuff); + } + + + // Allocation request + + if ( CmdGetPtrCpyAlloc == 3 ) { + + // Free mem if already allocated + + if ( VPtBuff != NULL ) { + free ( VPtBuff ); + VPtBuff = NULL; + } + + // Alloc new mem + + VAllocW32Sz = AllocW32Sz; + VAllocSz = VAllocW32Sz * 4; + + VPtBuff = (UInt32*) malloc ( VAllocSz ); + + // If allocation failed => error message + ret NULL + + if ( VPtBuff == NULL ) { + err_error (( ERR_OUT, "Allocation of %d bytes failed !", VAllocSz )); + return (NULL); + } + + // If allocation OK => ret buffer pointer + + return (VPtBuff); + } + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 + : EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : Mi26Nb - Mimosa 26 number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 => Creation with all job done in function body + : +Rev : 12/05/2011 + : - Code moved to EFRIO__FConfRunExt (...) + : - Call EFRIO__FConfRunExt ( ASIC__MI26, ... ) + : + : +Doc date : 12/05/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) { + + SInt32 VRet; + + VRet = EFRIO__FConfRunExt ( ASIC__MI26, Mi26Nb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DataTransferMode, TrigMode, DestDir, FileNamePrefix, SaveToDisk, SendOnEth, SendOnEthPCent ); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, + : SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : MapsName - Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + : MapsNb - MAPS number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 -> Creation of EFRIO__FConfRun (...) + : 12/05/2011 -> Change name from EFRIO__FConfRun to EFRIO__FConfRunExt and add MapsName parameter + : See " Rev 12/05/2011 " + ; + : +Rev : 04/11/2010 + : - Save to disk + : + : 21/02/2011 + : - Set new fields ( ParDaqVersion, ParMapsName ) + : + : 12/05/2011 + : - A new parameter MapsName must be added, in order to keep compatibility with EUDET lib : + : -> This function has been renamed EFRIO__FConfRunExt ( it was EFRIO__FConfRun before ) + : -> The new parameter MapsName had been added + : -> The former EFRIO__FConfRun call now EFRIO__FConfRunExt with MapsName param = ASIC__MI26 + : + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + SInt32 VMaxFrameSz; + SInt32 VRet; + + + // Check function parameters + + err_retnull ( DestDir , (ERR_OUT,"Abort : DestDir == NULL !") ); + err_retnull ( FileNamePrefix, (ERR_OUT,"Abort : FileNamePrefix == NULL !") ); + + // Debug print function parameters + + err_error (( ERR_OUT, "Call with : MapsNb=%d - RunNo=%d - TotEvNb=%d - EvNbPerFile=%d - FrameNbPerAcq=%d - DestDir=%s - FileNamePrefix=%s", MapsNb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DestDir, FileNamePrefix )); + + // Set hard coded parameters + + VPtCont->RunCont.ParMeasDataRate = 1; // Enable data rate measurement + VPtCont->RunCont.ParAcqNbToMeasDataRate = 10; // Uses 10 acquistions to measure data rate + + // Set default values to new fields + + VPtCont->RunCont.ParDaqVersion = 0; + + // Copy run parameters to run context record + + VPtCont->RunCont.ParMapsName = MapsName; + VPtCont->RunCont.ParMi26Nb = MapsNb; + VPtCont->RunCont.ParRunNo = RunNo; + VPtCont->RunCont.ParTotEvNb = TotEvNb; + VPtCont->RunCont.ParEvNbPerFile = EvNbPerFile; + VPtCont->RunCont.ParFrameNbPerAcq = FrameNbPerAcq; + VPtCont->RunCont.ParDataTransferMode = DataTransferMode; + VPtCont->RunCont.ParTrigMode = TrigMode; + + VPtCont->RunCont.ParSaveOnDisk = SaveToDisk; + VPtCont->RunCont.ParSendOnEth = SendOnEth; + VPtCont->RunCont.ParSendOnEthPCent = SendOnEthPCent; + + sprintf ( VPtCont->RunCont.ParDestDir , "%s", DestDir ); + sprintf ( VPtCont->RunCont.ParFileNamePrefix, "%s", FileNamePrefix ); + + sprintf ( VPtCont->RunCont.InfDataFileName, "%s\\%s%d.bin", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + sprintf ( VPtCont->RunCont.InfConfFileName, "%s\\%s%d.par", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + + VPtCont->RunCont.InfSaveDataOnDiskRunning = 0; + + // Compare run conf paramters to the max parameters used to calculate DmaHostSz in FBegin + // If they have higher values => DmaHostSz send to board at fw loading is bad => Abort + + if ( (VPtCont->RunCont.ParMi26Nb > EFRIO__MAX_ASIC_NB) || (VPtCont->RunCont.ParFrameNbPerAcq > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_error (( ERR_OUT, "Bad Mi26 nb ? Run conf = %d - Max = %d", VPtCont->RunCont.ParMi26Nb, EFRIO__MAX_ASIC_NB )); + err_error (( ERR_OUT, "Bad frame nb per acq ? Run conf = %d - Max = %d", VPtCont->RunCont.ParFrameNbPerAcq, EFRIO__MAX_FRAME_NB_PER_ACQ )); + err_retfail ( -1, (ERR_OUT,"Abort : Bad value of AsicNb=%d or FrameNbPerAcq=%d", VPtCont->RunCont.ParMi26Nb, VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // Update monitor context fields + + VPtCont->MonCont.InfFrameNbToSend = (SInt32) ( (float) FrameNbPerAcq * (float) ( (float) SendOnEthPCent / (float) 100 )); + + VPtCont->MonCont.InfSzToSend = 0; // Because it's not known at this step + + err_error (( ERR_OUT, "TRACE => InfFrameNbToSend = %d", VPtCont->MonCont.InfFrameNbToSend )); + + // Overwrite default values of AsicNb & FrameNbPerAcq + + VPtBoard->AsicNb = VPtCont->RunCont.ParMi26Nb; + VPtBoard->FrameNbPerAcq = VPtCont->RunCont.ParFrameNbPerAcq; + + // DMA host size => Already initialized in FBegin function + // VPtBoard->DmaHostSz = (MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * VPtBoard->AsicNb * VPtBoard->FrameNbPerAcq) / (1024 * 1024); + + // Configure others board conf parameters + + VPtBoard->BoardId = 0; + + sprintf ( VPtBoard->AsicName, "%s", "Mimosa 26" ); + + VPtBoard->ReadoutMode = 0; // Reserved for future use + VPtBoard->DataClkFrequency = 80; // 80 MHz + + if ( (DataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (DataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtBoard->EnableExtraChannel = 1; // Yes + } + + else { + VPtBoard->EnableExtraChannel = 0; // No + } + + err_trace (( ERR_OUT, "EnableExtraChannel=%d", VPtBoard->EnableExtraChannel )); + + VPtBoard->TriggerMode = 0; // Trigger mode -> disabled + VPtBoard->TriggerDetectTimeWindow = 0; // Trigger mode -> Window during which we count triggers to detect beginning of spill + VPtBoard->TriggerDetectOccurNb = 0; // Trigger mode -> Number of trigger required during "TriggerDetectTimeWindow" to decide that spill has begun + VPtBoard->AcqNbPerTrig = 0; // Trigger mode -> Number of consecutive Acq stored after beginning of spill detection + + VPtBoard->EnableTimeStamping = 0; // On board time stamping -> disabled + VPtBoard->TimeStampRes = 0; // On board time stamp resolution in [ns] + + VPtBoard->EnableTrigCnt = 0; // On board trigger counter + + VPtBoard->TagEventsStoredByDUT = 0; // Tag events taken dy DUT -> disabled + VPtBoard->ReadTluTrigCntEachNTrig = 0; // Read event counter provided by TLU -> disabled + + + + // Allocate memory + + // IPHC data transfer mode + + if ( DataTransferMode == EFRIO__TRF_MODE_IPHC ) { + + // Free tmp trigger record if allocated + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + // Free EUDET mode buffer + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.PtFrame = NULL; + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Alloc IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + + VPtCont->RunCont.InfZsFFrameRawBuffSz = VPtCont->RunCont.ParMi26Nb * (VPtCont->RunCont.ParFrameNbPerAcq + 200) * sizeof (MI26__TZsFFrameRaw); + + VPtCont->RunCont.PtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + err_retnull ( VPtCont->RunCont.PtZsFFrameRaw, (ERR_OUT,"Allocation of IPHC buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // EUDET data transfer mode + + else { + + // Alloc tmp trigger record + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + VPtCont->PtTmpTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtCont->PtTmpTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Free IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + VPtCont->RunCont.InfZsFFrameRawBuffSz = 0; + + // Reset frame list + + memset ( VPtCont->AAcqFrameList, 0, sizeof (EFRIO__TFrameList) ); + + // Alloc + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Upgrade for Ultimate + + // VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VPtCont->RunCont.InfFrameBuffSz = VPtCont->RunCont.ParFrameNbPerAcq * VMaxFrameSz; + + VPtCont->RunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->RunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->RunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq) ); + + err_error (( ERR_OUT, "TRACE => Frames buffer sz = %d Bytes", VPtCont->RunCont.InfFrameBuffSz )); + err_error (( ERR_OUT, "TRACE => Frames buffer sz = %d MBytes", VPtCont->RunCont.InfFrameBuffSz / (1024 * 1024) )); + } + + + // Reset run context results fields + + VPtCont->RunCont.ResAcqCnt = 0; + VPtCont->RunCont.ResFrameCnt = 0; + VPtCont->RunCont.ResEventCnt = 0; + + // Set status conf done + + VPtCont->ABoardsStatus[0].ConfDone = 1; + + // Set flag init done + + VPtCont->InfInitDone = 1; + + // Init for Labview because some emulation parameters are not controlled by GUI + + #ifdef APP_DLL + EFRIO__FEmuleBegin ( 1 /* RunInLabview */ ); + #endif + + + err_retok (( ERR_OUT, "end" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 07/03/2011 + : - Get disk sector size from OS + : + : 20/05/2011 + : - Use run param to calculate TCStreamFile max buffer size + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStartSavingOnFile () { + + SInt32 VRet; + char VDiskDrive[3]; + SInt32 VDiskSectorSz; + SInt8 VUseThread; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + EFRIO__TFrame* VPtFrame; + SInt32 VStreamFileMaxBlocSz; + + + VRet = 0; + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + // Create & write conf file + + // msg (( MSG_OUT, "VPtRunCont->ResConfFileName=%s", VPtRunCont->ResConfFileName )); + + // Set pointer to 0 before saving and restor them afer + + VPtZsFFrameRaw = VPtRunCont->PtZsFFrameRaw; + VPtFrame = VPtRunCont->PtFrame; + + VPtRunCont->PtZsFFrameRaw = NULL; + VPtRunCont->PtFrame = NULL; + + VRet = VRet | EFRIO__VGRunConfFile.PubFConf ( VPtRunCont->InfConfFileName, FIL__TCBinFile_RWB_MODE_WRITE, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont), 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunConfFile.PubFCreate (); + VRet = VRet | EFRIO__VGRunConfFile.PubFSeqWrite ( VPtRunCont, sizeof (EFRIO__TRunCont) ); + VRet = VRet | EFRIO__VGRunConfFile.PubFClose (); + + VPtRunCont->PtZsFFrameRaw = VPtZsFFrameRaw; + VPtRunCont->PtFrame = VPtFrame; + + err_retfail ( VRet, (ERR_OUT,"Run config file = %s creation failed !", VPtRunCont->InfConfFileName) ); + + // Create data file + + if ( VPtRunCont->ParSaveOnDisk == 1 ) { + VUseThread = 1; + } + + else { + VUseThread = 0; + } + + + // Get disk sector size + + strncpy ( VDiskDrive, VPtRunCont->InfDataFileName, 2 ); + + VDiskDrive[2] = 0; + + VDiskSectorSz = FIL_FGetDiskSectorSz ( VDiskDrive ); + + err_retfail ( VDiskSectorSz, (ERR_OUT,"Abort => Unable to get drive %s sector size !", VDiskDrive ) ); + + msg (( MSG_OUT, "Disk sector sz = %d Bytes", VDiskSectorSz )); + + // Set TCStreamFile disk sector size + + VRet = VRet | EFRIO__VGRunDataFile.PubFSetDiskSectorSz ( VDiskSectorSz ); + + // Conf TCStreamFile + + // VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + // VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + // 20/05/2011 + + VStreamFileMaxBlocSz = ( VPtRunCont->ParFrameNbPerAcq * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ); + + err_error (( ERR_OUT, "TRACE => Calc TCStreamFile max bloc sz - %d Fr/Acq - Bloc Sz = %d MB", VPtRunCont->ParFrameNbPerAcq, VStreamFileMaxBlocSz / (1024 * 1024) )); + + VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, VStreamFileMaxBlocSz /* Max */, VStreamFileMaxBlocSz /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + + err_retfail ( VRet, (ERR_OUT,"Run data file = %s creation failed !", VPtRunCont->InfDataFileName) ); + + VPtRunCont->InfSaveDataOnDiskRunning = 1; + + } + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 16/02/2011 + : - Test if ParTotEvNb reached, if yes => call EFRIO__FStopSavingOnFile () + : + : 24/02/2011 + : - Handle SpareW32Par as an array ASpareW32Par now + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSaveAcqOnFile () { + + SInt32 VRet; + SInt8 VUseThread; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TFileSpareW32Info VSpareW32Info; + + + VRet = 0; + + if ( VPtRunCont->InfSaveDataOnDiskRunning == 0 ) { + return (0); + } + + if ( VPtRunCont->ResEventCnt > VPtRunCont->ParTotEvNb ) { + EFRIO__FStopSavingOnFile (); + err_error (( ERR_OUT, "TRACE => End of run reached : %d events saved on disk", VPtRunCont->ResEventCnt )); + return (0); + } + + // Save acq on file if + // - Run conf "save on disk" parameter is set + // - There is something to save => ResAcqFunctRetCode = acquisition size <> 0 + + if ( (VPtRunCont->ParSaveOnDisk > 0) && (VPtRunCont->ResAcqFunctRetCode > 0) ) { + + VSpareW32Info.AcqStatus = VPtFrList->AcqStatus; + VSpareW32Info.TrigStatus = VPtFrList->TrigStatus; + VSpareW32Info.TotFrameNb = VPtFrList->TotFrameNb; + VSpareW32Info.DiskSectorSz = EFRIO__VGRunDataFile.PubFGetDiskSectorSz (); + + VRet = EFRIO__VGRunDataFile.PubFSeqWrite ( VPtRunCont->PtFrame, VPtRunCont->ResAcqFunctRetCode /* Acq sz */, VPtRunCont->ResEventCnt - 1 /* DbgCallPar */, 1 /* SpareW32InfoFormat */, (SInt32*) &VSpareW32Info, sizeof (VSpareW32Info) / 4 /* SpareW32InfoNb */ ); + + } + + err_retfail ( VRet, (ERR_OUT,"Saving Acq=%d of %d bytes on file %s failed", VPtRunCont->ResAcqCnt - 1, VPtRunCont->ResAcqFunctRetCode, VPtRunCont->InfDataFileName ) ); + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStopSavingOnFile () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + VRet = 0; + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_IPHC ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__TRF_MODE_IPHC not hanlded") ); + } + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + VPtRunCont->InfSaveDataOnDiskRunning = 0; + + VRet = VRet | EFRIO__VGRunDataFile.PubFFlush (); + VRet = VRet | EFRIO__VGRunDataFile.PubFClose (); + + err_retfail ( VRet, (ERR_OUT,"Error while closing data file = %s", VPtRunCont->InfDataFileName) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +#undef COMPIL_FTluTrigger2Str +#ifdef COMPIL_FTluTrigger2Str + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert TLU trigger info record to string for print or display + : +Inputs : Trig - Source trigger record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display + : +Inputs : Ts - Source time stamp record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger / timestamp as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in IPHC data transfer mode. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + SInt32 VNiFrame; + SInt32 VNiFramePMi26; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[0]; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VNiFrame = ViFrame * VPtRunCont->ParMi26Nb; + + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + VNiFramePMi26 = VNiFrame + ViMi26; + + if ( VPtFrame[VNiFramePMi26].Header != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Header, VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFrame[VNiFramePMi26].Trailer != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Trailer, VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFrame[VNiFramePMi26].FrameCnt; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFrame[VNiFramePMi26].FrameCnt != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].FrameCnt, VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in EUDET 1,2,3 data transfer modes. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +UInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrame* VPtFr; + SInt32 ViFrame; + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VPtFr = VPtFrList->AFramePtr[ViFrame]; + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + if ( VPtFr->Header.AMapsHeader[ViMi26] != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsHeader[ViMi26], VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFr->Header.AMapsTrailer[ViMi26] != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsTrailer[ViMi26], VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFr->Header.AMapsFrameCnt[ViMi26]; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFr->Header.AMapsFrameCnt[ViMi26] != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFr->Header.AMapsFrameCnt[ViMi26], VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 29/04/2011 ( DPXI version of 20/08/2009 moved here ) +Doc date : 20/08/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FChkFrameLight ( SInt16 FuncId, SInt32 CurFrame, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // Init frame cnt array on first frame values and errors flag + + if ( CurFrame == 0 ) { + + VErrors = 0; + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // Because CurFrame = 0 in this bloc => PtFrame[0] is first Mi26 + + for ( ViMi26=1; ViMi26 < VMi26Nb; ViMi26++ ) { + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "A - Frame cnt error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + } + + } + + else { + ++VPtTestCont->InfMapsFrameCntRef; + } + + // Check frame cnt & header & trailer + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter of CurFrame > 0 + + if ( CurFrame != 0 ) { + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "B - Frame cnt error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + } + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Header error [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Trailer error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + + return (VErrors); +} + + +#ifndef NO_MI26 + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 02/02/2010 +Rev : 07/05/2010 + : - Trigger calculation + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // msg (( MSG_OUT, "==> DPXI__MI26_FFRioAcqDeserData1Mi26 : Mi26NbToRead=%d - EltNb=%d - TotAnsSz=%d", VPtServ->PtParAcqReqFunc->AsicNbToRead, EltNb, PtAcq->InfTotAnsSz )); + + // Copy Acq inf pointers to local pointers + + // $$$ VPtAcqData = PtAcq->InfPtAcqData; + // $$$ VptZsFFrameRaw = PtAcq->InfPtZsFFrameRaw; + // $$$ msg (( MSG_OUT, "DPXI__MI26_FFRioAcqDeserData1Mi26 => AcqReqFuncSz=%d - MaxDataSz=%d - VTotAnsSz=%d", PtAcq->InfParAcqReqFuncSz, VPtServ->PtParAcqReqFunc->MaxDataSz, PtAcq->InfTotAnsSz )); + // $$$ memset ( VPtAcqData, 0, PtAcq->InfTotAnsSz ); + // $$$ err_trace (( ERR_OUT, "Start extract data for FrameNb=%d", VPtServ->PtParAcqReqFunc->FrameNb )); + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // $$$ VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VptZsFFrameRaw[ViFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[ViFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + VptZsFFrameRaw[ViFrame].DataLength = VDataLengthField; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32 = (UInt32*) VptZsFFrameRaw[ViFrame].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[ViFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + VptZsFFrameRaw[ViFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + VptZsFFrameRaw[ViFrame].Zero2 = VZero2; + ++ViSrcW32; + + // $$$ DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + VptZsFFrameRaw[ViFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[ViFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[ViFrame].SStatus.HitCnt = -1; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 09/03/2010 +Rev : 06/05/2010 + : - Add trigger extract + : Warning ! Copy Zero & Zero2 fields of frame chip No 0 to ALL others chips ! + : All fields Zero & Zero2 are equals to the fields of first chip + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + SInt32 V6iFrameP1; + SInt32 V6iFrameP2; + SInt32 V6iFrameP3; + SInt32 V6iFrameP4; + SInt32 V6iFrameP5; + UInt32 VADataLengthField[6]; + UInt16 VADataLengthW16[6]; + UInt16 VADataLengthW32[6]; + UInt16 VDataLengthW32Max; + register SInt32 ViSrcW32; + register SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get AcqId + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // err_warning (( ERR_OUT, "TRACE : Memset buffer")); + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + V6iFrameP1 = V6iFrame + 1; + V6iFrameP2 = V6iFrame + 2; + V6iFrameP3 = V6iFrame + 3; + V6iFrameP4 = V6iFrame + 4; + V6iFrameP5 = V6iFrame + 5; + + + VptZsFFrameRaw[V6iFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VptZsFFrameRaw[V6iFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + + VptZsFFrameRaw[V6iFrame].DataLength = VADataLengthField[0]; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VptZsFFrameRaw[V6iFrameP1].DataLength = VADataLengthField[1]; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + + VptZsFFrameRaw[V6iFrameP2].DataLength = VADataLengthField[2]; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VptZsFFrameRaw[V6iFrameP3].DataLength = VADataLengthField[3]; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VptZsFFrameRaw[V6iFrameP4].DataLength = VADataLengthField[4]; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VptZsFFrameRaw[V6iFrameP5].DataLength = VADataLengthField[5]; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + // Find max data length of the six Mi26 + + VDataLengthW32Max = MATH_FUInt16Max ( VADataLengthW32, 6 ); + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32Chip0 = (UInt32*) VptZsFFrameRaw[V6iFrame].ADataW16; + VPtDataW32Chip1 = (UInt32*) VptZsFFrameRaw[V6iFrameP1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VptZsFFrameRaw[V6iFrameP2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VptZsFFrameRaw[V6iFrameP3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VptZsFFrameRaw[V6iFrameP4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VptZsFFrameRaw[V6iFrameP5].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip1[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip2[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip3[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip4[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip5[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VptZsFFrameRaw[V6iFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + ++ViSrcW32; + + // DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + + VptZsFFrameRaw[V6iFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrame].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP1].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 1 + 18 + (6 * VADataLengthW32[1])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP1].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP1].SStatus.AsicNo = 1; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP1].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP2].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 2 + 18 + (6 * VADataLengthW32[2])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP2].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP2].SStatus.AsicNo = 2; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP2].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP3].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 3 + 18 + (6 * VADataLengthW32[3])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP3].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP3].SStatus.AsicNo = 3; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP3].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP4].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 4 + 18 + (6 * VADataLengthW32[4])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP4].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP4].SStatus.AsicNo = 4; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP4].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP5].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 5 + 18 + (6 * VADataLengthW32[5])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP5].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP5].SStatus.AsicNo = 5; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP5].SStatus.HitCnt = -1; + + + + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 6 /* Mi26Nb */ ); + // PtAcq->ResAsicErrorsRejCurAcq = 0; + + // if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 25/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 27/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointers + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // If length > max possible => Set it to 0 + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 29/10/2010 version handling 6 Mi26 ) +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V9iFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V9iFrame = 9 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 9 = 9 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; // 18 = 9 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 03/11/2010 version handling 6 Mi26 ) + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 9 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = 9 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + /* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + + */ + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + +#endif // NO_MI26 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + +#ifndef NO_MI26 + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + } + + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); + +#endif // NO_MI26 + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagLoadFile ( char* FileName ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagLoadFile (FileName); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagLoadFile (FileName); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagLoadFile ( char* FileName ) { + + HRESULT VRetCode; + WideString VStatus; + WideString VFileName; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + + if ( VJtag.IsBound () ) { + + VFileName = FileName; + + OleCheck( VRetCode = VJtag.MasterConfLoadFile( VFileName , &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Load JTAG file = %s failed !", FileName) ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagReset ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagReset (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagReset (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagReset ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfReset (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Reset chip failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagLoadChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagLoadChip (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagLoadChip (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FJtagLoadChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfUpdateAll (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + OleCheck( VRetCode = VJtag.MasterConfReadBack (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Read back chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagStartChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagStartChip (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagStartChip (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagStartChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfStart (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FHwStartChip ( SInt32 SpareS32Par ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FHwStartChip ( SpareS32Par ); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FHwStartChip ( SpareS32Par ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2010 +Doc date : 10/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FHwStartChip ( SInt32 SpareS32Par ) { + + err_warning (( ERR_OUT, "EFRIO__MI26_FHwStartChip (Par=%d)", SpareS32Par )); + + // Start = D6, Speak = D7* + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD6 ( 0 /* Id */, 0 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + + Sleep ( 100 ); // 08/06/2011 => Debug for test with Flex RIO trig emulator + + PPO_FOutD6 ( 0 /* Id */, 0 ); + + #else + err_warning (( ERR_OUT, "HW start not done -> // port not enabled !" )); + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 19/05/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FTestOnDataGetJtagRef () { + + SInt32 VRet; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + // Sel Mi26 + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( ViMaps, &VStrComStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Select Maps Id = %d failed !", ViMaps) ); + } + + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 0 /* RegId */, &VHighTrailerFromJtag, &VRegValFromMi26, &VStrComStatus) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 1 /* RegId */, &VLowTrailerFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 2 /* RegId */, &VHighHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 3 /* RegId */, &VLowHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + + VPtTestCont->ParAMapsHeaderRef[ViMaps] = VLowHeaderFromJtag + (VHighHeaderFromJtag << 16); // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = VLowTrailerFromJtag + (VHighTrailerFromJtag << 16); // Mimosa 26 trailer field + + } + + } + + else { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + VPtTestCont->ParAMapsHeaderRef[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = 0; // Mimosa 26 trailer field + } + + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + + CoUninitialize(); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 29/04/2011 + : +Rev : 19/05/2011 + : - Handle both Mi26 and Ult1 +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FTestOnDataStartStop ( SInt8 Start, SInt8 MapsNbToTest, SInt8 PrintLvl ) { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + + + VPtTestCont->ParPrintLvl = PrintLvl; + + + // Stop and exit + + if ( Start == 0 ) { + + // If already stopped => Do nothing & exit + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + // If running => Stop + message + + VPtTestCont->ParModeEnable = 0; + + // Print errors count + + EFRIO__FPrintTestOnDataCont ( "Errors count after Stop" ); + + err_retok (( ERR_OUT, "Stop command executed" )); + } + + + // Start procedure + + // If already running => Do nothing & exit + + if ( VPtTestCont->ParModeEnable == 1 ) { + return (0); + } + + // If not running => Start + Message + + memset ( VPtTestCont, 0, sizeof (EFRIO__TTestOnDataCont) ); + + VPtTestCont->ParMapsNb = VPtRunCont->ParMi26Nb; + VPtTestCont->ParMapsNbToTest = MapsNbToTest; + + + switch ( VPtRunCont->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FTestOnDataGetJtagRef (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FTestOnDataGetJtagRef (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRunCont->ParMapsName) ); + break; } + + } + + err_retfail ( VRet, (ERR_OUT,"Test aborted => Unable to get param from JTAG") ); + + // Enable test + + VPtTestCont->ParModeEnable = 1; + + // Print test context + + EFRIO__FPrintTestOnDataCont ( "Record state after Start" ); + + err_retok (( ERR_OUT, "Start command executed" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 29/04/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FTestOnDataResetErrCnt () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + SInt8 ViMaps; + + + // Print test context => To get errors count before reset + + EFRIO__FPrintTestOnDataCont ( "Errors count before Reset" ); + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + VPtTestCont->ResAMapsErrCnt[ViMaps] = 0; + VPtTestCont->ResAMapsHeaderErrCnt[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ResAMapsFrameCntErrCnt[ViMaps] = 0; // Mimosa 26 frame counter field + VPtTestCont->ResAMapsDataLengthErrCnt[ViMaps] = 0; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + VPtTestCont->ResAMapsTrailerErrCnt[ViMaps] = 0; // Mimosa 26 trailer field + + } + + VPtTestCont->ResTotErrCnt = 0; + VPtTestCont->ResFrameNbWithErr = 0; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef NO_MI26 + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + + return (VTotAcqSz); + } + +#endif // NO_MI26 + +#endif diff --git a/include/pxi_daq_lib_v.1.2/eudet_frio.def b/include/pxi_daq_lib_v.1.2/eudet_frio.def new file mode 100755 index 0000000..370ac50 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/eudet_frio.def @@ -0,0 +1,268 @@ + + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.def +Goal : Macros definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_DEF +#define EUDET_FRIO_DEF + + +/* ======================= */ +/* Conditional compilation */ +/* ======================= */ + +// Enable EFRIO__FRAME_TAGS_ENABLE to add tags at beginning of EFRIO__TFrame record and sub-records +// +// Each sub-record has it own tag, see list of constants at end of file +// +// EFRIO__TFrame -> EFRIO__FRAME_TAG +// EFRIO__TFrameHeader -> EFRIO__FRAME_TAG_HEADER +// EFRIO__TFrameData -> EFRIO__FRAME_TAG_DATA +// EFRIO__TTriggerRec -> EFRIO__FRAME_TAG_TRIG + +#define EFRIO__FRAME_TAGS_ENABLE + + + + +// Enable / Disable demultiplexing of Mimosa 26 data part +// +// It has NO effect if running with a single Mimosa 26 +// +// In case of multiple Mimosa 26 acquisition, Flex RIO provides multiplexed data +// +// W32[0] Mi26 No 0 , W32[0] Mi26 No 1 ... W32[0] Mi26 No 5 +// W32[1] Mi26 No 0 , W32[1] Mi26 No 1 ... W32[1] Mi26 No 5 +// W32[2] Mi26 No 0 , W32[2] Mi26 No 1 ... W32[2] Mi26 No 5 +// W32[3] Mi26 No 0 , W32[3] Mi26 No 1 ... W32[3] Mi26 No 5 +// +// Data are demultiplexed if this directive is enabled +// This processing will cost CPU time -> it may be done on EUDET SW side if needed +// that's why this processing can be disabled + + +// #define NO_MI26 + +#define EFRIO__DEMUX_MI26_DATA_PART +#define EFRIO__DEMUX_ULT1_DATA_PART + + + + +/* ================= */ +/* Macro */ +/* ================= */ + + +// Test if board Id is valid, if not return (-1) and lof error message + +#define EFRIO__CHK_BOARD_ID(BoardId) { if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) err_retfail ( -1, (ERR_OUT,"Abort : Bad board Id=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 ) ); } + + +/* ================= */ +/* Constants */ +/* ================= */ + + +// Maximum board number handle by the lib ( define arrays size ) + +#define EFRIO__MAX_BOARDS_NB 2 + +// Maximum ASIC nb handle by the lib ( define arrays size ) + +// #define EFRIO__MAX_ASIC_NB 6 before 21/02/2011 + +#define EFRIO__MAX_ASIC_NB 16 // Set to 16 on 21/02/2011 + +#define EFRIO__MAX_ASIC_NB_FOR_DMA 8 // 25/05/2011 + // Used to calculate DmaHostSz because Labview can't allocate memory for EFRIO__MAX_ASIC_NB = 16 + + +// Maximum number of frames per acquisition ( define arrays size ) +// - One frame = one readout of MAPS +// - One acquisition = N consecutives frames acquired in one call of board readout function + +#define EFRIO__MAX_FRAME_NB_PER_ACQ 1800 + + +// ************************************************************************************************************* +// Data transfer modes +// ************************************************************************************************************* +// Few information about how the Flex RIO board acquired Mimosa 26 +// +// - Flex RIO board can acquire the data of up to 6 Mimosa 26 and deserialize them +// Each Mimosa 26 is seen as an "acquisition channel", because fw is organized / Mimosa 26 +// +// - Now the fw doesn't care about trigger to select which frame to acquire, all frames are stored and the selection +// is done on-line by DAQ sw. Because it will be more flexible to adjust & modify trigger handling by sw rather than +// by fw and for 6 Mimosa 26 it seems possible to do it on execution time point of view. +// Later, this processing will be moved in fw, for AIDA but for EUDET it should work fine by sw. +// +// - The fw counts triggers and store it's own trigger information "Mimosa 26 trigger" ( the Mimosa 26 line read when trigger occurs ) +// This trigger information is written in the zero fields of Mimosa 26 ( by overwritting them ) +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 +// +// - An extra acquisition channel can be enabled to store trigger from TLU ( it has the same size as a Mimosa 26 channel = 2304 W8 ) +// It will store two W32 informations for each trigger +// - The trigger TLU -> See record EFRIO__TTluTrigger +// - The trigger from Flex RIO ( Mimosa 26 line + frame ) -> See record EFRIO__TFlexRioTimeStamp1 +// The extra channel can store up to 288 triggers ( 288 * W32 * 2 = 2304 ) +// +// We have decided to implement 4 data transfert mode, the difference is on trigger handling and only the last one will +// be useful for EUDET => EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// +// * EFRIO__TRF_MODE_IPHC +// +// Keep compatibility with IPHC DAQ -> limited to 3 triggers + data demultiplex which cost CPU time +// +// * EFRIO__TRF_MODE_EUDET__NO_TRG_CHAN, +// +// Send all frames, store 3 first "Mimosa 26 trigger", don't store TLU trigger +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_ALL_FRAMES, +// +// Send all frames, store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// Send only frame with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG +// store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// + + +typedef enum EFRIO__TRF_MODE { + EFRIO__TRF_MODE_IPHC, + EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, + EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, + EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + +} EFRIO__TTrfMode; + + +// We use the two "zero fields" of each 32 bits at the end of Mimosa 26 data stream to store first three triggers +// It's not trigger from TLU but the trigger we used in our first BT with flex RIO = Mimosa 26 line index when trigger occurs +// +// This is the field Mi26Line of the record EFRIO__TFlexRioTimeStamp1 x 16 because unit is Mimosa 26 clock cycle +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 + + +#define EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA 3 // CAN'T be higher than 3 !!!!!!!!!! + + +// The current frame - with trigger - is not enough to build the physics event +// due to internal MAPS logic ( double memory, pipelines etc ... ) following frames must be also used +// => This is the number of frames to read after the one which contains trigger to build physics event + +#define EFRIO__FRAME_NB_TO_READ_AFTER_TRIG 3 // For Mimosa 26 it's 3 + +// Constants to define extra channel size -> Hard coded ( don't use sizeof ( xyz) ) in order to reduce execution time +// The extra channel is a MAPS acquisition channel ( it has he same size ) but used to store trigger information +// It can store up to 288 triggers / MAPS frame +// +// Now 28/10/2010 +// - Each trigger info stored in extra channel contain two fields, each one is a W32, in the following order +// -- EFRIO__TTluTrigger +// -- EFRIO__TFlexRioTimeStamp1 +// --> Total trigger info size is 2 x W32 = 8 bytes +// - The extral channel has the same size of one Mi26 frame = 2304 W8 +// --> Maximum number of trigger info which can be stored = 2304 / 8 = 288 +// --> It means one trigger each two lines of Mimosa 26 readout ... ;-) + +// ------------------------------------------------------------------------------------------------- +// WARNING - 20/05/2011 => Solve bug of 19/05 = memory crash at second run ( first one ok ) ) +// ------------------------------------------------------------------------------------------------- +// - Ultimate allows 928 triggers / frame - Mi26 was limited to 288 +// - The test on max allowed trig number was not done in data processing loop => to save exec time +// but after the loop when padding zero part of frame is processed to find triggers +// - A test was done in this part, but only a warning was generated and waring messages were disabled ... +// ------------------------------------------------------------------------------------------------- +// Now ( 20/05/2011 ) +// - The size of temporary record used to stored trigger info has been increased to fit with Ultimate +// -- EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 288 +// -- EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 576 +// +// - But, in order to KEEP COMPATIBILIY with Mi26, the number of trigger copied to frame record has +// been limited to EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 = 288 +// +// - This may be increased LATER because frame record has variable size ( also for triggers part ) +// BUT now I DON'T KNOW if there are limitations somewhere else in sources ( run readout lib ? ) +// therefore I prefer to keep Mimosa 26 " triggers number limitation " +// ------------------------------------------------------------------------------------------------- + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 928 // Maximum number of trigger info = pair of W32 fields TLU Trig + Felx RIO TS +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 1856 // Maximum number of W32 fields + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 288 + +// #define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 288 // Maximum number of trigger info = pair of W32 fields TLU Trig + Felx RIO TS +// #define EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 576 // Maximum number of W32 fields + + +#define EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ 8 // Size of the trigger info = pair of W32 fields TLU Trig + Flex RIO TS + +#define EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ 4 // Size of one W32 field + + +// Maximum number of messages / board -> define array in EFRIO__TBoardStatus + +#define EFRIO__ERROR_MSG_LIST_MAX_NB 100 + + +// Maximum number of triggers in DAQ emulation configurable by GUI +// We can emulate more triggers than EFRIO__MAX_GUI_TRIG_NB but their value is hard coded in emulation function to 0 +// +// Only the first three triggers and the last one ( if EFRIO__MAX_GUI_TRIG_NB = 4 ) are configurable from GUI + +// #define EFRIO__MAX_GUI_TRIG_NB 4 // WARNING => Redined (with same value) in C++ Builder emulation application ! + +#define EFRIO__MAX_EMUL_GUI_TRIG_NB 4 // WARNING => Redefined (with same value) in C++ Builder emulaion application ! + + +// Tags values to be added at beginning of each EFRIO__TFrame sub-record + +#define EFRIO__FRAME_TAG 0x55550000 +#define EFRIO__FRAME_TAG_HEADER 0x00000001 +#define EFRIO__FRAME_TAG_DATA 0x00000002 +#define EFRIO__FRAME_TAG_TRIG 0x00000003 + +// Maximum size of one acquisition store to disk => Used by FIL__TCStreamFile class +// 20/05/2011 => Calculated for Ultimate + +// #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) + + +#ifdef CC_UNIX + #define ULT1__ZS_FFRAME_RAW_MAX_W8 7400 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 + #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +#else + #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +#endif + + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/eudet_frio.typ b/include/pxi_daq_lib_v.1.2/eudet_frio.typ new file mode 100755 index 0000000..4dc4e7e --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/eudet_frio.typ @@ -0,0 +1,972 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.typ +Goal : Types definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_TYP +#define EUDET_FRIO_TYP + + + +/* ============================================== */ +/* Board parameters configuration record */ +/* ---------------------------------------------- */ +/* Can be use to build a boards database */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// Remark for EUDET concerning trigger handling +// +// Most of the following trigger options will be useless for EUDET +// The operating mode for EUDET is : +// - The board takes data all the time regardless of trigger state +// - The fw store all triggers from TLU ( up to 288 / Mimsoa 26 frame ) are stored +// - The sw extract frames with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames after trigger + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + + char AsicName[GLB_CMT_SZ]; // The ASIC read by the board + + SInt32 AsicNb; // The number of ASICs read by the board + + SInt32 ReadoutMode; // The readout mode -> Future use + + SInt8 EmuleChannels; // Copy data of first MAPS in all channels, useful for test & debugging + // because it allows to run with one ASIC only but get data of all + + float DataClkFrequency; // Frequency of clock -> Future use, only useful in case board provide clock + + UInt32 DmaHostSz; // DMA size reserved on host CPU, must be >= size of one acquisition + + SInt32 FrameNbPerAcq; // Consecutives frames number stored during one acquisition + + SInt8 EnableExtraChannel; // Enable one more channel ( default is one channel per ASIC ) + // which can be used to store extra information -> eg : TLU trigger + + SInt32 AcqNbPerTrig; // TO BE CHECKED ! Number of consecutive acquisitions taken upon trigger detection by board + + SInt8 TriggerMode; // Trigger operating mode + + UInt32 TriggerDetectTimeWindow; // Time window during which we count triggers and decide to start acquisition if >= TriggerDetectOccurNb + + UInt32 TriggerDetectOccurNb; // Minimum trigger number during TriggerDetectTimeWindow to decide to start acquisition + + UInt32 TimeStampRes; // Resolution of time stamp + + SInt8 EnableTimeStamping; // Enable time stamping mode + + SInt8 EnableTrigCnt; // Enable trigger counter + + SInt8 TagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ ( HW line indicates that DUT has saved event ) + + UInt32 ReadTluTrigCntEachNTrig; // Period of reading TLU trigger + + +} EFRIO__TBoardConf; + + +/* ============================================== */ +/* Board status record */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + SInt8 BoardPresent; // Board present => 1, otherwise 0 + SInt8 FwLoaded; // Firmware has been loaded in board + SInt8 ConfDone; // The board has been configured by sw + + SInt32 StatusCode; // Current board status code + + char StatusStr[GLB_CMT_SZ]; // Status message associated to StatusCode + + // List of errors and last error + + char* ErrorMsgList[EFRIO__ERROR_MSG_LIST_MAX_NB]; + char LastErrorMsg[GLB_CMT_SZ]; + + // Registers read from board + + UInt32 RegDmaHostSz; // DMA host size in bytes + SInt32 RegFrameNbPerAcq; // Number of frames / acq + SInt8 RegEnableExtraChannel; // Extral channel state = enabled or not + SInt32 RegAcqNbPerTrig; // Consecutive acquisition nb per trigger + + SInt8 RegTriggerMode; // Trigger mode + UInt32 RegTriggerDetectTimeWindow; // Trigger detection window + UInt32 RegTriggerDetectOccurNb; // Number of triggers required during window to start acquisition + + UInt32 RegTimeStampRes; // Resolution of time stamp -> Check with CS if implemented ! + SInt8 RegEnableTimeStamping; // Enable time stamping mode -> Check with CS if implemented ! + + SInt8 RegEnableTrigCnt; // Enable trigger counter -> Check with CS if implemented ! + + SInt8 RegTagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ -> Check with CS if implemented ! + UInt32 RegReadTluTrigCntEachNTrig; // Period of reading TLU trigger -> Check with CS if implemented ! + + UInt64 RegTimeStamp; // Time stamp value + UInt32 RegTrigCnt; // Flex RIO rigger value + UInt32 RegTluTrigCnt; // TLU trigger value + +} EFRIO__TBoardStatus; + + + + +/* ============================================== */ +/* TLU trigger record */ +/* ---------------------------------------------- */ +/* Contains TLU trigger -> field TrigCnt */ +/* plus additional information */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 TrigCnt : 16; // Trigger counter read from TLU + UInt32 FrameIdInAcq : 11; // Index of frame in current acquisition during which trigger occurs ( 0 - 2407 ) + UInt32 EventTakenByDut : 1; // For future use : Flag at 1 if DUT has taken the event + UInt32 Reserved : 3; + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TTluTrigger; + + +/* ============================================== */ +/* Flex RIO time stamp 1 record */ +/* ---------------------------------------------- */ +/* This is the Flex RIO trigger, called */ +/* "time stamp" to avoid confusion / TLU */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Mi26Line : 10; // Line of Mi26 read during which trigger occurs + UInt32 Mi26Frame : 21; // Frame of Mi26 ( = frame counter field ) read during which trigger occurs + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TFlexRioTimeStamp1; + + +/* ============================================== */ +/* Frame header */ +/* ---------------------------------------------- */ +/* Each frame starts with a header which contains */ +/* - DAQ system info */ +/* - Mimosa 26 relevant fields */ +/* ---------------------------------------------- */ +/* Date : 22/10/2010 */ +/* Rev : 23/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_HEADER +#endif + + // New fields AcqStatus & TrigStatus 23/02/2011 + // + SInt32 AcqStatus; // Status of acquistion board for this acquisition + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + // + SInt32 TrigStatus; // No meaning now = reserved for future use + + UInt16 AcqId; // Index of acquisition containing this frame + UInt16 FrameIdInAcq; // Index of frame IN the CURRENT acquisition + + UInt16 MapsName; // MAPS name as a 16 bits code + UInt16 MapsNb; // Total number of MAPS in data + + UInt32 AMapsHeader[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 AMapsFrameCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 AMapsDataLength[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 AMapsTrailer[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + SInt16 TriggerNb; // Total triggers number during this frame + + UInt16 AMapsTrigInfo[EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA]; // First 3 "Mi26 trigger info" -> Line of Mi26 read during which trigger occurs + // if more than 3 trigger => look in trigger info block where all trigger are stored + +} EFRIO__TFrameHeader; + + +/* ============================================== */ +/* Frame data */ +/* ---------------------------------------------- */ +/* Each frame has a data part with variable size */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_DATA +#endif + UInt32 TotSz; // Total size of data bloc + UInt32 OneMapsSz; // Size of data of one MAPS + + UInt32 ADataW32[0]; // Beginning of data space + +} EFRIO__TFrameData; + + +/* ============================================== */ +/* Frame triggers list */ +/* ---------------------------------------------- */ +/* Each frame has a triggers list, up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB fields */ +/* which means up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB */ +/* trigger info */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_TRIG +#endif + UInt32 TotSz; // Total size of trigger info bloc + UInt16 TrigNb; // Total trigger nb + UInt16 TrigType; // Type of trigger info stored + + UInt32 ATrig[0]; // Beginning off triggers list + +} EFRIO__TTriggerRec; + + +/* ============================================== */ +/* Frame record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Data handling fields ( size etc ) */ +/* - The frame header */ +/* - The frame data part ( variable length ) */ +/* - Followed by the triggers info part */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new field DaqVersion */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG +#endif + SInt32 DaqVersion; // Version of DAQ - New field 21/02/2011 + SInt32 TotSz; // Total size of this frame + SInt32 TrigRecOffset; // Offset ( in bytes ) from beginning of frame to trigger info part + EFRIO__TFrameHeader Header; // Frame header + EFRIO__TFrameData Data; // Beginning of data part + + // The field EFRIO__TTriggerInfo is not defined here because "Data" has variable length + // the field BegData of Data field is used a pointer to beginning of data part + // The trigger info will be added at the end of this part but position is calculated dynamically + +} EFRIO__TFrame; + + +/* ============================================== */ +/* List of frames currently stored by lib */ +/* ---------------------------------------------- */ +/* This record stores frames list corresponding */ +/* to one acquisition */ +/* */ +/* It can be : */ +/* - frames acquired by DAQ */ +/* - frames loaded from a run file */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : */ +/* : 24/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// More information about frames storage in memory +// +// A buffer IS NOT allocated for EACH frame, a single bloc of memory is allocated for all frames of one acquisition. +// This will avoid copy frame by frame before sending them to Ethernet lib or saving them to disk. A single access +// can be done with a pointer on beginning of buffer and data size. +// +// But to process frames it's handly to have an array of pointers, each array item pointing on next frame, +// this is the goal of this list which provides : +// - The total number of frames in list +// - An array of pointers, eg : AFramePtr[2] points on third frame of acquisition +// - An array with the total size ( in bytes ) of each frame +// +// This list is built on-line while DAQ is running, or off-line via EFRIO__FBuildFrameListFromAcq (...) from +// the data of one acquisition stored in a run file. + +typedef struct { + + // New fields AcqStatus & TrigStatus 24/02/2011 + // + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + +} EFRIO__TFrameList; + + +/* ============================================== */ +/* Run configuration record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Run parameters -> Par... */ +/* - Informations built from Par etc -> Inf... */ +/* - Acquisition results ( ev cnt etc ) -> Res... */ +/* - Pointers to frames buffers */ +/* ---------------------------------------------- */ +/* This record is filled by EFRIO__FConfRun (...) */ +/* call with run parameters from GUI or Ethernet */ +/* ---------------------------------------------- */ +/* This record can be saved to disk as run config */ +/* file, but it can't be ONLY loaded from file ! */ +/* A call to EFRIO__FConfRun (...) must be done */ +/* because it allocates mem and do other tasks */ +/* -> load record from file */ +/* -> call EFRIO__FConfRun with record fields as */ +/* parameters, it will overwrite itself and all */ +/* " other tasks " will also be done */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new fields */ +/* : ParDaqVersion, ParMapsName */ +/* : - Change type of ParMi26Nb to S16 */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_... directive at a time ! + #endif + +#endif + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + char InfIndexFileName[GLB_FILE_PATH_SZ]; // Run index file name built from ParRunNo, ParFileNamePrefix, ParDestDir - 10/07/2012 + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_... directive at a time ! + #endif + +#endif + + + + + +/* ============================================== */ +/* Acquisition emulation record */ +/* ---------------------------------------------- */ +/* This record contains context of DAQ emulator */ +/* application, it means : */ +/* - Parameters -> Par... */ +/* - Information, calculated from Par -> Inf... */ +/* - Results -> Res... */ +/* ---------------------------------------------- */ +/* All emulation functions are implemented in the */ +/* lib, therefore application task is only GUI. */ +/* That's why emulation context is defined here */ +/* ---------------------------------------------- */ +/* All run param for emulation are taken from */ +/* run config record -> EFRIO__TRunCont */ +/* ---------------------------------------------- */ +/* Date : 30/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqCycleMs; // Delai between two acquisitions + + SInt32 ParEmuleDRamReadMs; // Delai added to PC DRAM access to emulate Flex RIO DRAM access time + + SInt32 ParEmuleFunctNo; // Select emulation function to call -> Future use = not implemented now + + SInt8 ParRandomDataSz; // Enables random generation of data size per Mimosa 26 + // By default data size is fixed in emulation function + // Used to check if variabl length records are properly handled + + SInt8 ParSetMaxDataSzOnOneMaps; // Set maximum possible data sze on first Mi26, overwrite value set by emulation + // function, but next Mi26 keep the data size value from emulation function + // Used to check if DAQ loose frames while Mi26 provides full frames + + + UInt32 ParAHeader[EFRIO__MAX_ASIC_NB]; // Emulated header of each Mi26 + + UInt32 ParATrailer[EFRIO__MAX_ASIC_NB]; // Emulated trailer of each Mi26 + + SInt32 ParTrigNbPerFrame; // Number of trigger per frame, set the part trigger nb (B31B16) of Mi26 Zero1 field + + // In data transfer modes EUDET 2 & 3 a more complex trigger emulation is done + // We don't emulate ParTrigNbPerFrame on each frame but on N consecutives frames + // each M frames + // + SInt32 ParTrigOnOneFrameOverN; // Start emulate ParTrigNbPerFrame on one frame over M = ParTrigOnOneFrameOverN + SInt32 ParTrigOnNConsecutiveFrames; // Emulates on N consecutive frames = ParTrigOnNConsecutiveFrames + + // TLU trigger & Flex RIO trigger emulation + // Up to 288 couples TLU & Flex RIO triggers can be emulated but only EFRIO__MAX_EMUL_GUI_TRIG_NB + // are configurabbles from GUI, now EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + // - First three are configurable from GUI + // - The last one is configurable from GUI + // - Others are configured in emulation function and set to 0 + // + SInt32 ParATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated TLU trigger + SInt32 ParATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated Flex RIO trigger, called "Time stamp 1" + + // DRAM info to emulate Flex RIO readout ( we need a PC RAM bloc of same size as the board one ) + // + SInt32 InfDRamSzMb; // DRAM size in MB + SInt32 InfDRamSz; // DRAM size in bytes + UInt32* InfDRamPtr; // DRAM pointer + + SInt8 InfExtraChan; // Extra channel status ( enabled or not ) depends on data transfer mode ( -> run config ) + + char InfEmuleFuncCmt[GLB_CMT_SZ]; // A comment set by emulation function selected by ParEmuleFunctNo + // -> Future use = not implemented now + + // DAQ emulation results + // + SInt32 ResAcqCnt; // Acquisition counter + SInt32 ResEvCnt; // Events counter + // + SInt32 ResAcqFunctRetCode; // Error code returned by acquisition function + +} EFRIO__TAcqEmul; + + +/* ============================================== */ +/* Frames check record */ +/* ---------------------------------------------- */ +/* This is context of frames check functions */ +/* - EFRIO__MI26_FChkAcqIphcMode (...) */ +/* - EFRIO__MI26_FChkAcqEudetMode (...) */ +/* */ +/* They check frames integrity, can be used in */ +/* normal DAQ mode or emulation */ +/* ---------------------------------------------- */ +/* Date : 31/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqNo; // Acquisition index + + SInt32 ParFrNo; // Frame index + + SInt8 ParChkMode; // Check mode -> Allows to define a level of test + + SInt8 ParChkVerbose; // Verbose mode or not + + SInt8 ParFrPrintLevel; // Define the frame information printed in log file + // 0 -> No print + // 1 -> Print general info ( AcqId, FrameId, TrigNb ... ) + Mi26 header, frame cnt, trailer + // 2 -> Print also triggers list + + SInt8 InfMi26Nb; // Mi26 number runnig in the system + + // Values provided by DAQ to check + // They are compared to the " same fields " of EFRIO_TAcqEmul + // + UInt32 ResAHeader[EFRIO__MAX_ASIC_NB]; // Mi26 header + UInt32 ResATrailer[EFRIO__MAX_ASIC_NB]; // Mi26 trailer + UInt32 ResAFrameCnt[EFRIO__MAX_ASIC_NB]; // Mi26 frames counter + UInt32 ResADataLenght[EFRIO__MAX_ASIC_NB]; // Mi26 data part length ( in W8 not in W16 as in DataLength fields of Mi26 data stream ) + // + SInt32 ResTrigNb; // Trigger info ( couple TLU & Flex RIO trigger ) number UNDER GUI control => limited to EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + SInt32 ResATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // TLU triggers list + SInt32 ResATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Flex RIO trigegrs list + + SInt32 ResErrCnt; // Total errors counter => Information provide by DAQ <> value set in EFRIO_TAcqEmul + + +} EFRIO__TFrCheck; + +/* ============================================== */ +/* Board check record */ +/* ---------------------------------------------- */ +/* This is context of board check Vi */ +/* The board test is done by a Vi on Labview side */ +/* this record pass the parameters to the Vi */ +/* */ +/* Parameters are set via call to functions */ +/* EFRIO__FSetBoardChk... */ +/* */ +/* Parameters are read via call to functions */ +/* EFRIO__FGetBoardChk... */ +/* Theses functions are encapsulated in Vi */ +/* ---------------------------------------------- */ +/* */ +/* The test results are written in board status */ +/* record ABoardsStatus [BoardId] */ +/* */ +/* Test results are set or read functions */ +/* EFRIO__FSetBoardStatus... */ +/* EFRIO__FGetBoardStatus... */ +/* ---------------------------------------------- */ +/* Date : 22/12/2010 */ +/* Doc date : 22/12/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParBoardId; // Board to test + + SInt8 ParDoTheTest; // Set to 1 to request the test + // Reset once test has been started + + SInt32 ParTestId; // Identifier to select different tests + + SInt8 ResTestDone; // Set to 1 when test is finished + + SInt32 ResTestResult; // Test result + // < 0 => Test has failed + // = 0 => Test OK + +} EFRIO__TBoardCheck; + + +/* ============================================== */ +/* Spare W32 bloc of index file */ +/* ---------------------------------------------- */ +/* This record contains spare info for index file */ +/* ---------------------------------------------- */ +/* Date : 24/02/2011 */ +/* Doc date : 24/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + + SInt32 DiskSectorSz; // Size of disk sector + +} EFRIO__TFileSpareW32Info; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains monitoring via Eth conf */ +/* ---------------------------------------------- */ +/* Date : 15/02/2011 */ +/* Doc date : 15/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 InfFrameNbToSend; // Frame nb to send on Eth = " Frame nb per acq * % monitoring " + SInt32 InfSzToSend; // Size corresponding to InfFrameNbToSend + +} EFRIO__TMon; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains tests on data conf / res */ +/* ---------------------------------------------- */ +/* Date : 29/04/2011 */ +/* Doc date : 29/04/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + // Control + + SInt8 ParModeEnable; // Enable test + SInt8 ParResetCnt; // Reset all error counters + SInt8 ParPrintLvl; // Errors print level + SInt8 ParMapsNb; // Nb of MAPS configured in JTAG + SInt8 ParMapsNbToTest; // Number of MAPS on which the test is performed + // MAPS no 0 to ParMapsNbToTest - 1 + + // Reference / expected values + + UInt32 ParAMapsHeaderRef[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 ParAMapsTrailerRef[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + UInt32 InfMapsFrameCntRef; // Mimosa 26 frame counter field + + // Current values get from DAQ + + UInt32 ResAMapsHeaderVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 ResAMapsFrameCntVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 ResAMapsDataLengthVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 ResAMapsTrailerVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + // Errors counters + + SInt32 ResAMapsErrCnt[EFRIO__MAX_ASIC_NB]; // Err counter / MAPS = sum errors on header, fc, trailer + + SInt32 ResAMapsHeaderErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + SInt32 ResAMapsFrameCntErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + SInt32 ResAMapsDataLengthErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + SInt32 ResAMapsTrailerErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + + SInt32 ResTotErrCnt; // Total errors counter = sum of N MAPS + SInt32 ResFrameNbWithErr; // Number of frames with at least one error + +} EFRIO__TTestOnDataCont; + + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : 07/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef struct { + +#ifndef EFRIO__V10 + + // Add on 11/05/2011 + // Lib version, eg : 1.2 + SInt8 VersionMajor; // Lib version major : version 1.2 => 1 + SInt8 VersionMinor; // Lib version minor : version 1.2 => 2 + + // Add on 11/05/2011 + char VersionCmt[GLB_CMT_SZ]; // Commetn about lib version = content of lib + +#endif + + SInt8 InfInitDone; // Lib iit done or not + + EFRIO__TBoardConf ABoardsConf[EFRIO__MAX_BOARDS_NB]; // Acquisition boards config + EFRIO__TBoardStatus ABoardsStatus[EFRIO__MAX_BOARDS_NB]; // Acquisition boards status + + EFRIO__TBoardCheck BoardChk; // Reserved for future implementation + // Parameters record to check + // - Boards + // - Mimosa 26 Clk & Sync signals + + EFRIO__TAcqEmul AcqEmul; // DAQ emulation context + EFRIO__TFrCheck FrCheck; // Frames check functions context + + EFRIO__TRunCont RunCont; // Run context = parameters, memory allocated, results + + EFRIO__TMon MonCont; // Monitoring context + + EFRIO__TTestOnDataCont TestOnDataCont; // Test on data context + + EFRIO__TFrameList AAcqFrameList[1]; // Frame list of acquistion - Can be extended to more than one acq if needed + + // List of frame Id to read ( Eudet3Mode => Trigger + 2 following frames ) / acquistion - Can be extended to more than one acq if needed + + SInt16 AAAcqFrameWithTrigList[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + // Used to solve FW trigger bug ( Ultimate => extra channel info shifted by two frames ) + + // For each frame Id stored in AAAcqFrameWithTrigList + // we store in the trigger nb in FwTrigBugAAAcqFrameWithTrigTrigNb + + SInt16 FwTrigBugAAAcqFrameWithTrigTrigNb[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + // Is set to 1 if this frame contains the trigger list of frame No - 2 + + SInt16 FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[1][EFRIO__MAX_FRAME_NB_PER_ACQ + 10]; + + + EFRIO__TTriggerRec* PtTmpTrigRec; // Temporary triggers record used for internal processing + +} EFRIO__TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/eudet_frio.var b/include/pxi_daq_lib_v.1.2/eudet_frio.var new file mode 100755 index 0000000..2242f88 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/eudet_frio.var @@ -0,0 +1,39 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.var +Goal : Variables definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_VAR +#define EUDET_FRIO_VAR + + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC EFRIO__TContext EFRIO__VGContext; + +EXTERN VAR_STATIC FIL__TCStreamFile EFRIO__VGRunDataFile ( "x:\\log\\err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); +EXTERN VAR_STATIC FIL__TCBinFile EFRIO__VGRunConfFile ( "x:\\log\\err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); + +#ifdef EFRIO__INCLUDE_JTAG + EXTERN VAR_STATIC TCOMIMI26MasterConf EFRIO_VGJtagMi26; +#endif + +#endif diff --git a/include/pxi_daq_lib_v.1.2/eudet_frio_print.c b/include/pxi_daq_lib_v.1.2/eudet_frio_print.c new file mode 100755 index 0000000..821d61f --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/eudet_frio_print.c @@ -0,0 +1,1148 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_PRINT_C +#define EUDET_FRIO_PRINT_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert TLU trigger info record to string for print or display +: +Inputs : Trig - Source trigger record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display +: +Inputs : Ts - Source time stamp record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger / timestamp as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) + : +Goal : Print run context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Rev : 21/02/2011 + : - Print new fields ParDaqVersion, ParMapsName +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Run context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParDaqVersion = %.4d", PtRec->ParDaqVersion )); + msg (( MSG_OUT, "ParMapsName = %.4d", PtRec->ParMapsName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParMi26Nb = %.4d", PtRec->ParMi26Nb )); + msg (( MSG_OUT, "ParFrameNbPerAcq = %.4d", PtRec->ParFrameNbPerAcq )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParRunNo = %.4d", PtRec->ParRunNo )); + msg (( MSG_OUT, "ParTotEvNb = %.4d", PtRec->ParTotEvNb )); + msg (( MSG_OUT, "ParEvNbPerFile = %.4d", PtRec->ParEvNbPerFile )); + msg (( MSG_OUT, "ParDataTransferMode = %.4d", PtRec->ParDataTransferMode )); + msg (( MSG_OUT, "ParTrigMode = %.4d", PtRec->ParTrigMode )); + msg (( MSG_OUT, "ParSaveOnDisk = %.4d", PtRec->ParSaveOnDisk )); + msg (( MSG_OUT, "ParSendOnEth = %.4d", PtRec->ParSendOnEth )); + msg (( MSG_OUT, "ParSendOnEthPCent = %.4d", PtRec->ParSendOnEthPCent )); + msg (( MSG_OUT, "ParDestDir = %s" , PtRec->ParDestDir )); + msg (( MSG_OUT, "ParFileNamePrefix = %s" , PtRec->ParFileNamePrefix )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParJtagFileName = %s ", PtRec->ParJtagFileName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); +// msg (( MSG_OUT, "InfMi26FrameSzFromFlexRio = %.4d", PtRec->InfMi26FrameSzFromFlexRio )); + msg (( MSG_OUT, "InfZsFFrameRawBuffSz = %.4d", PtRec->InfZsFFrameRawBuffSz )); + msg (( MSG_OUT, "InfFrameBuffSz = %.4d", PtRec->InfFrameBuffSz )); + msg (( MSG_OUT, "InfConfFileName = %s" , PtRec->InfConfFileName )); + msg (( MSG_OUT, "InfDataFileName = %s" , PtRec->InfDataFileName )); + msg (( MSG_OUT, "InfSaveDataOnDiskRunning = %.4d", PtRec->InfSaveDataOnDiskRunning )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "CmdRun = %.4d", PtRec->CmdRun )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResFrameCnt = %.4d", PtRec->ResFrameCnt )); + msg (( MSG_OUT, "ResEventCnt = %.4d", PtRec->ResEventCnt )); + msg (( MSG_OUT, "ResDataRateMBytesPerSec = %.3f", PtRec->ResDataRateMBytesPerSec )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "PtZsFFrameRaw = %.8x", PtRec->PtZsFFrameRaw )); + msg (( MSG_OUT, "PtFrame = %.8x", PtRec->PtFrame )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunCont () + : +Goal : Print lib run context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunCont () { + + return ( EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) + : +Goal : Print board conf record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board conf record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "AsicName = %s", PtRec->AsicName )); + msg (( MSG_OUT, "AsicNb = %.4d", PtRec->AsicNb )); + msg (( MSG_OUT, "ReadoutMode = %.4d", PtRec->ReadoutMode )); + msg (( MSG_OUT, "DataClkFrequency = %2.f", PtRec->DataClkFrequency )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "DmaHostSz = %.4d", PtRec->DmaHostSz )); + msg (( MSG_OUT, "FrameNbPerAcq = %.4d", PtRec->FrameNbPerAcq )); + msg (( MSG_OUT, "EnableExtraChannel = %.4d", PtRec->EnableExtraChannel )); + msg (( MSG_OUT, "AcqNbPerTrig = %.4d", PtRec->AcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TriggerMode = %.4d", PtRec->TriggerMode )); + msg (( MSG_OUT, "TriggerDetectTimeWindow = %.4d", PtRec->TriggerDetectTimeWindow )); + msg (( MSG_OUT, "TriggerDetectOccurNb = %.4d", PtRec->TriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TimeStampRes = %.4d", PtRec->TimeStampRes )); + msg (( MSG_OUT, "EnableTimeStamping = %.4d", PtRec->EnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EnableTrigCnt = %.4d", PtRec->EnableTrigCnt )); + msg (( MSG_OUT, "TagEventsStoredByDUT = %.4d", PtRec->TagEventsStoredByDUT )); + msg (( MSG_OUT, "ReadTluTrigCntEachNTrig = %.4d", PtRec->ReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) + : +Goal : Print lib board conf record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) + : +Goal : Print board status record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board status record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "BoardPresent = %.4d", PtRec->BoardPresent )); + msg (( MSG_OUT, "FwLoaded = %.4d", PtRec->FwLoaded )); + msg (( MSG_OUT, "ConfDone = %.4d", PtRec->ConfDone )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "StatusCode = %.4d", PtRec->StatusCode )); + msg (( MSG_OUT, "StatusStr = %.4d", PtRec->StatusStr )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ErrorMsgList = %s", PtRec->ErrorMsgList )); + msg (( MSG_OUT, "LastErrorMsg = %s", PtRec->LastErrorMsg )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegDmaHostSz = %.4d", PtRec->RegDmaHostSz )); + msg (( MSG_OUT, "RegFrameNbPerAcq = %.4d", PtRec->RegFrameNbPerAcq )); + msg (( MSG_OUT, "RegEnableExtraChannel = %.4d", PtRec->RegEnableExtraChannel )); + msg (( MSG_OUT, "RegAcqNbPerTrig = %.4d", PtRec->RegAcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTriggerMode = %.4d", PtRec->RegTriggerMode )); + msg (( MSG_OUT, "RegTriggerDetectTimeWindow = %.4d", PtRec->RegTriggerDetectTimeWindow )); + msg (( MSG_OUT, "RegTriggerDetectOccurNb = %.4d", PtRec->RegTriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStampRes = %.4d", PtRec->RegTimeStampRes )); + msg (( MSG_OUT, "RegEnableTimeStamping = %.4d", PtRec->RegEnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegEnableTrigCnt = %.4d", PtRec->RegEnableTrigCnt )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTagEventsStoredByDUT = %.4d", PtRec->RegTagEventsStoredByDUT )); + msg (( MSG_OUT, "RegReadTluTrigCntEachNTrig = %.4d", PtRec->RegReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStamp = %.4d", PtRec->RegTimeStamp )); + msg (( MSG_OUT, "RegTrigCnt = %.4d", PtRec->RegTrigCnt )); + msg (( MSG_OUT, "RegTluTrigCnt = %.4d", PtRec->RegTluTrigCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) + : +Goal : Print lib board status record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) + : +Goal : Print acquisition emulation context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Acquistion emulation record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqCycleMs = %.4d", PtRec->ParAcqCycleMs )); + msg (( MSG_OUT, "ParEmuleDRamReadMs = %.4d", PtRec->ParEmuleDRamReadMs )); + msg (( MSG_OUT, "ParEmuleFunctNo = %.4d", PtRec->ParEmuleFunctNo )); + msg (( MSG_OUT, "InfEmuleFuncCmt = %s" , PtRec->InfEmuleFuncCmt )); + msg (( MSG_OUT, "ParRandomDataSz = %d" , PtRec->ParRandomDataSz )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParAHeader[0] , PtRec->ParAHeader[1] , PtRec->ParAHeader[2] , PtRec->ParAHeader[3] , PtRec->ParAHeader[4] , PtRec->ParAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParATrailer[0], PtRec->ParATrailer[1], PtRec->ParATrailer[2], PtRec->ParATrailer[3], PtRec->ParATrailer[4], PtRec->ParATrailer[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParTrigNbPerFrame = %.4d", PtRec->ParTrigNbPerFrame )); + msg (( MSG_OUT, "ParTrigOnOneFrameOverN = %.4d", PtRec->ParTrigOnOneFrameOverN )); + msg (( MSG_OUT, "ParTrigOnNConsecutiveFrames = %.4d", PtRec->ParTrigOnNConsecutiveFrames )); + msg (( MSG_OUT, "Trig [0]=%.4d [1]=%.4d [2]=%.4d [Last]=%.4d", PtRec->ParATrig[0], PtRec->ParATrig[1], PtRec->ParATrig[2], PtRec->ParATrig[3] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfDRamSzMb = %.4d", PtRec->InfDRamSzMb )); + msg (( MSG_OUT, "InfDRamSz = %.4d", PtRec->InfDRamSz )); + msg (( MSG_OUT, "InfDRamPtr = %.8x", PtRec->InfDRamPtr )); + msg (( MSG_OUT, "InfExtraChan = %.4d", PtRec->InfExtraChan )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqFunctRetCode = %.4d", PtRec->ResAcqFunctRetCode )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResEvCnt = %.4d", PtRec->ResEvCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmul () + : +Goal : Print lib acquisition emulation context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.AcqEmul = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) + : +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmul () { + + return ( EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheckRec ( EFRIO_TFrCheck* PtRec ) + : +Goal : Print frame check context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheckRec ( EFRIO__TFrCheck* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Frames check record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqNo = %.4d", PtRec->ParAcqNo )); + msg (( MSG_OUT, "ParFrNo = %.4d", PtRec->ParFrNo )); + msg (( MSG_OUT, "ParChkMode = %.4d", PtRec->ParChkMode )); + msg (( MSG_OUT, "ParFrPrintLevel = %.4d", PtRec->ParFrPrintLevel )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfMi26Nb = %.4d", PtRec->InfMi26Nb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResAHeader[0] , PtRec->ResAHeader[1] , PtRec->ResAHeader[2] , PtRec->ResAHeader[3] , PtRec->ResAHeader[4] , PtRec->ResAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResATrailer[0] , PtRec->ResATrailer[1] , PtRec->ResATrailer[2] , PtRec->ResATrailer[3] , PtRec->ResATrailer[4] , PtRec->ResATrailer[5] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResAFrameCnt[0] , PtRec->ResAFrameCnt[1] , PtRec->ResAFrameCnt[2] , PtRec->ResAFrameCnt[3] , PtRec->ResAFrameCnt[4] , PtRec->ResAFrameCnt[5] )); + msg (( MSG_OUT, "DL [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResADataLenght[0], PtRec->ResADataLenght[1], PtRec->ResADataLenght[2], PtRec->ResADataLenght[3], PtRec->ResADataLenght[4], PtRec->ResADataLenght[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResTrigNb = %.4d", PtRec->ResTrigNb )); + msg (( MSG_OUT, "TRG [0]=%.8d [1]=%.8d [3]=%.8d [Last]=%.8d", PtRec->ResATrig[0], PtRec->ResATrig[1], PtRec->ResATrig[2], PtRec->ResATrig[3] )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheck () + : +Goal : Print lib frame check context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.FrCheck = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheck () { + + return ( EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - > 0 -> print state list for each line + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 22/12/2010 +Rev : 30/12/2010 + : - Add handling of N Mimosa 26 + : +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + MI26__TStatesLine VStatesLine; + MI26__TState VState; + SInt16 ViMi26; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + char VStrState[255]; + char VStrLine[255]; + + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + + msg (( MSG_OUT, "===================================================================================" )); + msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); + msg (( MSG_OUT, "===================================================================================" )); + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + ViStatesLine = 0; + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Copy StatesLine field + + VStatesLine.W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VStatesLine.F.StateNb; + + sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf ); + + if ( (PrintLevel != 0) ) { + msg (( MSG_OUT, "%s", VStrLine )); + } + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + VState.W16 = VPtSrcW16[ViSrcW16]; + + sprintf ( VStrState, "[Col %4d - %1d pixel(s)] ", VState.F.ColAddr, VState.F.HitNb + 1 ); + // strcat ( VStrLine , VStrState ); + + if ( (PrintLevel != 0) ) { + msg (( MSG_OUT, "%s", VStrState )); + } + + ++ViSrcW16; + } + + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + ++ViStatesLine; + + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + } // End for ( ViMi26 ) + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - 1 -> Print AcqId & FrId + : - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + : - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + : - 4 -> Print trigger list + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 06/11/2010 +Rev : 21/02/2011 + : - Print new field DaqVersion +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTriggerRec* VPtTrig; + SInt16 ViTrig; + char VStrTrig[30]; + char VStrTs [30]; + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Trigger record follows the data record which has a VARIABLE size + + VPtTrig = (EFRIO__TTriggerRec*) ( (UInt8*) PtRec + PtRec->TrigRecOffset ); + + // ------------------------------------- + // Print TFrame fields + // ------------------------------------- + + if ( PrintLevel == 1 ) { + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, "AcqId = %.4d - FrameIdInAcq = %.4d - TrigNb = %.4d [D]", VPtHead->AcqId, VPtHead->FrameIdInAcq, VPtTrig->TrigNb )); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + + return (0); + } + + + msg (( MSG_OUT, "==============================================" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "Tag = %.8X [H]", PtRec->Tag )); +#endif + msg (( MSG_OUT, "DaqVersion = %.4d [D]", PtRec->DaqVersion )); + msg (( MSG_OUT, "TotSz = %.4d [D]", PtRec->TotSz )); + msg (( MSG_OUT, "TrigRecOffset = %.4d [D]", PtRec->TrigRecOffset )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "H.Tag = %.8X [H]", VPtHead->Tag )); +#endif + msg (( MSG_OUT, "H.AcqStatus = %.4d [D]", VPtHead->AcqStatus )); + msg (( MSG_OUT, "H.TrigStatus = %.4d [D]", VPtHead->TrigStatus )); + msg (( MSG_OUT, "H.AcqId = %.4d [D]", VPtHead->AcqId )); + msg (( MSG_OUT, "H.FrameIdInAcq = %.4d [D]", VPtHead->FrameIdInAcq )); + msg (( MSG_OUT, "H.MapsName = %.4d [D]", VPtHead->MapsName )); + msg (( MSG_OUT, "H.MapsNb = %.4d [D]", VPtHead->MapsNb )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.Header [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsHeader[0] , VPtHead->AMapsHeader[1] , VPtHead->AMapsHeader[2] , VPtHead->AMapsHeader[3] , VPtHead->AMapsHeader[4] , VPtHead->AMapsHeader[5], VPtHead->AMapsHeader[6], VPtHead->AMapsHeader[7] )); + msg (( MSG_OUT, "H.FrCnt [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsFrameCnt[0] , VPtHead->AMapsFrameCnt[1] , VPtHead->AMapsFrameCnt[2] , VPtHead->AMapsFrameCnt[3] , VPtHead->AMapsFrameCnt[4] , VPtHead->AMapsFrameCnt[5], VPtHead->AMapsFrameCnt[6], VPtHead->AMapsFrameCnt[7] )); + msg (( MSG_OUT, "H.DataSz [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsDataLength[0], VPtHead->AMapsDataLength[1], VPtHead->AMapsDataLength[2], VPtHead->AMapsDataLength[3], VPtHead->AMapsDataLength[4], VPtHead->AMapsDataLength[5], VPtHead->AMapsDataLength[6], VPtHead->AMapsDataLength[7] )); + msg (( MSG_OUT, "H.Trailer [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsTrailer[0] , VPtHead->AMapsTrailer[1] , VPtHead->AMapsTrailer[2] , VPtHead->AMapsTrailer[3] , VPtHead->AMapsTrailer[4] , VPtHead->AMapsTrailer[5], VPtHead->AMapsTrailer[6], VPtHead->AMapsTrailer[7] )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.TriggerNb = %.4d [D]", VPtHead->TriggerNb )); + msg (( MSG_OUT, "H.TrigInfo [0]=%.8X [1]=%.8X [2]=%.8X ", VPtHead->AMapsTrigInfo[0], VPtHead->AMapsTrigInfo[1], VPtHead->AMapsTrigInfo[2] )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "D.Tag = %.8X [H]", VPtData->Tag )); +#endif + msg (( MSG_OUT, "D.TotSz = %.4d [D]", VPtData->TotSz )); + msg (( MSG_OUT, "D.OneMapsSz = %.4d [D]", VPtData->OneMapsSz )); + + if ( PrintLevel == 3 ) { + EFRIO__FPrintFrameData ( PtRec, PrintLevel ); + } + + if ( PrintLevel < 4 ) { + msg (( MSG_OUT, "===================================================================================" )); + return (0); + } + + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "T.Tag = %X [H]", VPtTrig->Tag )); +#endif + msg (( MSG_OUT, "T.TotSz = %.4d [D]", VPtTrig->TotSz )); + msg (( MSG_OUT, "T.TrigNb = %.4d [D]", VPtTrig->TrigNb )); + msg (( MSG_OUT, "T.TrigType = %d [D]", VPtTrig->TrigType )); + + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) + : +Goal : Print monitor context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Monitor context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "InfFrameNbToSend = %.4d", PtRec->InfFrameNbToSend )); + msg (( MSG_OUT, "InfSzToSend = %.4d", PtRec->InfSzToSend )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonCont () + : +Goal : Print lib monitor context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMoniCont () { + + return ( EFRIO__FPrintMonContRec (&EFRIO__VGContext.MonCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintTestOnDataContRec ( EFRIO__TTestOnDataCont* PtRec, char* Msg ) +: +Goal : Print monitor context record in log file +: +Inputs : PtRec - Pointer on the record +: +Ouputs : The function returns +: 0 if ok +: -1 if PtRec = NULL +: +Globals : +: +Remark : +: +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintTestOnDataContRec ( EFRIO__TTestOnDataCont* PtRec, char* Msg ) { + + SInt8 ViMaps; + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Test on data context record => Print only relevant fields !" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "Message : %s", Msg )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParModeEnable = %d", PtRec->ParModeEnable )); + msg (( MSG_OUT, "ParResetCnt = %d", PtRec->ParResetCnt )); + msg (( MSG_OUT, "ParPrintLvl = %d", PtRec->ParResetCnt )); + msg (( MSG_OUT, "ParMapsNb = %d", PtRec->ParMapsNb )); + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ParAMapsHeaderRef[%d] = %.8x", ViMaps, PtRec->ParAMapsHeaderRef[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ParAMapsTrailerRef[%d] = %8x", ViMaps, PtRec->ParAMapsTrailerRef[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsErrCnt[ViMaps] )); + } + + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsHeaderErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsHeaderErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsFrameCntErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsFrameCntErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsDataLengthErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsDataLengthErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsTrailerErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsTrailerErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + + msg (( MSG_OUT, "ResTotErrCnt = %.4d", PtRec->ResTotErrCnt )); + msg (( MSG_OUT, "ResFrameNbWithErr = %.4d", PtRec->ResFrameNbWithErr )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintTestOnDataCont ( char* Msg ) +: +Goal : Print lib monitor context record in log file +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible +: +Globals : +: +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) +: +Level : +Date : 29/04/2011 +Doc date : 29/04/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintTestOnDataCont ( char* Msg ) { + + return ( EFRIO__FPrintTestOnDataContRec (&EFRIO__VGContext.TestOnDataCont, Msg) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMsg ( + : SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, + : SInt8 PrintAsError, char* Msg ) + : +Goal : Print messages in msg or error log file from LabView -> A Vi encapsulets this function. + : +Inputs : DummyS32In - Dummy value used under Labview to easily " chain " function execution. + : + : To execute it after a Vi call, connect any output of this Vi to the + : DummyS32In pin and it will be automatically called after Vi end. + : To execute it before a Vi call, if this Vi has an integer parameter + : cut the wire and insert DummyS32In input and function output on it. + : + : Printing mode flags + : + : PrintAsMsg - If 1 -> Print in messages log file + : PrintAsTrace - If 1 -> Print in errors log file as a trace message + : PrintAsWarning - If 1 -> Print in errors log file as a warning message + : PrintAsError - If 1 -> Print in errors log file as an error message + : + : Msg - Message to print ( string ) + : +Ouputs : The function always returns the input parameter DummyS32In. + : +Globals : + : +Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) + : It can be used to insert this function call on an integer datapath under LabView + : + : If more than one printing mode flag is enabled therefore the same message will + : be printed in different ways. + : +Level : +Date : 09/08/2010 +Rev : 25/10/2010 + : - Implementation -> Empty function before +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", Msg )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", Msg )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", Msg )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", Msg )); + + return (DummyS32In); +} + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/files.c b/include/pxi_daq_lib_v.1.2/files.c new file mode 100755 index 0000000..a64121c --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/files.c @@ -0,0 +1,3773 @@ + +#ifndef FIL_C +#define FIL_C + + +#ifdef CC_UNIX + +UInt32 GetTickCount () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + + +SInt32 GetLastError () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + +#endif + +/******************************************************************************* +Prototype : SInt32 FIL_FFileExists ( char* FilePath ) +Goal : Test if the file exists. +Inputs : The file name ( full path if needed ). +Ouputs : 1 if the file exists, else 0. +Globals : +Remark : The result is not guaranted in case of multi application lock to file. +Level : This is a user level function. +Date : 17/04/2003 +Doc date : 17/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FFileExists ( char* FilePath ) { + + SInt32 VRet; + FILE* VPf; + + VPf = fopen ( FilePath, "r" ); + + if ( VPf == NULL ) { + VRet = 0; + } + + else { + fclose ( VPf ); + VRet = 1; + } + + + return (VRet); +} + +/* 13/10/2004 */ + +SInt32 FIL_FFileSize ( char* FilePath ) { + + FILE* VPf; + SInt32 VFileSz; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fopen fail !" ) )); + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fclose (VPf) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fclose fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "%d Bytes", VFileSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FCpyFile ( char* Src, char* Dest ) + : +Goal : Copy SrcFile to DestFile. + : +Inputs : Src - Source file + : Dest - Destination file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - fonction moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FCpyFile ( char* Src, char* Dest ) { + + FILE* VPfSrc; + FILE* VPfDest; + SInt8 VBuffer[512]; // Debug 02/06/2007 move storage class static to auto + SInt32 VReadBytesCnt; + SInt32 VTotBytesCnt; + SInt32 VRet; + + VPfSrc = fopen ( Src, "rb" ); + + err_retnull ( VPfSrc, (ERR_OUT,"Source file %d open failed", Src ) ); + + VPfDest = fopen ( Dest, "wb" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", VPfDest ) ); + + VTotBytesCnt = 0; + + while ( ( VReadBytesCnt = fread ( VBuffer, 1 /* byte size */ , 512 /* bytes number */, VPfSrc ) ) > 0 ) { + fwrite ( VBuffer, 1 /* byte size */, VReadBytesCnt, VPfDest ); + VTotBytesCnt += VReadBytesCnt; + } + + fclose (VPfSrc); + fclose (VPfDest); + + err_retok (( ERR_OUT, "file %s copied in %s => %d bytes", Src, Dest, VTotBytesCnt )); +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FRemoveFile ( char* FilePath ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FRemoveFile ( char* FilePath ) { + + SInt32 VRet; + char* VStrError; + + VRet = remove ( FilePath ); + + err_retfail ( VRet, (ERR_OUT,"Remove file=%s failed => %s", FilePath, _strerror ("")) ); + err_retok (( ERR_OUT, "")); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) + : +Goal : List the directory SrcDir and write the result in DestDirFile. + : +Inputs : SrcDir - The directory to list + : DestDirFile - The result file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - Function moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + + VPf = fopen ( DestDirFile, "wt" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT, "Dir file %s creation failed ", DestDirFile ) ); + } + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + ++VItemCnt; + fprintf( VPf, "%s\n", VFileInfo.ff_name); + VRet = findnext(&VFileInfo); + } + + fclose ( VPf ); + + return (0); +} + + +#endif + + +SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosDirOutFile ( SrcDir, DestDirFile ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FDosDelDir ( char* SrcDir ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : Compiled only if CC_APP_WINDOWS is defined +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosRmDirFiles ( char* SrcDir ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + char VFileToDelete[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + SInt32 VRetRemove; + SInt32 VFuncRet; + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VFuncRet = 0; + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + sprintf ( VFileToDelete, "%s\\%s", SrcDir, VFileInfo.ff_name ); + VRetRemove = FIL_FRemoveFile ( VFileToDelete ); + + if ( VRetRemove < 0 ) { + VFuncRet = -1; + err_error (( ERR_OUT, "Remove file=%s failed => %s", VFileToDelete, _strerror ("") )); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + + return (VFuncRet); +} + +#endif + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDirFiles ( char* SrcDir ) +Goal : Remove all the files in directory SrcDir but let the direcory +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDirFiles ( char* SrcDir ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosRmDirFiles (SrcDir) ); + +#else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available !", SrcDir) ); +#endif + + +} + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDir ( char* SrcDir ) +Goal : Remove the directory SrcDir if empty +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDir ( char* SrcDir ) { + + SInt32 VRet; + +#ifdef CC_APP_WINDOWS + + // VRet = _rtl_chmod( SrcDir, 1 , FA_NORMAL ); + // err_retfail ( VRet, (ERR_OUT,"Chmod failed on directory=%s", SrcDir) ); + + VRet = rmdir ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"Remove directory=%s failed => %s ", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + +#else + err_retfail ( -1, (ERR_OUT,"Function handled only under Windows") ); +#endif + +} + +/******************************************************************************* +Prototype : +Goal : Delete direcory files and directory itself +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelDir ( char* SrcDir ) { + + SInt32 VRet; + char VNewName[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + + sprintf ( VNewName, "%s.old", SrcDir ); + + VRet = rename ( SrcDir, VNewName ); + + err_retfail ( VRet, (ERR_OUT,"Rename Dir=%s to %s failed !", SrcDir, VNewName ) ); + + err_warning (( ERR_OUT, "Directory %s renamed in %s because delete is impossible !", SrcDir, VNewName )); + + err_retok (( ERR_OUT, "" )); + +/* + VRet = FIL_FRmDirFiles ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDirFiles (%s) failed ", SrcDir) ); + + VRet = FIL_FRmDir ( VNewName ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDir (%s) failed ", SrcDir) ); + + err_retok (( ERR_OUT, "" )); +*/ + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FMkDir ( char* SrcDir ) { + + SInt32 VRet; + char VStrCmd[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + #ifdef APP_DAQ + + err_retfail ( -1, (ERR_OUT,"Function NOT available under LynxOS !") ); + + #endif + + #ifdef CC_APP_LINUX + sprintf ( VStrCmd, "mkdir %s", SrcDir ); + system ( VStrCmd ); + #endif + + + #ifdef CC_APP_WINDOWS + VRet = mkdir ( SrcDir ); + + err_retfail ( VRet, (ERR_OUT,"Creation of directory=%s failed => %s", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FMkDir (SrcDir=%s) IS NOT available !", SrcDir) ); + #endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in + : the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT + : are not written in list. +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in +: the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT +: are not written in list. +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIL_FExtDosListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\%s", SrcDir, Joker ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIl_FDosListDirFiles ( SrcDir, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIL_FExtDosListDirFiles ( SrcDir, Joker, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList ) { + + SInt32 VRet; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + VFilesCnt = FIl_FListDirFiles ( VRmpDirPath, PtList ); + + return ( VFilesCnt ); +} + + + +#ifndef APP_DAQ + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Extended version which handles conf extension i,j,k +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtDelRmpFiles ( char* RmpDataPath, char ConfExt, SInt32 RunNo, SInt32 MaxFileCnt ) { + + SInt32 VRet; + SInt32 ViFile; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VInfoFilePath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VData0Filepath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + FIL_TDirFilesList VFilesList; // Debug 02/06/2007 move storage class static to auto + + + char VFileToDelete[GLB_FILE_PATH_SZ]; + + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + sprintf ( VInfoFilePath , "RUN_%d_%c.rz", RunNo, ConfExt ); + sprintf ( VData0Filepath, "RUN_%d_0.rz" , RunNo ); + + VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &VFilesList ); + + /* !!! DESY 20/09/05 !!! MUST BE CHECKED ! */ + /* previous line replaced by this one in order to be able to compile boards_db_man */ + /* VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &(VPtAFilesPath) ); */ + + err_retfail ( VFilesCnt, (ERR_OUT,"FIL_FCntRmpFiles (%s) failed Ret=%d", RmpDataPath, VFilesCnt ) ); + + if ( VFilesCnt < MaxFileCnt ) { + err_retok (( ERR_OUT, "Nothing to do VFilesCnt=%d < MaxFileCnt=%d", VFilesCnt, MaxFileCnt )); + } + + err_warning (( ERR_OUT, "%d RMP files are not deleted by monitoring => I will remove them", VFilesCnt )); + + for ( ViFile = 0; ViFile < VFilesCnt; ViFile++ ) { + + if ( strcmp ( VFilesList.AList[ViFile], VInfoFilePath ) == 0 ) { + continue; + } + + if ( strcmp ( VFilesList.AList[ViFile], VData0Filepath ) == 0 ) { + continue; + } + + sprintf ( VFileToDelete, "%s\\%s", VRmpDirPath, VFilesList.AList[ViFile] ); + + err_warning (( ERR_OUT, "FIL_FDelRmpFilesv => File = %s", VFileToDelete )); + + FIL_FRemoveFile ( VFileToDelete ); + + } + + return (0); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Creation of FIL_FExtDelRmpFiles to replace FIL_FDelRmpFiles + : - FIL_FDelRmpFiles call FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt ) { + return ( FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) ); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FFloatVectorsToTextFile ( float** SrcVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** VectorsNames, char DataSep, char* DestFile ) { + + char VFuncName[] = "FIL_FFloatVectorsToTextFile"; + + FILE* VPfDest; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + + + VPfDest = fopen ( DestFile, "wt" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", DestFile ) ); + + + if ( HeaderLine != NULL ) { + VRet = fprintf ( VPfDest, "%s \n", HeaderLine ); + } + + else { + VRet = fprintf ( VPfDest, "No header line \n", HeaderLine ); + } + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing Header line file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + + if ( VectorsNames != NULL ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + VRet = fprintf ( VPfDest, "%-21s", VectorsNames[ViVector]); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing vectors names line - Vector=%d file=%s => %s", ViVector, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + VRet = fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + } + + else { + fprintf ( VPfDest, "No vectors names line \n", HeaderLine ); + } + + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + VRet = fprintf ( VPfDest, "%.6f%c", SrcVectors[ViVector][ViLine], DataSep); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing line=%d in file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR line=%d file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + fflush (VPfDest); + fclose (VPfDest); + + err_retok (( ERR_OUT, "%d line written in file", EltNbPerVector, DestFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#undef CC_FIL + +#ifdef CC_FIL + +SInt32 FIL_FTextFileToFloatVectors ( char* SrcFile, char DataSep, float** DestVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** AVectorsNames, char* StrVectorsNames ) { + + char VFuncName[] = "FIL_FTextFileToFloatVectors"; + + FILE* VPf; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + char VStrCR[2]; + char VDataSep; + + /* Check parameters */ + + err_retnull ( SrcFile , (ERR_OUT,"SrcFile == NULL" ) ); + err_retnull ( DestVectors , (ERR_OUT,"DestVectors == NULL" ) ); + err_retnull ( HeaderLine , (ERR_OUT,"HeaderLine == NULL" ) ); + err_retnull ( AVectorsNames , (ERR_OUT,"AVectorsNames == NULL" ) ); + err_retnull ( StrVectorsNames , (ERR_OUT,"StrVectorsNames == NULL" ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 1" )); + + /* Try to open file */ + + VPf = fopen ( SrcFile, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFile ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read header line */ + + VRet = (SInt32) fgets( HeaderLine, 255, VPf ); + + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read header line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + /* Read vectors names line */ + + + VRet = (SInt32) fgets( StrVectorsNames, 255, VPf ); + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read vectors names line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + sprintf ( AVectorsNames[ViVector], "" ); + }; + + + /* Read vectors */ + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + if ( ViVector == VectorsNb-1 ) { + VRet = fscanf ( VPf, "%f%c", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + else { + VRet = fscanf ( VPf, "%f%c\n", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + + if ( VRet != 2 ) { + fflush (VPf); + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s", ViLine, SrcFile, VRet, _strerror ( "System says :" ) ) ); + } + + } + + } + + + fflush (VPf); + fclose (VPf); + + err_retok (( ERR_OUT, "%d line Read in file", EltNbPerVector, SrcFile )); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef CC_APP_WINDOWS + + SInt32 FIL_FGetAppRunDir ( char* StrRunDir, TApplication* PtApp ) { + + char* VPtStrExeName; + AnsiString VAStrExeName; + char VExeDriveLetter; + char VExeDriveId; /* 0 = default, 1 = A, 2 = B ... */ + char VStrCurDir[GLB_FILE_PATH_SZ]; + char VStrCurDirPath[GLB_FILE_PATH_SZ]; + + err_retfailnull ( StrRunDir, (ERR_OUT,"StrRunDir == NULL") ); + + VPtStrExeName = FStr2PCh ( &(PtApp->ExeName) ); + + VExeDriveLetter = toupper ( VPtStrExeName[0] ); + + switch ( VExeDriveLetter ) { + + case 'A' : { + VExeDriveId = 1; + break; } + + case 'B' : { + VExeDriveId = 2; + break; } + + case 'C' : { + VExeDriveId = 3; + break; } + + case 'D' : { + VExeDriveId = 4; + break; } + + case 'E' : { + VExeDriveId = 5; + break; } + + case 'F' : { + VExeDriveId = 6; + break; } + + case 'G' : { + VExeDriveId = 7; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown drive id=%d", VExeDriveId) ); + VExeDriveId = 0; + } + + } + + getcurdir( VExeDriveId, VStrCurDir ); + + sprintf ( VStrCurDirPath, "%c:\\%s", VExeDriveLetter, VStrCurDir ); + sprintf ( StrRunDir, "%s", VStrCurDirPath ); + + // msg (( MSG_OUT, "VStrCurDirPath = %s", VStrCurDirPath )); + + err_retok (( ERR_OUT, "" )); + } + +#else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 07/03/2011 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FGetDiskSectorSz ( char* Drive ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported under Unix !" ) ); + +#else + + DWORD VDummyW; + DWORD VBytesPerSector; + BOOL VRetBool; + + + // BOOL GetDiskFreeSpace( + // + // LPCTSTR lpRootPathName, // address of root path + // LPDWORD lpSectorsPerCluster, // address of sectors per cluster + // LPDWORD lpBytesPerSector, // address of bytes per sector + // LPDWORD lpNumberOfFreeClusters, // address of number of free clusters + // LPDWORD lpTotalNumberOfClusters // address of total number of clusters + // ); + + + VRetBool = GetDiskFreeSpace( + Drive, // address of root path + &VDummyW, // address of sectors per cluster + &VBytesPerSector, // address of bytes per sector + &VDummyW, // address of number of free clusters + &VDummyW // address of total number of clusters + ); + + if ( VRetBool == True ) { + return ( VBytesPerSector ); + } + + else { + return (-1); + } + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: ~FIL__TCBinFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + + // Variables for internal processing + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdEltId = 0; + ProCurRdSz = 0; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProPtFile = NULL; + + err_trace (( ERR_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + ProParRWBMode = RWBMode; + ProParMaxBlocSz = MaxBlocSz; + ProParBlocSz = BlocSz; + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + ProConfDone = 1; + + + // Allocate memory buffer for data read from file + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = MaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCBinFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProPtFile == NULL ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + + // Store current ( initial ) position in file + + if ( (VCurPos = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Goto end of file + + if ( fseek ( ProPtFile, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + // Get current position = END in file => it's file size + + if ( (VFileSz = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Restor initial position in file + + if ( fseek ( ProPtFile, VCurPos, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + + } // End file is already open + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFCreate () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProPtFile = fopen ( ProParDataFile, "wb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFOpen () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + ProPtFile = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz ) { + SInt8 VBlocNbWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can write to a file when RWB mode IS NOT Write !") ); + } + + ProCurWrSz = DataSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbWritten = fwrite ( PtrData, DataSz /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbWritten != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc write failed ! => System : %s", _strerror ("") ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + fflush ( ProPtFile ); + } + + ++ProCurWrEltId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", DataSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + if ( DataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > MaxDestSz=%d", DataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( DestPtr, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc read of %d bytes failed ! - VBlocNbRead = %d => System : %s", DataSzToRead, VBlocNbRead, _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + if ( DataSzToRead > ProParMaxBlocSz ) { + err_retfailnull ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > ProParMaxBlocSz=%d", DataSzToRead, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( ProPtrBuffRdData, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Bloc read failed ! => System : %s", _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGotoBloc ( SInt32 BlocNo ) { + + SInt32 VOffset; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + VOffset = BlocNo * ProParBlocSz; + + if ( fseek ( ProPtFile, VOffset, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Goto bloc %d => %d bytes from beginning failed !", BlocNo ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ) { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFFlush () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + fflush ( ProPtFile ); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFClose () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + fflush ( ProPtFile ); + } + + fclose ( ProPtFile ); + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + ProConfDone = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_WRITE, RecSz, RecSz, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFCreate (); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqWrite ( PtSrc, RecSz ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_READ, RecSz, RecSz, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFOpen(); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqRead ( PtDest, RecSz /* MaxDestSz */, RecSz /* DataSzToRead */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + + +// msg (( MSG_OUT, "Msg" )); + + + +// **************************** +// FIL__TCStreamFile +// **************************** + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl, DiskBlocSz ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: ~FIL__TCStreamFile () { + + // Free info record + + if ( ProPtRecInfFile != NULL ) { + free ( ProPtRecInfFile ); + } + +#ifndef CC_UNIX + TerminateThread ( ProThreadHnd , 0 /* Thread exit code */ ); + + DeleteCriticalSection ( &ProCsPrintMsg ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : 05/11/2010 + : - Error handling on disk access is not properly done, a message is printed + : but the error is not propagated => MUST be done. +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef CC_UNIX + +DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ) { + + FIL__TCStreamFile* VPtObj = (FIL__TCStreamFile*) lpParam; + + SInt32 VRet; + DWORD VBuffFull; + UInt32 VNbBytesToWrite; + UInt32 VNbBytesWritten; + char VStrMsg[GLB_CMT_SZ]; + + + while (1) { + + // Wait on buffer to read + + VBuffFull = WaitForSingleObject ( VPtObj->ProSemRdBuffHnd, INFINITE ); + + switch ( VBuffFull ) { + + case WAIT_OBJECT_0 : { + + + VNbBytesToWrite = VPtObj->ProParBlocSz; + + WriteFile( + VPtObj->ProFileHnd, // handle to file to write to + VPtObj->ProABuff[VPtObj->ProIndexRdBuff], // pointer to data to write to file + VNbBytesToWrite, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != VNbBytesToWrite ) { + sprintf ( VStrMsg, "ThreadDisk => Writing buff %d error !", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + else { + sprintf ( VStrMsg, "ThreadDisk => Buffer %d save to disk", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + if ( VPtObj->ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( VPtObj->ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + ++VPtObj->ProIndexRdBuff; + + err_retfail ( VPtObj->ProIndexRdBuff, (ERR_OUT,"Bad variable size => ProIndexRdBuff=%d < 0", VPtObj->ProIndexRdBuff) ); + + if ( VPtObj->ProIndexRdBuff >= FIL__TCStreamFile_MAX_BUFF_NB ) { + VPtObj->ProIndexRdBuff = 0; + } + + ReleaseSemaphore ( VPtObj->ProSemWrBuffHnd, 1, NULL ); + + + break; } + + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFull )); + break; } + + } + + + + } // End while (1) + + return 0; +} + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 05/11/2010 +Doc date : 05/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFCalcProParBlocSz ( SInt32 DataSz ) { + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VRecInfSz; + + VNotIntegerDiskBlocNb = DataSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (DataSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = DataSz; + } + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + SInt8 ViBuff; + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + ProParDiskBlocSz = DiskBlocSz; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + sprintf ( ProInfFileName, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + ProParFixedBlocSzMode = 1; + + // Variables for internal processing + + ProUseThread = 0; + + ProFileHnd = INVALID_HANDLE_VALUE; + ProPtInfFile = NULL; + +#ifndef CC_UNIX + InitializeCriticalSection ( &ProCsPrintMsg ); +#endif + + ProThreadHnd = INVALID_HANDLE_VALUE; + ProThreadId = 0; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProABuff[ViBuff] = NULL; + } + + ProSemWrBuffHnd = INVALID_HANDLE_VALUE; + ProSemRdBuffHnd = INVALID_HANDLE_VALUE; + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + ProBuffSz = 0; + + ProPtRecInfFile = NULL; + ProRecInfSz = 0; + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdBlocId = 0; + ProCurRdSz = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetDiskSectorSz ( SInt32 DiskBlocSz ) { + + ProParDiskBlocSz = DiskBlocSz; + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetDiskSectorSz () { + + return (ProParDiskBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void FIL__TCStreamFile :: PubFPrintMsg ( char* Msg ) { + +#ifndef CC_UNIX + EnterCriticalSection( &ProCsPrintMsg ); +#endif + err_trace (( ERR_OUT, "%s", Msg )); + +#ifndef CC_UNIX + LeaveCriticalSection( &ProCsPrintMsg ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt8 ViBuff; + SInt32 VNotIntegerDiskBlocNb; +#ifndef CC_UNIX + TDateTime VODateTime; +#endif + + + + // ------------------------------------------------------- + // Set class parameters from PubFConf parameters list + // ------------------------------------------------------- + + err_retnull ( PtMyself, (ERR_OUT,"PtMyself == NULL") ); + + PriPtMyself = PtMyself; + + ProUseThread = UseThread; + + sprintf ( ProParDataFile, "%s", DataFile ); + + sprintf ( ProInfFileName, "%s.inf", ProParDataFile ); + + ProParRWBMode = RWBMode; + + ProParFixedBlocSzMode = FixedBlocSzMode; + + ProParRequestedBlocSz = BlocSz; + + VNotIntegerDiskBlocNb = ProParRequestedBlocSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (ProParRequestedBlocSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = ProParRequestedBlocSz; + } + + err_trace (( ERR_OUT, "RequestedBlocSz=%d - BlocSz=%d", ProParRequestedBlocSz, ProParBlocSz )); + + + ProParRequestedMaxBlocSz = MaxBlocSz; + + if ( ProParRequestedMaxBlocSz >= ProParBlocSz ) { + ProParMaxBlocSz = ProParRequestedMaxBlocSz; + } + + else { + err_warning (( ERR_OUT, "ProParMaxBlocSz=%d must be adjusted -> Set to ProParBlocSz=%d", ProParMaxBlocSz, ProParBlocSz )); + ProParMaxBlocSz = ProParBlocSz; + } + + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + // ------------------------------------------------------- + // Alloc information file record + // ------------------------------------------------------- + + if ( ProParFixedBlocSzMode == 1 ) { + ProRecInfSz = sizeof (FIL__TCStreamFile_Old_TRecInfFile); + } + + else { + + // BUG ? + + // ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (UInt64) ); + + ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (FIL__TCStreamFile_TBlocInf) ); + + } + + ProPtRecInfFile = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFile, (ERR_OUT,"Allocation of info record failed !") ); + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // ------------------------------------------------------- + // Create or open information file + // ------------------------------------------------------- + + // Write mode => Create info file + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProPtRecInfFile->Version = 1; + ProPtRecInfFile->FixedBlocSz = ProParFixedBlocSzMode; + ProPtRecInfFile->MaxBlocSz = ProParMaxBlocSz; + ProPtRecInfFile->BlocSz = ProParBlocSz; + ProPtRecInfFile->BlocNb = 0; + ProPtRecInfFile->ABlocInf[0].Offset = 0; + ProPtRecInfFile->ABlocInf[0].Sz = 0; + +#ifndef CC_UNIX + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateCreate = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeCreate = TIME__FConvDateTime2Time ( VODateTime ); +#else + ProPtRecInfFile->DateCreate.W32 = 0; + ProPtRecInfFile->TimeCreate.W32 = 0; +#endif + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Creation of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + err_trace (( ERR_OUT, "Info file=%s created", ProInfFileName )); + } + + // Read mode => Open info file + + else { + + ProPtInfFile = fopen ( ProInfFileName, "rb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Open info file %s failed => system : %s", ProInfFileName, _strerror ( "" ) )); + err_trace (( ERR_OUT, "Info file=%s read", ProInfFileName )); + + if ( fread ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Read info file %s failed => system : %s", ProInfFileName, _strerror ( "" )) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + // Print info file + + PubFPrintInfFile (); + + // Set bloc size + + ProParBlocSz = ProPtRecInfFile->BlocSz; + + if ( ProParRequestedBlocSz != ProParBlocSz ) { + err_warning (( ERR_OUT, "Requested bloc sz=%d <> Info file bloc sz=%d => Use Info file bloc sz", ProParRequestedBlocSz, ProParBlocSz )); + } + + } + + + // ------------------------------------------------------------- + // Write mode => Allocate buffers, create semaphores and thread + // ------------------------------------------------------------- + + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + if ( FIL__TCStreamFile_MAX_BUFF_NB > 4 ) { + err_retfail ( -1, (ERR_OUT,"FIL__TCStreamFile_MAX_BUFF_NB = %d ! Handling of more than 4 buffers is NOT implemented !", FIL__TCStreamFile_MAX_BUFF_NB) ); + } + + // Allocate buffers + + ProBuffSz = ProParMaxBlocSz; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + // If already allocated => Free + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + } + + // Allocate + + ProABuff[ViBuff] = (UInt8*) malloc ( ProBuffSz ); + + err_retnull ( ProABuff[ViBuff], (ERR_OUT,"Allocation buffer[%d] of %d bytes failed !", ViBuff, ProBuffSz ) ); + err_trace (( ERR_OUT, "Buffer[%d] of %d bytes allocated", ViBuff, ProBuffSz )); + + // Reset content with $FF + + memset ( ProABuff[ViBuff], 0xFF, ProBuffSz ); + } + + // Create & init semaphores + + #ifndef CC_UNIX + ProSemWrBuffHnd = CreateSemaphore( NULL, FIL__TCStreamFile_MAX_BUFF_NB, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = Max = Max buff nb + + err_retnull ( ProSemWrBuffHnd, (ERR_OUT,"Create SemWrBuff failed ! - LastError=%d", GetLastError ()) ); + + ProSemRdBuffHnd = CreateSemaphore( NULL, 0, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = 0, Max = Max buff nb + + err_retnull ( ProSemRdBuffHnd, (ERR_OUT,"Create SemRdBuff failed ! - LastError=%d", GetLastError ()) ); + #endif + + // Init buffers index + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + // Create thread + + #ifndef CC_UNIX + ProThreadHnd = CreateThread ( NULL, 0, FIL__TCStreamFile_FThread, (void*) PriPtMyself /* Param */ , 0, &ProThreadId ); + err_retnull ( ProThreadHnd, (ERR_OUT,"Thread creation failed ! LastError=%d", GetLastError ()) ); + #endif + + } + + // ------------------------------------------------------------- + // Read mode => Allocate memory buffer for data read from file + // ------------------------------------------------------------- + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = ProParMaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 20/05/2010 +Doc date : 20/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFile () { + + SInt32 ViBloc; + SInt16 ViSpareW32Info; + + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record " )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Version = %d", ProPtRecInfFile->Version )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Date create = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateCreate, NULL, 0 ) )); + // Following lines crashing under Ubuntu 10, 64 bits +// msg (( MSG_OUT, "Time create = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeCreate, NULL, 0 ) )); +// msg (( MSG_OUT, "Date close = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateClose , NULL, 0 ) )); +// msg (( MSG_OUT, "Time close = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeClose , NULL, 0 ) )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "FixedBlocSz = %d", ProPtRecInfFile->FixedBlocSz )); + msg (( MSG_OUT, "MaxBlocSz = %d", ProPtRecInfFile->MaxBlocSz )); + msg (( MSG_OUT, "BlocSz = %d", ProPtRecInfFile->BlocSz )); + msg (( MSG_OUT, "BlocNb = %d", ProPtRecInfFile->BlocNb )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "ABlocInf[0].Offset = %Lu", ProPtRecInfFile->ABlocInf[0].Offset )); + msg (( MSG_OUT, "ABlocInf[0].Sz = %d ", ProPtRecInfFile->ABlocInf[0].Sz )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoFormat = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoFormat )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoNb = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb )); + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb; ViSpareW32Info++ ) { + msg (( MSG_OUT, "ABlocInf[0].ASpareW32Info[%.2d] = %d ", ViSpareW32Info, ProPtRecInfFile->ABlocInf[0].ASpareW32Info[ViSpareW32Info] )); + } + + + if ( ProPtRecInfFile->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < ProPtRecInfFile->BlocNb; ViBloc++ ) { + msg (( MSG_OUT, "Bloc[%.4d] : Offset=%.12Lu - Sz=%.8d [Bytes] - ASpare [0]=%.4d [1]=%.4d [2]=%.4d [3]=%.4d", ViBloc, ProPtRecInfFile->ABlocInf[ViBloc].Offset, ProPtRecInfFile->ABlocInf[ViBloc].Sz, ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[0], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[1], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[2], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[3] )); + } + + } + + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + err_retfail ( -1, (ERR_OUT,"File is opened => Get file size not coded in this state (TOB ...)") ); + } + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 + : - Calculation => file size / block size +Rev : 20/05/2010 + : - Read from info file field BlocNb + : +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + +/* Before 20/05/2010 + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + +*/ + + VBlocNb = ProPtRecInfFile->BlocNb; + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFCreate () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_WRITE | GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFOpen () { + +#ifdef CC_UNIX + + ProFilePtUx = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProFilePtUx, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#endif +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation + : + : 24/02/2011 + : - Handle SpareW32Info as an array now => New parameters + : +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + SInt16 ViSpareW32Info; + DWORD VBuffFree; + UInt32 VNbBytesWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + err_retnull ( PtSpareW32Info, (ERR_OUT,"PtSpareW32Info == NULL") ); + + if ( SpareW32InfoNb > FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"SpareW32InfoNb=%d > Max=%d", SpareW32InfoNb, FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Cant write to a file when RWB mode IS NOT Write !") ); + } + + // If variable bloc sz mode => Test max nb of blocs allowed & Adjust ProParBlocSz + + if ( ProParFixedBlocSzMode == 0 ) { + + if ( ProPtRecInfFile->BlocNb >= FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE ) { + err_retfail ( -1, (ERR_OUT,"Max bloc nb = %d reached in variable bloc sz mode !", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE) ); + } + + ProFCalcProParBlocSz ( DataSz ); + } + + // err_error (( ERR_OUT, "DataSz=%d - ProParBlocSz=%d bytes", DataSz, ProParBlocSz )); + + ProCurWrSz = ProParBlocSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + // Let thread write data to disk in background task + + if ( ProUseThread == 1 ) { + + // Wait on buffer to write + + VBuffFree = WaitForSingleObject ( ProSemWrBuffHnd, 1 /* ms */ ); + + switch ( VBuffFree ) { + + case WAIT_TIMEOUT : { + ++ProResWrBlocFailCnt; + err_retfail ( -1, (ERR_OUT,"Write failed for the %d time -> No buffer available - DbgCallPar=%d !", ProResWrBlocFailCnt, DbgCallPar ) ); + break; } + + case WAIT_OBJECT_0 : { + + memcpy ( ProABuff[ProIndexWrBuff], PtrData, DataSz ); + + // PubFPrintMsg ( "Thread => Buffer %d filled", ProIndexWrBuff ); + err_trace (( ERR_OUT, "Thread => Buffer %d filled - DbgCallPar=%d", ProIndexWrBuff, DbgCallPar )); + + ++ProIndexWrBuff; + + err_retfail ( ProIndexWrBuff, (ERR_OUT,"Bad variable size => ProIndexWrBuff=%d < 0", ProIndexWrBuff) ); + + if ( ProIndexWrBuff >= FIL__TCStreamFile_MAX_BUFF_NB) { + ProIndexWrBuff = 0; + } + + ReleaseSemaphore ( ProSemRdBuffHnd, 1, NULL ); + break; } + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFree )); + break; } + + } + + } + + // Write NOW data to disk + + else { + + // Copy to buffer -> "Automatically" add padding bytes + + memcpy ( ProABuff[0], PtrData, DataSz ); + + // Warning => Write ProParBlocSz bytes AND NOT the value passed via parameter DataSz + // because non buffered I/O functions MUST write multiple of DISK bloc size + + WriteFile( + ProFileHnd, // handle to file to write to + ProABuff[0], // pointer to data to write to file + ProParBlocSz, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != ProParBlocSz ) { + err_retfail ( VRet, (ERR_OUT,"Writing block %d failed %d bytes written - %d bytes requested ! - %s", ProCurWrBlocId, VNbBytesWritten, ProParBlocSz, strerror ( errno ) ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + } + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + + if ( ProUseThread == 1 ) { + err_trace (( ERR_OUT, "Copy bloc of %d bytes done in %d [ms]", DataSz, ProTimeExec )); + } + + else { + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", VNbBytesWritten, ProTimeExec )); + } + + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + +#ifdef CC_UNIX + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + SInt32 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VBlocNbRead = fread ( DestPtr, VDataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProFilePtUx ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed of %d bytes ! - %s", ProCurRdBlocId, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#else + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + UInt32 VNbBytesRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + ReadFile( + ProFileHnd, // handle of file to read + DestPtr, // address of buffer that receives data + VDataSzToRead, // number of bytes to read + &VNbBytesRead, // address of number of bytes read + NULL // address of structure for data + ); + + if ( VNbBytesRead != VDataSzToRead ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed : %d bytes read - %d bytes requested ! - %s", ProCurRdBlocId, VNbBytesRead, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( ProPtrBuffRdData, ProSzBuffRdData, DataSzToRead ); + + err_retfailnull ( VRet, (ERR_OUT,"PubFSeqRead failed !") ); + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : Limited to 4 GB files + : +Rev : 09/05/2010 + : - Use W64 offset => Not limited to 4 GB file +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGotoBloc ( SInt32 BlocNo ) { + +#ifdef CC_UNIX + + SInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = fseeko ( ProFilePtUx, (off_t) VOffsetW64, SEEK_SET ); + + err_retfail ( VRet, (ERR_OUT,"Bloc %d read failed ! => System : %s", BlocNo, _strerror ("") ) ); + + err_retok (( ERR_OUT, "" )); + +#else + + UInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = SetFilePointer ( + ProFileHnd, // handle of file + *VPtOffsetLow32, // number of bytes to move file pointer + (SInt32*) VPtOffsetHigh32, // address of high-order word of distance to move + // lpDistanceToMoveHigh = 0 => Limited to 4 GB + FILE_BEGIN // how to move + ); + + + if ( VRet == 0xFFFFFFFF ) { + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &VMsgBuf, + 0, + NULL + ); + + err_retfail ( -1, (ERR_OUT,"Goto bloc %d failed => %s", BlocNo, VMsgBuf ) ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 24/02/2011 + : - Handle SpareW32Info as and array ASpareW32Info now => New parameters + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ) { + + SInt32 VRet; + SInt16 ViSpareW32Info; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + + if ( (PtSpareW32InfoFormat != NULL) && (PtSpareW32Info != NULL) && (ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb <= MaxSpareW32InfoNb) ) { + + *PtSpareW32InfoFormat = ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoFormat; + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb; ViSpareW32Info++ ) { + PtSpareW32Info[ViSpareW32Info] = ProPtRecInfFile->ABlocInf[BlocNo].ASpareW32Info[ViSpareW32Info]; + } + + } + + else { + err_warning (( ERR_OUT, "ASpareInfo bloc not updated ! Pointer NULL or Dest size too small ?" )); + } + + } + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + return (ProParBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + } + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFFlush () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFClose () { + + SInt32 VRet; + SInt8 ViBuff; +#ifndef CC_UNIX + TDateTime VODateTime; +#endif + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + PubFFlush (); + } + + ProConfDone = 0; + +#ifndef CC_UNIX + CloseHandle ( ProFileHnd ); +#endif + + // Free read buffers + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + // Free write buffers + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + ProABuff[ViBuff] = NULL; + } + + } + + + // Get close date & time + +#ifndef CC_UNIX + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateClose = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeClose = TIME__FConvDateTime2Time ( VODateTime ); +#else + ProPtRecInfFile->DateClose.W32 = 0; + ProPtRecInfFile->TimeClose.W32 = 0; +#endif + + + if ( ProReadyToWrite == 1 ) { + + // Overwrite info file with update close time & date + bloc nb + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Overwrite of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file failed => System : %s", strerror ( errno ) ) ); + } + + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* + Prototype : + Goal : returns the start run time in the day in seconds + Inputs : + Ouputs : + Globals : + Remark : + Level : + Date : 11/05/2012 + Doc date : 11/05/2012 + Author : Jerome BAUDOT + E-mail : baudot@in2p3.fr + Labo : IPHC */ +/******************************************************************************/ + +int FIL__TCStreamFile :: GetTime () { + + TIME__TSTime aTime = (ProPtRecInfFile->TimeCreate).Time; + + return aTime.Hour*60*60 + aTime.Min*60 + aTime.Sec; + +} + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.2/files.def b/include/pxi_daq_lib_v.1.2/files.def new file mode 100755 index 0000000..f6b8b7f --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/files.def @@ -0,0 +1,89 @@ +/* 24/02/05 */ + + +#ifndef FIL_DEF +#define FIL_DEF + +#define FIL_DIR_FILES_LIST_MAX_CNT 100 + +#define FIL__TCBinFile_MEAS_TIME +#define FIL__TCStreamFile_MEAS_TIME + +#define FIL__TCBinFile_RWB_MODE_WRITE 0 +#define FIL__TCBinFile_RWB_MODE_READ 1 +#define FIL__TCBinFile_RWB_MODE_BOTH 2 + +// 07/03/2009 +// Macro removed because they are not supported under ROOT ... +// => Macro "calls" had been replaced by the macro code below in files.c +// => For new implementations : a copy paste of the macro code below must be done for each "flag test" +// +// #define FIL__TCBinFile_CHK_CONF_DONE {err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_WR {err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_RD {err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );} + + +#define FIL__TCStreamFile_MAX_BUFF_NB 4 + +// #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 // Before 07/11/12 => 50 000 - Maximum number of blocs in variable bloc size mode + +// #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 200000 // 200000 From 07/11/12 to 22/06/13 + +// #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 400000 // 400000 since 22/06/13 + +// -------------------------------------------------------------------------------------- +// 04/02/2014 GC : FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE selection by CC +// -------------------------------------------------------------------------------------- + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + + #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 // Before 07/11/12 => 50 000 - Maximum number of blocs in variable bloc size mode + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + +#endif + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + + #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 200000 // 200000 From 07/11/12 to 22/06/13 + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + +#endif + + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + + #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 400000 // 400000 since 22/06/13 + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + +#endif + + +#define FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB 20 + + + +#endif + diff --git a/include/pxi_daq_lib_v.1.2/files.typ b/include/pxi_daq_lib_v.1.2/files.typ new file mode 100755 index 0000000..ff6a400 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/files.typ @@ -0,0 +1,281 @@ +/* 24/02/05 */ + + +#ifndef FIL_TYP +#define FIL_TYP + +/* char FIL_TADirFilesList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; */ + + +typedef struct { + char AList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; +} FIL_TDirFilesList; + + +// 30/01/2009 + +class FIL__TCBinFile { + + + private : + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + // Parameters from conf + + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParMaxBlocSz; + SInt32 ProParBlocSz; + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + + SInt32 ProCurRdEltId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrEltId; + UInt64 ProCurWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + UInt64 ProTotWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + FILE* ProPtFile; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + + + public : + + FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~FIL__TCBinFile (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + SInt32 PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz ); + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + +// 01/05/2010 + +typedef struct { + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + UInt32 ABlocSz[1]; + +} FIL__TCStreamFile_Old_TRecInfFile; + +// 05/11/10 + +typedef struct { + + UInt64 Offset; + UInt32 Sz; + + SInt32 SpareW32InfoFormat; // Number which identifies the meaning ASpareW32Info + SInt32 SpareW32InfoNb; // Number of spare parameters + SInt32 ASpareW32Info[FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB]; // Array for user parameters + + UInt32 Dummy; // For alignment + +} FIL__TCStreamFile_TBlocInf; + + +// 05/11/10 + +typedef struct { + + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + + UInt32 Dummy; // For alignment + + FIL__TCStreamFile_TBlocInf ABlocInf[1]; + + +} FIL__TCStreamFile_TRecInfFile; + + +class FIL__TCStreamFile { + + + private : + + FIL__TCStreamFile* PriPtMyself; + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + SInt32 ProParDiskBlocSz; + SInt8 ProParFixedBlocSzMode; + + // Parameters from conf + + SInt8 ProUseThread; + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParRequestedMaxBlocSz; // Bloc size value asked by user + SInt32 ProParMaxBlocSz; // Adjusted depending on ProParBlocSz + + SInt32 ProParRequestedBlocSz; // Bloc size value asked by user + SInt32 ProParBlocSz; // Bloc size value used ( multiple of disk bloc size ) + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + HANDLE ProFileHnd; + +#ifdef CC_UNIX + FILE* ProFilePtUx; // Pointer to data file for Linux / Unix +#endif + + char ProInfFileName[GLB_FILE_PATH_SZ]; + FILE* ProPtInfFile; + + FIL__TCStreamFile_TRecInfFile* ProPtRecInfFile; + SInt32 ProRecInfSz; + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + +#ifndef CC_UNIX + CRITICAL_SECTION ProCsPrintMsg; +#endif + + HANDLE ProThreadHnd; + DWORD ProThreadId; + + HANDLE ProSemWrBuffHnd; + HANDLE ProSemRdBuffHnd; + + SInt16 ProIndexWrBuff; + SInt16 ProIndexRdBuff; + + UInt8* ProABuff[FIL__TCStreamFile_MAX_BUFF_NB]; + SInt32 ProBuffSz; + + + SInt32 ProCurRdBlocId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrBlocId; + SInt32 ProCurWrSz; + SInt64 ProTotWrSz; + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + // Results + + SInt32 ProResWrBlocFailCnt; + + SInt32 ProFCalcProParBlocSz ( SInt32 DataSz ); + + public : + + FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + ~FIL__TCStreamFile (); + + friend DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + SInt32 PubFSetDiskSectorSz ( SInt32 DiskBlocSz ); + SInt32 PubFGetDiskSectorSz (); + + void PubFPrintMsg ( char* Msg ); + SInt32 PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFPrintInfFile (); + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + // SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 SpareInfo ); + + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ); + + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + + int GetTime (); + +}; + + + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.2/files.var b/include/pxi_daq_lib_v.1.2/files.var new file mode 100755 index 0000000..7f38a20 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/files.var @@ -0,0 +1,18 @@ +/* 24/02/05 */ + + +#ifndef FIL_VAR +#define FIL_VAR + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +// Examples +// +// VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +// VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.2/globals.def b/include/pxi_daq_lib_v.1.2/globals.def new file mode 100755 index 0000000..296f090 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/globals.def @@ -0,0 +1,39 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_DEF +#define GLOBALS_DEF + +#ifndef CC_UNIX + #include "y:/dd/sdev/src/com/c/com/include/globals_root.def" +#endif + +#ifndef ROOT_ROOT + #define GLB_READ_CR { while ( getchar () != '\n' ); }; +#endif + + +#ifndef ROOT_ROOT + #define GLB_KEYB_CR { while ( getchar () != '\n' ); } +#endif + + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/globals_root.def b/include/pxi_daq_lib_v.1.2/globals_root.def new file mode 100755 index 0000000..26466d2 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/globals_root.def @@ -0,0 +1,44 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_ROOT_DEF +#define GLOBALS_ROOT_DEF + +/* CONDITIONNAL COMPILATION */ + +#define GLB_GC_CASCADE +#define GLB_FIRST_REC_FORMAT + +/* MACROS */ + +#define GLB_FILE_PATH_SZ 256 +#define GLB_CMT_SZ 256 +#define GLB_HOST_NAME_SZ 50 + +#define GLB_SEQ 0 + +#define GLB_RMP_FILE_PATH "/common/rmp/RMP" +#define GLB_RMPS_FILE_PATH "/common/rmp/RUN" + + +#define GLB_DEF_BYTE_SEX 0x3615ABCD + + +// #define GLB_DESY_VME_A32_BASE 0xd0000000 /* By default it's LEPSI config base address 0xd0000000*/ + + + + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/maps.def b/include/pxi_daq_lib_v.1.2/maps.def new file mode 100755 index 0000000..7a798eb --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/maps.def @@ -0,0 +1,49 @@ +/******************************************************************************* +File : x:\lib\com\maps\maps.def +Goal : Macros definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_DEF +#define MAPS_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define MAPS__TCDigTelMon_MAX_EV_NB 300 +#define MAPS__TCDigTelMon_MAX_PLANE_NB 6 +#define MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB 10000 +#define MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE 1000 + +#define MAPS__TCDigTelMon_CHK_PLANE_ID(Id) { if ( (Id < 0) || (Id >= MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + +#define MAPS__TCDigTelMon_CHK_PLANE_NB(Nb) { if ( (Nb <= 0) || (Nb > MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Nb, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + + +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME 0 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL 1 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS 2 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR 3 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS 4 + +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES 0 +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE 1 + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/maps.typ b/include/pxi_daq_lib_v.1.2/maps.typ new file mode 100755 index 0000000..63e1342 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/maps.typ @@ -0,0 +1,383 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.typ +Goal : Types definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_TYP +#define MAPS_TYP + + +#ifdef ROOT_ROOT + typedef UInt32 MAPS__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor MAPS__TColor; +#endif + + + +// 17/07/2009 + +typedef struct { + + SInt32 MaxBuffEvNb; + + // Hard coded parameters in next classes + + SInt8 MapsNb; // Nb of MAPS acquired by DAQ + SInt8 MapsName; + SInt8 PlaneNb; + + // Parameters from GUI + + SInt8 MonEnabled; + + SInt32 AcqFrNb; // Nb of frame in current acq to process + + SInt8 ProcOneAcq; // 1 => Process current ONLY acq + // 0 => Process ProcEvNb coming from GUI + // It can be more or less than one acq + + SInt32 ProcEvNb; // Ev nb to process, either + // - if ProcOneAcq = 1 => ev nb of one acq + // - if ProcOneAcq = 0 => from GUI + + SInt8 ProcOnlyFrWithHitOnAllPlanes; + + SInt8 ListHitAllPlanesMode; + + SInt8 ProcOnlyFrWithTrig; // Process only frames with hit + SInt8 HandleTrigPos; // Use trigger position to extract events + SInt8 StopAtEndOfProc; // Stop at end of processing, no automatic processing of next acq + SInt8 StoreEvents; // Store events + + SInt8 DispFrNbWithTrigOrFrNbWithHit; // Display in PubPt_ADispFrNbWithTrigOrHit & PubPt_ADispFrPCentWithTrigOrHit trig or hit nb + // 0 => Display frame nb & % with trigger + // 1 => Display frame nb & % with at least one hit + + SInt8 DispFullMatrix; // 0 => Display 1/2 scale matrix + // 1 => Display full matrix + + SInt8 ProcMode; // Processing mode + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + + SInt8 CumPlotGrayOrBlueLevels; // Cumul plot + // 0 => in gray levels + // 1 => in blue levels + + SInt8 CumPlotHitOrHitCnt; // Cumul plot + // 0 => binary display : count > 0 => set pixel in black / blue + // 1 => gray or blue levels display + + + SInt32 GotoRawFrNo; // Plot raw data of frame No + +} MAPS__TDigTelPar; + + +// 17/07/2009 + +typedef struct { + + SInt8 RunInProgress; + SInt8 LastPlaneSelForCoin; // Index of last plane selected for coincidence + + SInt32 CurEvNo; // Index of last event buffered + SInt32 FirstEvToProc; // Index of first event to process + SInt32 LastEvToProc; // Index of last event to process + SInt32 CurEvToProc; // Index of event to process + SInt32 EvNbToProc; // Ev nb to process + +} MAPS__TDigTelInf; + + +// 17/07/2009 + +typedef struct { + + SInt32 AcqFrNb; // Frame nb received from current acq + SInt32 ProFrNo; // Index of currently processed frame + SInt32 ProTimeMs; // Processing time + +} MAPS__TDigTelRes; + + +// 17/07/2009 + +typedef struct { + + SInt8 MapsId; // Id of the MAPS + MAPS__TColor PlotColor; + + SInt8 Process; // Process data of this plane + SInt8 RevertXDir; // Revert numbering of X direction ( columns ) in case planes are mounted back to back + SInt8 PlotCum; // Plot cumulated hit count over N events + SInt8 PlotCoin; // Plot coincidence + SInt8 PlotFrame; // Plot frame raw data + +} MAPS__TDigTelPlanePar; + + +// 22/07/2009 + +typedef struct { + + SInt8 PrevProcState; // Not used on 22/07/2009 + SInt8 CurProcState; // Not used on 22/07/2009 + + +} MAPS__TDigPlaneInf; + + +// 17/07/2009 + +typedef struct { + + void* AEvPt[MAPS__TCDigTelMon_MAX_EV_NB]; + void* CurEvPt; + +} MAPS__TDigTelPlaneData; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add CumTotTrigNb & CumFrameTrigNb + +typedef struct { + + void* PtMatDiscriBit; // Flat view of matrix X col x Y lines + void* PtMatCumTotHitCnt; // Hit count of each pixel over all events + + SInt32 FrameNbWithTrig; // Nb of frame with trigger + float FramePCentWithTrig; // % of frame with trigger + SInt32 CumTotTrigNb; // Total number of triggers + float CumFrameTrigNb; // Cumul MEAN trigger nb on frames WITH trigger + + SInt32 FrameNbWithHit; // Nb of frame with at least one hit + float FramePCentWithHit; // % of frame with at least one hit + SInt32 CumTotHitNb; // Total cumul hit nb over ALL frames ( with and without hit ) + float CumFrHitNb; // Cumul MEAN hit nb on frames WITH hit + +} MAPS__TDigTelPlaneRes; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add PubPt_ADispCumFrTrigNb + +#ifndef ROOT_ROOT + +class MAPS__TCDigTelMon { + + private: + + SInt8 PrivGuiConnected; + SInt8 PrivSetGuiParDontRead; + + SInt32 PrivFInit (); + + SInt32 PrivChkPlaneId ( SInt8 Id ); + + SInt32 PrivFSetGuiLabelsDispFrNbWithTrigOrFrNbWithHit (); + + protected: + + SInt8 ProRequestPlot; // Request plot from sw external to object + + MAPS__TDigTelPar ProPar; + MAPS__TDigTelInf ProInf; + MAPS__TDigTelRes ProRes; + MAPS__TDigTelPlanePar ProAPlanePar[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigPlaneInf ProAPlaneInf[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneData ProAPlaneData[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneRes ProAPlaneRes[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + public: + + // ---------------------------------- + // Fields to connect GUI components + // ---------------------------------- + + // Group + + TGroupBox* PubPt_GrpTelMon; + + // Label + + TLabel* PubPt_LbFrNbWithTrigOrHit; + TLabel* PubPt_LbFrPCentWithTrigOrHit; + + // Controls + + TCheckBox* PubPt_ChkEnableMonitor; + + TCheckBox* PubPt_AChkProc[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkRevertXDir[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TCheckBox* PubPt_ChkProcOneAcq; + TEdit* PubPt_EdFrNbToProc; + TCheckBox* PubPt_ChkProcOnlyFrWithTrig; + + TComboBox* PubPt_CbListHitAllPlanesMode; + + TCheckBox* PubPt_ChkTrigPosHanling; + TCheckBox* PubPt_ChkStopAtEndOfProc; + TCheckBox* PubPt_ChkStoreFr; + + TCheckBox* PubPt_ChkDispFrNbWithTrigOrFrNbWithHit; + TCheckBox* PubPt_ChkDispFullMatrix; + + TComboBox* PubPt_CbProcMode; + TCheckBox* PubPt_ChkCumPlotGrayOrBlueLevels; + TCheckBox* PubPt_ChkCumPlotHitOrHitCnt; + + TEdit* PubPt_EdGotoFr; + + TLabel* PubPt_ALbPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TRadioButton* PubPt_ARbPlotCum[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkPlotCoin[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TRadioButton* PubPt_ARdPlotFr[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // Indicators + + TEdit* PubPt_DispAcqFrNb; + TEdit* PubPt_DispCurProcFr; + + TEdit* PubPt_ADispFrNbWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispFrPCentWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_ADispCumFrTrigNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumTotHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumFrHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_DispProFrNo; + TEdit* PubPt_DispProcTimeMs; + + // Display + + TImage* PubPt_ImgMiniMatrix; + TImage* PubPt_ImgFullMatrix; + + + // ------------- + // Methods + // ------------- + + + MAPS__TCDigTelMon (); + ~MAPS__TCDigTelMon (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGuiEnablePlane ( SInt8 Id, SInt8 Enable ); + + SInt32 PubFSetGuiPar (); + SInt32 PubFSetGuiParGotoFr (); + + SInt32 PubFGetGuiPar (); + SInt32 PubFOnGuiParDispModeChangeFrNbWithTrigOrFrNbWithHit (); // Specific GUI behaviour + SInt32 PubFSetGuiStatus (); + SInt32 PubFSetGuiRes (); + + + // Set parameters + + SInt32 PubFSetPar ( MAPS__TDigTelPar* Pt ); + SInt32 PubFSetPlanePar ( SInt8 Id, MAPS__TDigTelPlanePar* Pt ); + + // Get parameters + + MAPS__TDigTelPar* PubFGetPar (); + MAPS__TDigTelPlanePar* PubFGetPlanePar ( SInt8 Id ); + MAPS__TDigTelPlaneData* PubFGetPlaneData ( SInt8 Id ); + + // Disable all planes processing + + SInt32 PubFDisAllPlanesProcessing (); + + // Disable group + + SInt32 PubFDisCumPlot (); + SInt32 PubFDisCoinPlot (); + SInt32 PubFDisFramePlot (); + + // Set results + + MAPS__TDigTelPlaneRes* PubFSetPlaneRes ( SInt8 Id ); + + // Poll plot request + + SInt32 PubFGetPlotRqStatus (); + SInt32 PubFResetPlotRqStatus (); + + SInt8* PubFGetPtPlotRq (); + SInt8* PubFGetPtMonEnabled (); + + + // Debug print + + SInt32 PubFPrintPar (); + SInt32 PubFPrintInf (); + + SInt32 PubFPrintPlanePar ( SInt8 Id ); + SInt32 PubFPrintAllPlanesPar (); + + SInt32 PubFPrintPlaneInf ( SInt8 Id ); + SInt32 PubFPrintAllPlanesInf (); + + SInt32 PubFPrintPlaneData ( SInt8 Id ); + SInt32 PubFPrintAllPlanesData (); + + SInt32 PubFPrintPlaneRes ( SInt8 Id ); + SInt32 PubFPrintAllPlanesRes (); + + +}; + +#endif + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 17/07/2009 */ +/* ============================= */ + +typedef struct { + + SInt8 Dummy; + +} MAPS__TContext; + + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/maps.var b/include/pxi_daq_lib_v.1.2/maps.var new file mode 100755 index 0000000..cd0d91a --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/maps.var @@ -0,0 +1,33 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.var +Goal : Variables definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_VAR +#define MAPS_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC MAPS__TContext MAPS__VGContext; + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/mi26_usr.def b/include/pxi_daq_lib_v.1.2/mi26_usr.def new file mode 100755 index 0000000..7771c7f --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/mi26_usr.def @@ -0,0 +1,75 @@ +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.def +Goal : Macros definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_DEF +#define MI26_USR_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ 1152 + +#define MI26__ZS_FFRAME_RAW_MAX_W8 2280 +#define MI26__ZS_FFRAME_RAW_MAX_W16 1140 // 1142 +#define MI26__ZS_FFRAME_RAW_MAX_W32 570 +#define MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 + + +#define MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 +#define MI26__ZS_FFRAME_MAX_STATES_REC 576 // one per line + +// ====================================== +// For MI26 discri analysis tools +// ====================================== + +// Submatrices number + +#define MI26__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define MI26__REG_BIAS_NB 19 + +#define MI26__REG_BIAS_ICLPDISC 0 +#define MI26__REG_BIAS_IPWRSW 1 +#define MI26__REG_BIAS_IBUF 2 +#define MI26__REG_BIAS_ID1PWRS 3 +#define MI26__REG_BIAS_ID2PWRS 4 +#define MI26__REG_BIAS_ILVDSTX 5 +#define MI26__REG_BIAS_ILVDS 6 +#define MI26__REG_BIAS_IVTST1 7 +#define MI26__REG_BIAS_IVTST2 8 +#define MI26__REG_BIAS_IANABUF 9 +#define MI26__REG_BIAS_IVDREF1D 10 +#define MI26__REG_BIAS_IVDREF1C 11 +#define MI26__REG_BIAS_IVDREF1B 12 +#define MI26__REG_BIAS_IVDREF1A 13 +#define MI26__REG_BIAS_IVDREF2 14 +#define MI26__REG_BIAS_IDIS1 15 +#define MI26__REG_BIAS_IDIS2 16 +#define MI26__REG_BIAS_IPXI 17 +#define MI26__REG_BIAS_IKIMO 18 + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/mi26_usr.typ b/include/pxi_daq_lib_v.1.2/mi26_usr.typ new file mode 100755 index 0000000..006161a --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/mi26_usr.typ @@ -0,0 +1,193 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.typ +Goal : Types definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_TYP +#define MI26_USR_TYP + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} MI26__TContext; + + +/* ======================================================= */ +/* Frame provided by Mi26 DAQ, it's independent of output */ +/* mode BUT data are not organized as in MI26__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by MI26__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + UInt32 Header; // Header of Mimosa 26 frame + UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 Trailer; // Trailer of Mimosa 26 frame + + UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + UInt16 ADataW16[MI26__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} MI26__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} MI26__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} MI26__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + MI26__TStatesLine StatesLine; + MI26__TState AStates[MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} MI26__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by Mi26, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a MI26 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + MI26__TZsFStatesRec AStatesRec[MI26__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} MI26__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/msg.c b/include/pxi_daq_lib_v.1.2/msg.c new file mode 100755 index 0000000..7dd5585 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/msg.c @@ -0,0 +1,230 @@ + +/******************************************************************************* +File : x:\lib\com\msg\msg.c +Goal : Implement user messages print ( screen ) or log ( file ) functions. + : It's usefull to send debug messages. + : +Remark : The way it works is controlled by 3 globals variables + : MSG_VGLogClosed = 0 ( disable ) / 1 ( enable ) user messages + : MSG_VGLogPath = '/msg/msg.txt' = path of messages logfile + : MSG_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : There is the same variables with RMSG_ instead of MSG_ they are + : used for on-line remote monitoring messages. + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_C +#define MSG_C + + +SInt32 MSG_FGenEnableLog ( SInt8 Chan, SInt8 Enable ) { + MSG_VGALogClosed[Chan] = Enable; + MSG_VGALogEnabled[Chan] = Enable; + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGenGetLogEnabled ( SInt8 Chan ) { + return (MSG_VGALogEnabled[Chan]); +} + + +SInt32 MSG_FGenSetLogFilePath ( SInt8 Chan, char* LogFilePath ) { + sprintf ( MSG_VGALogPath[Chan], "%s", LogFilePath ); + return (0); +} + +char* MSG_FGenGetLogFilePath ( SInt8 Chan ) { + return ( MSG_VGALogPath[Chan] ); +} + +SInt32 MSG_FGenStopLog ( SInt8 Chan, SInt8 Stop ) { + MSG_VGADontLog[Chan] = Stop; + return (0); +} + + +SInt32 MSG_FGenBegin ( SInt8 Chan, SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( Chan, Enable ); + MSG_FGenSetLogFilePath ( Chan, FilePath ); + + return (0); +} + +SInt32 MSG_FBegin ( SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable ); + MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, FilePath ); + + return (0); +} + + +SInt32 MSG_FEnd () { + + return (0); +} + + +SInt32 MSG_FEnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt32 MSG_EnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt8 MSG_FGetLogEnabled () { + return ( MSG_FGenGetLogEnabled ( MSG_CHAN_MSG ) ); +} + +SInt32 MSG_FSetLogFilePath ( char* LogFilePath ) { + return ( MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, LogFilePath ) ); +} + +/* 11/06/2005 */ + +SInt32 MSG_FSetFileLogLevel ( SInt8 Level ) { + + MSG_VGFileLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_GSetFileLogLevel () { + return (MSG_VGFileLogLevel); +} + + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserLogLevel ( SInt8 Level ) { + + MSG_VGUserLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGetUserLogLevel () { + return (MSG_VGUserLogLevel); +} + +char* MSG_FGetLogFilePath ( void ) { + return ( MSG_FGenGetLogFilePath ( MSG_CHAN_MSG ) ); +} + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserMsgFunc ( TUserMsgFunc Func ) { + + MSG_VGUserMsgFunc = Func; + + return (0); +} + + +/* 07/04/2007 */ + +char* MSG_FGenGetMsgLogConfStr ( SInt8 Chan ) { + + static char VStr[MSG_CMT_SZ+1]; + + sprintf ( VStr, "Messages log configuration \n\n - Log enabled = %d \n - Stop log = %d \n - File log level = %d \n - Log file name = %s \n - User log level = %d \n\n ", MSG_VGALogEnabled[Chan], MSG_VGADontLog[Chan], MSG_VGFileLogLevel, MSG_VGALogPath[Chan], MSG_VGUserLogLevel ); + + return (VStr); +} + +/* 07/04/2007 */ + +char* MSG_FGetMsgLogConfStr () { + return ( MSG_FGenGetMsgLogConfStr (MSG_CHAN_MSG) ); +} + +SInt32 MSG_FGenMsg ( SInt8 Chan, SInt8 Level ) { + + static char VMsg[256 /* MSG_CMT_SZ include file not visble from ROOT => must be solved */]; + + if ( (MSG_VGFileLogLevel == 0) && (MSG_VGUserLogLevel == 0) ) { + return (0); + } + + sprintf ( VMsg, "MSG %.7d => %s \n", MSG_VGAMsgCnt[Chan]++, MSG_VGAStrMsg[Chan]); + + if ( (MSG_VGFileLogLevel != 0) && (MSG_VGFileLogLevel >= Level) ) { + + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + + // 29/10/2010 => Alway overwrite log file + + // if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + // MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + // } + + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "%s", VMsg ); + fflush ( MSG_VGALogFile[Chan] ); + } + + } /* End if ( Level >= MSG_VGFileLogLevel ) */ + + if ( (MSG_VGUserLogLevel != 0) && (MSG_VGUserLogLevel >= Level) ) { + + if ( MSG_VGUserMsgFunc != NULL ) { + MSG_VGUserMsgFunc ( VMsg ); + } + + } /* End if ( Level >= MSG_VGUserLogLevel ) */ + + + return (0); + +/* + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + } + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "MSG %.4d =>", MSG_VGAMsgCnt[Chan]++ ); + fprintf ( MSG_VGALogFile[Chan], MSG_VGAStrMsg[Chan] ); + fprintf ( MSG_VGALogFile[Chan], "\n" ); + fflush ( MSG_VGALogFile[Chan] ); + } + + return (0); + +*/ + +} + + +#endif + diff --git a/include/pxi_daq_lib_v.1.2/msg.def b/include/pxi_daq_lib_v.1.2/msg.def new file mode 100755 index 0000000..c709cc1 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/msg.def @@ -0,0 +1,63 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.def +Goal : Macros definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_DEF +#define MSG_DEF + + + +#define MSG_CMT_SZ 1024 + +#define MSG_CHAN_NB 2 +#define MSG_CHAN_MSG 0 +#define MSG_CHAN_RMSG 1 + + +/* Must be after variables definition, instead CINT will be unable to handle these macros */ + +#define MSG_VGLogFile MSG_VGALogFile[MSG_CHAN_MSG] +#define MSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_MSG] +#define MSG_VGDontLog MSG_VGADontLog[MSG_CHAN_MSG] +#define MSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_MSG] +#define MSG_VGLogPath MSG_VGALogPath[MSG_CHAN_MSG] + +#define RMSG_VGLogFile MSG_VGALogFile[MSG_CHAN_RMSG] +#define RMSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_RMSG] +#define RMSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_RMSG] +#define RMSG_VGLogPath MSG_VGALogPath[MSG_CHAN_RMSG] + +/* 07/04/2007 MSG_VGAStrMsg identifier replaced by MSG_OUT because of ROOT CINT macros limitations */ +/* #define MSG_OUT MSG_VGAStrMsg[MSG_CHAN_MSG] */ + +#define RMSG_OUT MSG_VGAStrMsg[MSG_CHAN_RMSG] + +#define MSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,127);} +#define msg(Msg) MSG_PRINTF(Msg) + +#define MSG_PRINTF_LVL(Msg,Lvl) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,Lvl); } +#define msgl(Msg,Lvl) MSG_PRINTF_LVL(Msg,Lvl) + + +#define RMSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_RMSG,127); } +#define msgr(Msg) RMSG_PRINTF(Msg) +#define rmsg(Msg) RMSG_PRINTF(Msg) + + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/msg.typ b/include/pxi_daq_lib_v.1.2/msg.typ new file mode 100755 index 0000000..0f62f1d --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/msg.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.typ +Goal : Types definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef MSG_TYP +#define MSG_TYP + +typedef SInt32 (*TUserMsgFunc) ( char* Msg ); + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/msg.var b/include/pxi_daq_lib_v.1.2/msg.var new file mode 100755 index 0000000..2e8fc8b --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/msg.var @@ -0,0 +1,59 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.var +Goal : Variables definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_VAR +#define MSG_VAR + +/* + +EXTERN VAR_STATIC FILE* MSG_VGALogFile[MSG_CHAN_NB] VAR_INIT_A2(NULL,NULL); +EXTERN VAR_STATIC SInt8 MSG_VGALogClosed[MSG_CHAN_NB] VAR_INIT_A2(1,1); +EXTERN VAR_STATIC SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt8 MSG_VGADontLog[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ] VAR_INIT_A2("/dd/tmp/pc/msg.txt","/dev/rmsg"); +EXTERN VAR_STATIC char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ]; +EXTERN VAR_STATIC SInt8 MSG_VGFileLogLevel VAR_INIT (0); +EXTERN VAR_STATIC SInt8 MSG_VGUserLogLevel VAR_INIT (0); +EXTERN VAR_STATIC TUserMsgFunc MSG_VGUserMsgFunc VAR_INIT (NULL); + +*/ + +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, FILE* MSG_VGALogFile[MSG_CHAN_NB] , NULL, NULL ); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogClosed[MSG_CHAN_NB] , 1, 1); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGADontLog[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ], "/dd/tmp/pc/msg.txt","/dev/rmsg" ); + + +VAR_DCL ( EXTERN, VAR_STATIC, char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ] ); + +/* 07/04/2007 Replace macro MSG_OUT by a variable which points to MSG_VGAStrMsg[MSG_CHAN_MSG] because of ROOT CINT macros limitations */ + + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char* MSG_OUT , MSG_VGAStrMsg[MSG_CHAN_MSG] ); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGFileLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGUserLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, TUserMsgFunc MSG_VGUserMsgFunc , NULL); + + +#endif + + diff --git a/include/pxi_daq_lib_v.1.2/sync_index_rec.c b/include/pxi_daq_lib_v.1.2/sync_index_rec.c new file mode 100755 index 0000000..9ae3f53 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/sync_index_rec.c @@ -0,0 +1,163 @@ +/******************************************************************************* +File : sync_index_rec.c +Goal : Functions to synchronized two DAQ files +Prj date : 18/07/2012 +File date : 18/07/2012 +Doc date : 18/07/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef SYNC_INDEX_REC_C +#define SYNC_INDEX_REC_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Return file size or negative value upon failure. + Author : Gilles CLAUS +*/ + /* =================================================================================== */ +/* DOC_FUNC_END */ +int GetFileSize ( char* FilePath ) { + + FILE* VPf; + int VFileSz = 0; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + printf( "GetFileSize: fopen fail !\n" ); + return -1; + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + printf( "GetFileSize: fseek SEEK_SET fail !\n" ); + return -1; + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + printf( "GetFileSize: fseek SEEK_END fail !\n" ); + return -1; + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + printf( "GetFileSize: ftell fail !" ); + return -1; + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + printf( "GetFileSize: fseek SEEK_SET fail !"); + return -1; + } + + if ( fclose (VPf) != 0 ) { + printf( "GetFileSize: fclose fail !" ); + return -1; + } + + return VFileSz; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : Read the file containing the synchronization information + : between two boards, each with its data file. + : For instance a board reading binary sensors + : and another board reading analog sensors. + : + Inputs : + : + : + Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : + Globals : None + : + Remark : None + : + Level : This is a user level function. + Date : 10/07/2012 + Doc date : + Modif : + Author : Gilles CLAUS + E-mail : claus@lepsi.in2p3.fr + Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +int GetSyncPointer ( char* FilePath, unsigned char* PtDest, int DestSz ) { + + int VRet; + FILE* VPfDest; + int VFileSz; + + + // Check param + + if( PtDest==NULL ) { + printf( "GetSyncPointer: PtDest == NULL !\n"); + return -1; + } + + // Measure file size + + VFileSz = GetFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + printf( "GetSyncPointer: Buffer size=%d < File size=%d.\n", DestSz, VFileSz ); + return -1; + } + + printf( "GetSyncPointer: TRACE => FileSize=%d\n", VFileSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + if( VPfDest == NULL ) { + printf( "GetSyncPointer: Source file %s open failed.\n", FilePath ); + return -1; + } + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + printf("SYNC Version is %d\n", ((APP__TSyncIndexRec*)PtDest)->Version); + + if ( VRet != 1 ) { + printf( "GetSyncPointer: Error reading source file %s.\n", FilePath ); + return -1; + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + printf( "GetSyncPointer: Error fclose source file %s.\n", FilePath ); + return -1; + } + + + // Return record nb + + return ( VFileSz / sizeof (APP__TSyncIndexRec) ); + +} + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.1.2/sync_index_rec.typ b/include/pxi_daq_lib_v.1.2/sync_index_rec.typ new file mode 100755 index 0000000..bd3bcd8 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/sync_index_rec.typ @@ -0,0 +1,57 @@ +/* ============== */ +/* 10/07/2012 */ +/* -------------- */ +/* Doc 18/07/2012 */ +/* ============== */ + +#ifndef SYNC_INDEX_REC_TYP +#define SYNC_INDEX_REC_TYP + +#define CC_UNIX // Specify operating system +#include "types.typ" + +typedef struct { + + // The fields needed to synchronize DUT & Telescope run are marked with a * + // The other fields are extra information, which may be use to make cross-check + + UInt32 Version; // Record version + + // DUT events information + + UInt32 DutEvId; // * Event identifier from 0 to NbMaxEventsInRun - 1 + UInt32 DutEvTag; // Event tag = Mi26 sync signal pulses count = Mi26 frames counter + UInt32 DutTrigLine; // Line read by DAQ when trigger has occurred + UInt32 DutTrigFrame; // Frame read by DAQ when trigger has occurred + UInt32 DutTrigNbTot; // Total number of triggers seen by DAQ since beginning of run + UInt32 DutTrigNbAccepted; // Number of triggers accepted by DAQ since beginning of run = number of events taken by DAQ + UInt32 DutSpareU32; // Reserved + + // Telescope information + + UInt32 TelBegEvFrId; // * First frame corresponding to DUT event + + // Frame which contains trigger info + // + UInt32 TelTrigFrId; // Frame id since begining of run => 0 .. NbMaxFramesInRun - 1 + UInt32 TelTrigAcqId; // Acquisition id since begining of run + UInt32 TelTrigFrIdInAcq; // Frame id in current acquisition => 0 .. NbMaxFramesPerAcq + UInt32 TelTrigEvTag; // Event tag = Mi26 frames counter + + // Three first triggers of the frame (TelTrigFrId) + // Unit is Mi26 clock TS => divide by 16 to get trigger line + // + UInt32 TelTrig0; // First trigger + UInt32 TelTrig1; // Second trigger + UInt32 TelTrig2; // Third trigger + + UInt32 TelFrTrigNb; // Total number of trigger of the frame (TelTrigFrId) + + UInt32 TelTrigSpareU32; // Reserved + + UInt32 TelEndEvFrId; // * Last frame corresponding to DUT event + +} APP__TSyncIndexRec; + +#endif + diff --git a/include/pxi_daq_lib_v.1.2/time.c b/include/pxi_daq_lib_v.1.2/time.c new file mode 100755 index 0000000..1e98424 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/time.c @@ -0,0 +1,623 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.c +Goal : Functions of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_C +#define TIME_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateL TIME_FConvDateS2DateL ( TIME__TUDateS DateS ) { + + TIME__TUDateL VDateL; + + VDateL.Date.Day = DateS.Date.Day; + VDateL.Date.Month = DateS.Date.Month; + VDateL.Date.Year = 2000 + DateS.Date.Year; + + return (VDateL); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateS TIME_FConvDateL2DateS ( TIME__TUDateL DateL ) { + + TIME__TUDateS VDateS; + + VDateS.Date.Day = DateL.Date.Day; + VDateS.Date.Month = DateL.Date.Month; + VDateS.Date.Year = DateL.Date.Year % 2000; + + return (VDateS); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 23/05/2010 +Doc date : 23/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateS2Str ( TIME__TUDateS Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.2d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( UInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( SInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = (UInt32) Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ + : +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FDateL2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2Str ( TIME__TUDateL Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.4d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 06/03/2010 +Doc date : 06/03/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2StrExt ( TIME__TUDateL Date, char SepChar, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d%c%.2d%c%.4d", Date.Date.Day, SepChar, Date.Date.Month, SepChar, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FConvDateTime2DateL ( TDateTime Src ) { + + TIME__TUDateL VDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + Src.DecodeDate ( &VYear, &VMonth, &VDay ); + + VDate.Date.Year = VYear; + VDate.Date.Month = VMonth; + VDate.Date.Day = VDay; + + return (VDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FGetDateLOfNextDay ( TIME__TUDateL Cur ) { + + TDateTime VCurDate ( Cur.Date.Year, Cur.Date.Month, Cur.Date.Day ); + TIME__TUDateL VNextDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + ++VCurDate; + + VCurDate.DecodeDate ( &VYear, &VMonth, &VDay ); + + VNextDate.Date.Year = VYear; + VNextDate.Date.Month = VMonth; + VNextDate.Date.Day = VDay; + + return (VNextDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +WARNING : If return pointer to list is used, a copy of LIST ( not pointer ) must be done + : after each TIME__FFillListDatesLOfWeek () call otherwise the list content will be + : the one of last call because all pointers will point to last list stored in local + : variable of function. + : + : +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef ROOT_ROOT + +TIME__TListDatesLOfWeek* TIME__FFillListDatesLOfWeek ( TIME__TUDateL MondayDate, TIME__TListDatesLOfWeek* PtList ) { + + static TIME__TListDatesLOfWeek VList; + TIME__TUDateL VDayDate; + SInt8 ViDay; + + + VDayDate = MondayDate; + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + VList.ADates[ViDay] = VDayDate; + VDayDate = TIME__FGetDateLOfNextDay ( VDayDate ); + } + + if ( PtList != NULL ) { + *PtList = VList; + } + + return (&VList); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 TIME__FPrintListDatesLOfWeek ( TIME__TListDatesLOfWeek* PtList ) { + + SInt8 ViDay; + + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + msg (( MSG_OUT, "Date : %s", TIME__FDateL2Str ( PtList->ADates[ViDay], NULL /* PtDestStr */, 0 /* DestStrSz */ ) )); + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +WARNING : A copy of return STRING ( not pointer ) must be done after each TIME_FGetDayName call + : otherwise the string content will be the one of last call because all pointers will + : point to last string stored in local variable of function. +: +Level : +Date : 27/02/2010 +Doc date : 27/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME_FGetDayName ( UInt8 DayIndex, SInt8 Language ) { + + static char* VAStrDayNameFr[8] = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche" }; + static char* VAStrDayNameEn[8] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + + if ( DayIndex > 7 ) { + err_error (( ERR_OUT, "Bad day index = %d out of rnage 0..7", DayIndex )); + return ( "?" ); + } + + switch ( Language ) { + + case TIME__LANG_FRENCH : { + return ( VAStrDayNameFr[DayIndex] ); + break; } + + case TIME__LANG_ENGLISH : { + return ( VAStrDayNameEn[DayIndex] ); + break; } + + + default : { + err_error (( ERR_OUT, "Bad language = %d out of range", Language )); + return ( "?"); + } + + } + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUTime TIME__FConvDateTime2Time ( TDateTime Src ) { + + TIME__TUTime VTime; + unsigned short VHour; + unsigned short VMin; + unsigned short VSec; + unsigned short VMSec; + + Src.DecodeTime ( &VHour, &VMin, &VSec, &VMSec ); + + VTime.Time.Hour = VHour; + VTime.Time.Min = VMin; + VTime.Time.Sec = VSec; + VTime.Time.Cent = VMSec / 10; + + return (VTime); +} + +#endif + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FTime2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FTime2Str ( TIME__TUTime Time, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrTime[TIME__STR_TIME_SZ]; + + sprintf ( VStrTime, "%.2d:%.2d:%.2d|%.2d", Time.Time.Hour, Time.Time.Min, Time.Time.Sec, Time.Time.Cent ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_TIME_SZ) ) { + sprintf ( PtDestStr, "%s", VStrTime ); + } + + return (VStrTime); +} + + +// 23/05/2010 + +char* TIME__FTime2Str ( UInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + +// 23/05/2010 + +char* TIME__FTime2Str ( SInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = (UInt32) Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +#endif + diff --git a/include/pxi_daq_lib_v.1.2/time.def b/include/pxi_daq_lib_v.1.2/time.def new file mode 100755 index 0000000..a4ec9f1 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/time.def @@ -0,0 +1,40 @@ + + +/******************************************************************************* +File : x:\lib\com\time\time.def +Goal : Macros definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_DEF +#define TIME_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define TIME__STR_DATE_SZ 11 +#define TIME__STR_TIME_SZ 11 + +#define TIME__LANG_FRENCH 0 +#define TIME__LANG_ENGLISH 1 + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/time.typ b/include/pxi_daq_lib_v.1.2/time.typ new file mode 100755 index 0000000..3d88f0e --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/time.typ @@ -0,0 +1,140 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.typ +Goal : Types definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_TYP +#define TIME_TYP + + +/* =========================== */ +/* Date S => Short date format */ +/* Eg : 01/01/10 */ +/* =========================== */ + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aa in W32 + // B31B24 B23B16 B15B08 B07B00 + // 00 Day Month Year + + SInt8 Year; + SInt8 Month; + SInt8 Day; + SInt8 NotUsed; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateS; + + +typedef union { + + UInt32 W32; + + TIME__TSDateS Date; + +} TIME__TUDateS; + + + +/* ========================== */ +/* Date L => Long date format */ +/* Eg : 01/01/2010 */ +/* ========================== */ + + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aaaa in W32 + // B31B24 B23B16 B15B00 + // Day Month Year + + SInt16 Year; + SInt8 Month; + SInt8 Day; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateL; + + +typedef union { + + UInt32 W32; + + TIME__TSDateL Date; + +} TIME__TUDateL; + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + TIME__TUDateL ADates[7]; + +} TIME__TListDatesLOfWeek; + + +/* =============================== */ +/* Time : Hour - Min - Sec - 1/100 */ +/* Eg : 21/05/2010 */ +/* =============================== */ + + +typedef struct { + + // Fields order MUST be Hour - Min - Sec - 1/100 -> Don't modify it + // B31B24 B23B16 B15B08 B07B00 + // Hour Min Sec Cent + + SInt8 Cent; + SInt8 Sec; + SInt8 Min; + SInt8 Hour; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSTime; + + +typedef union { + + UInt32 W32; + + TIME__TSTime Time; + +} TIME__TUTime; + + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/time.var b/include/pxi_daq_lib_v.1.2/time.var new file mode 100755 index 0000000..3b0fee6 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/time.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.var +Goal : Variables definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_VAR +#define TIME_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN SInt8 TIME_VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.1.2/types.typ b/include/pxi_daq_lib_v.1.2/types.typ new file mode 100755 index 0000000..6945d52 --- /dev/null +++ b/include/pxi_daq_lib_v.1.2/types.typ @@ -0,0 +1,167 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.typ +Goal : Common basic types definitions. + : I never use default C types names ( char, int ... ) + : i redefined them here ( SInt8, UInt32 ... ). + : + : If something go wong on you'r plateform with C types + : definition you need to update this file. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + +#include "stdint.h" // added, JB 2013/02/11 + +/*H**************************************************************************** +FILE : Types.Typ +BUT : Define types. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_TYP +#define TYPES_TYP + + // typedef enum ELang { ELang_FRENCH, ELang_ENGLISH, ELang_GERMAN, ELang_LANG_NB } TLang; + +#ifndef NODEFTYPCHAR + +/* +17/11/04 GC + +BCPPB declares an identfier with the same name " Char " +this problem happens while compiling Mimo* JTAG application (MP). +This Char identifier is used in SpinEdit object. + +MP used conditionnal compilation, i decided to remove this Char +type definition, because i believe i never use it. +Wait and see ... + +*/ + +/* typedef unsigned char Char; */ + +#endif + +#ifndef UInt8 + typedef unsigned char UInt8; +#endif + +#ifndef UByte + typedef UInt8 UByte; +#endif + +#ifndef SInt8 + typedef char SInt8; +#endif + +#ifndef SByte + typedef SInt8 SByte; +#endif + +#ifndef UInt16 + typedef unsigned short UInt16; +#endif + +#ifndef UWord + typedef UInt16 UWord; +#endif + +#ifndef SInt16 + typedef short SInt16; +#endif + +#ifndef SWord + typedef SInt16 SWord; +#endif + +#ifndef UInt32 + //typedef unsigned long int UInt32; + typedef unsigned int UInt32; // correction for 64bits, JB 2011/10/28 +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + //typedef long int SInt32; + typedef int SInt32; // correction for 64bits, JB 2011/10/28 +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif + + +#ifdef CC_UNIX + +#ifndef UInt64 + typedef int64_t UInt64; +#endif + +#ifndef SInt64 + typedef uint64_t SInt64; +#endif + +#else + +#ifndef UInt64 + typedef unsigned __int64 UInt64; +#endif + +#ifndef SInt64 + typedef __int64 SInt64; +#endif + + +#endif + + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/Copie de eudet_frio.c b/include/pxi_daq_lib_v.2.1/Copie de eudet_frio.c new file mode 100755 index 0000000..a5dd45f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/Copie de eudet_frio.c @@ -0,0 +1,13185 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr + +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_C +#define EUDET_FRIO_C + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: Acquisition size if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 15/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FCpyAcq ( UInt8* PtDest, SInt32 MaxDestSz, SInt32 AcqSz ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + UInt32* VPtDest; + SInt32 VTotSz; + + // Check destination buffer + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + // Calculate total size + // = AcqSz + 4 because first W32 is used to store size of acquistion + + VTotSz = AcqSz + 4; + + // Test buffer size + + if ( VTotSz > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Destination buffer is too small => VTotSz=%d > MaxDestSz=%d", VTotSz, MaxDestSz ) ); + } + + // ----------------------------------------------- + // Copy data + // ----------------------------------------------- + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Add size on first elt + + VPtDest = (UInt32*) PtDest; + + *VPtDest = VTotSz; + + ++VPtDest; + + // Copy + + memcpy ( VPtDest, VPtRun->PtFrame, AcqSz ); + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotSz); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : MapsName - Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 +Rev : 11/05/2011 + : - Handle version information -> majour, minor, comment + : + : 12/05/2011 + : - JTAG version Mi26 / Ult1 handling + : + : 19/05/2011 + : - Dma host size calculated for Ultimate because we don't know at this step which + : MAPS will be used and memory size for Ultimate is > the one for Mimosa 26 + : + : 25/05/2011 + : - Renamed in EFRIO__FBeginExt + : - Add parameter MapsName + : - Create a new EFRIO__FBegin (...) which call EFRIO__FBeginExt ( ASIC__MI26, ... ) + : This will keep compatibility with previous sw (EUDET), because EFRIO__FBegin call + : will configure Mimosa 26 as ASIC as it was done for first version of EUDET library. + : + : 28/09/2011 + : - Update code because EFRIO_VGJtagMi26.get_Info (...) has changed => returns one more param = SW version now + : + : 26/03/2013 + : - Add EFRIO__USR_VGContext.ParCrIndexFile handling + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + SInt32 VRet; + SInt8 VEnableErrLog; + SInt8 VEnableMsgLog; + WideString VWsJtagStatus; + WideString VWsSwVersion; + +#ifdef EFRIO__INCLUDE_PARA_PORT + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // Select JTAG Mi26 or Ultimate + + switch ( MapsName ) { + + case ASIC__MI26 : { + EFRIO__VGJtagMi26Ult1 = 0; // 0 => Mi26, 1 => Ultimate + break; } + + case ASIC__ULT1 : { + EFRIO__VGJtagMi26Ult1 = 1; // 0 => Mi26, 1 => Ultimate + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + +#endif + + // Reset lib context record => Set all field to 0 + // BUT ! Set CmdRun to -1 + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + VPtCont->RunCont.CmdRun = -1; + + // Set version information ( only for version >= 2.0 ) + + #ifdef EFRIO__V20_AND_LATER + + #ifdef EFRIO__V20 + VPtCont->VersionMajor = 2; + VPtCont->VersionMinor = 0; + + sprintf ( VPtCont->VersionCmt, "Extension of V1.0 to Ultimate 1" ); + #endif + + #endif + + + // Conf errors logging + + VEnableErrLog = ( ErrorLogLvl != 0 ); + + VRet = ERR_FBegin ( VEnableErrLog, ErrorLogFile ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FBegin failed !" ) ); + + VRet = ERR_FSetFileLogLevel ( ErrorLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FSetFileLogLevel failed !" ) ); + + // Conf messages logging + + VEnableMsgLog = ( MsgLogLvl != 0 ); + + VRet = MSG_FBegin ( VEnableMsgLog, MsgLogFile ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FBegin failed !" ) ); + + VRet = MSG_FSetFileLogLevel ( MsgLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FSetFileLogLevel failed !" ) ); + + // Init // port + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FBegin ( VEnableErrLog, ErrorLogFile ); + PPO_FOpen ( 0x378 /* BaseAdr */, 0 /* Id */ ); + PPO_FEnableReadDataOutPortBeforeWrite ( 0 /* Id */, 1 /* Enable */ ); + #endif + + // Set default values to first board conf in order to get DmaHostSize initialized BEFORE fw loading + + VPtBoard->AsicNb = EFRIO__MAX_ASIC_NB; // Max possible number + VPtBoard->FrameNbPerAcq = EFRIO__MAX_FRAME_NB_PER_ACQ; // "Nominal" value + + // DMA host size is the memory size allocated for DMA on CPU side + // It must be equal AT LEAST to the size of one acquisition and higher value are not useful + // VPtBoard->AsicNb + 1 => + 1 for extra channel + + // 25/05/2011 => Calculate DMA host size in function of ASIC name + + switch ( MapsName ) { + + case ASIC__MI26 : { + VPtBoard->DmaHostSz = ((MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + + case ASIC__ULT1 : { + VPtBoard->DmaHostSz = ((ULT1__ZS_FFRAME_MODE_2X160MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + + + // Set default values of Header & Trailer for DQ emulation + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x8000800; + + VPtAcqEmul->ParATrailer[0] = 0xAAAAAAAA; + VPtAcqEmul->ParATrailer[1] = 0xBBBBBBBB; + VPtAcqEmul->ParATrailer[2] = 0xCCCCCCCC; + VPtAcqEmul->ParATrailer[3] = 0xDDDDDDDD; + VPtAcqEmul->ParATrailer[4] = 0xEEEEEEEE; + VPtAcqEmul->ParATrailer[5] = 0xFFFFFFFF; + + +#ifdef EFRIO__INCLUDE_JTAG + + +#ifdef OLD_COM_JTAG_CODE + + // Init JTAG + + if( ! EFRIO_VGJtagMi26.IsBound()) { + OleCheck(CoMI26MasterConf::Create(EFRIO_VGJtagMi26)); + } + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + // Init JTAG end + + +#else + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + + // JTAG Mi26 + + if ( EFRIO__VGJtagMi26Ult1 == 0 ) { + + VHrComErr = CoMI26MasterConf::Create( EFRIO_VGJtagMi26 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + // 28/09/2011 + // => Update code because EFRIO_VGJtagMi26.get_Info (...) has changed => returns one more param = SW version now + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsSwVersion, &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => Version %s - Status %s", TOOLS__FWideString2CStr (VWsSwVersion, NULL, 0), TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + } + + // JTAG Ult1 + + else { + + VHrComErr = CoMI28COM::Create( EFRIO_VGJtagUlt1 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI28COM::Create failed !" ) ); + } + + if ( EFRIO_VGJtagUlt1.IsBound () ) { + OleCheck ( EFRIO_VGJtagUlt1.Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + } + + + // Init JTAG end + +#endif + + + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + VPtCont->InfInitDone = 0; + + +#ifndef EFRIO__V20_AND_LATER + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "EUDET Flex RIO DLL compiled on %s at %s", __DATE__, __TIME__ )); + err_error (( ERR_OUT, "******************************************************************" )); + +#else + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "- EUDET Flex RIO DLL V%d.%d compiled on %s at %s", VPtCont->VersionMajor, VPtCont->VersionMinor, __DATE__, __TIME__ )); + err_error (( ERR_OUT, "------------------------------------------------------------------" )); + err_error (( ERR_OUT, "%s", VPtCont->VersionCmt )); + + err_error (( ERR_OUT, "------------------------------------------------------------------" )); + err_error (( ERR_OUT, "Max Acq Nb = %d", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE )); + err_error (( ERR_OUT, "------------------------------------------------------------------" )); + + + #ifdef EFRIO__FREE_MI26_NB + err_error (( ERR_OUT, "----------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! Mi26 number is free ( mode EUDET 2 & EUDET 3 ) = Not limited to 1, 5, 6, 8" )); + err_error (( ERR_OUT, "! BUT current implementation will slow down acquisition !" )); + #else + err_error (( ERR_OUT, "----------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! Mi26 number can be ONLY 1, 5, 6, 8" )); + err_error (( ERR_OUT, "! Because data demultiplexing is hard coded, in order to achieve the shortest execution time" )); + #endif + + + #ifdef EFRIO__CREATE_INDEX_FILE + + if ( VPtUsrCont->ParCrIndexFile ) { + err_error (( ERR_OUT, "" )); + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! Index file (needed for DUT DAQ interface) is ENABLED by line cmd param !" )); + err_error (( ERR_OUT, "! It will slow down the acquisition !" )); + err_error (( ERR_OUT, "! Maximum trigger rate (6 x Mimosa 26 saturated) without loosing frames : !" )); + err_error (( ERR_OUT, "! - Saving data on RAID => FTrig max = 1 KHz !" )); + err_error (( ERR_OUT, "! - Saving data on CPU disk => FTrig max ~ 500 Hz !" )); + } + + else { + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! Index file (needed for DUT DAQ interface) is DISABLED by line cmd param !" )); + err_error (( ERR_OUT, "! Maximum trigger rate (6 x Mimosa 26 saturated) without loosing frames : !" )); + err_error (( ERR_OUT, "! - Saving data on RAID => FTrig max > 8 KHz (100 KHz & 1 MHz tested) !" )); + err_error (( ERR_OUT, "! - Saving data on CPU disk => FTrig max ~ 500 Hz !" )); + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + } + + + + #else + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! This DAQ version DOESN'T create the index file needed for DUT DAQ interface !" )); + err_error (( ERR_OUT, "! Maximum trigger rate (6 x Mimosa 26 saturated) without loosing frames : !" )); + err_error (( ERR_OUT, "! - Saving data on RAID => FTrig max > 8 KHz (100 KHz & 1 MHz tested) !" )); + err_error (( ERR_OUT, "! - Saving data on CPU disk => FTrig max ~ 500 Hz !" )); + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + #endif + + + err_error (( ERR_OUT, "******************************************************************" )); + +#endif + + msg (( MSG_OUT, "EFRIO__FBeginExt end" )); + + err_retok (( ERR_OUT, "end" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 +Rev : 11/05/2011 + : - Handle version information -> majour, minor, comment + : + : 12/05/2011 + : - JTAG version Mi26 / Ult1 handling + : + : 19/05/2011 + : - Dma host size calculated for Ultimate because we don't know at this step which + : MAPS will be used and memory size for Ultimate is > the one for Mimosa 26 + : + : 25/05/2011 + : - Body of function is " empty " => it has been moved in EFRIO__FBeginExt (...) + : - Call EFRIO__FBeginExt ( ASIC__MI26, ... ) + : - EFRIO__FBeginExt (...) handles MapsName parameter ( Mi26 / Ultimate / ... ) + : EFRIO__FBegin still configure Mimosa 26 as it was done in first version of lib. + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + err_error (( ERR_OUT, "TRACE => Init done" )); + + return ( EFRIO__FBeginExt ( ASIC__MI26, ErrorLogLvl, ErrorLogFile, MsgLogLvl, MsgLogFile ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEnd () + : +Goal : Terminate lib + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 05/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEnd () { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FEnd (); + #endif + + // Close JTAG COM classe + // Avoid "assertion message" when LabView is stop and then restarted + + err_error (( ERR_OUT, "1" )); + +#ifdef EFRIO__INCLUDE_JTAG + + + // JTAG Mi26 + + if ( EFRIO__VGJtagMi26Ult1 == 0 ) { + EFRIO_VGJtagMi26.Unbind(); + } + + else { + EFRIO_VGJtagUlt1.Unbind(); + } + + +#endif + + // Free frames buffer if allocated + + err_error (( ERR_OUT, "2" )); + + if ( VPtCont->RunCont.PtZsFFrameRaw !=NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + // Reset context record + + err_error (( ERR_OUT, "3" )); + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : +Goal : Build the frame list for one acquisition + : +Inputs : AcqStatus - ACquisition status ( < 0 -> HW error, 0 -> OK, > 0 -> Frame nb lost ) + : TrigStatus - No meaning now, reserved for future use + : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : +Level : +Date : 06/11/2010 +Rev : 24/02/2011 + : - Add parameters AcqStatus, TrigStatus to field new fields of EFRIO__TFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->AcqStatus = AcqStatus; + PtList->TrigStatus = TrigStatus; + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) + : +Goal : Init DAQ emulation either in standalone DAQ emulation application ( without + : HW ) or in LabView DAQ application. Selection done by RunInLabview parameter. + : +Inputs : RunInLabview = 0 => Run in C++ Builder DAQ emulation application + : = 1 => Run in Labview DAQ + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : If emulation is running under Labview ( RunInLabview = 1 ), frames emulation + : function overwite memory already allocated for Flew RIO board. In case emulation + : is runing in a standalone application ( RunInLabview = 0 ), this function allocates + : memory in PC DRAM to emulate Flex RIO RAM. + : + : This function sets default values of DAQ emulation parameters. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// RunInLabview = 0 => Run in C++ Builder DAQ emulation application +// RunInLabview = 1 => Run in Labview DAQ + +SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + // Reset context records + + memset ( VPtAcqEmul, 0, sizeof (EFRIO__TAcqEmul) ); + + memset ( VPtFrChk , 0, sizeof (EFRIO__TFrCheck) ); + + // Set default value of DAQ emulation parameters => Mainly for Labview which will not control all of them + + VPtAcqEmul->ParAcqCycleMs = 200; + VPtAcqEmul->ParEmuleDRamReadMs = 0; + VPtAcqEmul->ParEmuleFunctNo = 0; + VPtAcqEmul->ParRandomDataSz = 0; + VPtAcqEmul->ParSetMaxDataSzOnOneMaps = 1; + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x80008006; + + VPtAcqEmul->ParATrailer[0] = 0xAAAA0001; + VPtAcqEmul->ParATrailer[1] = 0xAAAA0002; + VPtAcqEmul->ParATrailer[2] = 0xAAAA0003; + VPtAcqEmul->ParATrailer[3] = 0xAAAA0004; + VPtAcqEmul->ParATrailer[4] = 0xAAAA0005; + VPtAcqEmul->ParATrailer[5] = 0xAAAA0006; + + VPtAcqEmul->ParTrigNbPerFrame = 0; + VPtAcqEmul->ParTrigOnOneFrameOverN = 1; + VPtAcqEmul->ParTrigOnNConsecutiveFrames = 1; + + VPtAcqEmul->ParATrig[0] = 10; + VPtAcqEmul->ParATrig[1] = 20; + VPtAcqEmul->ParATrig[2] = 30; + VPtAcqEmul->ParATrig[3] = 40; + + VPtAcqEmul->ParATS[0] = 100; + VPtAcqEmul->ParATS[1] = 200; + VPtAcqEmul->ParATS[2] = 300; + VPtAcqEmul->ParATS[3] = 400; + + + // Set Mi26 nb + + VPtFrChk->InfMi26Nb = VPtRunCont->ParMi26Nb; + + // Extra channel or not ? + + if ( (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtAcqEmul->InfExtraChan = 1; + } + + else { + VPtAcqEmul->InfExtraChan = 0; + } + + if ( RunInLabview == 0 ) { + + // Calculate DRAM size + + VPtAcqEmul->InfDRamSz = (VPtRunCont->ParMi26Nb + VPtAcqEmul->InfExtraChan) * VPtRunCont->ParFrameNbPerAcq * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 4; + + VPtAcqEmul->InfDRamSzMb = VPtAcqEmul->InfDRamSz / (1024 * 1024); + + // Alloc RAM to emulate Flex RIO DRAM + + VPtAcqEmul->InfDRamPtr = (UInt32*) malloc ( VPtAcqEmul->InfDRamSz ); + + err_retnull ( VPtAcqEmul->InfDRamPtr, (ERR_OUT,"Allocation of %d bytes for Flex RIO DRAM emulation failed !", VPtAcqEmul->InfDRamSz) ); + + } // End if ( RunInLabview == 0 ) + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleEnd ( ) + : +Goal : Terminate DAQ emulation + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Free DRAM if allocated in PC to emulate Flex RIO DRAM. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEmuleEnd ( ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + if ( VPtAcqEmul->InfDRamPtr != NULL ) { + free ( VPtAcqEmul->InfDRamPtr ); + } + + err_retok (( ERR_OUT, "" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) + : +Goal : Emulate Flex RIO DRAM read + : +Inputs : Cmd - 0 => Do nothing + : - 1 => Fill memory with zero + : +Ouputs : A pointer to DRAM or NULL if not allocated + : +Globals : + : +Remark : A delay should also be added here later to emulate Flex RIO DRAM access time + : configured by field ParEmuleDRamReadMs of EFRIO__TAcqEmul. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + + + if ( Cmd == 1 ) { + memset ( VPtAcqEmul->InfDRamPtr, 0, VPtAcqEmul->InfDRamSz ); + } + + Sleep ( VPtAcqEmul->ParEmuleDRamReadMs ); + + return ( VPtAcqEmul->InfDRamPtr ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) + : +Goal : Used for DAQ emulation. + : Set the FrameId fields ( TLU & Flex RIO triggers ) of all triggers info in + : the record used to emulate triggers + : +Inputs : FrameId - The value of frame id to set in all triggers info + : TrigNb - The number of trigger info to set in record + : PtRec - Pointer to destination record + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : The field set are + : - for TLU trigger => F.FrameIdInAcq ( see record EFRIO__TTluTrigger in *.typ ) + : - for Flex RIO trigger => F.Mi26Frame ( see record EFRIO__TFlexRioTimeStamp1 in *.typ ) + : +Level : +Date : 03/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) { + + SInt32 ViTrig; + EFRIO__TTluTrigger* VPtTrig; + EFRIO__TFlexRioTimeStamp1* VPtTs; + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + if ( TrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"TrigNb=%d > Max=%d", TrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) ); + } + + for ( ViTrig=0; ViTrig < TrigNb; ViTrig++ ) { + + VPtTrig = (EFRIO__TTluTrigger*) &PtRec->ATrig[2 * ViTrig]; + VPtTs = (EFRIO__TFlexRioTimeStamp1*) &PtRec->ATrig[(2 * ViTrig)+1]; + + VPtTrig->F.FrameIdInAcq = FrameId; + VPtTs->F.Mi26Frame = FrameId; + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) + : +Goal : Function used to avoid data copy while transfering data from one Vi to + : another under Labview. Because sometimes, it seems that Labview use pointers + : but it's not the case, a copy of data is done, and execution time is lost ... + : +Inputs : CmdGetPtrCpyAlloc = 0 => return buffer pointer + : = 1 => store PtSrcW32 but NO copy of data + : = 2 => copy src to buffer + : = 3 => alloc buffer + : + : AllocW32Sz - Memory size to alloc in W32 ( if CmdGetPtrCpyAlloc = 3 ) + : PtSrcW32 - Pointer to source data to copy to buffer + : SrcW32Sz - Size of source data to copy to buffer + : +Ouputs : A pointer on the buffer or NULL if not allocated. + : +Globals : + : +Remark : It's mainly used to passe a pointer on board DRAM to DLL ( CmdGetPtrCpyAlloc = 1 ) + : +Level : +Date : 07/09/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) { + + static UInt32* VPtBuff = NULL; + static UInt32 VAllocW32Sz = 0; + UInt32 VAllocSz; + SInt32 Vi; + + // Get pointer request + + if ( CmdGetPtrCpyAlloc == 0 ) { + return (VPtBuff); + } + + // Store pointer request + + if ( CmdGetPtrCpyAlloc == 1 ) { + VPtBuff = PtSrcW32; + return (VPtBuff); + } + + // Copy request + + if ( CmdGetPtrCpyAlloc == 2 ) { + + if ( (VPtBuff == NULL) || (SrcW32Sz > VAllocW32Sz) ) { + err_error (( ERR_OUT, "VPtBuff = %x = NULL ? / SrcW32Sz=%d > VAllocW32Sz=%d", VPtBuff, SrcW32Sz, VAllocW32Sz )); + return (NULL); + } + + for ( Vi=0; Vi < SrcW32Sz; Vi++ ) { + VPtBuff[Vi] = PtSrcW32[Vi]; + } + + return (VPtBuff); + } + + + // Allocation request + + if ( CmdGetPtrCpyAlloc == 3 ) { + + // Free mem if already allocated + + if ( VPtBuff != NULL ) { + free ( VPtBuff ); + VPtBuff = NULL; + } + + // Alloc new mem + + VAllocW32Sz = AllocW32Sz; + VAllocSz = VAllocW32Sz * 4; + + VPtBuff = (UInt32*) malloc ( VAllocSz ); + + // If allocation failed => error message + ret NULL + + if ( VPtBuff == NULL ) { + err_error (( ERR_OUT, "Allocation of %d bytes failed !", VAllocSz )); + return (NULL); + } + + // If allocation OK => ret buffer pointer + + return (VPtBuff); + } + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 + : EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : Mi26Nb - Mimosa 26 number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 => Creation with all job done in function body + : +Rev : 12/05/2011 + : - Code moved to EFRIO__FConfRunExt (...) + : - Call EFRIO__FConfRunExt ( ASIC__MI26, ... ) + : + : +Doc date : 12/05/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent, char* JtagFileName ) { + + SInt32 VRet; + + VRet = EFRIO__FConfRunExt ( ASIC__MI26, Mi26Nb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DataTransferMode, TrigMode, DestDir, FileNamePrefix, SaveToDisk, SendOnEth, SendOnEthPCent, JtagFileName ); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, + : SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : MapsName - Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + : MapsNb - MAPS number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 -> Creation of EFRIO__FConfRun (...) + : 12/05/2011 -> Change name from EFRIO__FConfRun to EFRIO__FConfRunExt and add MapsName parameter + : See " Rev 12/05/2011 " + ; + : +Rev : 04/11/2010 + : - Save to disk + : + : 21/02/2011 + : - Set new fields ( ParDaqVersion, ParMapsName ) + : + : 12/05/2011 + : - A new parameter MapsName must be added, in order to keep compatibility with EUDET lib : + : -> This function has been renamed EFRIO__FConfRunExt ( it was EFRIO__FConfRun before ) + : -> The new parameter MapsName had been added + : -> The former EFRIO__FConfRun call now EFRIO__FConfRunExt with MapsName param = ASIC__MI26 + : + : 10/07/2012 + : - Run index file path creation + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent, char* JtagFileName ) { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + SInt32 VMaxFrameSz; + SInt32 VRet; + + + // Check function parameters + + err_retnull ( DestDir , (ERR_OUT,"Abort : DestDir == NULL !") ); + err_retnull ( FileNamePrefix, (ERR_OUT,"Abort : FileNamePrefix == NULL !") ); + + // Debug print function parameters + + err_error (( ERR_OUT, "Call with : MapsNb=%d - RunNo=%d - TotEvNb=%d - EvNbPerFile=%d - FrameNbPerAcq=%d - DestDir=%s - FileNamePrefix=%s", MapsNb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DestDir, FileNamePrefix )); + + // Set hard coded parameters + + VPtCont->RunCont.ParMeasDataRate = 1; // Enable data rate measurement + VPtCont->RunCont.ParAcqNbToMeasDataRate = 10; // Uses 10 acquistions to measure data rate + + // Set default values to new fields + + VPtCont->RunCont.ParDaqVersion = 0; + + // Copy run parameters to run context record + + VPtCont->RunCont.ParMapsName = MapsName; + VPtCont->RunCont.ParMi26Nb = MapsNb; + VPtCont->RunCont.ParRunNo = RunNo; + VPtCont->RunCont.ParTotEvNb = TotEvNb; + VPtCont->RunCont.ParEvNbPerFile = EvNbPerFile; + VPtCont->RunCont.ParFrameNbPerAcq = FrameNbPerAcq; + VPtCont->RunCont.ParDataTransferMode = DataTransferMode; + VPtCont->RunCont.ParTrigMode = TrigMode; + + VPtCont->RunCont.ParSaveOnDisk = SaveToDisk; + VPtCont->RunCont.ParSendOnEth = SendOnEth; + VPtCont->RunCont.ParSendOnEthPCent = SendOnEthPCent; + + sprintf ( VPtCont->RunCont.ParDestDir , "%s", DestDir ); + sprintf ( VPtCont->RunCont.ParFileNamePrefix, "%s", FileNamePrefix ); + sprintf ( VPtCont->RunCont.ParJtagFileName , "%s", JtagFileName ); + + + + sprintf ( VPtCont->RunCont.InfDataFileName , "%s\\%s%d.bin" , VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + #ifdef EFRIO__CREATE_INDEX_FILE + if ( VPtUsrCont->ParCrIndexFile ) { + sprintf ( VPtCont->RunCont.InfIndexFileName, "%s\\%s%d_index.bin", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + } + #endif + + sprintf ( VPtCont->RunCont.InfConfFileName, "%s\\%s%d.par", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + VPtCont->RunCont.InfSaveDataOnDiskRunning = 0; + + // Compare run conf paramters to the max parameters used to calculate DmaHostSz in FBegin + // If they have higher values => DmaHostSz send to board at fw loading is bad => Abort + + if ( (VPtCont->RunCont.ParMi26Nb > EFRIO__MAX_ASIC_NB) || (VPtCont->RunCont.ParFrameNbPerAcq > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_error (( ERR_OUT, "Bad Mi26 nb ? Run conf = %d - Max = %d", VPtCont->RunCont.ParMi26Nb, EFRIO__MAX_ASIC_NB )); + err_error (( ERR_OUT, "Bad frame nb per acq ? Run conf = %d - Max = %d", VPtCont->RunCont.ParFrameNbPerAcq, EFRIO__MAX_FRAME_NB_PER_ACQ )); + err_retfail ( -1, (ERR_OUT,"Abort : Bad value of AsicNb=%d or FrameNbPerAcq=%d", VPtCont->RunCont.ParMi26Nb, VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // Update monitor context fields + + VPtCont->MonCont.InfFrameNbToSend = (SInt32) ( (float) FrameNbPerAcq * (float) ( (float) SendOnEthPCent / (float) 100 )); + + VPtCont->MonCont.InfSzToSend = 0; // Because it's not known at this step + + err_error (( ERR_OUT, "TRACE => InfFrameNbToSend = %d", VPtCont->MonCont.InfFrameNbToSend )); + + // Overwrite default values of AsicNb & FrameNbPerAcq + + VPtBoard->AsicNb = VPtCont->RunCont.ParMi26Nb; + VPtBoard->FrameNbPerAcq = VPtCont->RunCont.ParFrameNbPerAcq; + + // DMA host size => Already initialized in FBegin function + // VPtBoard->DmaHostSz = (MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * VPtBoard->AsicNb * VPtBoard->FrameNbPerAcq) / (1024 * 1024); + + // Configure others board conf parameters + + VPtBoard->BoardId = 0; + + sprintf ( VPtBoard->AsicName, "%s", "Mimosa 26" ); + + VPtBoard->ReadoutMode = 0; // Reserved for future use + VPtBoard->DataClkFrequency = 80; // 80 MHz + + if ( (DataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (DataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtBoard->EnableExtraChannel = 1; // Yes + } + + else { + VPtBoard->EnableExtraChannel = 0; // No + } + + err_trace (( ERR_OUT, "EnableExtraChannel=%d", VPtBoard->EnableExtraChannel )); + + VPtBoard->TriggerMode = 0; // Trigger mode -> disabled + VPtBoard->TriggerDetectTimeWindow = 0; // Trigger mode -> Window during which we count triggers to detect beginning of spill + VPtBoard->TriggerDetectOccurNb = 0; // Trigger mode -> Number of trigger required during "TriggerDetectTimeWindow" to decide that spill has begun + VPtBoard->AcqNbPerTrig = 0; // Trigger mode -> Number of consecutive Acq stored after beginning of spill detection + + VPtBoard->EnableTimeStamping = 0; // On board time stamping -> disabled + VPtBoard->TimeStampRes = 0; // On board time stamp resolution in [ns] + + VPtBoard->EnableTrigCnt = 0; // On board trigger counter + + VPtBoard->TagEventsStoredByDUT = 0; // Tag events taken dy DUT -> disabled + VPtBoard->ReadTluTrigCntEachNTrig = 0; // Read event counter provided by TLU -> disabled + + + + // Allocate memory + + // IPHC data transfer mode + + if ( DataTransferMode == EFRIO__TRF_MODE_IPHC ) { + + // Free tmp trigger record if allocated + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + // Free EUDET mode buffer + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.PtFrame = NULL; + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Alloc IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + + VPtCont->RunCont.InfZsFFrameRawBuffSz = VPtCont->RunCont.ParMi26Nb * (VPtCont->RunCont.ParFrameNbPerAcq + 200) * sizeof (MI26__TZsFFrameRaw); + + VPtCont->RunCont.PtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + err_retnull ( VPtCont->RunCont.PtZsFFrameRaw, (ERR_OUT,"Allocation of IPHC buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // EUDET data transfer mode + + else { + + // Alloc tmp trigger record + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + VPtCont->PtTmpTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtCont->PtTmpTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Free IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + VPtCont->RunCont.InfZsFFrameRawBuffSz = 0; + + // Reset frame list + + memset ( VPtCont->AAcqFrameList, 0, sizeof (EFRIO__TFrameList) ); + + // Alloc + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Upgrade for Ultimate + + // VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VPtCont->RunCont.InfFrameBuffSz = VPtCont->RunCont.ParFrameNbPerAcq * VMaxFrameSz; + + VPtCont->RunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->RunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->RunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq) ); + + err_error (( ERR_OUT, "TRACE => Frames buffer sz = %d Bytes", VPtCont->RunCont.InfFrameBuffSz )); + err_error (( ERR_OUT, "TRACE => Frames buffer sz = %d MBytes", VPtCont->RunCont.InfFrameBuffSz / (1024 * 1024) )); + } + + + // Reset run context results fields + + VPtCont->RunCont.ResAcqCnt = 0; + VPtCont->RunCont.ResFrameCnt = 0; + VPtCont->RunCont.ResEventCnt = 0; + + // Set status conf done + + VPtCont->ABoardsStatus[0].ConfDone = 1; + + // Set flag init done + + VPtCont->InfInitDone = 1; + + // Init for Labview because some emulation parameters are not controlled by GUI + + #ifdef APP_DLL + EFRIO__FEmuleBegin ( 1 /* RunInLabview */ ); + #endif + + + err_retok (( ERR_OUT, "end" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 07/03/2011 + : - Get disk sector size from OS + : + : 20/05/2011 + : - Use run param to calculate TCStreamFile max buffer size + : + : 13/10/2011 + : - Add creation of a copy of run conf file in x:\log ( VInfConfFileNameCpy ). + : + : 10/07/2012 + : - Create run index file + : + : 09/11/2012 + : - Automatic creation of run directory + : + : 26/03/2013 + : - Add EFRIO__USR_VGContext.ParCrIndexFile handling + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStartSavingOnFile () { + + SInt32 VRet; + char VDiskDrive[3]; + SInt32 VDiskSectorSz; + SInt8 VUseThread; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + EFRIO__TFrame* VPtFrame; + SInt32 VStreamFileMaxBlocSz; + char VInfConfFileNameCpy[GLB_FILE_PATH_SZ]; // Copy in x:\log of the run conf file + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + + VRet = 0; + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + // Debug + + msg (( MSG_OUT, "EFRIO__FStartSavingOnFile () => Run No = %d", VPtRunCont->ParRunNo )); + + msg (( MSG_OUT, "EFRIO__FStartSavingOnFile () => Dest dir = %s", VPtRunCont->ParDestDir )); + + // 09/11/12 + + if ( DirectoryExists ( VPtRunCont->ParDestDir ) == True ) { + msg (( MSG_OUT, "Dest dir = %s already exists", VPtRunCont->ParDestDir )); + } + + else { + msg (( MSG_OUT, "Dest dir = %s doesn't exist => Try to create it", VPtRunCont->ParDestDir )); + + err_retfail ( FIL_FMkDir ( VPtRunCont->ParDestDir ), (ERR_OUT,"Abort : Directory %s creation failed !", VPtRunCont->ParDestDir ) ); + } + + + // Create & write conf file + + // msg (( MSG_OUT, "VPtRunCont->ResConfFileName=%s", VPtRunCont->ResConfFileName )); + + // Set pointer to 0 before saving and restor them afer + + VPtZsFFrameRaw = VPtRunCont->PtZsFFrameRaw; + VPtFrame = VPtRunCont->PtFrame; + + VPtRunCont->PtZsFFrameRaw = NULL; + VPtRunCont->PtFrame = NULL; + + VRet = VRet | EFRIO__VGRunConfFile.PubFConf ( VPtRunCont->InfConfFileName, FIL__TCBinFile_RWB_MODE_WRITE, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont), 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunConfFile.PubFCreate (); + VRet = VRet | EFRIO__VGRunConfFile.PubFSeqWrite ( VPtRunCont, sizeof (EFRIO__TRunCont) ); + VRet = VRet | EFRIO__VGRunConfFile.PubFClose (); + + VPtRunCont->PtZsFFrameRaw = VPtZsFFrameRaw; + VPtRunCont->PtFrame = VPtFrame; + + err_retfail ( VRet, (ERR_OUT,"Run config file = %s creation failed !", VPtRunCont->InfConfFileName) ); + + // Make a copy of run info file + + sprintf ( VInfConfFileNameCpy, "x:\\log\\%s%d.par", VPtRunCont->ParFileNamePrefix, VPtRunCont->ParRunNo ); // 13/10/2011 + + VRet = FIL_FCpyFile ( VPtRunCont->InfConfFileName, VInfConfFileNameCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT, "Copy of info = %s file i, %s failed !", VPtRunCont->InfConfFileName, VInfConfFileNameCpy )); + err_error (( ERR_OUT, "Copy of info = %s file i, %s failed !", VPtRunCont->InfConfFileName, VInfConfFileNameCpy )); + } + + // Create data file + + if ( VPtRunCont->ParSaveOnDisk == 1 ) { + VUseThread = 1; + } + + else { + VUseThread = 0; + } + + + // Get disk sector size + + strncpy ( VDiskDrive, VPtRunCont->InfDataFileName, 2 ); + + VDiskDrive[2] = 0; + + VDiskSectorSz = FIL_FGetDiskSectorSz ( VDiskDrive ); + + err_retfail ( VDiskSectorSz, (ERR_OUT,"Abort => Unable to get drive %s sector size !", VDiskDrive ) ); + + msg (( MSG_OUT, "Disk sector sz = %d Bytes", VDiskSectorSz )); + + // Set TCStreamFile disk sector size + + VRet = VRet | EFRIO__VGRunDataFile.PubFSetDiskSectorSz ( VDiskSectorSz ); + + // Conf TCStreamFile + + // VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + // VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + // 20/05/2011 + + VStreamFileMaxBlocSz = ( VPtRunCont->ParFrameNbPerAcq * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ); + + err_error (( ERR_OUT, "TRACE => Calc TCStreamFile max bloc sz - %d Fr/Acq - Bloc Sz = %d MB", VPtRunCont->ParFrameNbPerAcq, VStreamFileMaxBlocSz / (1024 * 1024) )); + + VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, VStreamFileMaxBlocSz /* Max */, VStreamFileMaxBlocSz /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + err_retfail ( VRet, (ERR_OUT,"Run data file = %s creation failed !", VPtRunCont->InfDataFileName) ); + + // Create index file + + #ifdef EFRIO__CREATE_INDEX_FILE + if ( VPtUsrCont->ParCrIndexFile ) { + VRet = FIL_FIndexFileTelCreate ( VPtRunCont->InfIndexFileName ); + err_retfail ( VRet, (ERR_OUT,"Index file %s creation failed => %s", VPtRunCont->InfIndexFileName, _strerror ( "System says :" ) )); + } + #endif + + // + + VPtRunCont->InfSaveDataOnDiskRunning = 1; + + } + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 16/02/2011 + : - Test if ParTotEvNb reached, if yes => call EFRIO__FStopSavingOnFile () + : + : 24/02/2011 + : - Handle SpareW32Par as an array ASpareW32Par now + : + : 10/07/2012 + : - Create run index file + : + : 26/03/2013 + : - Add EFRIO__USR_VGContext.ParCrIndexFile handling + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSaveAcqOnFile () { + + SInt32 VRet; + SInt32 ViFr; + static SInt32 ViEv = 0; + SInt8 VUseThread; + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TFileSpareW32Info VSpareW32Info; + + + VRet = 0; + + if ( VPtRunCont->InfSaveDataOnDiskRunning == 0 ) { + return (0); + } + + if ( VPtRunCont->ResEventCnt > VPtRunCont->ParTotEvNb ) { + EFRIO__FStopSavingOnFile (); + err_error (( ERR_OUT, "TRACE => End of run reached : %d events saved on disk", VPtRunCont->ResEventCnt )); + return (0); + } + + // Save acq on file if + // - Run conf "save on disk" parameter is set + // - There is something to save => ResAcqFunctRetCode = acquisition size <> 0 + + if ( (VPtRunCont->ParSaveOnDisk > 0) && (VPtRunCont->ResAcqFunctRetCode > 0) ) { + + VSpareW32Info.AcqStatus = VPtFrList->AcqStatus; + VSpareW32Info.TrigStatus = VPtFrList->TrigStatus; + VSpareW32Info.TotFrameNb = VPtFrList->TotFrameNb; + VSpareW32Info.DiskSectorSz = EFRIO__VGRunDataFile.PubFGetDiskSectorSz (); + + VRet = EFRIO__VGRunDataFile.PubFSeqWrite ( VPtRunCont->PtFrame, VPtRunCont->ResAcqFunctRetCode /* Acq sz */, VPtRunCont->ResEventCnt - 1 /* DbgCallPar */, 1 /* SpareW32InfoFormat */, (SInt32*) &VSpareW32Info, sizeof (VSpareW32Info) / 4 /* SpareW32InfoNb */ ); + +// err_error (( ERR_OUT, "***********************************************" )); +// err_error (( ERR_OUT, "TRACE => Saving AcqId=%d - %d Frames", VPtRunCont->ResAcqCnt, VPtFrList->TotFrameNb )); +// err_error (( ERR_OUT, "***********************************************" )); + + if ( VPtRunCont->ResAcqCnt == 1 ) { + ViEv = 0; + } + + for ( ViFr=0; ViFr < VPtFrList->TotFrameNb; ViFr++ ) { + +// err_error (( ERR_OUT, "EvId=%d - AcqId=%d - Fr=%d : Header=%x [H] - FrCnt=%d", ViEv, VPtRunCont->ResAcqCnt - 1, ViFr, VPtFrList->AFramePtr[ViFr]->Header.AMapsHeader[0], VPtFrList->AFramePtr[ViFr]->Header.AMapsFrameCnt[0] )); + + #ifdef EFRIO__CREATE_INDEX_FILE + if ( VPtUsrCont->ParCrIndexFile ) { + FIL_FIndexFileTelAddEv ( ViEv /* EvId */, VPtRunCont->ResAcqCnt - 1 /* AcqId */, ViFr /* FrId */, VPtFrList->AFramePtr[ViFr]->Header.AMapsFrameCnt[0] /* EvTag */, VPtFrList->AFramePtr[ViFr]->Header.AMapsTrigInfo[0], VPtFrList->AFramePtr[ViFr]->Header.AMapsTrigInfo[1], VPtFrList->AFramePtr[ViFr]->Header.AMapsTrigInfo[2], VPtFrList->AFramePtr[ViFr]->Header.TriggerNb, 0 /* SpareU32 */ ); + } + #endif + + ++ViEv; + } + + } + + err_retfail ( VRet, (ERR_OUT,"Saving Acq=%d of %d bytes on file %s failed", VPtRunCont->ResAcqCnt - 1, VPtRunCont->ResAcqFunctRetCode, VPtRunCont->InfDataFileName ) ); + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStopSavingOnFile () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + VRet = 0; + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_IPHC ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__TRF_MODE_IPHC not hanlded") ); + } + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + VPtRunCont->InfSaveDataOnDiskRunning = 0; + + VRet = VRet | EFRIO__VGRunDataFile.PubFFlush (); + VRet = VRet | EFRIO__VGRunDataFile.PubFClose (); + + err_retfail ( VRet, (ERR_OUT,"Error while closing data file = %s", VPtRunCont->InfDataFileName) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +#undef COMPIL_FTluTrigger2Str +#ifdef COMPIL_FTluTrigger2Str + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert TLU trigger info record to string for print or display + : +Inputs : Trig - Source trigger record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display + : +Inputs : Ts - Source time stamp record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger / timestamp as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in IPHC data transfer mode. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + SInt32 VNiFrame; + SInt32 VNiFramePMi26; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[0]; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VNiFrame = ViFrame * VPtRunCont->ParMi26Nb; + + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + VNiFramePMi26 = VNiFrame + ViMi26; + + if ( VPtFrame[VNiFramePMi26].Header != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Header, VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFrame[VNiFramePMi26].Trailer != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Trailer, VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFrame[VNiFramePMi26].FrameCnt; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFrame[VNiFramePMi26].FrameCnt != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].FrameCnt, VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in EUDET 1,2,3 data transfer modes. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +UInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrame* VPtFr; + SInt32 ViFrame; + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VPtFr = VPtFrList->AFramePtr[ViFrame]; + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + if ( VPtFr->Header.AMapsHeader[ViMi26] != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsHeader[ViMi26], VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFr->Header.AMapsTrailer[ViMi26] != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsTrailer[ViMi26], VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFr->Header.AMapsFrameCnt[ViMi26]; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFr->Header.AMapsFrameCnt[ViMi26] != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFr->Header.AMapsFrameCnt[ViMi26], VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/04/2011 ( DPXI version of 20/08/2009 moved here ) + : +Rev : 15/05/2013 + : - Modification of frame counter test, the test Fr(n+1) = Fr(n) + 1 has been + : removed because in beam test (EUDET3 mode) the frames in one acquisition are + : not all consecutives, there it detects fake errors. Now the test is only done + : by a comparison of all Mimosa 28 frame couters frame by frame. + : +Doc date : 20/08/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FChkFrameLight ( SInt16 FuncId, SInt32 CurFrame, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // Debug tool + + if ( VPtTestCont->ParPrintLvl == -1 ) { + msg (( MSG_OUT, "Nb Mi26 to test : %d", VMi26Nb )); + } + + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 26 frame counters to the one of Mimosa26 [0] + // This is done frame by frame = doesn't care about previous frame counter value - 15/05/2013 + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "B - Frame cnt error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Header error [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Trailer error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + + return (VErrors); +} + + +#ifndef NO_MI26 + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 02/02/2010 +Rev : 07/05/2010 + : - Trigger calculation + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // msg (( MSG_OUT, "==> DPXI__MI26_FFRioAcqDeserData1Mi26 : Mi26NbToRead=%d - EltNb=%d - TotAnsSz=%d", VPtServ->PtParAcqReqFunc->AsicNbToRead, EltNb, PtAcq->InfTotAnsSz )); + + // Copy Acq inf pointers to local pointers + + // $$$ VPtAcqData = PtAcq->InfPtAcqData; + // $$$ VptZsFFrameRaw = PtAcq->InfPtZsFFrameRaw; + // $$$ msg (( MSG_OUT, "DPXI__MI26_FFRioAcqDeserData1Mi26 => AcqReqFuncSz=%d - MaxDataSz=%d - VTotAnsSz=%d", PtAcq->InfParAcqReqFuncSz, VPtServ->PtParAcqReqFunc->MaxDataSz, PtAcq->InfTotAnsSz )); + // $$$ memset ( VPtAcqData, 0, PtAcq->InfTotAnsSz ); + // $$$ err_trace (( ERR_OUT, "Start extract data for FrameNb=%d", VPtServ->PtParAcqReqFunc->FrameNb )); + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // $$$ VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VptZsFFrameRaw[ViFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[ViFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + VptZsFFrameRaw[ViFrame].DataLength = VDataLengthField; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32 = (UInt32*) VptZsFFrameRaw[ViFrame].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[ViFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + VptZsFFrameRaw[ViFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + VptZsFFrameRaw[ViFrame].Zero2 = VZero2; + ++ViSrcW32; + + // $$$ DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + VptZsFFrameRaw[ViFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[ViFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[ViFrame].SStatus.HitCnt = -1; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 09/03/2010 +Rev : 06/05/2010 + : - Add trigger extract + : Warning ! Copy Zero & Zero2 fields of frame chip No 0 to ALL others chips ! + : All fields Zero & Zero2 are equals to the fields of first chip + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + SInt32 V6iFrameP1; + SInt32 V6iFrameP2; + SInt32 V6iFrameP3; + SInt32 V6iFrameP4; + SInt32 V6iFrameP5; + UInt32 VADataLengthField[6]; + UInt16 VADataLengthW16[6]; + UInt16 VADataLengthW32[6]; + UInt16 VDataLengthW32Max; + register SInt32 ViSrcW32; + register SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get AcqId + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // err_warning (( ERR_OUT, "TRACE : Memset buffer")); + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + V6iFrameP1 = V6iFrame + 1; + V6iFrameP2 = V6iFrame + 2; + V6iFrameP3 = V6iFrame + 3; + V6iFrameP4 = V6iFrame + 4; + V6iFrameP5 = V6iFrame + 5; + + + VptZsFFrameRaw[V6iFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VptZsFFrameRaw[V6iFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + + VptZsFFrameRaw[V6iFrame].DataLength = VADataLengthField[0]; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VptZsFFrameRaw[V6iFrameP1].DataLength = VADataLengthField[1]; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + + VptZsFFrameRaw[V6iFrameP2].DataLength = VADataLengthField[2]; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VptZsFFrameRaw[V6iFrameP3].DataLength = VADataLengthField[3]; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VptZsFFrameRaw[V6iFrameP4].DataLength = VADataLengthField[4]; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VptZsFFrameRaw[V6iFrameP5].DataLength = VADataLengthField[5]; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + // Find max data length of the six Mi26 + + VDataLengthW32Max = MATH_FUInt16Max ( VADataLengthW32, 6 ); + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32Chip0 = (UInt32*) VptZsFFrameRaw[V6iFrame].ADataW16; + VPtDataW32Chip1 = (UInt32*) VptZsFFrameRaw[V6iFrameP1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VptZsFFrameRaw[V6iFrameP2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VptZsFFrameRaw[V6iFrameP3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VptZsFFrameRaw[V6iFrameP4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VptZsFFrameRaw[V6iFrameP5].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip1[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip2[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip3[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip4[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip5[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VptZsFFrameRaw[V6iFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + ++ViSrcW32; + + // DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + + VptZsFFrameRaw[V6iFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrame].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP1].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 1 + 18 + (6 * VADataLengthW32[1])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP1].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP1].SStatus.AsicNo = 1; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP1].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP2].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 2 + 18 + (6 * VADataLengthW32[2])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP2].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP2].SStatus.AsicNo = 2; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP2].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP3].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 3 + 18 + (6 * VADataLengthW32[3])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP3].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP3].SStatus.AsicNo = 3; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP3].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP4].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 4 + 18 + (6 * VADataLengthW32[4])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP4].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP4].SStatus.AsicNo = 4; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP4].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP5].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 5 + 18 + (6 * VADataLengthW32[5])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP5].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP5].SStatus.AsicNo = 5; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP5].SStatus.HitCnt = -1; + + + + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 6 /* Mi26Nb */ ); + // PtAcq->ResAsicErrorsRejCurAcq = 0; + + // if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 25/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 27/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointers + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // If length > max possible => Set it to 0 + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode5Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/08/2012 + : Copy EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 to create EFRIO__MI26_FFRioAcqDeserDataEudet2Mode5Mi26. +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode5Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[5]; + UInt32 VADataLengthW8[5]; + UInt16 VADataLengthW16[5]; + UInt32 VADataLengthW32[5]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[5]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // Divide by 6 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + // err_error (( ERR_OUT, "$$$ Header [0]=%x - [1]=%x - [2]=%x - [3]=%x - [4]=%x", VPtFrame->Header.AMapsHeader[0], VPtFrame->Header.AMapsHeader[1], VPtFrame->Header.AMapsHeader[2], VPtFrame->Header.AMapsHeader[3], VPtFrame->Header.AMapsHeader[4] )); + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + + // err_error (( ERR_OUT, "### Data length [0]=%d - [1]=%d - [2]=%d - [3]=%d - [4]=%d", VADataLengthW16[0], VADataLengthW16[1], VADataLengthW16[2], VADataLengthW16[3], VADataLengthW16[4] )); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 5 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 5; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 5 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 5 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 5 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 5; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 5; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 5; // Bypass Mi26 x 5 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 6; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + // err_error (( ERR_OUT, "$$$ Trailer [0]=%x - [1]=%x - [2]=%x - [3]=%x - [4]=%x", VPtFrame->Header.AMapsTrailer[0], VPtFrame->Header.AMapsTrailer[1], VPtFrame->Header.AMapsTrailer[2], VPtFrame->Header.AMapsTrailer[3], VPtFrame->Header.AMapsTrailer[4] )); + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 5 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 29/10/2010 version handling 6 Mi26 ) +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V9iFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V9iFrame = 9 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 9 = 9 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; // 18 = 9 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + +// Mode 2 - 12 x Mi26 +// 23/11/2011 +// $$ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode12Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V13iFrame; + UInt32 VADataLengthField[12]; + UInt32 VADataLengthW8[12]; + UInt16 VADataLengthW16[12]; + UInt32 VADataLengthW32[12]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[12]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode12Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 13; // Divide by 13 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V13iFrame = 13 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + VADataLengthW16[8] = (VADataLengthField[8] & 0x0000FFFF) + ((VADataLengthField[8] & 0xFFFF0000) >> 16); + VADataLengthW16[9] = (VADataLengthField[9] & 0x0000FFFF) + ((VADataLengthField[9] & 0xFFFF0000) >> 16); + VADataLengthW16[10] = (VADataLengthField[10] & 0x0000FFFF) + ((VADataLengthField[10] & 0xFFFF0000) >> 16); + VADataLengthW16[11] = (VADataLengthField[11] & 0x0000FFFF) + ((VADataLengthField[11] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 12 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 12; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 12 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 12 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 12 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 12; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + VPtFrame->Header.AMapsDataLength[8] = VADataLengthW8[8]; + VPtFrame->Header.AMapsDataLength[9] = VADataLengthW8[9]; + VPtFrame->Header.AMapsDataLength[10] = VADataLengthW8[10]; + VPtFrame->Header.AMapsDataLength[11] = VADataLengthW8[11]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 12; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + VAPtCpyDestW32[8] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 8 * VDataLengthW32Max ) ); + VAPtCpyDestW32[9] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 9 * VDataLengthW32Max ) ); + VAPtCpyDestW32[10] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 10 * VDataLengthW32Max ) ); + VAPtCpyDestW32[11] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 11 * VDataLengthW32Max ) ); + + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[8] = *VPtCpySrcW32; + ++VAPtCpyDestW32[8]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[9] = *VPtCpySrcW32; + ++VAPtCpyDestW32[9]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[10] = *VPtCpySrcW32; + ++VAPtCpyDestW32[10]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[11] = *VPtCpySrcW32; + ++VAPtCpyDestW32[11]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 12; // Bypass Mi26 x 12 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 13; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (13 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * VADataLengthW32[0])]; // 39 = 13 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 1 + (13 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 2 + (13 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 3 + (13 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 4 + (13 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 5 + (13 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 6 + (13 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 7 + (13 * VADataLengthW32[7])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[8] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 8 + (13 * VADataLengthW32[8])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[9] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 9 + (13 * VADataLengthW32[9])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[10] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 10 + (13 * VADataLengthW32[10])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[11] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 11 + (13 * VADataLengthW32[11])]; + ++ViSrcW32; + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * MI26__ZS_FFRAME_RAW_MAX_W32) + 13]; // 13 = 13 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * MI26__ZS_FFRAME_RAW_MAX_W32) + 26]; // 26 = 13 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 26; // 13 times 2 zero fields = 26 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 12 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +// Mode 2 - N x Mi26 +// 17/11/2011 +// $$ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[16]; + UInt32 VADataLengthW8[16]; + UInt16 VADataLengthW16[16]; + UInt32 VADataLengthW32[16]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[16]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + SInt8 VMi26NbP1; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 (Mi26Nb=%d, P=%x, EltNb=%d)", Mi26Nb, PtSrcW32, EltNb )); + + // Mi26 nb check + + if ( (Mi26Nb < 0) || (Mi26Nb > 16) ) { + err_retfail ( -1, (ERR_OUT,"Bad Mi26 Nb = %d => Out of range [0..16]", Mi26Nb) ); + } + + VMi26NbP1 = Mi26Nb + 1; + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / VMi26NbP1; // Divide by 7 because of extral channel + + // VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = VMi26NbP1 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsHeader[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsFrameCnt[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthField[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthW16[ViMi26] = (VADataLengthField[ViMi26] & 0x0000FFFF) + ((VADataLengthField[ViMi26] & 0xFFFF0000) >> 16); + } + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, Mi26Nb ); + + /* + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + */ + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < Mi26Nb /* 6 */; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + + for ( ViMi26=0; ViMi26 < Mi26Nb /* 6 */; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsDataLength[ViMi26] = VADataLengthW8[ViMi26]; + } + + /* + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + */ + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * Mi26Nb; + + // VDataLengthW32ToCpy = VDataLengthW32Max * 6; + + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VAPtCpyDestW32[ViMi26] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + (ViMi26 * VDataLengthW32Max) ); + } + + + /* + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + */ + + + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + *VAPtCpyDestW32[ViMi26] = *VPtCpySrcW32; + ++VAPtCpyDestW32[ViMi26]; + ++VPtCpySrcW32; + } + + /* + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += Mi26Nb; // Bypass Mi26 x 6 data + + // VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + + VPtEChanSrcW32 += VMi26NbP1; + + // VPtEChanSrcW32 += 7; + + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32); + + // ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsTrailer[ViMi26] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + ViMi26 + (VMi26NbP1 * VADataLengthW32[ViMi26])]; + ++ViSrcW32; + } + + + + // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + /* + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + */ + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + (2 * VMi26NbP1)]; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += (2 * VMi26NbP1); // 7 times 2 zero fields = 14 + + // ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, Mi26Nb ); + + // EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode5Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/08/2012 + : => Cpy of EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 to make EFRIO__MI26_FFRioAcqDeserDataEudet3Mode5Mi26 + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 28/08/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode5Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V6FrameId; + UInt32 VADataLengthField[5]; + UInt32 VADataLengthW8[5]; + UInt16 VADataLengthW16[5]; + UInt32 VADataLengthW32[5]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[5]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // Divide by 6 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V6FrameId = 6 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 6 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V6FrameId = 6 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 5 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 5 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 5 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 5 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 5; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 5; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 5; // Bypass Mi26 x 5 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 6; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 5 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 03/11/2010 version handling 6 Mi26 ) + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 9 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = 9 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + /* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + + */ + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for N Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : + : + : Mi26Nb - Mi26 number + : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/08/2012 +Rev : + : +Doc date : 28/08/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[16]; + UInt32 VADataLengthW8[16]; + UInt16 VADataLengthW16[16]; + UInt32 VADataLengthW32[16]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[16]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + SInt8 VMi26NbP1; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 (Mi26Nb=%d, P=%x, EltNb=%d)", Mi26Nb, PtSrcW32, EltNb )); + + // Mi26 nb check + + if ( (Mi26Nb < 0) || (Mi26Nb > 16) ) { + err_retfail ( -1, (ERR_OUT,"Bad Mi26 Nb = %d => Out of range [0..16]", Mi26Nb) ); + } + + VMi26NbP1 = Mi26Nb + 1; + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / VMi26NbP1; // Divide by 9 because of extral channel + + // VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = VMi26NbP1 * VFrameId; + + // V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (VMi26NbP1 * 3) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // if ( TrigStatus == 0 ) { + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + // } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (VMi26NbP1 * 3) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + VZero = (TrigStatus << 16); + } + + // else { + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + // VZero = (TrigStatus << 16); + // } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * VMi26NbP1 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = VMi26NbP1 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsHeader[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsFrameCnt[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthField[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthW16[ViMi26] = (VADataLengthField[ViMi26] & 0x0000FFFF) + ((VADataLengthField[ViMi26] & 0xFFFF0000) >> 16); + } + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, Mi26Nb ); + + /* + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + */ + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < Mi26Nb /* 8 */; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsDataLength[ViMi26] = VADataLengthW8[ViMi26]; + } + + /* + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + */ + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * Mi26Nb /* 8 */; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VAPtCpyDestW32[ViMi26] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + (ViMi26 * VDataLengthW32Max) ); + } + + /* + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + */ + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + *VAPtCpyDestW32[ViMi26] = *VPtCpySrcW32; + ++VAPtCpyDestW32[ViMi26]; + ++VPtCpySrcW32; + } + + /* + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + + VPtEChanSrcW32 += Mi26Nb; // Bypass Mi26 x 8 data + + // VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + + VPtEChanSrcW32 += VMi26NbP1; + + // VPtEChanSrcW32 += 9; + + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32); + + // ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsTrailer[ViMi26] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + ViMi26 + (VMi26NbP1 * VADataLengthW32[ViMi26])]; + ++ViSrcW32; + } + + + // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + /* + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + */ + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + // // 9 = 9 x 1 Trailer + + } + + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + (2 * VMi26NbP1)]; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + + ViSrcW32 += (2 * VMi26NbP1); // 9 times 2 zero fields = 18 + + // ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +// 14/06/13 + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26ExtaTrigInfo ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[16]; + UInt32 VADataLengthW8[16]; + UInt16 VADataLengthW16[16]; + UInt32 VADataLengthW32[16]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[16]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + SInt8 VMi26NbP1; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 (Mi26Nb=%d, P=%x, EltNb=%d)", Mi26Nb, PtSrcW32, EltNb )); + + // Mi26 nb check + + if ( (Mi26Nb < 0) || (Mi26Nb > 16) ) { + err_retfail ( -1, (ERR_OUT,"Bad Mi26 Nb = %d => Out of range [0..16]", Mi26Nb) ); + } + + VMi26NbP1 = Mi26Nb + 1; + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / VMi26NbP1; // Divide by 9 because of extral channel + + // VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = VMi26NbP1 * VFrameId; + + // V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (VMi26NbP1 * 3) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // if ( TrigStatus == 0 ) { + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + // } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (VMi26NbP1 * 3) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + VZero = (TrigStatus << 16); + } + + // else { + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + // VZero = (TrigStatus << 16); + // } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * VMi26NbP1 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = VMi26NbP1 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsHeader[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsFrameCnt[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthField[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthW16[ViMi26] = (VADataLengthField[ViMi26] & 0x0000FFFF) + ((VADataLengthField[ViMi26] & 0xFFFF0000) >> 16); + } + + // 14/06/13 : Search max size on Mi26Nb - 1 because last one is the extra trigger info + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, Mi26Nb-1 ); + + /* + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + */ + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // Test done before 14/06/13 "if ( VDataLengthW16Max > 2304 ) {" => Don't remember why 2304, should be 1140 W16 => ??? + // Rq : 2304 = 1152 W16 x 2 = Total size (including non data fields) in W8 => It may be the explanation + // but it confirms that it's not the good value + + // 14/06/13 : Modify the test => use the good Max W16 value + // + // If one Mi26 data field is out of normal range => Force all of them to 0 in order to + // - avoid SW crash during frame processing with corrupted data + // - indicate that there is a problem with this event => data size set to 0 => event not processed + + if ( VDataLengthW16Max > 1140 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + // 14/06/13 + // If data size fields of Mi26Nb connected to DAQ (Mi26Nb - 1) is OK + // => Set maximum data size variable and data size fields to MAXIMUM possible value + // because for extra trigger acquisition, we must process the full frame + + else { + + for ( ViMi26=0; ViMi26 < Mi26Nb /* 8 */; ViMi26++ ) { + VADataLengthW16[ViMi26] = 1140; + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW16Max = 1140; + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsDataLength[ViMi26] = VADataLengthW8[ViMi26]; + } + + /* + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + */ + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * Mi26Nb /* 8 */; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VAPtCpyDestW32[ViMi26] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + (ViMi26 * VDataLengthW32Max) ); + } + + /* + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + */ + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + *VAPtCpyDestW32[ViMi26] = *VPtCpySrcW32; + ++VAPtCpyDestW32[ViMi26]; + ++VPtCpySrcW32; + } + + /* + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + + VPtEChanSrcW32 += Mi26Nb; // Bypass Mi26 x 8 data + + // VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + + VPtEChanSrcW32 += VMi26NbP1; + + // VPtEChanSrcW32 += 9; + + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32); + + // ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsTrailer[ViMi26] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + ViMi26 + (VMi26NbP1 * VADataLengthW32[ViMi26])]; + ++ViSrcW32; + } + + + // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + /* + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + */ + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + // // 9 = 9 x 1 Trailer + + } + + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + (2 * VMi26NbP1)]; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + + ViSrcW32 += (2 * VMi26NbP1); // 9 times 2 zero fields = 18 + + // ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // 14/06/13 : Force to test only 6 Mi26 because the last channel is not a Mi26 but the extra trigger info + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +#endif // ifndef NO_MI26 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 17/01/2012 + : - Implementation of "sw" handling of Mi26 / "hard coded" + : It is enable by EFRIO__FREE_MI26_NB directive and ONLY implemented in mode EUDET 2 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__USR_TContext* VPtUsrContext = &EFRIO__USR_VGContext; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + +#ifndef NO_MI26 + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + } + + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + + #ifdef EFRIO__FREE_MI26_NB + + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 ( Mi26Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + + #else + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 5 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode5Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 12 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode12Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + #endif + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + + #ifdef EFRIO__FREE_MI26_NB + + // 14/06/13 : Uses ReadoutMode command line parameter to select between normal readout & readout with etra trigger info (Debug BT June 2013) + + if ( VPtUsrContext->ParReadoutMode == 0) { + msg (( MSG_OUT, "Normal readout" )); + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 ( Mi26Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + } + + else { + msg (( MSG_OUT, "Readout WITH extra trigger info" )); + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26ExtaTrigInfo ( Mi26Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + } + + + #else + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 5 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode5Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + #endif + + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); + +#endif // NO_MI26 + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagLoadFile ( char* FileName ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + msg (( MSG_OUT, "### EFRIO__FJtagLoadFile (FileName=%s)", FileName )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagLoadFile (FileName); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagLoadFile (FileName); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 13/03/2013 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagLoadDefFile () { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + char VFileName[GLB_FILE_PATH_SZ]; + + sprintf ( VFileName, "%s", "c:\\ccmos_sctrl\\Mimosa26_jtag\\config_files\\Default.mcf" ); + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagLoadDefFile (FileName=%s)", VFileName )); + + VRet = EFRIO__MI26_FJtagLoadFile (VFileName); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagLoadFile ( char* FileName ) { + + HRESULT VRetCode; + WideString VStatus; + WideString VFileName; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagLoadFile (FileName=%s)", FileName )); + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + + if ( VJtag.IsBound () ) { + + VFileName = FileName; + + OleCheck( VRetCode = VJtag.MasterConfLoadFile( VFileName , &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Load JTAG file = %s failed !", FileName) ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagReset ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + msg (( MSG_OUT, "### EFRIO__FJtagReset ()" )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagReset (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagReset (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagReset ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagReset ()" )); + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfReset (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Reset chip failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagLoadChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + msg (( MSG_OUT, "### EFRIO__FJtagLoadChip () - ParMapsName=%d", VPtRun->ParMapsName )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagLoadChip (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagLoadChip (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: -n = error number on JTAG readback +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 28/09/2011 + : - Update code because MasterConfReadBack (...) has changed => return one more param = Reaad back errors nb + : If <> 0 return -(errors number) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FJtagLoadChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + long VReadBackErrorsNb; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagLoadChip ( ))" )); + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfUpdateAll (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + // 28/09/2011 + // Update code because MasterConfReadBack (...) has changed => return one more param = Reaad back errors nb + // If <> 0 return -(errors number) + + OleCheck( VRetCode = VJtag.MasterConfReadBack ( &VReadBackErrorsNb, &VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Read back chip parameters failed !") ); + } + + if ( VReadBackErrorsNb > 0 ) { + err_retfail ( -VReadBackErrorsNb, (ERR_OUT,"JTAG -> Read back chip => Write <> Read => %d errors !", VReadBackErrorsNb ) ); + } + + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 24/04/2013 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagResetAndLoadChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + msg (( MSG_OUT, "### EFRIO__FJtagResetAndLoadChip ()" )); + + + // ----------------------------------------------------------------------- + // Print JTAG file name in messages log file x:\log\msg_eudet_dll.txt + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "Reset & Reload JTAG => JTAG configuration file = %s", VPtRun->ParJtagFileName )); + + + // Reset Maps + + VRet = EFRIO__FJtagReset (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + err_error (( ERR_OUT, "EFRIO__FJtagReset () has failed !" )); + return (VRet); + } + + // Send parameters to Maps registers + // If read back registers <> values sent => an error is generated => VRet < 0 + + VRet = EFRIO__FJtagLoadChip (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + err_error (( ERR_OUT, "EFRIO__FJtagLoadChip () has failed !" )); + return (VRet); + } + + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagStartChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + msg (( MSG_OUT, "### EFRIO__FJtagStartChip ()" )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagStartChip (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagStartChip (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagStartChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagStartChip ()" )); + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfStart (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FHwStartChip ( SInt32 SpareS32Par ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + msg (( MSG_OUT, "### EFRIO__FHwStartChip (SpareS32Par=%d)", SpareS32Par )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + msg (( MSG_OUT, "EFRIO__FHwStartChip => Mi26 HW Start" )); + VRet = EFRIO__MI26_FHwStartChip ( SpareS32Par ); + break; } + + case ASIC__ULT1 : { + msg (( MSG_OUT, "EFRIO__FHwStartChip => ULT1 HW Start" )); + VRet = EFRIO__ULT1_FHwStartChip ( SpareS32Par ); + break; } + + default : { + msg (( MSG_OUT, "EFRIO__FHwStartChip => HW Start request - But unknown chip !" )); + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2010 +Doc date : 10/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FHwStartChip ( SInt32 SpareS32Par ) { + + err_warning (( ERR_OUT, "EFRIO__MI26_FHwStartChip (Par=%d)", SpareS32Par )); + + msg (( MSG_OUT, "### EFRIO__MI26_FHwStartChip - a - (Par=%d)", SpareS32Par )); + + // Start = D6, Speak = D7* + + #ifdef EFRIO__INCLUDE_PARA_PORT + + msg (( MSG_OUT, "### EFRIO__MI26_FHwStartChip - b - (Par=%d)", SpareS32Par )); + + PPO_FOutD6 ( 0 /* Id */, 0 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + + // Sleep ( 100 ); // 08/06/2011 => Debug for test with Flex RIO trig emulator + + PPO_FOutD6 ( 0 /* Id */, 0 ); + + #else + err_warning (( ERR_OUT, "HW start not done -> // port not enabled !" )); + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 19/05/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FTestOnDataGetJtagRef () { + + SInt32 VRet; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + // Sel Mi26 + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( ViMaps, &VStrComStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Select Maps Id = %d failed !", ViMaps) ); + } + + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 0 /* RegId */, &VHighTrailerFromJtag, &VRegValFromMi26, &VStrComStatus) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 1 /* RegId */, &VLowTrailerFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 2 /* RegId */, &VHighHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 3 /* RegId */, &VLowHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + + VPtTestCont->ParAMapsHeaderRef[ViMaps] = VLowHeaderFromJtag + (VHighHeaderFromJtag << 16); // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = VLowTrailerFromJtag + (VHighTrailerFromJtag << 16); // Mimosa 26 trailer field + + } + + } + + else { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + VPtTestCont->ParAMapsHeaderRef[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = 0; // Mimosa 26 trailer field + } + + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + + CoUninitialize(); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 29/04/2011 + : +Rev : 19/05/2011 + : - Handle both Mi26 and Ult1 +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FTestOnDataStartStop ( SInt8 Start, SInt8 MapsNbToTest, SInt8 PrintLvl ) { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + + + VPtTestCont->ParPrintLvl = PrintLvl; + + + // Stop and exit + + if ( Start == 0 ) { + + // If already stopped => Do nothing & exit + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + // If running => Stop + message + + VPtTestCont->ParModeEnable = 0; + + // Print errors count + + EFRIO__FPrintTestOnDataCont ( "Errors count after Stop" ); + + err_retok (( ERR_OUT, "Stop command executed" )); + } + + + // Start procedure + + // If already running => Do nothing & exit + + if ( VPtTestCont->ParModeEnable == 1 ) { + return (0); + } + + // If not running => Start + Message + + memset ( VPtTestCont, 0, sizeof (EFRIO__TTestOnDataCont) ); + + VPtTestCont->ParMapsNb = VPtRunCont->ParMi26Nb; + VPtTestCont->ParMapsNbToTest = MapsNbToTest; + + + switch ( VPtRunCont->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FTestOnDataGetJtagRef (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FTestOnDataGetJtagRef (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRunCont->ParMapsName) ); + break; } + + } + + err_retfail ( VRet, (ERR_OUT,"Test aborted => Unable to get param from JTAG") ); + + // Enable test + + VPtTestCont->ParModeEnable = 1; + + // Print test context + + EFRIO__FPrintTestOnDataCont ( "Record state after Start" ); + + err_retok (( ERR_OUT, "Start command executed" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FTestOnDataResetErrCnt () + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 29/04/2011 +Rev : 29/05/2013 + : Since 29/05/13 it also reads JTAG reference values from JTAG application. + : The sequence is the following one + : 1 - Prints status (ref values + errors counts) in log file + : 2 - Reset errors counter + : 3 - Reads JTAG references + : 4 - Prints status (ref values + errors counts) in log file + : + : As switch "Enable Data test" is now forced to 1, therefore JTAG reference are read + : only on first run. The modification done in "Reset data errors counter " is the + : easiest way to update JTAG reference values at the beginning of each run. + : +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FTestOnDataResetErrCnt () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + SInt8 ViMaps; + + + // Print test context => To get errors count before reset + + EFRIO__FPrintTestOnDataCont ( "Errors count before Reset" ); + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + VPtTestCont->ResAMapsErrCnt[ViMaps] = 0; + VPtTestCont->ResAMapsHeaderErrCnt[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ResAMapsFrameCntErrCnt[ViMaps] = 0; // Mimosa 26 frame counter field + VPtTestCont->ResAMapsDataLengthErrCnt[ViMaps] = 0; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + VPtTestCont->ResAMapsTrailerErrCnt[ViMaps] = 0; // Mimosa 26 trailer field + + } + + VPtTestCont->ResTotErrCnt = 0; + VPtTestCont->ResFrameNbWithErr = 0; + + // Rev : 29/05/13 + // Get JTAG reference values from JTAG application + + switch ( VPtRunCont->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FTestOnDataGetJtagRef (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FTestOnDataGetJtagRef (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRunCont->ParMapsName) ); + break; } + + } + + EFRIO__FPrintTestOnDataCont ( "Reset errors count done - Reference values after JTAG reading" ); + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FRestartDaqWaitOnDutDaq ( SInt32 TimeBeforeWaitMs, SInt8 WaitOnDutDaq, SInt32 TimeToWaitnDutDaqMs ) +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 29/04/2013 +Doc date : 29/04/2013 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FRestartDaqWaitOnDutDaq ( SInt32 TimeBeforeWaitMs, SInt8 WaitOnDutDaq, SInt32 TimeToWaitOnDutDaqMs ) { + + SInt32 ViWaitLoop; + SInt32 VWaitLoopNb; + SInt32 VLoopPeriodMs; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + + VLoopPeriodMs = 30; + + // Set "Start/Restart" line to 0 + + PPO_FOutD4 ( 0 /* Id */, 0 /* State */ ); + + // Time before wait on DUT DAQ answer + + Application->ProcessMessages (); + Sleep ( TimeBeforeWaitMs ); + + + // Wait on DUT DAQ acknowledge + + if ( WaitOnDutDaq ) { + + VWaitLoopNb = TimeToWaitOnDutDaqMs / VLoopPeriodMs; + + // Wait loop on DUT DAQ ack + + for ( ViWaitLoop=0; ViWaitLoop < VWaitLoopNb; ViWaitLoop++) { + Application->ProcessMessages (); + Sleep ( VLoopPeriodMs ); + + if ( PPO_FInBusy ( 0 /* Id */ ) == 0 ) { + PPO_FOutD4 ( 0 /* Id */, 1 /* State */ ); // Reset "Start/Restart" line + return (1); + } + + } + + // No ack from DUT DAQ + + PPO_FOutD4 ( 0 /* Id */, 1 /* State */ ); // Reset "Start/Restart" line + return (0); + + } + + else { + + // No test on DUT ack => Return 1 after " TimeBeforeWaitMs " + + PPO_FOutD4 ( 0 /* Id */, 1 /* State */ ); // Reset "Start/Restart" line + return (1); + } + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef NO_MI26 + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + + return (VTotAcqSz); + } + +#endif // NO_MI26 + +#endif diff --git a/include/pxi_daq_lib_v.2.1/Copie de eudet_frio_emul.c b/include/pxi_daq_lib_v.2.1/Copie de eudet_frio_emul.c new file mode 100755 index 0000000..3b219ed --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/Copie de eudet_frio_emul.c @@ -0,0 +1,2100 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_EMUL_C +#define EUDET_FRIO_EMUL_C + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( + : UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb ) + : +Goal : + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 09/03/2010 +Rev : 10/03/2010 + : - Add parameter PtFirstFrameNo + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VAEmulDataSzW16[6]; + + + + err_error (( ERR_OUT, "TRACE =>DPXI__MI26_FFRioEmulDeserData6Mi26 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + err_trace (( ERR_OUT, "1" )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + err_trace (( ERR_OUT, "2" )); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + err_trace (( ERR_OUT, "3" )); + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + err_trace (( ERR_OUT, "4" )); + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + err_trace (( ERR_OUT, "5" )); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_trace (( ERR_OUT, "6" )); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = 0x00030010; + VPtZsFFrameRaw[0].Zero2 = 0x00200040; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + err_trace (( ERR_OUT, "7" )); + + err_trace (( ERR_OUT, "Begin emul data loop" )); + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw[0].FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 29/10/2010 +Rev : + +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[6]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + // err_error (( ERR_OUT, "TRACE =>EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + err_trace (( ERR_OUT, "1" )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + err_trace (( ERR_OUT, "2" )); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + err_trace (( ERR_OUT, "3" )); + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + err_trace (( ERR_OUT, "4" )); + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + err_trace (( ERR_OUT, "5" )); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_trace (( ERR_OUT, "6" )); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + err_trace (( ERR_OUT, "7" )); + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw[0].FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 03/11/2010 +Rev : + +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[6]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + // err_error (( ERR_OUT, "TRACE =>DPXI__MI26_FFRioEmulDeserData6Mi26 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + err_trace (( ERR_OUT, "1" )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + err_trace (( ERR_OUT, "2" )); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + err_trace (( ERR_OUT, "3" )); + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + err_trace (( ERR_OUT, "4" )); + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + err_trace (( ERR_OUT, "5" )); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_trace (( ERR_OUT, "6" )); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = 0; // High W16 = trigger nb => Set in frames loop because it depends on frame Id + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + err_trace (( ERR_OUT, "7" )); + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + EFRIO__FSetFrameIdInTriggerRec ( ViFrame, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB, VPtTrigRec ); + + // Emulate trigger on one frame over ParTrigOnOneFrameOverN and on ParTrigOnNConsecutiveFrames consecutive frames + + if ( (ViFrame % VPtAcqEmul->ParTrigOnOneFrameOverN) <= (VPtAcqEmul->ParTrigOnNConsecutiveFrames - 1) ) { + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + } + + // othewise => no trigger + + else { + VPtZsFFrameRaw[0].Zero = 0; + } + + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw[0].FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 29/10/2010 +Rev : + +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioPrintDataMi26WithEChan ( UInt32* PtSrcW32, SInt32 TotFrameNb, SInt32 FrameNo, SInt32 NbDataW32 ) { + + SInt32 Vi; + SInt32 ViFirstW32; + SInt32 ViFrame; + UInt32 VADlField[6]; + UInt32 VADlW16[6]; + UInt32 VADlW32[6]; + UInt32* Va; + SInt32 VAiTrailer[6]; + SInt32 ViZ1; + SInt32 ViZ2; + + if ( FrameNo >= TotFrameNb ) { + err_retfail ( -1, (ERR_OUT,"FrameNo=%d > Tot frame nb=%d", FrameNo, TotFrameNb ) ); + } + + ViFirstW32 = FrameNo * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 7; + + + Va = &PtSrcW32[ViFirstW32]; + + VADlField[0] = Va[14]; + VADlField[1] = Va[15]; + VADlField[2] = Va[16]; + VADlField[3] = Va[17]; + VADlField[4] = Va[18]; + VADlField[5] = Va[19]; + + for ( Vi=0; Vi < 6; Vi++ ) { + VADlW16[Vi] = ( (VADlField[Vi] & 0xFFFF0000) >> 16 ) + (VADlField[Vi] & 0x0000FFFF); + VADlW32[Vi] = VADlW16[Vi] / 2; + VAiTrailer[Vi] = 21 + ( VADlW32[Vi] * 7 ) + Vi; + } + + ViZ1 = 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7; // 21 = (H + FC + DL) x 7 chips + ViZ2 = 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14; + + + + msg (( MSG_OUT, "===============================================================================================================================" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ 0], Va[ 1], Va[ 2], Va[ 3], Va[ 4], Va[ 5], Va[ 6] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d (H) - E=%.8d (D)", Va[ 7], Va[ 8], Va[ 9], Va[10], Va[11], Va[12], Va[13] )); + msg (( MSG_OUT, "DL [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[14], Va[15], Va[16], Va[17], Va[18], Va[19], Va[20] )); + + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H)", Va[VAiTrailer[0]], Va[VAiTrailer[1]], Va[VAiTrailer[2]], Va[VAiTrailer[3]], Va[VAiTrailer[4]], Va[VAiTrailer[5]] )); + + + msg (( MSG_OUT, "Z1 [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ViZ1], Va[ViZ1+1], Va[ViZ1+2], Va[ViZ1+3], Va[ViZ1+4], Va[ViZ1+5], Va[ViZ1+6] )); + msg (( MSG_OUT, "Z2 [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ViZ2], Va[ViZ2+1], Va[ViZ2+2], Va[ViZ2+3], Va[ViZ2+4], Va[ViZ2+5], Va[ViZ2+6] )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : Trigger handling NOT done by this function => To be implemented in fw ! +: A crosscheck with sw can be done, but therefore we need on bit of RAM to +: store trigger => acq of 15 Mi26 instead of 16. +: +Level : This is a user level function. +Date : 02/02/2010 +Rev : 10/03/2010 +: - Add parameter PtFirstFrameNo + : 26/10/2010 + : - Moved from daq_pxi lib +Doc date : 02/02/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VEmulDataSzW16; + + + // err_trace (( ERR_OUT, "DPXI__MI26_FFRioEmulDeserData1Mi26 (P=%x, EltNb=%d, FrameNb=%d)", PtDestW32, EltNb, FrameNb )); + + err_trace (( ERR_OUT, "DPXI__MI26_FFRioEmulDeserData1Mi26 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + err_trace (( ERR_OUT, "1" )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + err_trace (( ERR_OUT, "2" )); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + err_trace (( ERR_OUT, "3" )); + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + err_trace (( ERR_OUT, "4" )); + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + err_trace (( ERR_OUT, "5" )); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + err_trace (( ERR_OUT, "6" )); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + + VPtZsFFrameRaw->Zero = 0x00030010; + VPtZsFFrameRaw->Zero2 = 0x00200040; + + +// VPtZsFFrameRaw->Zero = 0x00030020; +// VPtZsFFrameRaw->Zero2 = 0x00400080; + + err_trace (( ERR_OUT, "7" )); + + err_trace (( ERR_OUT, "Begin emul data loop" )); + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + } + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw->FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : EmuleMode parameter is used to define number of trigger to emulate + : - EmuleMode >= 0 -> No trigger + : - EmuleMode < 0 -> Nb trigger = absolute value of EmuleMode + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 ViTrigToEmulate; + SInt32 VEmulDataSzW16; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ / 2 ); // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) / 2 ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw->Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + VPtZsFFrameRaw->Zero2 = 0; + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + ViDestW32 = 0; + + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw->FrameCnt; + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + // Free trigger record + + free ( VPtTrigRec ); + + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : EmuleMode parameter is used to define number of trigger to emulate +: - EmuleMode >= 0 -> No trigger +: - EmuleMode < 0 -> Nb trigger = absolute value of EmuleMode +: +Level : This is a user level function. +Date : 03/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 ViTrigToEmulate; + SInt32 VEmulDataSzW16; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + err_error (( ERR_OUT, "TRACE => Begin" )); + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ / 2 ); // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) / 2 ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw->Zero = 0; // High W16 = trigger nb => Set in frames loop because it depends on frame Id + VPtZsFFrameRaw->Zero2 = 0; + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + ViDestW32 = 0; + + +// msg (( MSG_OUT, "********************************************" )); + + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + EFRIO__FSetFrameIdInTriggerRec ( ViFrame, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB, VPtTrigRec ); + + // Emulate trigger on one frame over ParTrigOnOneFrameOverN and on ParTrigOnNConsecutiveFrames consecutive frames + + if ( (ViFrame % VPtAcqEmul->ParTrigOnOneFrameOverN) <= (VPtAcqEmul->ParTrigOnNConsecutiveFrames - 1) ) { + VPtZsFFrameRaw->Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + +// msg (( MSG_OUT, "Emul => Trig on frame %.4d", ViFrame )); + } + + // otherwise => no trigger + + else { + VPtZsFFrameRaw->Zero = 0; + } + + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw->FrameCnt; + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + // Free trigger record + + free ( VPtTrigRec ); + + err_error (( ERR_OUT, "TRACE => End" )); + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); +} + + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/__eudet_frio.h b/include/pxi_daq_lib_v.2.1/__eudet_frio.h new file mode 100755 index 0000000..1c5f59b --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/__eudet_frio.h @@ -0,0 +1,37 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.h +Goal : Functions prototypes of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_H + #define EUDET_FRIO_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/_errors.c b/include/pxi_daq_lib_v.2.1/_errors.c new file mode 100755 index 0000000..c96cf37 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/_errors.c @@ -0,0 +1,320 @@ + +/******************************************************************************* +File : x:\lib\com\errors\errors.c +Goal : Implement errors messages print ( screen ) or log ( file ) functions. + : Each function use " errors macros " to log errors and return code. + : +Remark : The way it works is controlled by 3 globals variables + : ERR_VGLogClosed = 0 ( disable ) / 1 ( enable ) errors messages + : ERR_VGLogPath = '/tmp/errors.txt' = path of error logfile + : ERR_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_C +#define ERRORS_C + + +#ifdef CC_APP_OS9 + +char* strerror ( SInt32 errno ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + sprintf ( VMsgStr, "Not avalibale under OS9" ); + + return (VMsgStr); +} + +#endif + +#ifndef CC_APP_WINDOWS + +char *_strerror ( char* UsrStr ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + strncpy ( VMsgStr, UsrStr, ERR_USR_MSG_SZ-10 ); + strcat ( VMsgStr, " : " ); + strncat ( VMsgStr, strerror ( errno ), ERR_SYS_MSG_SZ-10 ); + + return (VMsgStr); +} + +#endif + + +SInt32 ERR_FEnableLog ( SInt8 Enable ) { + + ERR_VGLogClosed = Enable; + ERR_VGFileLogEnable = Enable; + ERR_VGUserLogEnable = Enable; + + return (0); +} + +SInt32 ERR_EnableLog ( SInt8 Enable ) { + return ( ERR_FEnableLog ( Enable) ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetFileLogEnabled () { + return ( ERR_VGFileLogEnable ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetUserLogEnabled () { + return ( ERR_VGUserLogEnable ); +} + + +SInt32 ERR_FSetLogFilePath ( char* LogFilePath ) { + sprintf ( ERR_VGLogPath, "%s", LogFilePath ); + return (0); +} + +char* ERR_FGetLogFilePath () { + return ( ERR_VGLogPath ); +} + +SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath ) { + ERR_FEnableLog ( Enable ); + ERR_FSetLogFilePath ( FilePath ); + + return (0); +} + + +SInt32 ERR_FEnd () { + return (0); +} + + +SInt32 ERR_FStopLog ( SInt8 Stop ) { + ERR_VGFileDontLog = Stop; + return (0); +} + +/* 11/06/2005 */ + +SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel ) { + ERR_VGFileLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetFileLogLevel () { + return ( ERR_VGFileLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FLogLevel2Str ( SInt8 Lvl ) { + + static char VStr[GLB_CMT_SZ+1]; + + switch ( Lvl ) { + + case ERR_LOG_LVL_NONE : { + sprintf ( VStr, "ERR_LOG_LVL_NONE" ); + break; } + + case ERR_LOG_LVL_ALL : { + sprintf ( VStr, "ERR_LOG_LVL_ALL" ); + break; } + + case ERR_LOG_LVL_WARINGS_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_WARINGS_ERRORS" ); + break; } + + case ERR_LOG_LVL_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_ERRORS" ); + break; } + + default : { + sprintf ( VStr, "Unknow error level = %d", Lvl ); + break; } + + } + + return ( VStr ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetFileLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGFileLogLevel ) ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel ) { + ERR_VGUserLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetUserLogLevel () { + return ( ERR_VGUserLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FGetUserLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGUserLogLevel ) ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetErrLogConfStr () { + + static char VStr[GLB_CMT_SZ+1]; + + sprintf ( VStr, "Error log configuration \n\n - File log enabled = %d \n - File log level = %s \n - File stop log =%d \n - Log file name = %s \n - User log enabled = %d \n - User log level = %s \n - User stop log =%d \n\n", ERR_VGFileLogEnable, ERR_FGetFileLogLevelStr (), ERR_VGFileDontLog, ERR_VGLogPath, ERR_VGUserLogEnable, ERR_FGetUserLogLevelStr (), ERR_VGUserDontLog ); + + return (VStr); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FUserStopLog ( SInt8 Stop ) { + ERR_VGUserDontLog = Stop; + return (0); +} + +/* 10/06/2005 */ + +SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func ) { + + ERR_VGUserErrorFunc = Func; + + return (0); +} + +SInt32 ERR_FGenError ( char MsgType ) { + + static char VErrMsg[ERR_TOT_MSG_SZ]; + + /* ERR_VGLogLevel */ + /* == ERR_LOG_LVL_NONE => No log */ + /* == ERR_LOG_LVL_ALL => Log 'T', 'W', 'E' */ + /* == ERR_LOG_LVL_WARINGS_ERRORS => Log 'W', 'E' */ + /* == ERR_LOG_LVL_ERRORS => Log 'E' */ + + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_NONE) && (ERR_VGUserLogLevel == ERR_LOG_LVL_NONE) ) { + return (0); + } + + sprintf ( VErrMsg, "%s%s \n", ERR_VGStrLocationMsg , ERR_OUT ); + + /* File log handling */ + + while (1) { + + if ( ERR_VGFileLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Write error message to file */ + + if ( ERR_VGLogClosed && (ERR_VGLogFile != stdout) && (ERR_VGLogFile != stderr) ) { + ERR_VGLogClosed = 0; + if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + } + + if ( (ERR_VGFileDontLog == 0) && (ERR_VGLogFile != NULL) ) { + fprintf ( ERR_VGLogFile, VErrMsg ); + fflush ( ERR_VGLogFile ); + } + + break; + } + + /* User log handling */ + + while (1) { + + if ( ERR_VGUserLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Call user error function */ + + if ( (ERR_VGUserDontLog == 0) && (ERR_VGUserErrorFunc != NULL) ) { + ERR_VGUserErrorFunc ( MsgType, ERR_VGStrLocationMsg , ERR_OUT, VErrMsg ); + } + + break; + } + + + + + + + return (0); +} + + + + + + + +void FPrint ( void ) +{ + printf ( "%s \n", VGOut ); +} + +//========================================================================================= + + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.2.1/_eudet_frio.typ b/include/pxi_daq_lib_v.2.1/_eudet_frio.typ new file mode 100755 index 0000000..fa09c63 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/_eudet_frio.typ @@ -0,0 +1,792 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.typ +Goal : Types definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_TYP +#define EUDET_FRIO_TYP + + + +/* ============================================== */ +/* Board parameters configuration record */ +/* ---------------------------------------------- */ +/* Can be use to build a boards database */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// Remark for EUDET concerning trigger handling +// +// Most of the following trigger options will be useless for EUDET +// The operating mode for EUDET is : +// - The board takes data all the time regardless of trigger state +// - The fw store all triggers from TLU ( up to 288 / Mimsoa 26 frame ) are stored +// - The sw extract frames with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames after trigger + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + + char AsicName[GLB_CMT_SZ]; // The ASIC read by the board + + SInt32 AsicNb; // The number of ASICs read by the board + + SInt32 ReadoutMode; // The readout mode -> Future use + + SInt8 EmuleChannels; // Copy data of first MAPS in all channels, useful for test & debugging + // because it allows to run with one ASIC only but get data of all + + float DataClkFrequency; // Frequency of clock -> Future use, only useful in case board provide clock + + UInt32 DmaHostSz; // DMA size reserved on host CPU, must be >= size of one acquisition + + SInt32 FrameNbPerAcq; // Consecutives frames number stored during one acquisition + + SInt8 EnableExtraChannel; // Enable one more channel ( default is one channel per ASIC ) + // which can be used to store extra information -> eg : TLU trigger + + SInt32 AcqNbPerTrig; // TO BE CHECKED ! Number of consecutive acquisitions taken upon trigger detection by board + + SInt8 TriggerMode; // Trigger operating mode + + UInt32 TriggerDetectTimeWindow; // Time window during which we count triggers and decide to start acquisition if >= TriggerDetectOccurNb + + UInt32 TriggerDetectOccurNb; // Minimum trigger number during TriggerDetectTimeWindow to decide to start acquisition + + UInt32 TimeStampRes; // Resolution of time stamp + + SInt8 EnableTimeStamping; // Enable time stamping mode + + SInt8 EnableTrigCnt; // Enable trigger counter + + SInt8 TagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ ( HW line indicates that DUT has saved event ) + + UInt32 ReadTluTrigCntEachNTrig; // Period of reading TLU trigger + + +} EFRIO__TBoardConf; + + +/* ============================================== */ +/* Board status record */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + SInt8 BoardPresent; // Board present => 1, otherwise 0 + SInt8 FwLoaded; // Firmware has been loaded in board + SInt8 ConfDone; // The board has been configured by sw + + SInt32 StatusCode; // Current board status code + + char StatusStr[GLB_CMT_SZ]; // Status message associated to StatusCode + + // List of errors and last error + + char* ErrorMsgList[EFRIO__ERROR_MSG_LIST_MAX_NB]; + char LastErrorMsg[GLB_CMT_SZ]; + + // Registers read from board + + UInt32 RegDmaHostSz; // DMA host size in bytes + SInt32 RegFrameNbPerAcq; // Number of frames / acq + SInt8 RegEnableExtraChannel; // Extral channel state = enabled or not + SInt32 RegAcqNbPerTrig; // Consecutive acquisition nb per trigger + + SInt8 RegTriggerMode; // Trigger mode + UInt32 RegTriggerDetectTimeWindow; // Trigger detection window + UInt32 RegTriggerDetectOccurNb; // Number of triggers required during window to start acquisition + + UInt32 RegTimeStampRes; // Resolution of time stamp -> Check with CS if implemented ! + SInt8 RegEnableTimeStamping; // Enable time stamping mode -> Check with CS if implemented ! + + SInt8 RegEnableTrigCnt; // Enable trigger counter -> Check with CS if implemented ! + + SInt8 RegTagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ -> Check with CS if implemented ! + UInt32 RegReadTluTrigCntEachNTrig; // Period of reading TLU trigger -> Check with CS if implemented ! + + UInt64 RegTimeStamp; // Time stamp value + UInt32 RegTrigCnt; // Flex RIO rigger value + UInt32 RegTluTrigCnt; // TLU trigger value + +} EFRIO__TBoardStatus; + + + + +/* ============================================== */ +/* TLU trigger record */ +/* ---------------------------------------------- */ +/* Contains TLU trigger -> field TrigCnt */ +/* plus additional information */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 TrigCnt : 16; // Trigger counter read from TLU + UInt32 FrameIdInAcq : 11; // Index of frame in current acquisition during which trigger occurs ( 0 - 2407 ) + UInt32 EventTakenByDut : 1; // For future use : Flag at 1 if DUT has taken the event + UInt32 Reserved : 3; + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TTluTrigger; + + +/* ============================================== */ +/* Flex RIO time stamp 1 record */ +/* ---------------------------------------------- */ +/* This is the Flex RIO trigger, called */ +/* "time stamp" to avoid confusion / TLU */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Mi26Line : 10; // Line of Mi26 read during which trigger occurs + UInt32 Mi26Frame : 21; // Frame of Mi26 ( = frame counter field ) read during which trigger occurs + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TFlexRioTimeStamp1; + + +/* ============================================== */ +/* Frame header */ +/* ---------------------------------------------- */ +/* Each frame starts with a header which contains */ +/* - DAQ system info */ +/* - Mimosa 26 relevant fields */ +/* ---------------------------------------------- */ +/* Date : 22/10/2010 */ +/* Rev : 23/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_HEADER +#endif + + // New fields AcqStatus & TrigStatus 23/02/2011 + // + SInt32 AcqStatus; // Status of acquistion board for this acquisition + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + // + SInt32 TrigStatus; // No meaning now = reserved for future use + + UInt16 AcqId; // Index of acquisition containing this frame + UInt16 FrameIdInAcq; // Index of frame IN the CURRENT acquisition + + UInt16 MapsName; // MAPS name as a 16 bits code + UInt16 MapsNb; // Total number of MAPS in data + + UInt32 AMapsHeader[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 AMapsFrameCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 AMapsDataLength[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 AMapsTrailer[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + SInt16 TriggerNb; // Total triggers number during this frame + + UInt16 AMapsTrigInfo[EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA]; // First 3 "Mi26 trigger info" -> Line of Mi26 read during which trigger occurs + // if more than 3 trigger => look in trigger info block where all trigger are stored + +} EFRIO__TFrameHeader; + + +/* ============================================== */ +/* Frame data */ +/* ---------------------------------------------- */ +/* Each frame has a data part with variable size */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_DATA +#endif + UInt32 TotSz; // Total size of data bloc + UInt32 OneMapsSz; // Size of data of one MAPS + + UInt32 ADataW32[0]; // Beginning of data space + +} EFRIO__TFrameData; + + +/* ============================================== */ +/* Frame triggers list */ +/* ---------------------------------------------- */ +/* Each frame has a triggers list, up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB fields */ +/* which means up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB */ +/* trigger info */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_TRIG +#endif + UInt32 TotSz; // Total size of trigger info bloc + UInt16 TrigNb; // Total trigger nb + UInt16 TrigType; // Type of trigger info stored + + UInt32 ATrig[0]; // Beginning off triggers list + +} EFRIO__TTriggerRec; + + +/* ============================================== */ +/* Frame record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Data handling fields ( size etc ) */ +/* - The frame header */ +/* - The frame data part ( variable length ) */ +/* - Followed by the triggers info part */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new field DaqVersion */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG +#endif + SInt32 DaqVersion; // Version of DAQ - New field 21/02/2011 + SInt32 TotSz; // Total size of this frame + SInt32 TrigRecOffset; // Offset ( in bytes ) from beginning of frame to trigger info part + EFRIO__TFrameHeader Header; // Frame header + EFRIO__TFrameData Data; // Beginning of data part + + // The field EFRIO__TTriggerInfo is not defined here because "Data" has variable length + // the field BegData of Data field is used a pointer to beginning of data part + // The trigger info will be added at the end of this part but position is calculated dynamically + +} EFRIO__TFrame; + + +/* ============================================== */ +/* List of frames currently stored by lib */ +/* ---------------------------------------------- */ +/* This record stores frames list corresponding */ +/* to one acquisition */ +/* */ +/* It can be : */ +/* - frames acquired by DAQ */ +/* - frames loaded from a run file */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : */ +/* : 24/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// More information about frames storage in memory +// +// A buffer IS NOT allocated for EACH frame, a single bloc of memory is allocated for all frames of one acquisition. +// This will avoid copy frame by frame before sending them to Ethernet lib or saving them to disk. A single access +// can be done with a pointer on beginning of buffer and data size. +// +// But to process frames it's handly to have an array of pointers, each array item pointing on next frame, +// this is the goal of this list which provides : +// - The total number of frames in list +// - An array of pointers, eg : AFramePtr[2] points on third frame of acquisition +// - An array with the total size ( in bytes ) of each frame +// +// This list is built on-line while DAQ is running, or off-line via EFRIO__FBuildFrameListFromAcq (...) from +// the data of one acquisition stored in a run file. + +typedef struct { + + // New fields AcqStatus & TrigStatus 24/02/2011 + // + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + +} EFRIO__TFrameList; + + +/* ============================================== */ +/* Run configuration record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Run parameters -> Par... */ +/* - Informations built from Par etc -> Inf... */ +/* - Acquisition results ( ev cnt etc ) -> Res... */ +/* - Pointers to frames buffers */ +/* ---------------------------------------------- */ +/* This record is filled by EFRIO__FConfRun (...) */ +/* call with run parameters from GUI or Ethernet */ +/* ---------------------------------------------- */ +/* This record can be saved to disk as run config */ +/* file, but it can't be ONLY loaded from file ! */ +/* A call to EFRIO__FConfRun (...) must be done */ +/* because it allocates mem and do other tasks */ +/* -> load record from file */ +/* -> call EFRIO__FConfRun with record fields as */ +/* parameters, it will overwrite itself and all */ +/* " other tasks " will also be done */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new fields */ +/* : ParDaqVersion, ParMapsName */ +/* : - Change type of ParMi26Nb to S16 */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + +/* ============================================== */ +/* Acquisition emulation record */ +/* ---------------------------------------------- */ +/* This record contains context of DAQ emulator */ +/* application, it means : */ +/* - Parameters -> Par... */ +/* - Information, calculated from Par -> Inf... */ +/* - Results -> Res... */ +/* ---------------------------------------------- */ +/* All emulation functions are implemented in the */ +/* lib, therefore application task is only GUI. */ +/* That's why emulation context is defined here */ +/* ---------------------------------------------- */ +/* All run param for emulation are taken from */ +/* run config record -> EFRIO__TRunCont */ +/* ---------------------------------------------- */ +/* Date : 30/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqCycleMs; // Delai between two acquisitions + + SInt32 ParEmuleDRamReadMs; // Delai added to PC DRAM access to emulate Flex RIO DRAM access time + + SInt32 ParEmuleFunctNo; // Select emulation function to call -> Future use = not implemented now + + SInt8 ParRandomDataSz; // Enables random generation of data size per Mimosa 26 + // By default data size is fixed in emulation function + // Used to check if variabl length records are properly handled + + SInt8 ParSetMaxDataSzOnOneMaps; // Set maximum possible data sze on first Mi26, overwrite value set by emulation + // function, but next Mi26 keep the data size value from emulation function + // Used to check if DAQ loose frames while Mi26 provides full frames + + + UInt32 ParAHeader[EFRIO__MAX_ASIC_NB]; // Emulated header of each Mi26 + + UInt32 ParATrailer[EFRIO__MAX_ASIC_NB]; // Emulated trailer of each Mi26 + + SInt32 ParTrigNbPerFrame; // Number of trigger per frame, set the part trigger nb (B31B16) of Mi26 Zero1 field + + // In data transfer modes EUDET 2 & 3 a more complex trigger emulation is done + // We don't emulate ParTrigNbPerFrame on each frame but on N consecutives frames + // each M frames + // + SInt32 ParTrigOnOneFrameOverN; // Start emulate ParTrigNbPerFrame on one frame over M = ParTrigOnOneFrameOverN + SInt32 ParTrigOnNConsecutiveFrames; // Emulates on N consecutive frames = ParTrigOnNConsecutiveFrames + + // TLU trigger & Flex RIO trigger emulation + // Up to 288 couples TLU & Flex RIO triggers can be emulated but only EFRIO__MAX_EMUL_GUI_TRIG_NB + // are configurabbles from GUI, now EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + // - First three are configurable from GUI + // - The last one is configurable from GUI + // - Others are configured in emulation function and set to 0 + // + SInt32 ParATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated TLU trigger + SInt32 ParATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated Flex RIO trigger, called "Time stamp 1" + + // DRAM info to emulate Flex RIO readout ( we need a PC RAM bloc of same size as the board one ) + // + SInt32 InfDRamSzMb; // DRAM size in MB + SInt32 InfDRamSz; // DRAM size in bytes + UInt32* InfDRamPtr; // DRAM pointer + + SInt8 InfExtraChan; // Extra channel status ( enabled or not ) depends on data transfer mode ( -> run config ) + + char InfEmuleFuncCmt[GLB_CMT_SZ]; // A comment set by emulation function selected by ParEmuleFunctNo + // -> Future use = not implemented now + + // DAQ emulation results + // + SInt32 ResAcqCnt; // Acquisition counter + SInt32 ResEvCnt; // Events counter + // + SInt32 ResAcqFunctRetCode; // Error code returned by acquisition function + +} EFRIO__TAcqEmul; + + +/* ============================================== */ +/* Frames check record */ +/* ---------------------------------------------- */ +/* This is context of frames check functions */ +/* - EFRIO__MI26_FChkAcqIphcMode (...) */ +/* - EFRIO__MI26_FChkAcqEudetMode (...) */ +/* */ +/* They check frames integrity, can be used in */ +/* normal DAQ mode or emulation */ +/* ---------------------------------------------- */ +/* Date : 31/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqNo; // Acquisition index + + SInt32 ParFrNo; // Frame index + + SInt8 ParChkMode; // Check mode -> Allows to define a level of test + + SInt8 ParChkVerbose; // Verbose mode or not + + SInt8 ParFrPrintLevel; // Define the frame information printed in log file + // 0 -> No print + // 1 -> Print general info ( AcqId, FrameId, TrigNb ... ) + Mi26 header, frame cnt, trailer + // 2 -> Print also triggers list + + SInt8 InfMi26Nb; // Mi26 number runnig in the system + + // Values provided by DAQ to check + // They are compared to the " same fields " of EFRIO_TAcqEmul + // + UInt32 ResAHeader[EFRIO__MAX_ASIC_NB]; // Mi26 header + UInt32 ResATrailer[EFRIO__MAX_ASIC_NB]; // Mi26 trailer + UInt32 ResAFrameCnt[EFRIO__MAX_ASIC_NB]; // Mi26 frames counter + UInt32 ResADataLenght[EFRIO__MAX_ASIC_NB]; // Mi26 data part length ( in W8 not in W16 as in DataLength fields of Mi26 data stream ) + // + SInt32 ResTrigNb; // Trigger info ( couple TLU & Flex RIO trigger ) number UNDER GUI control => limited to EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + SInt32 ResATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // TLU triggers list + SInt32 ResATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Flex RIO trigegrs list + + SInt32 ResErrCnt; // Total errors counter => Information provide by DAQ <> value set in EFRIO_TAcqEmul + + +} EFRIO__TFrCheck; + +/* ============================================== */ +/* Board check record */ +/* ---------------------------------------------- */ +/* This is context of board check Vi */ +/* The board test is done by a Vi on Labview side */ +/* this record pass the parameters to the Vi */ +/* */ +/* Parameters are set via call to functions */ +/* EFRIO__FSetBoardChk... */ +/* */ +/* Parameters are read via call to functions */ +/* EFRIO__FGetBoardChk... */ +/* Theses functions are encapsulated in Vi */ +/* ---------------------------------------------- */ +/* */ +/* The test results are written in board status */ +/* record ABoardsStatus [BoardId] */ +/* */ +/* Test results are set or read functions */ +/* EFRIO__FSetBoardStatus... */ +/* EFRIO__FGetBoardStatus... */ +/* ---------------------------------------------- */ +/* Date : 22/12/2010 */ +/* Doc date : 22/12/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParBoardId; // Board to test + + SInt8 ParDoTheTest; // Set to 1 to request the test + // Reset once test has been started + + SInt32 ParTestId; // Identifier to select different tests + + SInt8 ResTestDone; // Set to 1 when test is finished + + SInt32 ResTestResult; // Test result + // < 0 => Test has failed + // = 0 => Test OK + +} EFRIO__TBoardCheck; + + +/* ============================================== */ +/* Spare W32 bloc of index file */ +/* ---------------------------------------------- */ +/* This record contains spare info for index file */ +/* ---------------------------------------------- */ +/* Date : 24/02/2011 */ +/* Doc date : 24/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + + SInt32 DiskSectorSz; // Size of disk sector + +} EFRIO__TFileSpareW32Info; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains monitoring via Eth conf */ +/* ---------------------------------------------- */ +/* Date : 15/02/2011 */ +/* Doc date : 15/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 InfFrameNbToSend; // Frame nb to send on Eth = " Frame nb per acq * % monitoring " + SInt32 InfSzToSend; // Size corresponding to InfFrameNbToSend + +} EFRIO__TMon; + + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : 07/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef struct { + + SInt8 InfInitDone; // Lib iit done or not + + EFRIO__TBoardConf ABoardsConf[EFRIO__MAX_BOARDS_NB]; // Acquisition boards config + EFRIO__TBoardStatus ABoardsStatus[EFRIO__MAX_BOARDS_NB]; // Acquisition boards status + + EFRIO__TBoardCheck BoardChk; // Reserved for future implementation + // Parameters record to check + // - Boards + // - Mimosa 26 Clk & Sync signals + + EFRIO__TAcqEmul AcqEmul; // DAQ emulation context + EFRIO__TFrCheck FrCheck; // Frames check functions context + + EFRIO__TRunCont RunCont; // Run context = parameters, memory allocated, results + + EFRIO__TMon MonCont; // Monitoring context + + EFRIO__TFrameList AAcqFrameList[1]; // Frame list of acquistion - Can be extended to more than one acq if needed + + // List of frame Id to read ( Eudet3Mode => Trigger + 2 following frames ) / acquistion - Can be extended to more than one acq if needed + + SInt16 AAAcqFrameWithTrigList[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + + EFRIO__TTriggerRec* PtTmpTrigRec; // Temporary triggers record used for internal processing + +} EFRIO__TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/a.out b/include/pxi_daq_lib_v.2.1/a.out new file mode 100755 index 0000000000000000000000000000000000000000..f37cf08511ac8eb694c2f3971d14920b1ab638b9 GIT binary patch literal 249084 zcmeFa4}9Iz{Xc%wrbLCCSP@$h7FKjsTANx+OD;t(MMG^WR2%JD)wKyl%dI4J-}l{1 zN>Q6lN6}eP6lFzHS#D|_RhF@b`o%4Rb&%L>6E9vLA@8|pY_CfCJ zea?BG_v_zzo!5Dtf3JT1&u{k(1OmPBe=q#MFa96CM<7rc$j`_Cd?NlYE*?ATjL^?R z=bwuQ_g{_+bpGXg{ZLtP@wm|VaYjDh$>*2UFTdLd|MQpsii=Ap&nZ=~dQN_S} z?|#!OFcL3h`o;JVaUY9|XJ2>K#H*(l&n_*Sh{RMJ-g~lFpbhEo-QO!fJl%g;eN-JF z9q;hv;wh7-&zw9sX39mX8kvmZA>I&i!Y?#l>YauAMq#Qt{LoC0C|YVRC`GFu<#0`sF*SV<75Sin0S!>L4A1ygIJBnu3^GT3k{#GKp>QXP_@Un(x1I2+>d{-xGYz3GLF!}d`an0T0V5LWhO%$et$9V$H2wH0k^GlZF- zW!t?<7tHq#4+J7?I|1Yu;HLn;?yF3mgXftLq;q`lz?p^+J zW@UBRmw3o_{xYstz{)Ieu0u!GUR70u*ITn4vS@rPoD~gkkA=5Kqx&D+J0L*OK^iy! zDTz=!3)-P}E7W0!I?8LaC%hayG{QvvBlYFQLRrz!_E>0p@WpEU$M4;-efxGR)NZ_+ zH{sM5u!w1BnI_QmhMpee#1YxYI@XK45EFZYI;0h96*$u*BqdXZbw@LU*D5YdZ6L z*Xr;1{*LO`_}I|J@HRWV&5EwuVR(CBrtH(LHi zdwCGb({=mJw?kQ|HWvCi8u};}`YIawFc#_nA4~dd*t5h6HQJ#@E9BTA#|pLCp|{&;r&LXdl932p4%T~ zZw=;zvbF|uL))U^Z(`wZB41^Iu(I!iw7STH&%BV4@f?+TYw+kAmTGI6ikw)KIVf6o zq*o3_azfisCh`a5;X(iMofA;XPss^y3l6HeCP!Y79Q968A-u+X{K*Zq6T+X|Q0rTv z*7914IHmpU8a?km-4#8|@#*1{PtON+mX4zNS5iAd#BFJ!GRcrTrdLQ@$rj{2qZWzL%-&WqEC;%i+!`FyYy%!;lVUn;ppl!R%CF_3Q7k z!_JpqSw(G?8%qaKlzwiLaw7oMpu?>N{BwceBig{-U&Rulod z=Eq1{sCC4*eDSuQsHgIdfj8wMwY=kyV8uulyG0jklw!TzV#n)ZKMqzL!D5%W8E5H? zA;F6Mm~n=iF-~Wk9jxfXj6rV3WSvnItRODU`@0#}>Wq?L#lM)b4S$I70{rT%Il+p} z%=$oQEn!xWg>C^6c?%R@yzrh&(ek_ zxH^SH4$qBqU`Y!T3k=UK`w@YW8N&}RJ6NDz!-tf8PoUnz3(NM>W3-k%0YD1iw&!H! z&adQN|8$ z#;P8Z%#E=L$owXD?};nq`5SqDCw6b%Bl7%?6>hRVu*w?kvL@?Sd3IT&^{al?c{$c~ z+1ABb@v6s&5HPFi^%x9Kt`*ws90=s>(B^nVlC;Cv3MDD89e!!?FW|>0`|kO(C(9sy zr~d2!gE+<$B470mKC=#@wZg5zTlP|I#;UQ4+U$j~$#{%s=WhQ1qOFS*JpsF&h@6L? zbIv^{l!$}@jk$14aUyaip>xjw6ao}F|NP?S4@K^6s{E)iWANq<%Ri~g*F}m^L!cxP znSkH(FGxf#RyCfR5CqOS;{tqzI9xR9{4;l4XUpY+_eHuw;?D~CGEhW?J3^?XK*dNP zw^3QB$B+_fv~r!&7)8_;kIHkn-43^N?8Mm10Lo`DD7q5=-;Mvtb z3a}M}7OQBpRo38K?-uE`C*Ry?ePT~&vWoNV35`~9e|y4at2i%y&wj|Xiu+mD=2&NB zTNh=;=hs1*tur#?^CzwZ=k|0?vdB3n9+7ACxS>{eoH9m~TgRTfv56fSof!y}cLYk& ztDyJd6WLZ7WkpCBla$RTW|tt_w<786$Ag%kV9AA`%rDusy*Z(uDu0PvepfMl=awB} zx(3;4z7K0OR7uMY=h#Krc3GBH)?pPv(b{B?-e`v#Yd$!jruhK7s4-(>&8K@?AJ6|_ zJEHv7IoZ~QS@GyQHh6zdW;|N^IC#G=ZOfkom-fo)Qn;3F=+tk_hc{t|H^&!Aq09nn z9KsJPR57RrJ&(=0hOipDDpNERqe?SgvWxiU)HLS=pIrx(Yd-8#^XdN9$G~>}hublD z6`Y5;I1lx3-m`0*rI5zCV*%NWuFAz(GCSey#xqQNZ*aKHDr&XR6vAy{`2Ph}k4@MT zd~vI?^VUb!+5M~wa;(|e)(v3soiGH}*cLp~czQjMQX0vTQVx0`iAj1eP%NT~C+--(&ia~!-a#&UxgL5? zl#_?)(UVddz28eYpeKoG(Hp7yx9_G;N9|_)d}}BAS>CGqPc$JFpGFf>@#uKuhzvg} zOyjEBk@Miqy%6t{p*XCiJHSRHN%iMmAEg6}79+Qdgf26VW|YrXlQ|M4aFY0~cb^wfGzP3ZHCZT(l_`eOV=xWhX+yxaJl3m<6-n6koKFo_Il|^Bk>D2@fal5MfhGI9$ovNUV(Vk?};IpOMl_*8}Tv*I`gG2 zQd_D%QFfA7TRA>B(0j5zjIR{ZW@TD^ouz!=#RZi*^HhSzwbC1q?LPG`+fzs_Lv-9r z?4=UNm7XVwW%~Q4NwwGDiQh*|83gmm9n+EF@zvyidg9j;&*l zL|4}_tUh?#Vv!OP${mD)I;;<^Q?sqJve0eCqf20sth4CSQBnFjE%V5@MmxHC9G+h( zUz=f72?+MKvFxmV@s*zlkb^q#o>u{f+kF$K=A8i45~pT|@LA_xR0r!La2{q!bSr6o zP;kQJP?KFaKN}4wSXrr(^cblzUX_WCLPoNJTCOv;=co-cP|Gk-n};F4+kp3h!PI!E zfrM+O3uW5F>)%cJr17Uk6b(1-i`qtH!5IzSdRr2K4e_cdESeBlz>!04VpKK@I#cFS z1PyjH?*dN*0zw4K`3gmFh5$+g1%xTX0z?Qz1ot7R=ZfGUROgD|&TmL3EcN#7&8O+W zA9>Fh6+VfP@=&0{@%3Q*=ATnECJ`A3=<@s#BNCATfPPhYd1)d-gvXYSx}qmI-f!So zc7u=OzrOZyyiZ~X7*=$`F<;|2W=wv*!f^!9RXENr%?Gv$$1ziTg5v`Qj;~+u;}|w@ z{6=`!2EENljLIByA|%*)9VIBEs?lg>7(z6%O|eC`S@Q>C@s8xeHO*!^e4sP4ID5P~ z5o%(G(ehK86}XpYW+8ZDExcL1f}}PZqvvt+@fv+k_cfF*uf~iSoqcKab6x2b? zp3whiMgKV9|@Yib&!Tse}bb>`ITO$1e=A%d#WCaGt#eMML!zd?G}b1M+XTM-DIVm=au2AclaCx_?*`ulftw z#7HNRruod7!gohy^T#?KAXw3Wb)_YV5atJ(R}-{D8-p)ZQ)O#LPOBc9Q4<>#hI@>4 z1h1ycJ4fZM@0@36)HLo{;~aRzcAyl`tb|qtP|MpW`DzJ<&cTJhWeT3~JzrdV-;^pY zw0nw+KhEs39&@PC5LW@JbH%l^efxGW;?=#tom#PzwLoq?P~9tdt44MGcR;niw8yCa z!$9>qROh1l@2!IB`ean!E*bG~M(|epaX|d-Bvdcz#MOsc_o(dU_;C*IIjUS`iPkKN z|LSZX)w2|;Z$F%&nF$YP5KJvNy#Xq>A3>#Z2z6{gkOtwT^0lIQYwg0=04NUV!D5p< z%ovsQX`~7@;Ejfo5%+=ExFWV8iP$?*iOpV0Dt`*Jdf2+YFsO89`BYBYA_8epoChUn zL+eWHA`rCEE^9BZ8#!&=*o;^0F?S89`QVV6=0mWSru>86N4MNVwS z<9p3-Dze^#@&$qmKhQ)XYm-d!q1+~w^?Q}YCYzprHI031983*YA6EZ|?c0Na(gAq+ zJym>@u)A$)HQAG~wl1?TmKoHG>esg%yrXj9WA*C@1mdH_#K|CPgjK~5$GY<7J{(n? zhmM9d=|b=MwQiO|nJkp63T-ICw^7pu6vF@E^(Dw$_%6l+NTAJt?qvD8LzP2Dm$YXl z>rS`zW;<4I_fT&R2i9)uSc&S~hCHxsSM?@ym-J>;lHR;z=uOMDV3k&yn|Go#nVpp8 zNW8oYO0&yaF>_b6Vn}+ecvZBbH{wMUzE+uyS`pB1*=G)i+T1(@zNd~e!nej~xYoii zyyr&v(#i)euf6QjV)}7~P$V}#Pk(Nv0}chod*OL|^&KtHfm1xE4nyjAxH>T^Z}R1n zU`6{)oj&<|I2I+LYfgtvJ#)t7lEkR2<42u34zB*`;i*Fs8K<8)rWk&$_<<{em7L1A zLn{)Ia>N9RWUBHeKqKI2B_cNfy1aA>1}xVCLfvB%k=cMQn03YJcJ#^++!!_D77#9B zIXZfAagPx|xwx}o?!+aWy&V8Y-0|;;7K%S`^bFBLfgk!OUBb;^_x9%HbfYCay9-F> z*)D6SEnuDWfr;(ynwBa7r@1#(DENbW>)ek7D$Km5nBR&bL1-_&O zDnzp*==CnevK>JyA7z>!MtUst#BeOUVV@2VzM~ypMghmFE>pU5yNYMx8M%uSJ;chMC}J}W7rlew7jgZ9a>&q zJCg>^xf8E&)>vZ4(_Q0+@VOdlkIe*mSbcFj=eX^%Hv1Ww&Bi=amUU64^;0Xf!l{+7 zVi+!kIY5^Qal{B2M?Kull^U4K8tlDja`8@b>Y15VxZV!eqlR?3Kx+eBL5m@g&hKVh z;RejNNl2t~ZVso}FrPUZiq|=}pEbH)y7WBE{iRFqZ;i&fy3Y0FTch(6&=9Q^vJ$`^ znGegOTX-V0hMD5kp}kip6%1FGR}YxBZc0WyL#-Ww8|NC|SR--}=9PKn%GVB<_Ue?3 zSDyPmDzXyRn_D03@)Z>QVoJsq)Nhxqw7#s_eyII@`~1v|t+`)YuUg{<540}H8i3Y` z<$hLZP0OKDk$f)+FFU-Fk*1aC(ZwIE24II*vwa+oZUPlpY%?BjR)Hn3DRq&%5V=Pj zCN|RRqy$7K^&7>s26#>;r-Gy#Qn)_W}17IhWnEe%Xvfq!!TC zvq~o?BGrIqm(84+h^zs0&efPskFFfy(IX(}=?6bf=qV))nw~YVFQg~3=1Ty*K+i)# zzterX#Bb5ZeN1}b|B;*C93SIKY^k6oDXNcfUF^(Enb&Cy#?=bI#=6KJKroPq^uo`K z$)xeyj$WAlpLBI1@-?86{27400F-~))u3^UHw5%~q4Id zTF#7xK9Mf2!>*V=UB5UmHIeTR#`|7+LKS8;NXyKKhCadX@ZL9~HR78zriqc`VF}~>T<3jO&@)+;8>&==>fCNG`y-JR8%gtdiU_?DOL;fI=7kh&&g(fg zl?FDw3~X-vQ21&`gi~1gf{9WvsHj8roSeVIRCc1UfXko*nElOm$|howRYykf&gufl zu`L#Aqd$?JuMH`b+=6#|$k(Vr$%&}W*GnH6qpgs@Pxu}1I&^4N`sKm(%^*-oqI_vd|mjMUr zb)l=*1d{a{@A*U=PJ?df^`1Q^;%PS03+kAcn6 z1~w19uk~6um89474ASZKZ;MU6-VzIKNz&^izNYH+<9N4+l-z4jav7>~`MUW%UpWqw zQ5N)?R8g;gbE&D!@Iv4fBeAKyZ z4V^p9D_p7WchC>2Pl+palKPau&%7&K0^uMA%V4=^sJxcba_$&Guh$Je8_u_j`rBoB z_Pl=fgd8ih9&2Yxtne%1W5H`_wI(>$ye6zO$9i4FU=Yv@y^W}OU1VV!u!r{*!!JFP z1^89o*Uf;G_jMy7@xHDHq`a?d04eWl79iz)mEZ^n9r6$mKFZf{4aNI98eO~Vqs*dF zqW3lHGXV6y{*8VTfj99{emcSD_EU&C1MnH<5>j?=x*8o!V%mSq7nE^=AGjWJVkAR?O50{=J;R?9)%zyxq`b)$fRs169FX!Rmq{+Y$)$jlH@WzDk1_#4 zSs|QWk<@r}r7mSlVSdEzTiObM-sB*IviL82%Ju?fbY`?S+17losI7K{WZ2b8A7x)Q zcWhDf2Iz1v&*!J(tNv*<|u`xw4;xIE@%oo@ol21*OZ%0N_+EqO*PiZ z$vWDOX!uL|^hIAr7v+QNb&-6C7_GhEaUKH&1OwYdBe0mGf$E?K8u_$SRQ3E8095s# z;{Xw;x?nTLz^wkQ1?fYtW80z|lqA#U=1((M5YGxV)wh z*HE~`HaLd~QSIf`ed=f?+v_5HOF?``bHdy6CJLyEiofiF=nCBm_JxEo$Y@VQ`T^oU zsh9Fs&|w~wjW1->h29Ue>@P2HxViSsiDn*14T$Cl!#RM1rm|P=ED;6;a>lt&r-k%#iE2; zxj>T37hR5ftzq8tNhmv_7=jKOKv8eCJ^e904vd{FB%^wAq_z=yaP+paT+flxPM( zqxUo>wcR$mYtN|-@zTuD zp&oky?Y@yP%uN`G5`L6~Pb`0y%Emf8B=8?z7TXARkSa8!?vwOSMUwOyVSLE#LDp>) z&q#d^9;UKa%R<{CDvWiJAWwij1 zlGXJ`d1@yhWc84=9jM*OY&g0REw~6UU6utOX<5}7vMN1a2oqVgy`Chimg|#5vFbd^ z2DlRiFt+>Of5l*IJ8E?qI}_j6i(yj&m?`l~?eQqTLbn72F;z=wtc#r9B-}j}KZ?62 z15(^Q36SFMPXH$&%!Z=`ktUZ zB{t%TSLIV=gv=)>x0r+AoqO!rz^N`W;{!o$;t`(i3CIqG2A3Vmk<>TcvS+|3Nry7y zeE{qpm-q3z$6uf0x2yvMwN{0iw@r2D9=jZIkmRvnf?DChh{wLE5ueo_d!eMmW3Mmp zkQWfh&vB7oh#uQTeiICjAiwE7jeM1X{JUWv`HTNbzNSOo>*;lLAr{V$xxt0lRXDLO z8%uv=Z&RB!p*4C{iwZ16i{6ih--C(iBlKa2r*}!+gs&nw7H)|~ds7scj)Ia$GhMh5 z&bfkP;rF9aN=?eY7meh__#H;FQdf0OMk@vaI)2snBMzegj3kbG1iJ5}VtVe(Bvb~>Xd$b?f&Yt^P z#r6nV%_9c9+`jk@7O;}ci)p%y? zL}r;i8TX6%OQOXwEozB|KLsD_GB6%%i{Wum28}D>Pos-^DY(1_N2RoSNuB_cV@RRzrP z8mi0lbNciLoHBSoi2=F<;04RzoO z`6$NY;m=~>&t#Co{kd4dV9#qyKSDte;x{rO=hQ_G1HoX^{`sB-6A+BrOAHs9(pzMX zHou3#}>!vzyIODPX|nX0D@e{=I(m>^Mg6m+U?lCD`P8Qf5kh3{Y8g**b4~k z&zANN?0;Zje+6uvV1LD1X|SI#+Qi~l9)ZC&m!gQ*hymo;eo zUsl`~L-yM4C?twuuBQ)fR?Ukk$k)adSl@e%0oR&46af=86VD zQ)gXJiiH7y&M%u$h;9(and%{~fFNTgyKDC03#m9-i8jFqk&Ni3zXPB>zQ-Wr&C`7{ z&ad;xXgQLedAK#csDgEVY+aaX?U6WLO>|G^JDs-rvai?sRZV(3?;leO3Y%Qoo9ZH4 zz+g(Z4ZmZseWMk>YWs!*NNwL}0yMUid!8C_WU3}yKoDL_>q5fsrOs)>n`k^pc+;Bz zNcf}pj5~yUH{=t3@t;Y!+B;SOlYqEIJi3{6Dj%8O79aT-WI9*jP3}hO0V2;Ch>SB3 z*-+~tVk{UTXH)l2dLuw{q@uR$I4)<=WN(Me$=NFWlCul(t2i44q&QmvNO5)!&VbdN z6%d?Vj`4+Xb~syu=4=H`DLGs5H^rE|m_bl^q0iavFOwiO^Qk!N#G`Xrr{XNX?Q`~f zcvFJ1-ACju1Cg&!^AWkmN5l(x`w`{&t%c~0-KcDqU3FeHFxk&4Qjz6$Vv7x-Q+3A` zJx(;rs%*l#JLe93#um_y9)S~AH3tO*2k#V<2;FR^K57mg2kR#sJZ_U>K;B*k;-d`2 zUs&sL&_mpg^TYNcg{58Af#q|RjYujB+VVTUmh?bvoO4d?-U~qJC&oEC z?eQvcNc4O|<$8EEPBy-S0IVHqltG2sE2szJQX*beK>l1`1uTAR2cH zU|Ei8;JsM|5H#NBrQrQXywY>LA29H~7&W?0;cqYcc%Mi?R&D~)C>&_{nO)gH0^*zT zm%C)M3lI;LGfrAnaA^# zMCkiEGXy`%p(jG;B0>mV{Q3T<(RF{9ydcaYx6m`g3cyqjcn zF9ZJl4g4p;gbDtW{;Kgm!oYv}a36o?PhH`!M=xXDzBtY9WHmSHE-l^QE-l?q7kL4E zgRGvzkBZ7Z4M;_0p8%wyvX25%QQ1F8E~By!0#Z@gd-n5a6%e$BTv{ifTXtpjAnhJI zo(I5HPHJ2)wy;~vtl>n ztk`3cbL%CyUY`})Zd>ZCScI7yTJ{hho1q|#bg)ePR@Hm)iBeE|CLor}sQ@Bt5Q!xj z_Ydo_G=c`H7oa*<8n3PPNkzz2>B+tTumrh6EkOoCi-=H)o(zMWoQ)^;7_;vgm_3K; zT+B`|Fhgf7LO`G;$_Z=H=EI0(pmbm72F_mMkjMEeRhAt=%SWuNfr}N=tT+AOr=Uiy zX2Pn|iib$ZBBZIsZ5NOvEbp*5O>P%8$VMaULbb~Xy!b15!Hz~+%)U;ap0nVG1`D16 zA}$M#f7Tbysp48d4~Z56d_u6G$d;{m5v+KMv`pjDX7Xc|%MSra6FGDg_LU%WwVNqG z*nxcYQ8pm*s}v2)CwqEk4}PqOl&tmGjtd4O6ySSzSd#&x;mlN<}Za7s5u1pqI2Ot{X=sbsAl)6^< zGI4H$$9L)?f2s#TiO93~nLLR>q^AItTt0PrBJw!XE}sND_D4V$O#apRiO9o%#+FSy z-H!eS=XB`)TR`*)L+FpP|1L(a?Dh!{!)A${c(@J#`-D3TO`3j!uSw1-vOxN{mKlN^ zzXoo1|5JAw+|E#+5_!(Ur^F(k@ zhgWs&fs(p90+u4R9=8kx7jR)XkLE(GXgxbfo;^4;0U!sFSC&kS%wjdpw4qd549o`b zPz&V`2?&0U6*mI>>@fP+p)icX&!K6vqM zYHGCO?U(JE-asUY-tQ@Tx8LN^d(BOn);TV%g%oy<6Ca|fJF%}voq(Wjxex{FvJC19 zVW@<QzB2+-IpFlf6|eVitCPL@ZkfFO2?&B+N-*ixR0DUKZH-NBl~ z=$;;l0)oUfLK#RLPcK)KxEMx7NL*Y4fbz5r5^qIyE{T12k;Do%)8zA%L|=DKA6`qP zubrrpzEzY!j`N>mHGRwX@aPi|^yRzs&0!Qk)3*xtMCe;p4S@9BWYG5*s&nZ(`te;8 zp-G>&Gp=(yTpw-cMs3kkeFzRSYTJlkMr}9aS4C|b09}#KGr%?hQs*tz_wfi65Cl#V zxj}$SFi3U@+ywm>0yn*+3Ea51?{NQhkWb*5kC8wX5C1!Ojs8Q%0=EmiQv_95Ss}=c z_1#DC4Fkb}27=2U^$=_srYG>YFBDT2O;DlCD0@7DxdfYJJE%HAtZi8R+`sFt*XRm6 zo$vLXQ;aPB}K!Hz$A2)6vpmDgcPUUp^_ zZMk}f68l?M5`&dYS-G_E+2wK*(#jczux9 zi5Td+@+yT16nT}d(eir2V8>O*`0QwY#A8SEzthQU#|SEUDFi96?j!i5f#CY1eFR7Q z2)110%4>utFOJ8Gns7hEmSE0;ZBWGEfclc)j19pHUk?s=WlQjq`Ypkq*Rb_1LhF-l z+kWeNF1;*M;&0!n{XGeWQ=TjFOL?xquaf6-KuVs=04aGc33&1p5b}(Q7$MIobUAg0 zunY!A^_3`8whS2;3GI^xrboO zDXu(^Q1UFXGe;|d;vgip#4hBP=4e-A<=JUBm==t)`Qy<<$;@Bl2ort>v}IV8=gyed2r79g1SzlX zBY3-k;1~nJ`iDFOcOlOEi(&CZUW=dB^7@s*j(CC3j=h%cL|!{aP{~Un zNO^T1!C3}^tv~b;obrH&;11;V%z@97Py+-8Xu82YP!3AR^D%onwMh2Yr42bh} zm4|aI)G@6(lTQ!x2_bGQG*l&nl~HL_9eVxr=6KbK9PDwxJq zZ!nl3`1ExS?KwVU6h0Cp+i;lRBk&mDBhF}tg?sBw)qKiRdR^f_lYt0m1Z- zSe8tGmR_f3`c|ljaB1rk0Lb*ES^fyGCEsWIl}pKVnNmUc5z*3?<8hiA$>A^xV<&8k z&KwPg0E)sHXF775Wf;X1oG|grVH8JJYI~Q8RCw`*Mt|!G)L1xQ7kx94|HF+I@a4G4NX7-{;q8AFq~?SfWp@;F3_7tW6lN<2)Yh)Iop+ z=Yi2aY!dshN$dkpC6H6;=57GT`68OEUTLEbE9j(8h;Qz|zftQ&8(j@@&qi#FSN()- zoxRkm#{lFydw~R)GdsF`3!aq*2?!0U5W4^knnSl!H;+}YC}JR1tpGp`y20Sc^FQ!8 z@{`|4^AHW1A{x{ol2RIkkXSWPfCjC>kJ6ykfRqLiJEcM0$LmG|ufq+ze)nr1uMNU% z6{^$6RqYfnr9s`t>m~!Q*!O*Y?cw9qDdNMfrKC?FqTJ#VEAu?|B>pM?>|DBx_@wl= zw5Od9u!kkZc8yjsJq@nnv})6X>nZxsicoRNDfe7w!$DLW^t9Ku;aMq;fKZ%k#o|D5 z&Y=IR6{j4wN))I35dc)2i3TI)qdM2U`OgvxNP61lX=>8gP@IOk$ZbFYieuwPDb6i` zl;RLOr8wQkYqEh?bDodaWCO1^L~)c!REo26yp-Z}AFmPvuk#GN{(85^FS_Q+C&5t4 z^+|BX@~0)VJMgD)@HBPDbWE_0V=jhLji898z@1%|P3WF~;@cZ>&gnn%p7tWnd=|kE z&kf6E=_NF_w)e&T0%R!S%!l(1Bc7L+iHezjJ@ zLYO;I!ouYMsDu|7Ox<>XFYGyYc~-*c+!?-c*Nb`U$&-dE`n1iW4mz$)b8+!DdVuy} z^*4ExtK~sRl{@u}b%0z#KN2BDS(`ER4*>RcrUE6QaKJzDtSA%^6wYB;_V68aVl{4cLCM|WA^U3R3@zmBPc}Gm33z}3cDflL z9GE-zWj$_j*FPKghq5<8CAgYgE)k_ZwBr_X8Lz7jrHL$XJCi1y(2PixuwWep#7OcD-EEu69MJ-2*5;%GS zh0=%pA?08M6hfr$NWaRlEBZrFzTREw#E~ZXQ9u#qIydENe&jiLR{Ri<{19UR9dPJ<>Sj;?TPFM{xE}!d zaje0Q!KlvV$BL?CesJ+d*Zi3G-{HqyY~kcbKZ-ZkxjIMlBkL19D}D$_evo(6j|L3L zU4Ha~9Ta}_`#k{i<9h}_@==}3k9%)Z`~Vw7Kk%E5AI~WLxW?cIZ+FMMR9gLDo}nMS z`MoFlv4G8;{K%wubDiR#=10dr@T~YDAo(HI5&Wp9ld1J16NXUuk+~EA`SE3@-(GT1 zoy(7fwaJMf-l<^uG1ahUFMCCeX?n|y9%IGxVS#d=` zazzX#xUw4KXO}DOuoJ?S_TK>@S2h`3`FbCpE7!!uYRLF)3pj$_!*IhlCn5ppnOfew z4alhF%^iTIA{w2D5Wx#3Pao40)c$UuR&1d5&O#5hmY*l!y28S_y&SHDgyYLz4ky{@ z2?Z}Q*9dcm=r9*O=rk+T$lg79D78kM2X+BUrM=F-f=#7+_U;)rRZ4E?eE?wpv$Z}C z_z2HRasonfBgO1Pavk*Mv_21oMH9&l{Vf1Wj_Y1M`;Y2eeO_ZLeTL{-!sLsv$06!1 zKUT)x;|Mzd#SzEjNSYRo6TkE(5%)fI)wUz7bf@bHR6JsH8hw6<4VGLfpgQI{*X^zK zIqyR}E3ODguH++$R?ne7==K7zYr>U+djXIuJoU@v%F(FK<;p`bPidOd>hoZrp!9hl zAf?X(04aSYf=ZvekJ^0(YPa?EQQO-`P4ta*s^Zqw&o z^Jm^8E#M;`rH&5v;~aKevq_W&S2xT(a|xq!}`F%{6+ER}x}da5%3U2%EY>_p@=K&AN;aXY{%fYkP;Aw*M&Pe6$8DXKoz z`51~!i|-T|U=iObO8`)OPZ>j!-|yjz@8AU#-zMo;Z$5w>E5=>^yq0FqNBjuq?}!Sf za*9!dBGHa^AE##&PBLw`kHSe{tCI3lp>$cZC|D>iDVsXtc_b>YLQ)@$w zb7;-iedC$EaQTXjtlRTYYS`Lf#jmN*IEOjH1l)k+?QPN8QA|n=?HC1wdQRecgT&8! z`y@^)_hqqxch^*|0)0RcIBu{bQ8r0l6r%CPO>tIb0rVR;aoLgad+6hnB=Dv2e}MR_ zDLbX#iBq!%QdXzpvppx|U4xJ#4MOg}*(YRA5P~}(VIp~d4SpNts+wA?XjhcgmRDyZ zY{QFu^ZNs}ANB%jA?)j02737~QP~DIWDC>|NMwaOQ`9@z2jiX3Gr+~l6Tu7hLaXLm zBD9u+Pb|w`;F{Z6Jw>YZ6h9n~cXx{Tmpi9K=;m3%mjZJhFuNx5okRDmtx;Rry0P6Y<+tiZsX z6&Sp;0z-FJ;KY;yCAMgaUTtuv(38E$E?OhZOD0H{RafZAYn@1(lu~`C0#kNYVEWDq z%-mUl(w!BUlTu*!@xTf#OsU&sfEB9RVeaA`<}TS`?!7zAU7C{HQ;HYb;f3=*;91Z$ z%{iD6ipQs*A(U8^{INl1QPunpCHqrkQ4f9{naw zXL35L`uDbs-C)@+H!Ry*sL{1-MRQ#gRd8QBA*XS$<2xbFL%Riui3Sqm3?w$(fP3sJ zpJKPsTo0OK0wX$GVpoJjyx?DO!F}nng3ngR;(V1yL%W-2bq9R|sW2Rj#&329D@zP2 zZbgkQEBk^9g*nbW7YfwV@IJv?j}}c3hpKBy@4Z{l`=x>2=U@BiO}if6TxBT`Nje2k z-_N8ShQvs53(!e{*MYb+s+8iWo;hQ`OGSywF(}R#6P1M;Qi`vKI)~|@&eZECV=%*^ zPU+?O7|d{}Gbw-47$Y@w#MTpkku zY8s0(1qxVVFAP&(gU_y;wyu}8P}tpdu@dW*`5%4@zP$dawOBZ+%6?lNm8#X#@IE)* zsjSGf>Ry&`Qa!%zSi((u33i;4EwQ4@z+{y$M)+cwb*sY*h}&1HO}paCp*7y=KRmYDMYcAkU6d>Q=O$JZhIEo*7jK zXrVw{Mg~^pdT>w5Q#axjQTm`(<%Z7#OtoH#XP@W2&|qfOe2^Kh$WrfYHZ%Cn zBJUj@pOvT_itmDiK=TBms_;>VZSh`6c`nB)T9qMZe#xU8$EENzN)vC%76MXB3;srF zK1*rING&ZS8KwCwr6nV^w9sjk=ChQRjMUO3T^}hXRPtF$OGa{Oqu18;dwv?3Ag>Wf zdQl@X~Q=7D8p7-DJu^vS}|S5;wE=A+sc3{M+t8W9fUlV2`qlcm?aXg(Ic%9!z83ib)Kt^EajRt(mOV19;+Db=uIov@MQgN}YeD=9XJJHSgsi98mxr68QK8mAA^ zsL4oUxe}FO4-kUucW;3P`s68yrok58gHqTY?UG(uqu10C#l@3%v4WOu~oST zo?4Coi3EiA1n?PMOny`q=zP$FimY%bH+T=+S+$I}=kpF7B(S_n;9){YV09{?FA`8k zANGX^xY+TL$eOk;lgF`bL+i#Rw21)h5#Qoh?C=^4^t1F6)L~k6mK|pxhD+SmSfeuW z21fpvUIAc_%(UZD4aUZ}a65~~vhM3_#yNL(Wjm{veiyH*QfJC{JD4FcE;~+`xU7;i z$${a(RpZI8GY#s$I)<-G@P-H6AYy}Z1Aw&{aRL%BTMAFn4lh@0FE-e5)(!WAskqLW zbCJuvV49Q*-u8D~jBZ!1KtVRbkQaADX~ci5`HaDNiC#oV)*K^up_?lJ%U3Z)h*Ad$ zsRO>}*D}U0x9ujM&-gzP|F1*0^IhZrUB>)x)-iwl>X<(v74rwAWBx3qV*Y@1%pZ`B z`2*51f1;*i{sa;8KW0z-O3WXGP6FR~71c3K%pV`uF@Hch<_}26`~m5h zf44C@!r;;^|Ma=k8yLA<`h%$KF2wv1+*iYGAZB?n|G}uX=d3&0K=i#8zT)G6S~&SU<2OU!@ej$-~RQ-|cmq}0%kFc9iFi9a<+{HDbx@!DxVi3dx}pT-9| zh3=UtiTNu7*JaF~`0JQIWrg;lV*cmgvppwdv_Z)61|g3jh~>&^oP^uIL(Ko! zPk~x;%%8mm92yMA*%@$@#Cy_>nEyA;@=l*M`(f5n(z9|9jK?$r+2@p?%7pmjWTu)* zLC3(JLA_GB67|MH?_vE)j$#XD+Gh5WPB0N#!MB>f!5`ejuI3Hkb?v}2D?r`ciIUE1 zW1j1?2`tk#NBFMTAt->ZR(|k}QcN$e(0w6htZ)Yk-WPve)|CrY($%d-M$1@NsKnkb zS~2XExj#^SPI<@n(&JH;>iUkVFYoAm6GHPls}UuncUAzk3J)tvJk+EOnOKqtVFcg&W{|!`=n)3fg&?eh8AUfUv;q#$TGTA8o?1 z6y#3Su+98mIZ;CmqHbZ(xzmXnmemtA1kGs(aLXF?zjdN!H}T+q(L_y;DE{9uQS-OA zF={aVXc59g3=lG+}UCg5f+_q1%CQ9UgE%nh`qi!rp!? zp%D1$!kdx{t1v2N8gzC;`t061TcW^bltS06vnA}?IlGU}W_Y(#qicmqNz%aa(mJLNn$)?%Alu_@+av}%XihnI6qP@qb_f3_MA~pV(6)n zau)AmcxFb*4?!^wVPw;xUYBq;gG+ud=SIr++`K!q_H#pPpMJ;J+T(r!ZA?@WABmI` zD4`lwv1L~|!CG04m9$+aWpw6%O0d+n>Yb2oF z{_PF|>QYToK;3?eTGWA;{D8WYQUUdC%#i4{inBAI&Tx{gLi{?Qp7gp7s3*nJ-C;V{ zgfoUdte%_o5I|>LDuB)+s$;;fJE~ueY%Y%6zYU*s*H)H}^5W&NlgUAJ6(;A%my-%R z2%yV{lpZNeQm8$$=D1w?SV0@E21 zoUZ@G4^C&ktAo>-Q}F_W(`Os|335=K>ya+Jh$H`2NMG$2qK58ZKf&zXu%F<&@1MN} zVKd=JJITp)&i%XQhx4e%4*|)K&ow_*f9&(49cD?wr|nm2eqj7vQ!R ztsh={NzspMb`w8j{_S3jtQ`m^(0Tt&1&t~9-;@(bzyF3=QSQHC;du0=M?hwe=igWt z7NWfa9pavwzvEZUzr8_7=HFfeq~_oL!csE-mH?#Y-(Ci!=HFfdq~_nAB5G>>O+bk3 zCQNpS$o@z%={+|u!H9{-UYevu_70X)xhnkQH++%(;e3j06HQ$6L0F*2$eOw5MzQ3N z{0L`QhzjQ4S~fz5gk5&D`#8O)a2m&Ebq{KUnGtw@;FLW7Ml2E$a!JjwH_lbe%rKr)h z&~K0R5j{&GYR3hiMO5pw^KU2YG3E+y&rSAs+H<3{<9$+UXvbeS><$ufa+{~IH=stB z#4peFNxYIbQB^L4cCht(ZcC>QJ@Pm-wV47fRE_zKG<~qa_);B9fEGNb<7OWLUkVtrBm1!HCvi zDV&VuK)u+w#>ocfj=;Dsz}X{%eRg3+av^Kf6qAo>@~4{&O_M*<r+rRNRxY6FQY3?$w^lN&y48X&#lgD@r!>L0 zpm(i--naEWde@^}#w#xa%Mv3oNJRg^KUfpZj)zO5)ek}te9{{}$l;XYQZ6oXNy+KD zB6GVab&cO>UVuM!m4BzyTZ&==$b1n~uzA8>C`Jj>4cItAw0BUXSBbSyv_X|2|5=NA z!W_}>m5R#*&55YWeZ>BWq4LQ3Rj5f#5>4`+9|D%P+D#^tMlwlMIo->bd7{dh-t!76 zU+O)p*&-4xn~5PdO=5Y?Xe%x=D~1issFCFLAm227 zI=Nnw%`QYr*GjV4g-CL>B%57`Br`&vG)J{8Il+z#x$9)z>GJe>?i>|^O-5brtL_}t z%JkWpdJ<|?`fPWOiZQZ;gkT|*K=W1+jUcPoc4t1>pS_5iI+!d|K9aAt4#$OyW+_r5 zrGzXU{S&5|rAU;N66$2_lO3-`qHUHUZBj~z)Jt=P*z3@9*3N2qtisUlfB1@rhzLCUV7D5yb{tt}D8M=dGMFV4H18kfz zH80LjacXp(a=T-Vq2gqv;yaU@Hm)ot$R93bv#=9<{BP{k_fFP zGO_R*k*~Iwfy33YNFF*gRKp{!uv%{qi9R}#b1-snC2r-9MQYV{q!3d!C{%V1vJ;U3 zc;Y|j^9rz(3O*1ik~LUo$-_|pL0>v|G;dvqj756$>!<*wRNbf~W*vgBqJO&Q%daXo z1}mT72X1vgzdNQw5DRS`zDG24 zU$EjX$+(Z4K0sxlpH}W7gjqF>L1>wTD}q#W9jh8%7BnY1gi_W^&Iuyq^+%SKCFk%= z+>qBP3GJqxasf&)s{a5+Yi`KvBvj|RSkIio5nVl6*Y@V8;fMgo9isB>OFc&AVFQ)N zQJss*F$O9}r$Obl6t2wfIVyiNP$@7_S$eY1mHRNbq!1x1Lx{g~h4{O!g!ltYnVLeZ zeX+-!d(J?&4Ar@u`_~8`-8QIust{9A8P;=DUNBJk^aUT45(AaVX;7J#!j;GHZVy$v z#z3XmK;@m`K3Cqxa#jklSFn6n9F=zsR1P#yx#MR(A8*Gv zCl=bsQAPL-4k?OS?J~!n*Jw}JY{AdLl>|jNA!4yrw$LuCvW6DeWecrR+#@{~_efuY zd!!2sa)K|`;HO{k#kKg!a|%B}2Oe78yoXf1V=5zm>M_GVHmE!f)wv9R^dz53PU-AS z_Wy=4=%MUCHBfm7)w!q~ZlH45E}-(uo}==afyxgIRPG+;bLB3y61JhT2Xzu@Dk_Kf z9F_eIRNh$aqjIi+$~i!#nGxw!6-&kEc2v+q6+76#=QIPKmwxKA=0$Nvk{ezsDtq=E zmBS2FRzK^rW~h%!%TJpBieM#20pZnFv;vV6Y?h>7ccACjAxDiC=F`hVwuR%vLbyeJ zJ+^ktuch}b?s(N&Sj{uxM!5fnQM>{F^LYsRbT^&9FXDNRy#j$1Xa?^8i}2iEKOctQ zl=Dk>ZGFba2tbLpPdZaPxtE@yNU=U+eBATo1cWD7kEtv1w08{co4qag3dp< zevWDQlN)M$3uA75v~>lz&`EzfpXaPjh2NCQwN3G=hv?3eYXwvSoPWEDT-$^jg>8>( z0)lJHF{vh8b6)njRshQ;Tq_7^u6=AwC?1XKT&_JdB!z2EOKHNr(9C1rX7}7#%!fdc zcsqb%-exin*I5{exezap1#aYU(?3C(C&sT;Q^%!QJPi?Nv}KWfxO@RuMG)dy`v!9x z-U>CiEG_KB&(7^Jo&H_OrbSL}A|tT=<0-9w^_Is;0l~>qOneC^m#p)(-VfaKb;LgCt1PiXyH67{$yAh!Y0xmiFiZqsBCRsCSJl9 z9AaJqP`R!!DSLDm`Rg^K$BBA6=dPrrP-gTko}>hXq{gr;BL{hi z2e|#sI9O0+Uq@+4;e=UFQUO%wN^0)0DUxc{cW(3cYM}#{RaYzQKoM^3Q8#b8P20`0 zJ_OyTW()e4rl4Q-c#qM?*^WeC*3yhZbwFR>7Y4CsaE(mM2*SKws2c170Z|HK3+{Yz zg`x;4ugS24-)30Luu*;o(DW9}o$df46mydQ&>ekgZ%Csr+mN_pec@}#`oa{gFKzTs zIGPSN`EB^1^5Pc}U2>&uuQ??_)r zhtd~f*Ok5~%zb?sM3fBlFT?j#Bk4B!-zfA&M{*VV0>?4Kv?F~{1SowWY)6Ih)E5Fh z)R%Pk$KV#FWd91cC|!dfmRRcclOYbQe_cU_-~u*>dr?&6P(a9YumlXz{#Vn-)c$5W zTDWkueYlnzwzbV~;Wj4S*5DbG$f+bM9$(&ii6Ak4XZLBUJBZe} zw-31Y5Us&g42YHqPoEqiJpJYo@^p*(2VlF3zjOU#2dOfHy5_36XHl9^mL*rEK5_p&wkMfSI1yDztzzuL` zz*c(wq4f&J=*Mrbs6(|^u%6kS?<>7TA08ATMf%!Ov{&AjHdZxP)j{H}u$NfGDr=7x zZH#B21L_YVR77fKhTj)XED9W(jjw-&aBLB(=KC|wvis&8C`}ePEc(3NI z2~-Gb#ijM&PZ+lyl1fUb$@)+kQrF4ahgcgF9s`s-3ghQxSXJMVzS|Xj(oMeiAS!Q6 z1mxjjEGZKdC^DyI1VaHeHD4Xd18trpLH6^cFQYB@D=Q|H-Yls%6ZiPY3`+prjj$r9 zpE)Aj@K$I;dF|Lsi}ihr-O?W%Rs#Kb>NQt?Uh<$nxsd9|nqk`!vrE<`zL%^^Owqb@ z8y#zM`sJUBF4e%F7fwHWgQrUZLYJn=a0$9}3r6FvF1-x-stQifx-`wurCF%X?KwXC z;f{2PIN4EBCb~qzI_c5{Q1q^JiSMV?rN5?7`2GV1g`!K}k-n=9UAi5WdAhU@2<%dq zNRa(J=~KESl-?| zKYoSC`Xk)m&|Yr4g<+4c1%@8eIMKKA)>4ho*4V zX+8o)LA&9E;dYERV4}9Kv;tDsXgPq?HCn_|U8B`~4EHlI9Bp7&dq^h?%i&@m$VpEl zNdp?(Fz3m@A7M^)UEBbAlni7-$c%IHMl>iyr~$iT(ZDcL8IS*S!&tIo20VF3>}v6d zd`}6AGGsw}S`O#mlRPYrlKdbod3vnw_`dD8zT~GLoWj@E=0hQZvppkIQE63a!tqa&+Z>6+fghAR9&IB%YA1`Uwpl+!rjrS*mHKy^312EE$oUH` z_X-mPz7pHRg<|Co!&zy;@Ne0Vg@4}&A$TJI^kczQJR0Z z82lTI>RkS5l$9?XTg9T zx_)f_Z#mYzYQDet6r1IYfL6O`vz(3D=~nr-*{#)%fxM={8&vga@U2b%a)=&4S7my~6WvNmN z1yEhWCKxTDe$$bf`gMk@_3oWM^%w6?vRmWPfAjTlTQmEPSm^8F8PQNn>7lVuOGS0r zV1*zLzNwhs&g;5EZOspOh^zE|yw)7)wyMBiqDq3?F@q-P7r>y01ifVtlx+|c#WHl0 zASjmw&k)XS?NIn=Y5Hp|pG2rF6R6v`@KR0GeZ(;zLjyxag&-~GfyEl{0n9kx{C!TZfc+Dztivj5hYUdi;vH5cH`oR%<$gth>ms*79dKM~B#z%PV-gVyzqksr zC=saygzKJ1BqH+xjV&EB)sB|^(j!tp5c!1A25lS0_NCj}e3&R<)cgXxz@^Na7y{P^ zP+Wb7uWcXo6z?nF&noJ$!tHT&oEfCMADguDxq*d z-xd-D(Myo1P^1eSSJMT$LMmLgbt*RGG~xYtbSkT*<{d_@>FW$+g_37S_n+zsML-C} zVsV;)x2SDeD2KsfsycqCg@U;xPbhCM@`Z9?E;WywYo^Z(%oUlbSlyX|)m^Bg=UBa> zuoBn2P+=u-bq=r+n(HEDL!c+5uU8+DhW37y-{^jUk0e5^pql1L-H5HPgIT2Hu62j% zMBU-9uRE=`W$2kKWmeSqZ<1=995&>blY$J4qHU@*MAdE#z#R!zV1KV-g~-m8{*6YPn|ya`k4(h&cF)pTw{{217}p2WmpiYI}F z1Rf) zEROyY3>YAC2S!XSm8enBB1J{TiW-FDk8*%Q1Q7%UA`}FKL{SJFCg45yaF8Has_;S; zEmbNJBBY3rU`&Fd{E=c*)QG7(A*n<_h=S(#o!RH#-Lnahqo4Qv^<%ls^E|UVGdnvo zJG(pUrf`f{vk04UQ`9A&=aEL!rKwmfaXm|Bk)JE&n5feM_JUvz$2%x(Uj;G9t;K_) z2pRN)U=WMk`&b14gSgxSxx^SHW0t5@{Q)CGGD~b7m!#zY^2?D3DY!lOXE>Hc<@=+G zKJyf17LA48vBithEP07nz2QM44yWrH-LuA!8Y6PFCYXH-0%j~VdDQ8xwYnfNWsT}z zL%CGMdNLOwH6m;PshL4Or!F;lq?t(D=OQE>66W|l+2ZH2?Nn9o)P%} zgCAg+@`wYKV#JYDdUw;Pdh+5h*3^P5U1oVb(u|oQfQnd{Ye6gwHGg0*Fl=;|nxk_~ zFlWX;AV)MhSrFaYlWN3*xZ5^5JD@sabiRTtc_E_{PCNFf+D9kIrnnuA&SL=@ow-B^ z{t=^-S4Q!VeVnfS3~A|$(s*?Gz#4r&&{^s8d}Cx9`aD0F{Q?a#(&zENTIcwjfQ z>W_WI9GP6i$V}pZ1V(0=&4!bHg}mV zsh1i`eKt!Kg;6mh5&UHRKcX<~MJZ%F1%_b+B+eK=tnh`@p)ssN;~#ICMD(;uL-Yhv zpBYL|{(aR6!l+kpNM2|V`)=v2&=5&rt^wy#}L-aagOoWJ@(=dQ0 zL-b|<^2?D>J8lpDsoyYc`3&Qo4TJC`&e@-k$zNOY(MkT6T*mVE@8@)`_#ZaqkBgAM zd=5xJ{)Um?s9T053v~HglAz1qAe;QXfa(nSYjdGP{?Pcj%U>mpJ0WSLPZ2wl$e{J+ zzb%B*&P51^5erEOncdKT^CM<=s!a$xpgKbcUuk+SLU?T6xe8&(`e5VrAI%F{|B?8# z*2V!3q5nph@)t`*$X|cjlt6QsGV)<{`HP2!6Z(&04&<3!ZIi#YsLqhT#W4=~Ls+;G z^7p(ce~9{!Ifuti4yv*o(r&FK!ms@dAv7xL~=AB z&rL77+9yY9kDI|HvOH#80&cX{{`IWRjTsN(Z{aC(5%Rd37S%`|`;vF8%VQQ~faNg@ zP9@9ZPdLG3%&+F7Izt|t;O4v#XG^QZ@I7~VteR$;T^2?})u0d|Rl56E;o2G#izg2E z?`&l4IAonHQ$03#Ru;cJ8~fXrxJ7ctoONq6=SIv~mrc$(p*lm()l!*lyeF~6bdy)mtU9?Yd_%>qcdbXw#1GCTZB zp4Jrcw5G_i@j|Y}B*`Y%^-OEdMy}83TV8qAIy4u)B?VYmhf*)PwUyYU7-26~h+gDC z!yr^=$o9@((2LX!!s($6dEr3^&~Nyb?Ev}ZNRFQ1pZa~vyw5y&Vp=2OQ+j^lfHyvn z;wJ9Lsp+u@9@At<-@|Ea-7HJT@_$*0uh$x}^^U$q45YQMFCK&(is_FBm|ysY;1}2< zS_JGXn_=#)Z^!!vWbv{#)n(g`hmBYCM31>|GSJp#CBFVBjhmJ_sl?Y8r5h8cJc$lN>4CxN zk4M6|4K~KTKGR~{HK)QESA`9}Cf5up2suunk>ubX`_@qVk$^0c`bh2jHHgBozFmD0 z`o6XH<1@MyT6Ui)JY0nE4B_<)2+w%(F?D^rdX6qUt6S>A^O%hXuc10a-(LB1I1efj z#A$?mpCJ?>JDaotC1kQKp2FJyS7+MKoV7N@OnW@7ERr^49=o-irz7U^ESomG8`T-w zaBJ3JU5RrRo}1W)Q8j!@TywVxUE+w_J1WzCl11c5S=`?)uz^|nfVagpk zk?IQ7iS$I*iGMSe*SfM)YM0N@bz;YXrdV?kVqHt$k{eM=uBtB9U73 zL|>oV^^_&n_nvf!^`n+fBzjaoVdm6{i%^SGCtfXp!A~D?hxiJX(yYjQkU|gOzM7Fs zzhIlthobEE>A!wrWtcwf1+G9JCgVrw!|o^veb@~pp%005LLWAsX_Q>UVA_jMT1;zu zBAjVeU37gY&=wLPILD_GiG}B&9^sPO^S1Q(gtyLIMQmSYC;R5z8x>>50{A zY0XI<=%4F$U}1uG0zJC~4gh_Fhri5zW@ z-AN+7>hcZ`JO3H4V}4ENXMC-nYG=xg>D7tvq6=v(S94U<`;zmlL_xxbQ{=>7Gu zt-so%I&=Kjg!flvOPCy;G^5LgVIV-#>hH2GkSJT1&769cT}B}V{cO)xCnX3rEl4P!Q|GEhpy1oBoDr>Q2?M#RFnV+gCUCG%X|k z#8da7|A8ROerzw3KU@TV4$!yM|7DnC8~llf3T6Jp|B3?fC(6bj7pgP(qgJ1pKPx8L z_!BQt$o~!gl-Fn9Fh2fGt8B!d<3yfYyAufV_|Wb)`NKuj#_|w*=FON*L_%pG}!JnI1e$XC%{b`Uj-LS!o{8GPGgPec599}EA? zpMAfe0Q(Pum_MbI5JQCRxd{I3Bwn)pCm+(V|IiT3pM9rLApQhx^0Vtt7Ju$N?BLHe z%pd3zFr@mlT>G7gAvXX0tn4>s&2FUq&aCc62*=?cF@=SbV0l|YP2-WFremR|W3`tj z(2&q5poM>gTOzX@LVI>I_c_b`5y+n1+{PsV1KO(jFyai2po(`&nd{-8&)P1<=1O=$ z+(Gaowej4FVWCW~>~|0vyVoVivw3sI9tP^??c*&KVerG!3Njx`XiacNAZo3jo)KTl zU2a)a6W_-nl@fd{SH_NSoAZfpM;@poHG;GGq$3UYi9J~H2X@xz9XpTpgvB74=m@8R zYBk+Wwl5eD4fSV*-k(P0#GeZCvb_*lCx57ZS@)Q2nj7?eAWH5}qYj9`4~-jwXI=kX z+hDMH@YJhvZ6aYH#johRMHj)rfL9zapo~@lfBQqxQ9kSf_h{*tVRvu9pC}%r$CZc; zua$^^A`o>FONuz(7tHx&)|TiA1yM1$r)RtVIB)JJS(w(J%q)pkwuo}MGAK@&8XL^X zpa2tDtxvM?iCgoJBdv^f^oCto$H8IqNg(A!w>_=}<#=Yc8OVyBSP>o7Jt}R2`3wgP zzCfF5&PxYTUz^)@r+LkH#o~Ltfl z#-bLSt4^skncg@ZbNplYL!HogvF-dy)EoWKn4!Ims1Oi9F{%WnXbwHw24l{3 za^*PMl0)DC>>V4Ndy4Al9iz0>awVWy1}L{22HFk_{Q@*y0@{y3bzF&^$@KZO7~)y% zDiEdJC4ss)9BPsc3Y?14noFR*JVg{X#FrJ1IQjB7h61m%;3UydXw6)rzevKn0)!tB z?et(UJ)lmaFU(K*oG%>(;wRK?*72rgggosFB00l4jhCwgo{g8bWLvE3*U^@=J%a-o zB_3QZfdeNKcuY{6I7`s@rr?yDbI<2RQ$wf+T%suyLGy9@37#;2SRcPCUG7<{`jfsP zp^d|a7)xmHKqYkE=$BE>{<-jHy;lWbe+QseB7xfTQwY=oCsd9E>LojriX$-M*vk%r zrtzgMmH?&Nfn=0v*GQnc*rAG@WV`L}Y2cI*68gXyPaV)qQtRinHnIuov<-^R7-+j6 zcDA)T94ax(YHI}KUVBjjHQ5do%$BgYvjnP}9f~mQWos(|vZ~3TnuJ4*w?UmIx@t!{ z>DqZRj2jDVP;mscT>|w&I8<&p)B*|AXgidoKa<7#Vqeiw9+3IBn3jf%;KV*|2bSj0 zSYp38+E_$o3I-L`pg_SOOo`0_*+gK%19CPF>)=oy$RZ_VKLlu-j}33+0l!V)K>kVdKauI!bYL4EQ zQ@9}dvL{p)_hrv2y)TR5e;bj%n};(;nXb1!BVp!~la&Rq_$)H7d_kr|%>bUo`e+h+ZIol4!Z9OP~8e@l2F>-|67)ouj-54$b z>TCy+lJ)&CCt0;eiLB#+_T@Zt~LDN?SkXFeZN`ot*%V}s9bAk6#3D7R{}CAHm;+E5SfDD)iS-ikp* z-Ad=YVv|S-V!u4#B{Ao5e@klnXHBCJ8!M@5GOB8roX!%cZh&Gw54QN6 zHTU#;|BSAeqEjYC7fUKUbVN?ks)lh}oZ@8la#YnY)CdVwDxjPcbuVgwqV{CpSa^C! zD!im|6cr3{QuM+1GTdf0gj-J&w^t<054t&25>$HckVC!_R1hl;Y>XU#THbLDI(2A;%aVv2UR^R93b;K z(R58bhZ`tSgw~a=%jTpW#xy&@@bBQxht99PwFtCfE^Rn=)o|=)d@CHgH2ez3ZYoN` zv73aFaO}pTBpkc3C<(`I7^MOc@h~pJu}hkPUL+?y8yi22S;|9cH( z-H1WVeRk~1cJVBQA{3QB5#K3bQ?!R1yS20~Y`SRdY*i0*_S=a{>TMmWxJO$={CdPs z8(Y%DJ#E~WDJ4DP#?44eEa?$DX3FHWk{&T>Q>G=BM0=-9o)GRR{KH<6wE4#+%|FFZ zwJL%@h@lbYy7M)d7{lT{NdlIvgC)m=!%Z>ax=P?;Ly_#1=HOB304I<3!gDrxBqeRJ z1Zuf}D)x~8U_>;&_n#BJ&!gaB(Gr(G|ET^sD(_Fotk%av(6=-R!+`EqrKnqLthor` zS3IXx&*{t}3;~|s%&ne^2$dK_SQ6j_F}@El)kA`q<4Q`6-+Kh%IvN!7@==Lv9$!+y zC)4Yxxl1qK^YEVjL`E@y9q=Fb!Rz&(=pnJMlOe z{S^u{4i<{=8O#0sQdA?B$5f{%eWsLN&QM3|O(PI)^I@3j&A@w&Vu znM2AY1Q?~Ieg{AsxNBR=R^^Z~6!~Iep2X)vV-%P6pak&xFhK05)Z<$$D>e5z+xq$6 zb#)-7EOlN1Zo33a_>W928vNJ~ejtlM<>RbXcH&B1I?IC>rTC~cwXi%cwNQ&oa``=* zgY&kKC~O0}Hl>te{C+z3P?Rq!s_=+QnH{funt2Gn?!v<{a}U;C2;v`zQwGGUL1Ixb zXBZKMSzR+N3mBr`vI?;5VPimWDb;SoNS?w+;hN_rkb!iMd^BixvFDwrN=hL|d6-S4 z3xIS1kZuK}Tcs+6ncrLx>=7LdzJrB2AYGt*S9rLIfnKb-lyTdfMYzqT1UKxY1L}KI2zKpcDaf&$kV1* zy5`!y4Jt2~y@@b0P3Rv`o%Z*>&JNyikUDr@DpUz~+<{cJUn_JC<$P1`kAw2SRhjBm zs#Ez^>FHMPjZ+542In85>U+j0w`+=|){$H*YViGxhEeg=b>M*N#S?|jsG)(m-|!=9 zX7LGrv==f=UpX6VPwoIW)=tt`%{N4X(HI6v3xg7FE48o^4+KHnQflF0JlHE~=U%g& zygp7=`Oyv(%U*QM>p&RNycg0uv7iYqJV1aTF6hmJeIhpvD{Zk@z{3*d0M)B;oh zBqx-iGfdb864=ouEEI_YcCiUNNCKN=!n!4}YfadA39R-d(+ZqnTO92co3Ld)o%F6{ z*oHcDk_75W(W08%1*%Q$*9l5fy}zTHen5RPNzFK*&Pl}0!|Frr6i*g=YYB?i$6v-P zOJ~&q+mvkO?HN>9&jbBkO8o+dX~k4}HZn^Ym86dJDWekA74*3>s-3!mK37I1s4Mu} zQSmB&tc-FS;mB`^P>v`ax!XzTdk2_FYVuS@WD=u1o>3mlD34~8M=0|q5f0>I4pV~T zsZ1meQI?LSG9f;i3OeE=P$tBO(X$l$}0Xt*YV^)vE9O(jm!Cu6Cf>B-9{%#U7NsJ{PEH<{^JW}9yu|> zeo$&c)Tsmq(Id82!b9GnEbUK^i0r;p(8=zFGLfB3&sI=HOg4ct*#yL76A+Wl5JWbC z*vQT_$-b?Jv)3;A0`;RWe0(|`9idRNQtG?KrBr~#Z7iY!gl<~_6(Dyn!3D-tr#l*A zSUO*=1iR6nR6`#9xwI?&Nn~}Qf=*T^l!>g4^lSxHz+@39lSM#G76CC?3_)ZOh>fgW zCRvXrJIT7`bJTCSED{xZ;w~pt6hom4eaArp8@5pObS1gItV;hQ0WbWF8YS>X_$E?c z=q_rH-IEMSd-sL37m0f^#cbyiNjsHgpld!me+!wDlwF>diDTLMTYIOIlN$*H=ZT`! zg{*%LA`@qD{&H&OZcO;JHzhF7>M*cGcA$+W(9;qiuK^Sr0<^~j>Lme601)}M7o;cP zhZkaKxfumcE84t9e?8}Jn+&ac0?3RjmPp}LNe$1S2D;`p zD%?0$6HzREQzT$LbugzPZ$@Xe817aHTuT9G`stw(e}xHqs=JfeUHchTzzWYe6t=qw zyG;W7JYaRFcOyod<;j|Eti$OICP4>iE#5XgS-8jz`n|zK0=PEM1hBDGeV1O6_xmnY z>vVuyNRa;OUuWR}-+<~&!I3z?e?cV;y?+|-Y2sQgR@@n9o@`>)T0^tec4#2IwaUM9 zi)d!b7mI1Re~hN}c+6Kbt7q9lzQ{8oZb_*yBDNKX*cN{zBDUM{E2gGfQ4&+r%_xb8 z?M9SD#CAPOB4Ya*rA`qMTP|X{`Z{e^q=@ZTqo^R3;@3l&@N{+khbYi=^$Ls#W4ih} zur;Qu*KDTgss_61DvJ>5#;jfSx7k9|&7VgC)*N>nvHhcfgw$AD4}0w+rs`0L(@vQ- zHVSdtM8sI0Atsoa z-$#P{Oq?=2Hkf-4p-iDe?dYveYK!*>K}a6WjgR2QhjHUWxbZ>Ucz=biC`98sjmAr< z@gg;SH#feM8!zR?i)@Y0HyclvG~Q2d+_wq?g4$QeHzgDnlPgMCY$R`!5ZOi>^az)i z7NDRY6EdNLTRmBLQ}PL&JT<+5(b>Z2jE<>J zB;s3jvy+G)cj-isb`2kDxBkf(YTrpfHyfbs7!>p;P=V-=rvlOMrb0%Ax{}%MS*4UK z-sP%ymC_gKikB;W-TIM$MFXg*zA;LIHdE5nKx*na){~1^Pnw&Z3}kahqmevWi` zl=>WN??O6{zKDz81pmy6{J!|$pIMRL=T>^e2A^X^-XjJDQsmJkJrc09kkl)?LEm&` z{&9IEY%LTyIuknFT#lTjUwqjsbUiZYyQC%7U)%^r()vpeY)6%?zpyNV?AiAy343-JC1KCLLrK`PgD44mw!ejG&$vkTYzz%|*t1p-QbE|WgHStc z&kh!$K=$l?u+gw*pWno6;PC4M8!UVF4R57~0N(vJ*|Y100yfm1{YgL))6A{(X&;dQ z>QG>~uxIhYp1IQ|OqmS!Kb}765m>h=lM~0mx*-+xgp%kUW1dJ4w{9Kml}S-Jbfa?& z{IFAu0U`f{y>8vUBIdAl`%VJ3SqIatn+@(K6Yfn3+_MH8B1$lAHn{k)Mte_6;O-G{ zO?QyYg+czogzPSXbPLD;LQ%RswKdw;1dWz}{_8_q_XM+FcXsO18=M?n$xt?q5v>(*3KbK)RoeGwFWjt_Nq#$pCu`Sod$S z>Ha&ZDc1dSBux#brk?r^xcRHGLbO5h$PIGr>$BB33AwFKl3 z04aWs3>}O;n>JzWxk$#I6fzlmwsN|$XDdg>o~;}i`-6ZtjQ#OW%n3I3Q`gFjy>ZKR z7CJB7-d}wI?0q*Z`jEZ9qE>G2ZRaofKo9N+5Ie~=WBRIL`g-9uVeT)$uQ2y@TMcu6 z3MFCgPogBu{V|k;xj#fXGsN_ji!k@MKMY2Yxo>|T6@1+(cu;^2RfxxalNU_;IQOaV#UG0pwF_eq#^D97~mk+k&b zFz{m&r>B)f-#z7#Y2gOGw;f#CXfsKpZiYHe(^pN+A$)ZMKatqM2EM5T?6V@m72Ctb zZtGCcMJDJ6*Ez?`{}`Z6+2V$RZZJU?NkGRKpv@$ppPHaUB%mD`)a;UXoL!<_>%{fw zdrT&;aD^gz%53dB3EXA@hrKf4Y;8}m5oYU~61Zm>t|2V%mO%9vt?>eWczb*lg4?@O z0@+4~TuxESFaa22Vj3fXEZc4q)?l`TpUXNr`S~(KVc+I*Ua=2lX{OoW^Aga<4A4~) z(7&0W!z7@c1Zcpw8lV!%`Ot*EOalFVp^yRJ8cD-POwg}8ILY0>pbd5BbO}_3XfWVg zD@XTYs30Li6D81h8R+Ip(7n|J?IHnS){_I(C$b_3&+r+hyf_*4k=f$TE14VRRyojdtt>N7PjVP@x z5TKnk{`{ZtSola>1XorO2>D1geW)OOq#~#i_K}J6Pt_#0p(sA@{JI2e6^;;Rpdq{cgI4sqc`mp3BLhV_A1OWa_$;*bRF9RZeEfW-}LUbn$rN&>`i z>m+cQdUHPFVmN456EsZ%+SdS$m4FU0L2r|QUL-(~pU3A0Fy(wR`K%m7CMT?0=cZ8= z99KEf-pQvA{%Px*VD@rnj|L=AOBkwF^~FnYUSi@rPXhX&0h%BI%`-vok$_$fGn9$uM&~ax(cPC^ee7?DVBl9QVyIJ05p4n!R1bUePjpZ6yx9&5c z=S!f63ux8XO~R_!_KigOe*Ie~v6XN005A5Djew4z?3ZgF|ci>8sY?0W^8nY*1d`h%Fhw0 zeUAlQwAvGcUt!;)P!jh2^jgEd*PtdAq2C#-vQWA`#wuRQfHg?ef|a(F#%QF zqYc}5I&T&y&YQ)G^JX!8-Yoil$}$y}da0Ma25Gx7l6G5#LTzzk`*DJEK$NZL(T{CE z&3L0EYzW`|Aof1YAZD^sE|tJ87qA>v358p3!evX~#xk7AR|%#`5~$8bYly{!wpL)a zcBKUF#9K_En(PjTt1#gXU+Uz{Rs#;pxS{RE(&%EYte3#e7jOYz0-RvOF57t8$%Iam zK=(DEeXNvyIbWwnPg5=MpE6)-Y6U zQ(PG5XfM%h??nmZzSv3U z=l{@I)SaesVZ*%IZ16(~=t>4{sKHSZs0l`cy(A5~Qw(_>E&=UqfcBMub~QoUOF)mU z)yeEH0Uc(7R3`ynUg9OC1X-Gi>lyB)n6r5q;nMwaq4CX)LjP7LnJt_ zGI8!A0gW+0he<$-Owb=&JIUSgMu<|7n0!S7^}K*8_K{}-ud?xONwIKC*po~VEpd5I zc70xDc>Z7WJoLOn(NRr%wG!)dPn?ji&+&OkT0+*yhZ%-T&(sum;Bk@NtH%HM5hX?Q zdkDwlVm=g61aXV`V3foy<^xe0JZ(&(>hFoxb*9PPlq(mFnCrg0WU5f58a z?0X1}!;2)mkc|rIs0c4)qe?_#DwKMSo1PX4UfKfOpfRH!vEqOVU8H#z!xJ&*~HzDEC@GjS+(z8{JA zRB`GZdC@Muz)f#P4{feN(pPGLrashxNQHSfn&B!NFJ5$>!w|1y7g^mnC5WBnd~g%I zFX0Zvm$>nu{X>a8u>Jc6jI7#GhxDx5sOx2h!lO$f&*i*leV!_a)6e80D+0 zySfgUT7xl7lpaZvFYpp)_OHf=cZGk0T|=n0BY;qFZB01>$s0t%sPw?qOrotUe-YtM zi-`q^QBh$n&ZTGdej3)a{;?M5o8a$z3s{t@_HCD{^z9~!@hEl$>p#X|DDmI`0se(o zN1_)~ujsY#8lu-Z&M8_=UTawN4!%nDA7L+}NaV?#TZnq1G7IA-7Q{psDqcEJkHfLG zQLd~6oawLp1-1l_KIWrD1!~M(#gmV}H}cy zClqQ4xGNt2(LRaFnZMTg3;o_aT$^0@jk~ZC?{?rn99hvm(%)@BUItW)gKApl_T-5> z21S1m@aFmN@yecW@ZU2)e;!E53#4y|I;y5?nZ*qEvHyYo0QLRUe0Ga~C(rL$SM14a z9`J1F&JQ;DJ#Q9!HsHY_4EdHk)?M>{M7KK$3-lNOZb>k>$IA)Nz>9PsjWcv>)Rm-k z6whkf4Yf-3uIAlP*bi&&gzZ3`$Gf4PXyNQU&uZ$NH_=?cy8)F4Qr01pbzo$kYwIy} zWPahd7Zz4ss(6;G&v856WzZKXOVpI*%6$oH$}((%QB#&E*a7oI+}v;L(5cFUvB5u2 zr#A14QKGe9nxj-6nv`PCE3At?)=xu!toJnN-7Ahl2QO|)C+|0Ok8&+^!S^rryd70p zi^_FY1-x$qRix5@fZ#NIfg1mU-VYFqVr9s}j-gzpQ-mR)dT-Z}B#MA)b`q;^$w8X?Y|W*Bg?73)w@vw*kqB36+eO z8)ke=Lz2;}e#w}ZMjR+tmQE$MEv3K0MI=bCSW5Z~0Bd-F?uOk8my*@1OevvNng+yJ zM^=}TFQiiP{@F`Oj6_Pr5o94Kd<2t zfZWiB4!I#HmYbQx5|*2Hn>tyNv+|teCXeLi0OW>vr|X=J&H=Pi7X_H1$7at_%He+n za}E(Abh7~aMDCL0*zx#G>j11Gbd566nQ)CbMQs@Zy>RHbJOme}Rkd}Xx8OgB{py|1 z4n=n%$hy-w4Axyu?jG(lUPC*!*k?=^O#pc-c-rrO8aCY5^7}H8*@%z-l+P`q`HOxk z!AG^(@)w8XvvmhjjI_lm$B?ZU6Mml6l)2_D1sD#w7W?MDKoVWzn}c7PL(IhQ9SBO7 z_?|*(IxYYx@l8i*P+G5Xs{gUiL5zq$a}l$gF*uOUvz$?6X7teebkemn%bC6e1)Am1 zUIfDpopgcahHB5!ET;leS68_msPIitpJY+|Ig@HO4Nn}7OQ1`aQwQMozuD?PmRyCl#l(7&XfObU{y`Ch|W?8o8cPL*lAv(fxOkvz9}7BiW?= zYKCm?jj%I`3bv)bTNCf7W8j&$d-z%P#Q zRF=krCT-#O$Ogvr2ZQa1NPev6IY&Yu>-%|b`hN0!KI+U3FjcrJkc@G>akyRO?{LgL zR%>%gAfua-!;Bau^Qk~GA0vs@s$Xf4a$jNHP%PTbEh6!In9@UXKD~PKV~v^#CDL$y zta~9nLM;2BB*d~ON_DY97JwFm_g z%UYXQ-u5f^hzIP|-p(MgEN8JiZ~3uS&LIK(a|g6-s$5Qyp#0*Lh3EfF`s9rHv8c|F z{8%MaJ?Dg&AgT2ZuCHK;dZT_t>H#h*~0PXFS@$ zct6MdSO?S0WB+H$6X5l0G1k|7;GR)*=EoXBh_Yg+I^|@@wxv9z&N4q1H6bxH&!7@V zek}S{Dq5W-Xmmpjw8|f4qlDGk6DIc8OTeOaFgm!0Ob&tr45ylKKOz(suGMxd5zXnT zploojnsDz*;BpK&Of*B=+h)SelfXU5a7d{nnDPaE96H{9BZ0b#p^W@kHY8h+!Qd`U zkbqS`&oYiptl>x|nQ-MlIhm4Yz=`}=w)SW*zG!ca1a6jqL%`6?k7a`$X2MRAz$Tlp zW_~Oi>@*X$iv%{tgf;VH*!g!OujJ^0G?nvRMV=o^AkK5m^O7IyQkf~-zDSsj_I?(`RBJL|>; zBx~!+1te?h!UZI2V+cuptaTC*{ZDmh8Dg+f#e&3yqYtcSA^fk+>%V&31k~=48u`AlNdW zkP9wkV`Lu8Wan>z1mpz*5&5y0D3Kp)7B$1Ca2HBo9@SxBi5A*`UNC_klmK0C03kn? z4d^WsC`kfTyMUqr_2$QV`Um~Bo*#=T&t7y5kT=cn5OT5?A9XToIqEjN8#6zas6k@L z2T5uejvB1|SWJ|VzMVuA8}fk?u&Z=1ry>8&gu7G%SEX`uFvud0ZK$Ub-N|V4iyxfC zt}|iH{8%=8+nKN{C9u;0t2@0|-lBl1p6T^W`LPa9IBUOG_1Zv)arjLg5oNcl{)5 zvZ~n8Zp?m@$Kmuv?2SF{9)b`>Z|{VgkWQ*!|52*{ z=u~phzx#uI5L|VY0VLT8%pyAq$B863V*j+P1&Nx?NL+m)%8T5nz6;4iq6FSM7I#KP`@{6 zUw!YSaJ`=>+`@6TEhr$|dt2$OmHObfr8mo0bC~^l_j&TtTdJPC%p!4+T>Jb#l3wF1 zF#hgS_%uwy_0&_>NP+>B0xx+$#r2TM_<|vhbi0vHHQ#`fKX)W)6OWe zlKT_*5{}57=Mj;k^NA<}5gg)+NuuZ(WSXLA*yaokf9H5y4Ht%?W@1>1xKTKU%R_68 zmDO4{&ROeEX06jCwe}9JHBMIR;>Vn|wxIFK+-xVQwPs!j2i&q+J4tZ;tyybvm6HQ6 za;@h_SO$b*h+W5_($dMqq`L$YcPKP=(S}0bVM70kSZjDs?#&9}PP=gE0VZ^T1bRs* zbYeL4C=>cw3G@RDeSUb@!j4I1K}Qplu%oL}2_s$usi}ls58Dh-lo`T}E@mzIxLsz_ zvt9x{KNPxaICOytohE_q8w%Ym99lD>Z;?Q^05lwpgJShXAMe=2aFDi>^zwH%ipUAP zo)wXKKb@QOKTmkS!dAd=`B?uf`vM2``0_z`FsKsoWn{%+-PW%g>_O0`V&Zvk9^$#! zK~+Ker4qq+tY#TH$XkK#nYd$obg7yQfidbysmLtsIC1az=skMczr|dAdPU~;juTIe zk3OpB0o=%sGb%ERJ5H<{AN{MI7;qau9$ArD(sAM!MAnd>o~Ds zeDr%z@d`5Xvz<^iED7xXfn4l3~Nmc|AtW> zt~O>GwMt!scSqJ&Yn&c^yHvYRQtQ=5ty0(EsZsUSnrPN~3VV6Oaov@nb3p1Ew5}J| zu4b*TN@{(YYc=ILB5A$ez!0v1tS|bSnEY0P$&pz)eQ*tA&?8LfFJV5yx$~9*4c9;h zJ=KI>DS@7DKtt2ZptDTqME!Mc*Zqkz@fgWc-!!?jWe{Vt$mOytfpy3+GpfA&dg_mlVNT4gR zH3AO8esU0C#P_oiug1kR`nFZ1o7Q+r+nm4y{J!j5cb>Z zX4l|(RxZLRz}61hR?SWUSqciCVJ8mkJ`8iA+5lafdf>N}UO_k4-{5$vVN!fGdF4yA^M#suFEV zN)a3U0?H1YvBl_qZ@%i?soV>%u~fM?N%a;f_X3v!=iV53UA3Pc**7!Z2F3& zfW3m79wx7Vcm0rGMK{ouXBJK3Jz1fro&#RDs&B%oRZ@=oy~p^<_zP$YH1;H5yX$kW z6O!;P3LyjPfhi z@23KN{W|&I0Dvnxm}fG9i^PO0btb$9V{0(sdnhDk!uOMPCd9TtWBQh#^

{=nNB4 ziF3KqcK?bGBWyQLw97m4{wUhz^2QNp_pdyTob+BBdAn}WE^oEijy{HI;PRblx2lt@ zSMtPHA-yv7$-27CqORC!lA7HeZyv}0!RDxuV3=(`6z@M-j_1OK40yY$DP7d`PHG0W z1Sct;1*#{}?^RWAJDf=KB;X%!JpM^>D=AqJEG6BirpGGjbdTFHSL+lF|9C6#4-)Wu zA(&;#$bCu%@^<@JIb`98PQau3Jtdf!@PuU{npQmvumSKx^fw(!FTtjF(ubB5pTs>$YPo#rXN=$>n-+ zIY)(;tDfad&Fqh9WYWO%tff*pl~z*;a1rIVQpmP`s zt#RJYbATvagFnD6F1WoFuFi$7`HPu>{Af6XgB``J5lOqd zx#!*5AfOW=bsYtDY%HP$bzIJPfT+u(p2dMH`XQ95(`=pNS)xlq%{In-Guj-kw_iI2oz0c*o&8-?9_TG{K&ob4s3>JOIB{F)oZ^6|1V=xzE(T&oZ5hS@VLnkBDguPR4ie(#QokFu zy5qsf;Wz+_LERpkc($x zw;b0G5C_u10RyK=4xDIQ6GDUm5V9~()0ZoU&~%>!WRg+R%K+hlA$RGq@VCkOPnfUl z6MTKYrF)i0{eZ7^%m_n)8R01W0K!rD0Rl(z0~(LxLpB_@?X_^c-G*Zg8{05HfKU^D z0HG%Q076ap0RlDh0~(Lo2peiiHq=(#XR$9u<_FY|8utL}(~!E!BF1g${Y;~QLC0%CCn+`$ZC|ABpk%y`Pi zjIVcD%y?*^#SFJ;|3L#E8D2{lE3d(sD>58x`C9{#HQ00y-MjEvMjzpRy7=avI9!@X zMEEm_2s&-SJ=#K>ismB3ezw4#ZTb}gdoHgSK-k;uyXsjBp@18?79jQ z=UsbSX@Vbhgc!53s$`D_u6P;OX;d!N;A01;_n~VGc;HYav=~35ka@t~Y0LX#|7uGWCZ=E-@{s$x+sn@J; zB5`1|{@6z>cjyeutl$2a#HOCRS=TYB$E;Tn3T)OZb~;hWPnDn`G3#W*t($?&{H|g1 zdDkXy0#0SdyEdh}10%bt8C@WVs;5(`;$5tIJEkfr*=kBss*=7?O;7ZX45}mBDH(n> zBaSb}W#gVvjo9KsWX+&MF4_1+HUZCK{C=m5ELU)v3>U0mVb6oPJ?y(5^ZbA(==XdG zVdaUSnBgzM44+cJ(+vM4eue!!hLW)CM^F-${o9wp9uY0$A}sr@$T`E7eFNt0hGjnj zHN*q^$Oyb8%f7x9*r{7~!+75B4Ho91vj8bpmO`}siaZ5wLqc352dy$!Wb*|P5pnc?r$joFf5_U~Im zO31PkK9*&F1huIc5)tq%--cWp8*&T#T73H>TlUqYY-om$xzOtH89rtQn4a;hXEjgX zV8d7IGklD=!x(Yv@%tTq-^4HS6ck_y0cY@bTw995n@F1g!m z@M}U0{2GfVQye^D1Me-3m?yhzJoyzdcq8iZOdpFU*TBGo5FlOvqn%k94I>Xi)~807 zg2r6D%2mDPAXCf}TSwCqe4wS0xetJq^gyry+#u@jj#KV|*{mK{d8QbyIscKALrdK!s z`P}LGRntS>=7L!A0rL25UR8?qHmrqJ!WE!^iQ-uW(+UTJCi9rrL$sF3CiCKXn8@jq z`C;q|P$-lp^9N|j1;3$_d!44L&Y=XWDewwDh%Oaw8p(RNT(9BT`D)DO-w${`v}W^S zfM7N+27@`9rvZVjySCZ9sMVa!V*n3Co(Z%ppUriaB>+*{a@HwOi+*C?{N z)~JIxTC;h96K3;aIO!M|vv~^xHGQ>gHXlPqjLrUkikv7EJ}g0j%>EiNk5?#Qv)7UK6WA%2gPErFDTKzh6~GCMHRt)wr&P7yZt`eqUT$SQyOVSh@c;;rB% zrEEU-4U3MIv;{Pc_bh>p4|rbkdv=9d_vNsmEr$y0ej$E^4ZQ#*VcqKrR-t zbj%1tff?Z_tUKW-th>OGtb5~eY-z*sLK}{m2)7zIig`N?B*VHd7t9mZolq0jolq0j zU7$wRz455U*-)Fb-D02C!$M8W+wG1=gQ$^pKOd-FWJ7IFp@o{)hMJhS?+&rv#(a6uzkvuMW6r(XLR-5nVoEv-O4xvpM0KEq%b(pzlxzVu zFy?I21D;Kc74-z0^3^3C?&?ZfVPJE-HV_jF8oTjCehYW+ma56NR~x&r5jRZyVDnXI z&1-}SU&AJR4Tm;XlL?14hy1LPnQ-wuOs;ejKAKH9&2`9xm(!jKGUXvAU8kk0lbuX8 zWv$JClQ@TqE-f%{=wePuz_ZIT;9?BGfD3sy4LHd>cA3}=xTw`M;25K$JY>Mv$_@A- z5&<^g>)z$w;vO;#c;-;Dp4PyE-~i21U2)T!dZUgndVB z*Du&<+4Z}iLU}0PMQOpvu8+A0{i)B|KY54ymS^n)Z|9N7c0E@bj~}RGMi>gr2uESp z2}fbq1&(Cb8;|2y8;*al;rIq(sK(xbIL0w79#5zVyH2PHyH2PHyDm^8yWV)z#@SF? z0;^-FWVa2qCwSH#wk}^kYGl{X2WqJ{)PDM>gI^&o!!1NvBVzT_ZIkh^SiODa{r{g>eM4RL zUys$V#HAVa#_Bte0b!f}&fDB`AvS*zwi}#>C3qc!dSdlM2nDwJ-6SZ)$xvuGR_`Mk z>fe9&e=1&oZy(+A<5#!*DCw3TCEfC?V3C;7-$X@N{#`$l!N-jL0z^8D8U0;QvSM(< z&tuE~P8@nwxBQ=Nu(VFfO*A$|yncf;UO!OBj4;$KKT5jgM@hH*C=E(u%im}mx7cvJ z*@oj=2(B79x@7TsLQS{)DCw3TCEfBfYHax%joQ05)LvX~v9GNSwKQ40zJAo$@}CFP zw%Smud&@#?<_#9tK4Z&YZ@hlyPY@Tj{J_Vu{BNN)j^nbdHA?IXZOA=pL+-0C7INL$ z@~@`Bdfwvon?$^RQ+@IJ%YS>Oc>Oj9PuKxiksC2j%4|Ftfa(kf;DbL{JfXWu5a>Nq zynd58yQlEH5wD+b#_O34npmx{;`PUfG&cRz-7T~o>msJfH9j-3wcWcd;1o>2duYP=m0ycCeCxj9urU)#L($| z!x4KEpZ}eR{mPpgh}d@^8^Xqa>p!^fXe^rh?-uuwgv*VEdNFLzCStE+P*22u2%*5n z|8@xqE*T09MeMEpcmF5i^$*=8tou;>3L82YC1KqMq9m+)&rA$Qp=P-V>wfYm*h1F* zVuZ;I>pl>Ql*jKtx(1Er^{s6x<54~y3mYQnk`YQnk`YQnk;)X2Iw9<_^YsBL-O zVqZ5KYTvVU4~y5=j~ZF`^MP8t4Yez5sI9ox;@V*0c+?lKSAT%GkaZ_~EbIQs-$@=2 ziEBLHF0~<-h3X7T7G*EOUg_gjcr!I^IrF=Y0j+@sS}tu| zA2sTwZ()F*tk~ftW?h2*SfK*Abovw7DX{>j>mt80!dAY_G76K)!|H zc?>aMVYS6x^?6=M7BP+-5}TevEak2IS`l@3EZ0e2^*U=LtA_5fzYVh;t5WT(A!?eX*L3eSjI+Y6kWJE>f{U0M~(d;uLQdd{%7x^B$%1q9e`C ze{k-XV4Du|U3*@@??ENwfP%xlDPcPS7hxwLJ~_%4`vhq>8~uf?EBbQfG8}U_40ez$ zIC2Zw0`22hXgDmxmaJz?--CFR>{>)=P}-ohNN{X!!||t87LMtO79Y2=pCp!M&V=KG{{W8Yg4fe!nHsjylX==%aqFS z!OM=-<0~UpFo`y{U5@Gu1@q$N7TdmsV+Be;jdyKo=-x(5)A2MnRf)w16eFpS>}doG zY}+7~VNWBGLv9r-$`;zI{}VAC9RwZhRy}~~47Y0U?}!dZjD)wGz6rc|Bg86QC@Nt{ zNll^0>)F#dJLGNnp2pGETVqe7-ok3JA!0Reh@kzj*ablwB9?<~q{QhA1xX=`SuIJS zatzrhx~rKbrr0Un7urRRGby?jc-f_~ZD-`|jkdFjIJ;=b{2gX%pf3eGJNM%5HE@CM zUURKGi5yw!%Ys{NBcVizUu3okV3JDS0D*0Vb4bbs?#pnckTra^V}Vg|>o0>jwvmH3 zI~BLSQ4;fUV=z`CsAU^%7AN%asKzXWXrZkgYWkYY;^^RJZf*zj=~VQGY8-C9OUL^Y zxczIw2_D2J)vhbm%>%E72ZbBK#JRn4g>UmxgM5mwZ@hlF7p|9^8mA144F*0X!Nl!V z-Ly6cZG<~C-`z|OjXvmgZipS0i{NcR%viHjlJ+xMBb1Ac2gM=8*eQwLrN(Vi*E7nv z3y-i)L$$bhi%&YKLH?_6yfVzKpMB~Zr_2D>G2}}C>n_>|#Q4Io?ovP251@LTj?m4S zYIqzqO!Xq~X03kB47P9US0HJ{zG?7R=?bK&_@yh5CgE3HfixZ^ zaRt&?lm?~spP>4OJz;u9T!dFt^bIH>uc#eHtl<@ng<4{5G4}VmSG1f&NB4>*yvQVb zfSLC1-_T&M0abOC`|zOHb0n(jVdJ{STDp2slA~(QC6xCGw^bJX7WIn+o8J&3oD#CR zsGle|o$D`eqTI(v=r*?_`0d_o_DfhIFZK~_NR!fd!d45yc;=P;7bc9$ae^>H0y8BA z=}A1t^_&=di!b^ov$~_Ldrqs~)4}Xl-^b}{?p&9HU^cWrl7BX zISSrtN{fO$NLmLx*TzGF)hMt^yN*6H-x_sj?HRgS;GuYGRZneZQAZ@`u&oEu{aK?8 zjP%qkYW`qc+N<8BWE@vG(+1ME1iht5+d3g_9J05%CyyCA4W8+waf6>O=@C0_M(+uf zV7K4ov3i1C{o1W9#)i`^*xv!65VyzNj*{@zZbeCWkvE|vyvPnyOljjHr0vkxBxI1b zDv~fg-^NWVP$t`S)3v&^9dBbv+o?ZW()QG)ByHs^ZFNnUpV*le%=!GUs39f^7x~0! zJ@CC4TI~8lsetWUu>X&m#?77B@(bCkv3C69oeNzeFaYvcL3j>zQ082J<4O40MnX3m z33+WT61p=98oFCeDbVGCdK@Ad1zO^?w_YGxX!mwzZL}-PLCaIWIBB^(jFxv$M})Lo zaIw`LlTe-Ev1k~^Mt2}@51Qcw5gV3TSmUt01M9-mPOL|TVcj%xtee}g-UyTotZ%eo zy&0U=u|ByZ1Z#{pVw)v5EhSjb3B!6Inu(CtE*sWSHmqmGo4l^N(3#75i<-j&9l4y3 z--hXSetHXv^%RY!Tg)^UXmhpqfh5QNfspxr66X7fnD1lWpOK)B?5KErss~s829d=N zgT|ezEG0XR=_3R6J-Y!mV3;UKF?|Bk8G*9X=b}X)Jo-}UAxRPX{tdfPY zilS`b!RO{|cn2p~a^V;U7d?9b9SWrYRjhS_k54%y=8D9oxvGx}HU;4e`ak>v-$OxM z`7_a)Ybgl4dyeWN6;*c)D~MF856tl&`;)2TxCkBh4t+~HZWCMsL&w!Y!HWu#bRE~h zrXVgwb%uC8--bGRCs=_KhfokfkH5s@CzU{E!Mgx`T`kYHxdGwZX35T8cDP9~Z&Q%qnUN_7gQM0LZ`a|h-UyOI2ES$=;DIFVs zn*2oksSe@K-Z1|3Mja9Ir<;vGCvzBKz_DZ}h?`7!E<5cgg- z+~=S=LoQFbOx&y5G2&#Wcxr-iMP*1WXhQot`8Y4mJo(fdRtC^YHPA})=+4^o)++zb zEizqRZ3=>WPW=RTW{Ba=#H!g@aZoF5aO0xlJs$M#gA4PBaA79(oHmYK7-$8F3lsEL zya}yaIN5AK2j6ct>q_uwVA9_)bXj2?U?&Ky^jOIhD%mw2) zm+i$nQpZc$(O}lbb34%I{?Vp3;3Bla*iY~+X@mYbR1o*0E`jrYxO6)mha*3}EzrEwm5??EndOSJ> zSvQ-EGI_*B@aP2bns`(U!)WlR6?7u=s1@ZnA)9AUj_~7i7LT5|5YZz~Z6G-YN8qrs zSczM4fo^TUmx9e1I8YV@>k0p${~nS8x)vP?0ZDIS2h7L?YHgBxTDih+zv22EzpdgVWnvNPCZG>UTrn3`Z0a(0R(M z;yIfyNNoqQPgW|puYuAGgHDckc*`lFGu^wS42V&hmGq7S8=|!QdFU&THm|^?V6r6o zZ!ZZ2M&&|arFug-(>9DVdjTI|mws&HOeU%`I8zrxU8+IWs&H-trMM(_WhfxxPb~s96 z&_2L#Y0%z}k{GnTA2J6m7cppG{1{z9gSG|v61rl$AF7K-*Zqhx@}QmMvPMO6mc_y? z7np=qeic4mQ48T5^iv{HeY_Gf)_C2P$zQ1c#$)!l4YSu!ozb~h+A!;7V0Hxx-J{Z4 zX=%vNfnlr6&4q3u8HN<;Efg)3_eN3s=@Q5U7py z=={jj`QhUNDK_E|WsL)~@{N~VpqE@fW?u;QyOjZyCzCsTEAeOm)HCy_m39$`!iz}y zd7j`A52vkjnMYjyV>Auo@?sWq4Bo~|Qoz>22wMwfQHGkps-&1?Wft|qWJ=GTY2JQE zTWi#mMBCg6Fok<#`-Kc48pZ##moM`kB2T z#P@itC)uQNh|iM7-F3f!(}XLVzulD+SR87?4Rle^znh$UVW0^kYruazhXkPrK31dA zyT*pz+o;YM@Hgn_Sq6G{WyuB9956Ho{!HZEpmhR$;Mb6wt`Gc;CurdBM4*EQK5Rc= ztM!3j6wI#t07TKiXOdcL-6E%@i;b4b*%mG1ekE2@z@;+AAVG|K*F5NOqDl8Iu#jV3 z;)Jme!o=9;d}dkenFijeob?))WpG$xMyPSy4jhnQg#NCl_BfiRM&srRu%W6OPEsECPKY{ zoTg?Fh7pNS55e}KRNXXG2NB}(_orFHRi99sHMoz6E(3z{MEpoeONzzPUYvFUc|IDF zlUanhO-|gABiz>}Cxx>tIk|%oW;sE)lRC~2bzQG7KpGB~3Zd80`$Dgy*9^T5kr8?w zFNI#mOQF}RL-aa2C5lKRz0O0Rm3A|5iLfsQ3es4Ye>am!{e`lp|X?(%?-FlI$tQF$xA4SHaM%T;AiGq60RTwR>i z9EJ26HKQQ7axooB#j+M|{%Ds3L5+dH#$t&i4g%{&$S59~8XdI-etF2X;wC6kh>ARb+<;9xs` zZL84*LI0D49E$+4wT1T6jEIqIC6MFs@;a&ma$LR!$mw_fVc#4(e3~(AlUAc(S^Co>uqvu6fS7Y=XgqmU29Yh$MN6#ymTpHbyi|UMS z>2#7P7aLcEVAmG=hCuouW++i40eyo~SI|L76#ED%_>GOnFfM2Z z4TbDAF>dM8Z%qz(I|WiYVz)JRS_d9)7eMTNWITp*z~lCN-|;`b8EVa+@=t$yJ_mM4 zx%oX+2)GA4`F_v00ncW?vD-S}`KRCWX~6T2-?JaoaZkO#2y7|#O==EGOMK(;GXO`G zN_=Bc!VXgCw$Ug}A2$iQa0E(&(!5Wr{y|=|cese&>9t+&op?AaM(>P(*5=+BaiQKj zeOg$()8*q{Pa5edl20acT!?!(@jHZ#3@wgykC>qx`PG>T>e4|c=!Bl}H&<=P%_4^Zn8JG9_ z{WKS#vY1Inr@Qb+iEj{8Lq}9vb&>gJcF{9U@Q2FpAdFfIw8!2Q-*IaA;5^7gtOGq) zKqL#lRrDQVlUEV4pG=Fm3;ninwHehJTJM&l*0@^PlBp9&lPvP>u+%FwLOyuH_LfMx zm9U~|Lx0fE#8M%YqzVa19f+i;$Vtk!k#q>i86=JQ!6IoVzA^iONg^B#l1@(Lw*emw zWXz)H&B37O M6qA(JzKLH(3Xp~bzIqX|C`jBg7@$H)s`j7^I(icnPkOQtTIT00F zHDdZzl8lC^Df*x7!!BWe^H;X_vHJU(u1Y~jFac_crSWmQy9Or-9aNY(~44iMb;k^1n#yLzZ z?g>L?E}$c1;1+=lo01y^GF*Q1KflyfZWqIkvEXf-{j<=6Fy*ud)@wsC^vpd`x2dGAj@puVX%`kJrn?czri2jF8tm zY`i`;(c<-#DvQ@;cAZD#uQNU*IT7P;m!4xXDAk1F<8L8gBgFY58_svxaDL~og>#a? znXr8k8!EY{*i%Su$1>0E9%)L`qZHniD{G-3!{$mkJi?-|e%Sn{h-vyv(8TW3L{tZv z=klRS7BkDDM#Ba&HDn=~lvyCP*i#Z!`5u%y?&(0Fg5)u4?j*cGH>D+nKV+^sgEh(8-_BFKOjt=f)5L7L-=LiNH6RBL2<;b&XF_d#`r zUU*Nl`n{9Eo_f&g7KT>c_=wRuCD3B6kc;Yo7MD8#E$%4`6|%$&0>o4Dm||)A98(8I zYJC9*Hq+q?q--teeu3-%vG*?EQ5M(#_~e2jMFFc8mFgm(cma|CF(N2Q*gz}^X%a3~ zY*;oM64_+qZW6$+ZG(UYVl*f!UTRUPQl%{_Dz;vNUj(bPrHU<9)TmS!r4}vLOHKCw z`J8!gdr5-C{-59T`!&zAZ|0r%%$ak}oH=vmegn>lVsdl?D*;a`8NR{{TN<(acVTk~0G=>^Bx5f~J0h`Go-~$7VCN!0OwD;J^&L1}Pm){a=Wocf~j2Tab-0o8JU< zX7Q!IZx!E%wIF-@CaeNjU&j z0u4>eN-61mElsQ7+Z){?5<`r7$;MMY7V^I4rX#0}JCDsmz7OckLO$I=+0qndgS85& zV!{q#uA^m*5NF4+erO*91Yb(2(8ti^hA-(ooyR!n{CBxc=c0YK1YZ+d0tu#2g4i8m zNpJ$jEMg^i0XPU>1ysG1;IR(MJPyj$?OvJRYbHl%CQC`-a-cKY3I!%1zwKfjVDpZ=0-oc@ z;S5I(cfZXXP{E}9G2&~_pYs~(?$^F(yVq{oy>_%ihfKRyfsnR)^AXZ^?}rF!yLYL4 zrQMr_khXi5WLb7kg0OqP`87mMyLTMgb<^(6f@Kr=&-w%b+PzyHI^y=&I0WDq`kT6$SJ$cLD@qpL zj9JfHabU*Ru7{|kf*T>7+I7eO^zIHaOBWWa^RvjM{P7$vv9BJX**qn^n`+>L+ruj#>4aVMP3X{G{SIs>G zT7CscoR+n{@vVah?Pz=*|MY^DzaXS*=qm{68u~|sbPat;zOshyKuFin-}0yy?U_gr zHT1%b5Ik$>Ptf?9HFO6IjMUH_A0faR$~)Sv_WyEQhfaTk!aTG}PouW)=OJHwx4e_p zntUwBqy^Bmlmywe^faL3abQhHPTdX%b$uMvE#0fB6KZ6lw|zh7Y2l5ElYFBlZbu^p zs85!o0QJdo6kt(Z(4_^)14?>B;_n7{g+-dg2; zi|*3TP3>)l=R$Ys;;qGny zIrZ4a+gr)~AQ2x(h=7DC!q4?{@X>eJ;bZS|=LXQ~S@nzs5>*gGkYQ}-i4TRq>=-hYPCCR1lZe~Gr$mx{SbWUFUW+qJDGLAI?90-b2| zkyBUhpza3_>R$bGysh418Xc=TpMFYAb;jt2F@-&$4?QdFij(uPV%FU3X=$y!7o5)rNYhiZ4Ur`#7! zyQ}xK2OYHkX{Jqk!K*9>q5T3)yJ<}g&+o3mM_@x>V6^9VFxF^Z$6}$;lwvt9>;^5p zRIw$RHL)lE!qc=T!QF;EVOFpwN3O&_cI2?ek;6dbaJcrwIA>&K{h^g;ig1#J<@N0~ zy}rHM8{d6TEXiB=r!C3r2x&|57lgDWc?BVDN&YBbX-Qr}NL!L;&#^3t1Yt>DqR?qc zmZ4EKEy+tTjABV%+J^uw$u&noc*fA)FH3A4Ir|l-CE2(Cs6H$+SQ2A?*w{w2x25TI zW~40%39>E8NT7q7H8&kOb;}*p4RBD`{IX$5NR6?)uRPA{+qYzr{_C+f*QS*7zkZHCQZGx~nUuo+rlJ(T7+G5|9D7L5Tt zKrPYmw}H5qqU3SQW8^+Jx#hJi~T)_ifxPsM1bOo{Y>s@=~ z4BXxb4~4GaxF@WUv%M{?izoxOE>b9i!aqjhUb23tgY_{$XSOa6{n2LqdecPr2fGuK zu$>g=Es2ZE`2p_?5`l=p_$uRS@a`B!WS`;ukHN#$GH3R%$SbQEgY+qd1Iy^%t?UgxrP>V~fz5+Va>RrlH3g$&cE_(0_n`+R(p;kT&%1Afyfb zn+Rz`|5y1+L;q)lw4r~IC#2}^y#!(CU;HVGk%s;TG^?he|1%7R7?3}|i2x1#Jcp`n zE3j2<^6x3T&yDW=!TleJx?vD5x)+EAsDEZg+6IsyG4z=VLoXKt9V=(kkyGb&PSj&5kTxLoSI}FrASYQywR}k6|tbWC-AApb_M?G~Iy~ zgw^`;M>$Q8HMYbAj*OlUAcD6ef_7Ik7`~HOd&gO&gR|*CXIAkSUa~mjUJWd!Wn0Fg z*e+ukm`H=lkPayHkqfrkq0qnoo~_XNI(uLTgHg+B2b|9P6BC`6X8AEKO~XJJHU;c( z?-2|I?c0}*MB@RmV*jdrjL7crmBUP19#ETy zQs968xhyv9Ixzm9U}Qg-|5wi36`sZ|D+POw!4xQVzU^X5Q2%dgwHejkNA8uw#(uqN zk;n~Xf;?RMp%Yv-H?>?3>?U8vjM46v)@9^~?OqCP$)NDH`Gnft-1ON{%NR)z#^@o! z(iokI*32|UDGak#rR+t3#^`kj&U8l32RgG-Jo*BS(H`z(cuZ@BSvoDNm%WU{kQ8b= znGs1qQj`)vDJ@G%uD7o{7Vkrh|1QGfT?%pK%$?!q{^aC+C#84pE@xDXIH-bp0uAE$ zZHzb;P3yHd!VYna1Uge3>vveV<Mk9JiRP=H)+7*ZTxhT}(E4CR32x;T}_OFfT;Zf0Zb#zP9PGDjF-+GS*fx8@& za6;tnY&44ZyD4j!aBUY^V7oOmPFo6}lLwHWZ$ZI9uToi@tpnBq*Pw7Jz8E#Sj|9WE z>J29dYvShD1okV*1Jc;=U8^Qa5H)c+VObOZ0#j?&#LWy-AvXU70oKGdP$$$xDZ^g^ zomrk|i=Z8Om&WAX*!#S1(Rt5C>4(#G-V*+$6ow=3t7Gy`?S0<2>b!wSg&&(Dd`mdp zRD=^y;(7phR^OJ^^`t;e-P< z_>s3nF|Ei9MDB3I3}cxIHr=tfSqH;wBr$Zf(x7Ff8L`=jSZqdoZbU3V#L9Lwe=V!e zyaU03;e5n!^PELl7UKtnXCOY@7msD1_cK-=ezMB_3C_ycZy>l(BOpu*%zrF` ziPglKu1lmMHccZj{lfo){60)i@V!=lzYO1j#mF&*Qe2*kM#LDLyjK>1L89aS0CXtb zr!mzcrMvq@9Z`vOzTwqq@piZmAvKU4G7qoiA!E_!i_KbkU^$whFaa^EXpJm=z7p;h zMo3rOh2u`c-Um7&OugVHVx9*Xz)#gbR|rj7^ExNy3-&{=nJhh2Be0-keY4b+BOO*EaNGEge2f7%TmXK zQCy%(a?_BKU7MwP*Cs`V_`&=i9)Jxl*5v$;YMX_v?Tw@yP0*2(J;_0~Z?aAH+s{&t zY!UaL460jJh{&Oj+i|+pe}a(74np=`Y!foaCWHs5am;`#MWe+BvGs+$=^xH~`#(cn zu7kRZ9Mt{h8B0u`pd@TD2ZZ?5z^xd*T`3n zEBqKCJ+2T$-^&->+1z*-pu;ypJWR%{1i*n z9#=S9*V)*yMRv=XksendLDFcRPf@);k#fPf!jV%q(Lo*7>|5645>RK3E8Hm6!7;8d z0)8#bx{NCfAPtGf74DT{0|Pl|o@n9w+{ZpdqH%?n$)bo&7!2q3p0jKRXNNAdIjjAx z&Dmo@p)s_eckFUWDa&Pt3>e}&B>Z_Fjt|D{zXAjY2>G|8k)3ex!3Lf%%jd1* zY3czF{`L2j2J&#aZe3oLANDb?)VFwtoTd&#D6a8?!oiyDjko;{p&gAk zsQ}Fk;crLdbyjE@LREer;(mfqNzj|u+!VsbeZyu*5H{m`%`_G8na_vUVA_nI&}gzT z`N<9hXfxhM@55|^!{hBTEq{z+)+YtLhN3`4JVL4=9MDRtMLt5cUN3j#RKMe(I>SNr zuQuCM4-=|oIBvz)mo>a0gKA%JdX<*-G@qxuH?rpKQ>Lu19%sw?^G9u}tBL+rhwdY^;p?PG1Ka~xDZfrgpeX|O%;uw`BCqh3(2gP}r? zrWzF}VCZ#Sa8_@q{+om9fexy#f5et`l2E;7N8_C!Vw5Xg?U1^t6_(XeD=e#{)agc6 zN2%6Aw$yA?BmGZYy~nvqG>T6NR@0%$!7c? zAlZ)`l8vOpS6vxk!F;Ffhh2Kxlv-sU7!M#yy*TMbW zyxCG9supe2rK+e>>qWly4<+KK}-n!%{!WTgTtEUnRhi^esl93 zV}60mL#2UI z_?T!egYYpub+d4BPikJCKVbTpyIWS3T?2U<%U_qBOZDA|dk-D$#BO7H=&qL5G3YKz zJ2Bu{1O|oQ0KDA#o`QuAhG!{3c$Qw`rDwSV?W*Zn4q!vX!W-~30`x4ea2Tr_fX>vY zeh*Rh`XZip`!E|0r`HVwZCC=p(VV`xL$c-J&8#}X)RoEMo#!CrUiab9SdgCxB?S3} z27%^rNPop6C=CF!p8W`4jG$kFcVTif1cWf#H?C$q+ikDoz_*);Qy8Hn`h{Q7iJF^^ zToQ{Nl2{IOrXYXjA5{~_T7b!7vr9&RlqtuO+2;XWjT`F`Pz zXN!DH=C|0)H{y%Id_aN@=5J~x^SIS5~(B9vKr>UwdPGv8OBpCP%UF)roq;^NkLkTY%2w`4|V!?l0{8E-^c_WWBV!hw1$5(9M0Nk z$NifLR!G8lqp1v!Kz4c`C0n(YwUX7omZrrpvb68NZe|gFZrgW!n{l-vfz3}K&@cQ? zWJjN_X~VzquE$*^h?dSzShjS2wEJdDw;AS3M7SAahk{0^?jSS z+_(-&WW1~XK-1+P@=l3@_Li2NtU@#8GF9$GS+NZroRuwYc!vKv3@KJH$mVqq-j;<^ zwlD9)B(O;z!X_a-l@hqHBu>tx7X&S>=l>5xCjRu*NY}Drr(FKHk1E=?xrLduJUoRk zV*KVXC#=3~d10+&hF)1}_|zMt4u8H`SU%8Pu+!3WomW!{@le$Rs5mI-enL0%Xm0X; zi6~vx5=2=ql5A1dXTeu7%Q^tFt#NE74vw*>*k!%t47;qy-OI9un(x_v73{S5lkN6m z{hfw=m-ST!fz2@lRsmhJeCrK?12uu77T?hXO8Dk`s3Lo)BK!A5uH6+|esM#gdj2CKl>0+*GQ+Q3<3f_{9e^vHxAXTt6V_5`pmP|I$iwn97gjR{)wR)0T|Cer~QP4)$eL6cfQ=~tG`i9u>yf{LCFKHLy-cPG!sRH5O!?m?6Ee>I?D`62jSu$Qx?KggFktP)=Pj-5 z1G2z_>2wzpnO2G;c|{4aCRXC;z+c*}SD0H?o$?mGZ^< zKGyE9l;1L7#jVH)*HmwB{O3l5b~OG2|EA+=`5lcPA~XqW4|X)Zk5CA=DeP!`7onoM zDZb_=o*818P6@(vp2eXOy1;j$Sv5_kSZkWjcOOI~P3MGfBOk-~+;g(6Oy9ko#iI|f zXcXhaeH`KUpg3PJ3qX1%GezE-a*b>N2K=p59s9pgay`=gF4yrR9R6lZyMfHa` zLi?#F|9Q%b3vo-}uC3wIw|?2DB{f+)SbAj$^s9Nb*c`Zqa<%+0HizUV&Z36=R!WV!H^%>%|LVIH<6G7ldC$x8RyX7^f$d2sNuXGuIS`(k(*(tBRo z9K8IVVS|_an`~aRdDuqtaGZl``2E^EIH*1&0o8q}rflB~m97AeUaHb|2i4zkP<``i zi)xyOwkH=v1nb>(Xts1UvyJeEcAc)9G_?mL6ziA>$Wi zAJT3BH(lC?I@3NRzK+v7Bmy2Pe^xCZfY_5niMI|uQw56c^3 z>J+}MixKDxg1c7&z0bkO5}-5d)TcMt0=-$>hi>cxuah+wz2F!w?Fu<~*-{_R%eEL^ zz59|4R&L$;#pzr3pW2ezckAbUqFsme&8wwuo3>#cZNs{y+Zw^G*oJ@gm!3|7 zk^5Eo`Znx+16JH2viV$Y6{3Lt^mqCJGK!>oaQj+Xr!RoeSeL&183KdCZcr?v^&h>9 zcirYo5OsP!VOggiK?`cu=`X>q)afsOiU8~Mp>Kg{W7{I>gaArGNjP{t>(T*?*6;tT zXdn(UkP~Z?2CUFSlsFlH=fuejb1d;E90u`C$gP*eCy`)-_zN7wKh|s!kNup?1t$_v z9(r?xNDs{S%^{~RLIS;{<7iEXwCxX5phnv`3Urv8Bi0z@yN*LlQsqHIujBt%~yYj)6i2rhRB#E(!KXK=LJYAPo_ zKuyoV?sub`uhq02dpyg5nQB^0EgKZRyB{Uoj>~Z0#=BNi2|`WJ@ga(8+K&!{v6#P@ z=9$tcz7qke>GnQ$NzVW}Q%zr5DJCBkW&bM_EDyak&f8cqT1PkzurSrsB)?SL%`9)kT}hEnioK5u3im*4?P47@f%Vf z*?Yp@(1g2LO}OmY)a#i|)N6f*`&=2vFpdcU<>=ai7rVo z4}%i%P>!^{)Eq9VF`bqZ9XzbQ&gNmQI4w30;k8Fo`W(Enr5`;c>5%^Hngr5+5Eyz% z`F;oGmjRtA{l8pmQ~sv5&E`p+<{fp`DE$8(+eL3A;2OWxc246HSM-Yy&kN625+gWj;*%%pF=W_8Efe?}I{!MUsXy z{1OmavJw0IH4WOo9Tfc-Vaq;$vD~oFB*bt490RC5*k|JiWSrRi;%%&ijoa~0?`7mc z4SFx*GYILujK4uh?`3>kzH%?)BM9lejQ76|3beVFAk6h0Wr(7=z5?xwX|5lkt)g%q zxdj25>ys#BVxqcAJzDy}qg8 zcrlr1RgRp@QygS|0Xt@rS-*^Bu#e79ty#fn%yFgiLGOW)xxNW=pJPAAUs&tXG5$(}YR=TMl#(x`dS`EZQZJlfYZ8 zKWP851AUPKrNR~_6^krX7zov}ZGH7Qw3x3A$Q%>177ksts3rrFp8nA+g zHK5ogG39_2Q{?SXOVg{6LQCuQaHu&3V;qfRkvAv8CyjB?z=W z{9`0M9*IZ}Ge%;_d9Ih|26=9j=O%e>mgg3EJ|)jKd2W;E3wSD3iJ#hkE%c-k6-Dj8 znxSC~1sTd4%F8Ct;5I))k;x|N}87`mRJ)eK$3&^-(-X6RQ8)iCrlLu9pbCqtJq#2)4TB8EO- zD32kYhqQkpLr0;O?WgD}Ph@B$Lu?H9V;WyoUc}G|3>7ehzJRK{oFN2M{k}|~2C@zWmWJJxZSy&TTtk6vb52oN0eU37iko?ck|M_W>OI3TSYDRmBx2UMBEN`l>PLLMWF|WdatAbfDgQ^;rzlw9#7rBZ8 zRW)_c8&O{YFU*OfA)O>xcysEj{N(~V9Z2$mf$D7Um6-U(a|+M&w|b z+zl!E!wzbMi#&Ce|G~1XKo%hs zAUB8#C7yUnxCjG9CV!?@1?$v|T3?MT6sTuO5Dg7yg$DuDT2|t6+HQ9ZDqw~F9`t#< zmA-P+P!yscat@)I1%2K?usnqSykAVs_5^FHY8J>V{}YTtLmgutlaL1l&l(=`)q2nh zz-q!|vzjW3jcLsM084vRi!41Atd$9}o$vE{>O($PwP&$wzEmGqsOl;o^CzvUC>Y3_ zSz8Vz&95oWQ43&l{eh4VG_#0Zm7b8xU`v^s-^;_ zCraFaD=p5>b-O@p5vH%a`85@S7lN6iW=qP%$v{iWcXve5V3dNF#{=BcV%R<TkrP`4xa`_m{S|4m8^9?mA5_)9 zMCx47HM^>&Jg_K4_M;j{GcWgIi3WZ$PZd^q^)+7c99e9Yo|Dh#*Ha_yimrzqZABMV zLJY;Tb6nN18fH044pJ`}Vw*xsvyk=9sI<;XIF!yK^o8~zs&)oRD8*9lx~w{MxnYp5 z6zq=5AH^%UnKWYbSQz?{>AB9#uc^y2{nruY+JOaM-?U#>4OfG{92}l$@Zl;KmLTJ? z8O3y*DMw1WTiQmA%{V_ZYxHRTJOA=%Jn5NV15bJeu%u_i;>gk{dZfef@hv_mz^}sx z(r1nzKX&}(4p|V#*Wm#;GR6}_3=V?_o~h+^St_ljWEVi>wM%%k2ewOl>TpUA|B2ik z-*l1KAD!tmn~A?MU3zBXZ<@8l-cFovw6}MLRSw>tXXBGJ_)@7SnQ*t zB}^Lq7X45AU!L+S>fw9PSu6_r8ma>IbQV#O44k7}g}z1382Za@zpnJ?M$iD5uZ}XP zU7`h%9SnMwlm;|1d9ll>c8L~9LYOH5Hu#k^2^DB6>MG$nqE}VJerM2!epUl$=9h~4 zy858c1>e%B2h-4yNQUW|If1}JMIROv>aGi{W;OVQa{$`YELuvu9=}f$NyQ+Kw$6}6 zOM$emm!gv!^215fT$TnjCz96G!xv=b{Pi;M5z|+msBO(fE{h&1t^69J zChI(*1XhfhhtMs+M%IQ5rc_l_6#2?Qxaf{R$RqAMvNYmIX%ruSuIobKSXHIdK>fw@**~y~&CGISgl^q=|ySm^K7kua1V8DwpKb?e?{vx*Ny0!!F zsBhvAc&5!ZhTY)Ol%oVN{8qC7z3ovtyV>cPuA2EeS48O{hcwVCPK(Q1Syg)(hLSV@ zfMd#kJ|rkur9VmIM;_{eRSOnCs1;Q{KO{Wg>}YB%6SenL?EsW+*-$mB6ba2?4j?iH z5~f#GL&qR8CPCMzx)%1AUh<+UFj7#Jkx6>v#%2nuGRJ3T(5(9wW86kmZ>)5iz6NZ( z%7Mqjp;KfbK88_uth&THH#P(8IqDkTt?z`_-xJW8AJ3Cir$qdB1)Gp3(|u_!;xoE-K@ z*9WT{wOq!=<)!l}o1G7LxU@Kb>etQDZl9bwEbSdt+|Y6JJ-enHu`GSIX31u?r~bX*!t zUjSVY>aK$hfoHoE9T)Wus=x#w(fq){!>i??=m?r|Yd{+i0JS1CUTp&m;*7i;aUdWD z&Un|hfmz$%(=*L>KQ>V+kM^ywl(CqoY|*W~11b-lrRtTz3rQTMmcQ zzHwP#lnZApQW~(?nB}85m@!7F^ms~cOujSW!6xS15tZ01mfu0 z8{;rOKL>U2lToiF1PV$*bJWCi8q0ltABI?A)T^qkYHYWcVh>8H7F2s!4<#V#YWOh| zTqX6@8M=!;aT2r{20(x&u}cx9!)CoOk!k&=K4+Ox4joRi3r$7QC83}=}*Mq#dR5xA(HZO0&~`J$>Fkj{9MJ|n+s z$&kpWVo=*m9ZjIf+<=!%2?{zbUQOBq{yJ12>#H-JWP=qCv2n9hLCI7|<$OI-%?Wqi z+(UH=XSjm(nA;3^%C$c)^Ptjsw73WRj3g^i<67l+yitYG19KWoIt$Fr|j5z8C0q0%;gM$1i1p?FE=%5X5Fp~XdeU*`rshLiNws` zhS7P&KpF&@ctrnzDGDkEM%qdl8gM|xz!)?;0OIMvI*4G^;%E>pSx{3NFlf*+0eY^O z!3UwRaQCP;d@tF~&f&kvZ(UC`%vIY{;U8f_t&MxWGsWjuSs#H#O_#&z1231Qn}G}?z`AF`mX<&?-NBZQ zz6|~mhP0T1*>PD^sSLb_RH`5gV9lGzHXbQrj3pw%|Y0-(GVk77-8}tnlPjR0oEr6VUh+#V*EvY5q-}uk18Fq zIc>C9JoJSmRa6>>EsS9k$*e|AmkQ-6CCGr3AOmArlnjhB1LMs=rWrV22Qa2NI**2t zbO_EYLn-*582O(F`JedspXm6X*!Z8wvS78Rjb`1J0{jMW85Yviz~1w!%McB^ZfYD- zhtBJdFl_-{MY`4dXn3h6-NH}lQseN&sqzL*Qe&r#o>AkYHs~7R{8So;Zw|{3RSRFb z!iP^#VWXL~R7)EN`Bb{3*3w7nGc`5VZspRqq~#LT#uPu_4Szw}WABx)tj3=vnbCPc zJJzW0jE2)hpFx8=p|y`-E^cM}g_5Buw!H*KvK%b^SZvk>1aw_MK-UEXbX`C|*99(h zR;9g2o0n^pI4gjzg9zw+5zzS}pz}pQ=PNW%nSO+6+3Y*Y(2y7wb4^Wz(4v70Cs0L4 zvyMi!L$G%4>Utb-;$^#1kLfPjWFMmR;9yYJ+8O1VyTt4F6^LO(f!U=+48AGFo@y>r z;P;qMvVz7ae&Z7gQ&RC$Zna)1h)*Hrgt@}V%Nb^%iempkP1*4I@vXkc4XL}HMcuuZ+-#}pPX-0?pSUQ-`eQ11$SjM+bwN)q78;q~421M~y;n;46~l{{ni}=VXgG{y z_9u5k^cRyt)VV1AlZi#$s8R>@JR@Bzw7-V#Nu1rhniTTCksszBIX{V6{}89uqyH?J zyhYPxSR(qfyjd_Pp^7P7a~c0h?+_gQ1yia$(*j(!6#rctN5F_$7S4wfqa+=079D`mT{cSzYOvQq{+uvKEm%ZV zyTHS5XkBfKZooP57%)>XXz9fQu4QC$lib&wN< zNAqPtazsS_ob(tlpgdY*oiOkg-3?s-UV@I2uRLeTl$mHb9Qp@(X!}b2^&}mL+*k`- z$Z!-r7A2Yt>lu|-93>ho3dYLELLmVQ#+-lS0P6f6=I+@Jc2y@6e`77NYb*MV*eaph ziLUCZL0ERE%FC&OXsShyAtfJelV-t~Oi{p?;OJ7h*kI)P7h+=r))UltmzW5UK4Uay zrh2L@Jyn#RDoIZj#8B!k>5o$S1QjFddxA<~DOVR2qNmExQ$^^h67*C7;&qIA6r+2_ zNG`Pt!PqegdIt_4&@5s8H?>5@jk+kxC>Wr3c%&ApC>V~gG+6#}Vi*F@L*R;6$6pj4 zswO%!H6iS^ag=`)42#$C%|sOiQ-bM5jNV}}wE0>7N5f#OW=4%0YdNC+62lbbIvdO= z7_Jq=^ivcPyZ{F4R#6UQm~|PgZUt6rn}62#OX@reOc?W{k={j@!`$ps>{(_F-*2vLhZn2VYd@5N{OagyEYpQ zG-uu&ZG^pF%gqg4!c%F$%ny4$u#*d8VY95hD^`?o?GeU>*fG^_78F^TJvME+43={B zb?J=KY;67zhuc_PCA)tBq}Q00BZax{YJm@f(cB^-d%!4wau)zOZf!2UVmhHQYQdI3 zUWRX%E7zmb}An+PPg*rCfief(_aOEb1~nL5MV4LAd?1dXDuj*)^}@1q6|!+4AnW`+@Cr}6xdbZlIaNyqE0};pp>|u0`9GhBZu?~y-KX!JBRdv z2I{$}90p;>VGvepihhaq>7*!F*Yw)41eHD}O5h|8t>j^ilSj4hk{?=eot@qS6SZkk z#CUjP-{4iCF)YWKDsE`QzDF0vhTxHFg*V(!^b5E((2&Lim)KGadt{3BK?6%+;eBj* z*R!C?g+{~JFQ?JEuy`eEtQz}ESWjhhi{AdN=zK**Xb5h~GuliI;fTn? z`cWJ(rr7GC?W-#mp99VwoQuboUE%;l5oMSQVS$irSf!>JK{2IgOs|Jdb5{;Vu3VQ% zYey~DsJb06k)bacAmm;d(H}5EM?eivP{gtw2lXzlq!AZa*occOZwt;*!WLX~TwK8e zF0SkmXDI_pN=n;^i_!q45bG?qF4Z6gt~)h|#px`$SXJl_HdY;CVY^ca!v5#fVi;^n zj9$QY*m0as$DdxiB>OP9EkPCt!Exg9NtBr79qH}Pb7J0qV7)6k)8^hd4>yuv-B-XB zs>XVDHoLNx&?T8o%P%RNA&XOT@(Z~p~F8xxZsIK=`y5?imPmQt49P7@x>@zNv z=nLovkuYNB@MuT7$H0E zNE52poXZ%+kEoVEuwD|#POoB&mnq}15jRW+Jv2t^0L z>1-<`E9KFsV#|%*=TI=Sq}1G9V+gb*5svGY3t zifFn^eSUbc?gr)I-gakQGBegYQ@I8Td-t(c!B}o((bEOKXjY8Y9`#YDGl&!>y7;EI z!pDA$%Plv^ZSY;t-j$%c!V(=nrM^zfCZ?>d_&9Krn65t1E^fP{?CCn3Ym))_^ zxPV(XDB{4)Ckn1@ua~nJuwy9ds1@$orY7kn!nQTO7(OHiO_>_m*d&=}xmGot1Qy%Isxf7zFOGyN=ohsuJ%<2u-Az$zI~cO1-r?p zm2$8K(Ff;KV5}BA_rjz;wsb^pOas$Yuq5R3SJ+LJe3OwmtXHnW03H6JnUWx6W9-#p z0m*J@5M+hvrw1@JWH~d`8*^c*wLKHtU)Ty^;j@NzBv;YvDUo}?7+JPhfsCT|j5=Yw zwM!guqUS6Z=`olty+bNWPHuo~6Mf4!V<|_eqCU()ikuTAfcl3VCtpORrq-ftMXwGc zttDfvgdy%p=S~9)r!yY;;;5eZZ`37QPI^hI^evs$$y5*c-*S#g901Cl+jGgeuD3XM zgKTJCJjQ-{G*mI$>EqP^=~>R*8;uy-@b&V9(y>14E&O&~iTH)i<wNd?^$9N^v!$ zOIoaRM=TSU#}<>8Mp_|MRU8e#^Ce`Drd_clp>+s>7MeD!3B_eC=j0g#Y;Aq4GTj|P zpffIW6Iv$+8mDT0=46Dce0FsuU9o62j(}c#b zEz(Jy4Ppe>&Mqne2Y11*VQEpJoCa3gcbfN*l0!|n-GfJ;j2=@RS|A~eDb#a7HSvrUpaAjGr?l;T5zrfz8YW9a9qqg2^|$@ zPF$A`^%`l63zb67lp@i@z^jucaY3NR;u1I=5s1MFr+pPCpd2y<`Y}Pl z;uK#ahH{?ECH^97b+NG~2!5RDOFC?WISSUDZLlnr)J^&=iw@6k5gH`5L4-ts6>7|!4-WvTO+W_Zun5;!GQ(yr|^e6K} zH~FIurE6IyW((glbo*P0vVgkyxh&bR@>Db9z%$r5!{=zw@{q$SaUy2d;3FzVcoiQk zZlj+UL?-O#F&SGcXos1}EG!9P6jTQW8UaBqcHe-~e8{MYA&1g{$(34!lS)JmU3`a% zJ2`aF#DN<>O_uhGD5#& zyt3R?Tu>y$qH)84Cv=_kE=HbuhHde(AAto74)W2~V2~`RImF>9)oMg&F7!>);UJ=c z;LJ!n3>D&yk#yHkL(lN71dWoyX(qmft`fKVd)Oh4VeIu9xgn&Tn0`z>8jEiz$)4JclXlllzi$N(eJmN*aR!pTqe z;aotF15>}g(>|{Y@?+J zxQ$ky;s-y74En^{;H#*QPD}OiVr8P(Ca58ga73TQHL`R@j%)Pj(PyjN`XKhsI@5@Y z)kS_X{$ZUVXyh+cn&YT!kEsL55`_xghgGce@r;i7?Bf`dkwe)CGa`gBTn6Ppzo9A# zJPpCG4}P*i)cB8ckP(-Z7pbH?oThvrMTO>ZhnPF6FMRhkd7U6iaQFHTOXy*fFi?doK;YiV-wZ*G8W??_HPR?A+U0QUHo zbXBoRy1H-D!2W$wn;>cz;#hv0PU?v8+#8ij`5)JJd2%WX=h##{T=-4K@9Hx;A|Cut z1jDnjS&v@;%u!4kizoFcL|)tHy3}PU!x3u5Z{zTe$XaF>2g_Wq6}T-34L`FZaxxX9 z8@P6S9&&a^Whn>RFaM z0XOgaJFbZ; z+*Q_9nb`D=16<|2?%`Os<^rx0aGl6MK3_)KHnoX)S9C-|31w}=4o9lZfE`@f5%~b& zc)T{9djZ!DxII0oDNf1Fp&65&1rT0e2qYcHv^dp750dZVPTse4+>Xt_ECDb4TQu9^lpk zE(^Dv_JnUI>BF_KJ>lbxs#|dBZFg`iyCMCRT8A5pKm86~;_3|)%JAC>I}NaP4|GH_ zdw^xR)B(2XneOu^++BdHeYPVaUB9^eQ<=Z?1-1chPFv4#2LLyDYxi*E>c{J2e8Bc-VxztO!4Jn+a2Of#m!h*|LBNZ(gQ5ZCJnH2KkkT(?S@vu z%>i89Cq2s&;~DC%e|AJ7J>c6we4lni{@DZEF2GIytRr%M4{)CYuKe?!;amfu-(R3! z_keF2;MRQEJsf3S3%HH{?y3&h#wFAT8*U=t+LJmX=O%=+>p?l-!YQ4R+Y{=o4R<}@<{jM`sp|pXX25MZ zrZcjn2e`d}8`!@ya(xeQsmG%}AJ-Wv?*Z;Sz_ktRjO^+Gt`u;U-|md?(%SgCXY+eC z;Mz~@jMVf1w;pgK2X{su=mBmg;5MDoGu$D-Wqr3ZQqYZFxj_1mZ=*a;>x{@`Y-~G# z@6^%BfVm4W2fM*VxJtm4yE?n@gKU|!0&e2a&d6y!;M)SYacA@l*ABSzhIK~1(*wS~ z7zi9byfeaau&&C?g->aK>p!AvnXrzR0w(M1&dA>r;)<^0jez~?oX*G-J=Bd2fLk-V zGt$%z9P{2qeCgfiy$m=A`xRi@#&$;TWRo6SzNt2yE_@z&BIG@(GcpO`I9NonjHd&p z2rxUl(Nh=T>Hzoo#hsBfgcIQ+ZEFFOI=M5#OJCz)Qu`v(?mKS-?4I1t$R@OT@vzbU z%0a-+Ee6kQF5`H%+fWxi4><|)oYOs>lL50AFk5IAd%))hZ0)@6@wEcxYQT)>p-d?6 zrvTen)!E}Xz&^lDyP`AlkAytib+12s*MV2|jBgy^_5jY8kVcJ<@|z1d*Z*|SZzEvN z1I(Y`o5ss8y6iRrw*9)!$gK(W%hp%QW)EOXS9N9kbsI)KQ-dML>km(N&I9b^J3Awf zC#=`D?hx-Bz`l4_XXLdW^n$R<0lRp8XM~rZ$IHOROTIP%cK*iBF2*CZ?1^&^;L3m1 z8Tlw-{?T$xJsI`;@y^JrhXI=g*u778Mh+YX>|DUEd%iRB^kKj@0e0N)J0l+-2JB|Q z_I>s6cxwmj&b^(HSqWtuEr2X&&JA z{-ZN;9l~*Cizq37z)U;X85zoCaW=%(Yr<{4h?-^@t&T^j*6IwjIA9BJGDxaW?FM1DkZ z#L396BZS=z*uniHk&J|S+pwgQlYFNQh(wn6Afu6hyJ}!0G7vs=cli@%DPVu-ibOsm zn{l+-yk8Bt(IX;}mV|U_IP$X|aBD_JA`d0xJz76@0rrH^k;sgMc}K&31=y^NNaWKV z@D2wJBQejMoE3@uF`@0XX)OZW#tD%~K@a&8=hcASbx|ZTK4JbEC*jruE}RQG6UvDO zL+jE`z&$=S66u!^&c=5LaBDA#L_SIgr}0tlLvWq(yuwIiKF87G%F(WCgq;T1^>ZST zSv}Y<@>2)cJ!O%|VH5KfA#PFgQS#hu=l`O~bDkzq$BT;8%;^RroE(?*{zV;&(58 z8}WM_zc&0{#BVo#Z{iom?-TsK!tbcZlGQ-`PQhEE>G;jUZ}P)rHu{e$ z=lt_dm|Is}%Zne)HP6nk|M!PEwz>|o(#vbGKDoSn3O{=Z)c4i3kZ`x?ds zvFhCs_y1Bbg1_$g9rmYWbvAxu@XNyQBK)S}SBM|~X5;@4@vFeE7QZFF(oKlgShXk2D}uW0+kH{w1}7&ER>0b^cYnd9YOl)8y5= z*i(jGF4!l^xN#CEU3I=@#n8dcDvY0qcr(dlg!KU|{4#}aa$XDHrtuADD~9+ooiE&c zGkj)Y{+x`ow6TmWVyx_Vt>9~^yw=xw`7+0N2}Pxt%UEtjBFH@b;$yg+;gHvZvnKFX zDQ`UU1}}c|ML4hJ8~0=JQypKp5zZHt%VI=>a&IN}m;>r+y!rzR($o0Tn1nZ;xrBpF z@VZ=HebqQNg0D@+E3PZz>-BuC#dWL*w@R4XdxgX`@(N~+Ox7CjBCfmmqPMFt={o(& z4eoqh&sU4r4f1A7aihFn859CG$xB_(i!0rcaCR3J(qZN?Xz zrO9;LjMo|i?F-hsAY!#jE>p)she1VilImBcJhH>QDch}{%_&e@rev#E+=X+pgA3HF zdA^#4s$if-eV8|E>Wun2wRIY|g_X^kYHe~;H|NVuk+Y`Co^`b?U!_!6LJfHmzOPJg z@l@9(U8-7>%4&mw1tO}C^Vlg)QEiyG?VGNiPs&gqBxhk2Q(?M#XW&@X{_RYCQc{C@ z`=oK|SKqw=RVXOj7kSky7pZ>Z)IXBOs=JdfP#>pcsGs-AR39CcrFQl`U;VxBc=fA( zY3k`y)75?BRI*&$s5+7g)TjOMCf8SCPrFy$o{XJl`Z~u3wR3EW;*z9Pf~(&p;}X0w zb<4N(Enw=ai)A~UY+A#HHqh`!b`-9^CF5?$8aD^iyz2fTDT>RHj>%B1DQW7}KIv-r z(c{#6CyiC>2cNGt4H>TKnl1S2mx=x$Ymcbfxo5}s6Y3Y!Ya$d`4qnC8Q8## zou27qb!6#GiS-tF{p#^kH0L;O+lL+PdIw{J`o(vJ$ms2%MP4uJ?4KYI$P-kMydqCs zWrJGU2Rq^&F_7EGr>3ZO5T%R7T?6vh^`WryBzzD<_^nvIlOiQ)E)6sWysfjxebBv7AVha82dnvOCgC}#z#=Pp#qpiSL+ z6tO&glqJ;ZICs+TRa=fSL~6Y6I|^hYA5-=c-Jsrz0&7tF0oHmv6`PNPSZ>qDt?oHm zpD(69I#vX&erpI9S<80+qB_5NXox2G<*}MzW^b|o$D^IZ?BtRRu}jfrszmKOcDj5hiT*HM?MEJ%EeCN(ox%hC#%ARD zu+3cEa~xjsYvja3Ki=OtZ%S1~MUk%@XF?SDD~c-o>JSSA)5s9rs{9_XT8^muq9r2Arg|I&kFbVr32xIo@;{igS z!COT|h1z=_DOJyoSIJ{D)O7>R8+(gFpyOj9@!o-Kmny+wX}>OcY^@sWW-;)?@8 z3M^vVzzjT}ABgfh1EjPKBZ-LFBk^w_e$#NouN#5*ajYI?rMWp(H7rooJm`EQ2DQiM zsg}sCgH)d>>KB79;Ertd*3fiy!x>o;-Z(5*y$r*hfinT07?h6ZQ-dIxGlBlzGnG0j zBMnC?<*D$XbangjQ`GvCHHw3$=c=cNY82}xtK?jqeyPu1%7IH*a+TY!)*L@mj*An6 zSn8SY_W}8br>CgRzYb@VUWz>FGrhr^GbUgnX6^!SD zxS_ZY4^7vxa+sD|eLez(gnP7cu0IZP$Jr%9%AdatOi^(S>h*6+>x84gC?TAI;x5X# zAWm|)dfw+XU|^&(%G9$HQ`G%uK|DLpLW`5GetqItqseJHXS{iEvp(oLuegc_+~Mc~ zpB!K%CpdfkMb*`)5Y=99Nc|}-%}gTH@B-1OJ4K5!GR#ANqQ8On53;h%#N8hxUz9%9 zL?UgVw>+n$`#e4dW&ZV<4djImlf_$}M|2KDf(M98V|x^@U1Ynde;@4hQ`GJY zw4FDbesLXcIhnd06?F%_i40`jI+pp5rDZ{dd*oy>0QmS7ykvEMCgRxyLoU^|Y=^7q zss8n35rx`40n$I8Ao}(koY!E%bQ&^vC9Lw5UbP)gn|RYPO%XAEc}j`+3=yC_IEi^jx!Wa# zS%0cz{)_kW!#rK6hQ7VpX- zid-g~f=Bxlq^9WIi&2gtB)(@zv3hU>E&)N$jvwgoscm$q-At6nFv}C>RC#W}1lPVxJ1?Nwp>m*fFcPIR8a*Ha|HRqUBT$kiQ z)T3Pm$o*gmNVbfTZBI=5P#SPn)dU8li%MODX6v=ndN7P`-pQQ7D_b&W`s>nRAz>iB zXsXAUhD+NEakdN9ePbZ4nJl2FYO3wHr@ROTrt7-;-s$GCNzrFq(JmELg#0CCMfAnh zv)Lj(eWnpE2sTp*5V9yqFZ1H3p3jEfR6&A!gDi9&af|x2#w90WB6Pb;GzN_ox^C); zp($$1VnAPe6-patK*|YR?xF@TT;va_H}oaZFduj?7KKs zHDXX9RbAVHY3^ixDx8n}mJX#H(Cjs+TXIs>?i=`(ttKg>h~4n|hf3)i?HVAToCwI( z#P-omd~RIBROtrMuMEvFLa$-<@VTma3lnsi0j4 z@S}8N|Bo}IMUSCr-LORM`~AbB+xM3yM>`6SW?PQJov4EjY27i*A+0wjJ4LPjH91vn zzmIfXi|x*-YTbimmpv}>DXO=9*bI!*K{Q_h_RWU~^&Gb-8$wa<4bw7F2f*XYkMeu# zWBg8I87EcwtKq3?7Z*M!PiIf9F1xlC$MXRM zSpGHKUzQh*B_WP$Mu49!LeFpbJopsx6)eeVw#ydJ+cSFCUFDa!nCtHb9>6;ub(tz+ZWOKfWC zZ2#>{@ws0>_h)Q|^fKU2pP8O%1ecu!lHXvyo8FRqnbG>QjI3v6l;>2BPpeS(WNLI- zMzZJ55)a3CI{+lDZ!@`-Mf+J+7VqKfL2L_$oc8hA_8uU0-^DO3!id^5QhF_BoR?jn zf1NG)m~n8U{OYT-QF3A8i1KBwJzF~mB8vibeR`Ay7w?6d3rED!JXq0cnJKVaB}>(I zHn}k~_A}$(oSmL&MuZsg0Vvt^q2}BCP|Xkf9FQm`zd8uW#($9eU7zsT_%A*;eZgn@ zSA4cMV)!u`j+uJ&9J#oQXXI-~r!+tzq-RQ*hd46xFN_%IZ`nNBANQgI0PYrF(3wJ~ zNqu&XPLu$kP5?U20U67anf0~II#1nvuBmaap}0kt)IH~xsI69RIf1~!5dPF}&lUf1 z!z2_%6H`+$H4#E3ng@1f51uP@>E32xAl+X9WBnPHb{|~HjN5qrQHs7kLbIb;MB(`}O1?R>7g zQ^G%$=g*isF=eSWqeRct)=|1Dy^#i6pza%m&M2Ls-5Dy`vzVdBMpf1D|8GZu{CkLI z*L~!_KCvjQ?Q(xBr~L2f1wyz!3q4h4ZVYG`NIs!I{@Z5_)qqO6NfW zlR)**Xws)X7!AXksh${(?(=73h-mw0k_f@PV4(4=1E!1lff;ub7r1^w5ikpQU5CQSfBYtujg{@)GY#14tyw=^pXWLJaV~XQQM|gpWTJfKb6Q>Ra8HdmUropeC%yyiv zh{}O-Me};_Zn7Y~2z=Jf^7G@Q*MUJv_<#`5%UNLi9%1`_i($3Wa;U|Tldb~tlL3af z-oE-Jnt(hl7_)C_jFYiSR;WkEoA&X(^TFnW%&q-l=4K6K)dB3S@ng-wt7^Rd4d$-> zae@6Up9k9{{5+qVUgC4tF5<|jpvv5mnJ)kDq#C>`@PFlVT{~b>s;vh3_n8vROhe=R zN~W~ZWf`+7)LoFn!FL4fyTqzf2-v3tLrCE61zg+vgg}Mx1*hUfXSDSd>Zj+I=VVw> z73x;P?I+x<0Ir8y;IklqM@UCxh1vkv_76#?&<1KgIA8KdXjN8uj`|e<8b1Q_&L9}eZl9t zFZpczH=hSP`P_7EA3WPy_}sJ_i}O?B28sS~fn$6_e1r?kE~Mjw`s_l{A*x3gO7sA_ z2)ouJkJN&IoIWkcOlPDNk?Ic<@^A~izSF)a-Bi(1BT_weA$qaK73q%8Mx^@iLgQF# zL2RWqBGrw^zxC(HKl%S_?p)xcDz5y0Zubn2sLQO6jb<@BiW;LP+dT|0_=pX|JV+2m zc?8L$XPg;e)|sI*42W)a?HI)8-}L$*J|f#7QI=rrztKcj$Fxc!K4LmPvX~&uCM02v zk9K7hA0hiYRj0b^c2_@i|NHs;;d5_)r|zj!b?erxTeohVQ%I^0J)Ys!bPx$*R6s>A zZ;D6`LEZGjGjP$ivV88$itmin8M%&9KV8Ks!2AdMAE4gj9k z%a<1&d=xEQ>N+Ub590@vEW!L3Jw!aIFi6QgSo}BIUOOv1Rdq|y`SYjq7WbGoj74ta z-{*an?GahcK>xr1)cB?E{~YuT_YV&j>3N8=^fT6wdYSjh*ObnKyifeoI1XpeO~Kqs zJ!oLj6S?wi_)^uw$9PwI=4|*y&Hc3#ugdA0I1*&k3NOgf0MZ^Fpr5j2E)2o++}W&} z-?Fvl-*Q8JJ13mDi}%T`ydS-n_rJfN_nSt>d1&PE`p)A4ZzHwc+mTv;Uq;oqO+Vcl znWLTP^Q&J!T?U<_KW7ZnH}QVU2HtPj%KPj+yiY#>OR7MZI2_jxrMqXat7CrWLyK;;}>W&>_z@%W_Y+p)(3oBr6oV1U1Fs~Gpp#{2b( zWwf;!>(lcWKKdp!>yLso(yTt*(SJ1~w~xYJI)LN9Y}T*6tn*$B@bMRSdZSs5e)P~g ztxD~lb`&;ZVE;Jc1zGVevrH0KwdFqe(zlSDPG#FHN%l{zHS{K;VPJ(L^Jp^tV%7`{ zMPUL6H+H>PC}9K{M*-}f#Rc%Q77EUw_hxb0NJ{J5*rp2Nt~RRSM3J#I-_f6*U$l#sW`kJp*(hQ);c<(^h(S8+0C3a zJrU)HI%Ds&AcX#@9fdhGM3=X6dUv<#E6rI%P2JdPzHs7?yKvHbp|gheDb40oaOg=} z?&pwuRmo+QTsQ4$MSG0U_>&xat=eCy_SdR?QtdaY{U)`)L+v-K{T8*~s`lHkSJgom z;3I9wG=C_i?QJ!5w-QMy5uDk-w=JB1o^?Im!I|RmL~rG;(3=S1J6RRqHSOwg%9ZqI zs2gdehUM>QH&^s`w){hR`6nQse3s8G{=C}1$ouqe#rxDAex`6V%lo9-?| zM+pDwdB^`cB9TaaB%=QaMPi|hr~k+B@9@KiPHK$TbmC~r3&n$x$Tn|5=%ghnkNw)z_VUFc&qn__a6R!*4q}`8A#Xi z-+P0JnnygydRcEYkO^d!%9NKt{71ZlhwMklDE{kxDwqmpu<8HVU?PwRAe%L*nsiMf zFzO`(as1~{{-4Hi-V%X$DE(Oz8lN=!@kAhnwA99N;VL;@lfiE$5U+{jSN~50lED;m zm4-}mY`ivJo2bp!WNMSxr)pERnLuYY7!M@X|3siO7E2-bvAEZX@buWk*laL)L?lxi zijPYjn>;L(o)AhMp7pYaVLLoDdQ1}fQpf%<_^S!)>$cWpCyY+WPDoFP*MaI1M$oko$wLm-))QWfiGBEW;!7>N9Am~OVZsa%#hFux@Y!53ol1m5 zirE%&rf?^CB{Movr#%p$TZPwxeB3(J4+vj50((y3o58;k-VDYE9u+qO{-W?+@D0NI!A}d*BLR9}_(K+Zy$-;5)7laewLE$8Li}1CN1!#}(#K!~lG4wfDPY-yC z@D^}XcrW;B;gh!q2wfp1-w)m+oB$t=jtA@625uGJ0lq|dFZlby^b=e=;fdg*&nw}Vd;egQmRcrW;J;X`)>=x*VO;61{P;IWvl zsqzEOGgc*FS=S=YDh3A0(LHI`S7U3=6=Y<~z zzc2g@coHV|v7TMvg~I#6YlTA@oQrS-{DN=?_J$9iJmCBk*E7rjil{<#3% zB^(0(R(Lsh3>rR;n*xW0_k))S*FBFmLHGplBf?GKSA^$)kHRE3*3$`|A$%n`CY%C) zM|eB7aYLUHI91#e2Q@6izr*+ zx}B(>!U^!b!ViEw_`Bh_>0brtOyMRtoxfN(vJ35i@PSd>Q^GsYAWz0jG>+T;JJey} zUHby`FTw}FuL?*0h4+dkMMr*M&Z!ASo=V@9bAux9Lsltqrz*z|16vU?-AYt{v>=qu>1$$ zPT|h?P(Ow51Me1o_|T;3Z5jq7d%UNAGlZeRq#4t zdU3?tCS3p0i1)N`%tws9`TMmS?iC1&k(*2+%J3!_zvOC;9m;g10MfrId|}< z48J_$4GC`tuNU3{{*iD7{A=Nz;17gH!N;AVb?yT<3unR0g%5zQ7N*@J-VcOpz%L1p z19QKVuS*^HRNd#5S%fV*|_k%lxW8hxq!_c0$2WgezX+gS5IDUGN zZWm6W4s0_rPmFkv3DealGabHK^iZ-2{IFzkB13Rs zb*F@PBK&^C@FB5XcpKvG6uuk$s&ESYXW=+_Y)I#s{n|_reh~RQRyaN#?GLkuJU0+c z6Hc!nnk}4)5q(LxBMkpM!kK!Hz9Aex$DT^smCn zKN0;xxSl-PC!Cn=(LuwcYclND4aj%p$-mBKO>yJ6KjA8C;o-#E5h+Q zk5&oOE~5VI$np86Zos>qaC}XGI)u~z z48P)rze9AnFwdR;j&S|49^EIL#eKX>IDz}4W~$bYWk>0g!f|kua0bt-4&nNKqCVl+ zAklgw1K(UJ;bg$0r-U(CpMEPGM<3?{;X3rQj+&;^9R+_@xNee1vxQ?Jk9v#@9HCz- zT;J}|w}sPlJi13XgudqvVFLfVaOyUsD?HlZ(a}wEz8E-}ESx>Wqq!y={h;N-N$_RD z9mklU3l~}uqvFc!>P@qNy7DLAI=nxApZ-6L%7!lh1u}p z3gIk%Hwt$ijXEQYVq zJu4jgH;>*I&c5!^DQD@ll4AmNzTw;9_fR-9!=syoW1ojk!w7#`I60B%_ri5x?{ivb z3_MXd0-h$E=<}#sxU(1aTsV%t&j#TP`e^@Z7-cmoJi0MJbhg%?z8&vG!u2;ISeX9c z(Fzle>2@20QwLEFhA}hjpkX-SKQ^LuW?7GL{TDp?l5n~iOUntfY0?eCNwgLB2*-{k zdPz704$jaz>u&a_UO0jCJx4f%HgiCjebQcS!ohb5*Pn>@ZsEFHFs>q;{Um(B&D8p7 z0^ZkzW4EC03D+Iv(Km(D$a7MdpTj>kGMD216^^VyIW%jXi3>bx7p7Zq?j{`9@>LFzlx3KZWb>_2`6lt)~OmrA>Hr9mc4I<0zZ^g|YS_;Zu(8Gfed8u-TduM+a!O zaB8tfR|?Y!Sno_Yeve1538yy@ed6;vE?tju5U#rc<8i`~Z=+rbr?Tiv2q!mrbkY}e z+!Wf*ZwQC>;J!BDj}yIR_~3 z#Cnjzch151oA8En(a#j#xg&CHjr< zx*mLwn5*^dMtE5Glf3~tSNO4IM5_#c70(*s!A{ge;ph5@o)=F19r{AT$4`QZ{5-9{ z4t$*Ox<$Aa!gDV|pHq0wKfs5k@TSkgm!$Al8!)CS{QFZdmerwkj(O3eX5sik^xuRR ze39rj;rG59pzXqg=M!ax|LP|mO*~iYd0{cGk?=Ff=S9NVXV5Paz7yf^3iDXYr_a-I zzl^$ezVP}p19XM(;b#PBtMF+{h@KN3gR*~HxCz(u6Z5s6lfHsFBfKBHMEL8c5Un;c zr(&%>=ELB>6z@bEz(KDL9c!X{C7k_#J|yyy{s28{_~S%RfIT!lgnt=}cU$}ii{G{Q z&;|LpAGi2;i%+&VWO0+lXInha;>8w6EnZ>qYKy;a@mhj}PghP#(W!v-1*Og0b#w9T0}a|W!9XGhr-Zc!U1b;uNwXmm+qSo!N2?(2^B zVcGG%uKvDD)J&Xc*I-YS&Ax|Lb@R-eXsE9b%9bn%Pu1pbuyj##^e`i=CEO5=wl198 zykPdcxzVT+Ynb-ot>RpI!qc@Lzn=}4WaIyiA)G6z24x1+`VlPIT-xU9`N%K_$8;Yt z{?-=U#kSbh##ffwV&3(k;;5?8vbx$hVPzd=+i5A2xT>T348y99Wz5IS6tt=%I&9dg zj_a^=t2VB>8hH~t=MCek1n8>8x#eS#4Sj+T3CdQl<4RZA|Z2E!*8WvpFSyHYf#_bjp>` zjGR=dnI)Z?!;%Ai8*vWYFJ+C!KubJx6#6~qLplmT_-xZLg5!VnsO;IXD7MF*|~EamOD(f zCwy`x+I^`wMy$}**qH^NYUH3A)x{RePSw+_RuDGHb62ndb9ItzEn#^>L}VkMe$d9aqVHg}%YRP8AgF9kU_R!+G_ zAlvdXF&V1-sxB|yGE=kdAOS1jFQ&e~VL^N-!@08VdpUCD+ z^x10PDXy!X$%Wr|-xWdHRuh3e|15H9ma1t9y5$-|dK|gHC!s6thDI%_yfnZ}ef}kI zLo}nmZy7qEF8T0OpK~ABBBE*UhE1?bcyex(TB-M&{wBS_J=)35a z8fP!EA=mj+*D2?~K&5GNv>+GkOwoV6af)g z;*6ok_H!|cJb^eP6(nQ17;%ahq*35m#2KX^1w=7!OI+g4hC$tVmA<4E`vlit;PO5) zKU{kGcsb7}E(PJqy8n}Rh2oNOotFCYroE$ls3`hlo#jWx9lPK=pa0W~^D#I#To^|c ze7+z)LPDj#@l;3)5vxnC=$m>~(JBf_SK%vbB@xP%%C+A5#VBWDCXc3?N4;v=cVSW$tz?GVVN-_-_$&EyPq zF7RmVj#zlF{Lf;QoCp$I-8HmQO-OQ%<5nE7p4_;ob!hGds32Vz_Rbhqb2#QL#XCpq ziXr}OHG0~1TRi?#@(O|5-HaO&GX zTt={Q5#p3Mj&arM6tQ3_MZEk)RXH+(P}H@?kt04{RgR3HrN|oW!7#omq<&wPiv_Sw zhkZ_d0hL!RVDeflAR0uVA?N-P7Y03Po?)jK0^)Q~0pyg6m-(>{H-vKoiN2+T{35b^ zK#`Y!TPpXSSnTNE5(`g}uAN!5r^w}hOB3gv59|C-mk4;VDz`M2j>bYdnjT2CR@CzQ z_n*V#yDBAjl=-|kfIrH7N0iA@da}e=%d|ysXN7B_^6(Kpy)-Rir-yK~hTBZN48j|# zn*M0tlWJ^SeWE~e{lo0Etc(n*!m5E10_y8U1tm(xQsS$YIxGB5!LOx+P+2wV(?lgT zN+_?U+(4>NRXIU4m#g&^D(q2ASbQF)hA&wc-JtUrIH<*e+L z7P50!TB@4N>CxZHnbUF=GN*+qWll>KWG)=`dACIyV(u&RrKrjm%xR0@QFrC=Vtwg8 z+{>xNJzvGO7du3KM|M;r%dahq*kvDgJ;ZliG#6<3u#-Tiq7!)+Kb9yq2Cpq3C%kT%!l|Akk~5Od=lK^u~R{r*Ujk~&w*AD%0b)} z`UAD=JToUe?<&!R~X; z(?v_J=se6-;`InA%C8T|Wv;8suJVckF&044a|#?ZM!9yYa%5Q4HY1lK`I{f-+UKGY zg+wkdJy543AxIZb{%>7A^0z4<`4c6C5EGkYLV;WoE#g1Dd>EoBSBFux1Zg+v-_;aV zPiN!Y5$D0nk)n+ZhxnSbs-7#a+oyum%a&PQA|GOwnNT5|q(7SfOQh1|ZyHokgG$dV z_ostYde$6G9g5ykeokgCC_e{N1r-fO*rE2ztPbbIb$v&H>a#8A8fZC{BQAISx}^j8 zlnW!PV(=|D$fcvd`WDC*ehOAfj4QgF3 zm5YJ{YNakdP;4)x6#2impjDHPrgD(mEN%i#9(Ay8M=DLDuw)B8_^S*lErml(I+CtB zg>x9~W4Ma>X_xi^{bfV1qp6Zn1)?kfa_gYw!^^%8X|+ zeZUn%riJjDqw4(fZH6_w#6F~2LW#x8n&xBq<{lJ>%c25WUhcenOR3MLNnMZp^ANWK zp6Dodd3{q)kNmV?`w&;V+(a8*y3~rMt0bBnp3))(?S3IFj-@XGoY5EQQ%88M)8ZpC z{8HkGGmaD~udHh6(~Y7W<8>?wj^!rb@S+y^W7ehM#TbeX@U)ZURqE4o7gqNVxlgFCtUiME)THOgN2GgJa^zU6)KwL8Qq+TAR=rZ$$Q@CY zwdjalI=qgSj*~wpej-~LR6QSe2F)REp`}BL6|s4dVx`k+xyr4f4%rgZa#)QyRJg9F zI^>&tAyYt9xi>jy&h}XokI`HbgKsHz*4%xBf zkb3@9X~d;VLd8Jt3KpqTCzZSCx+Tb8b@Sm~YKpPm(He8H^quC6#fMz6RBPl|ILOM5 zZTj_Rdmthl+4^-9b!(ZE)f6IM3^I<>`L_MPJD4sm`-x5b^N6PAE|N2z6P z@~0t(@{8dV9nv%G?DUfZ0rk(+#@KI@ygE=7}h z)QS3K^UJvS^c0OpOH{e3@IsGPPR7LbIqA`Exj%9*{Afh*j>@Z-sFtLm%=ajrg1Rws zFa5stEK~+{HMhs7%%X9Hht1@a60=Kma+W$HUt-Y}mwJ7xp*!zbLZy^^sl`|3sQ$VJy(VpN3H z+^a3IJiSWYFIi%RdzQ?7?ND_&KPygU)PGP_bRIu**Yuol@pltZ=6^=$PF#;ZH9hKq z@{k+Rf6!k|3+9+;<$e+0r(Kso(OeiUWK~f8I4HL&p(;Kd!)>W%>(uI0U(#3u$YEby zFntJJ85*Qf8}xT0WE`qs@@l!6oGK~*oW^qVMjhg%rp7u%%gvS)aeqxv19y0d(pABX zH<_wXaMXXHt;s`Lwg0exl9Wrrn%|@k>kFzc7gu(kwWUTuWW>j95W?dRY!Fgf2Oju& zi8529l?I>Hs(Owa6I3?bEf(SIHW?AM*eX{}pBDARHX>^6RVCu<398%QEDNs=tK#%K z>QD^@=C1Lf=mN*e@G7DzMrj&-^V@ai?Zf^>>U8YuQg)kV!CI3djm^N?$PI8JCMudBlxdTimR}s)^f#Vt}Cu8 zb=Nd>N3`4%txSRWr$+k?4)hDB%&1b=veJwwoe9TX#SOnqE~;>A=|QHd=5MLgWW=JJ z1(%kS*Uk?)SC!-b53Dj&^js%d&t`A$8W`vsTs8~S`q->+iQ=5q zU=BFu(EBDM>ogrwB`R}GT{Qb+*JMY5elnxsSK!xBf6wqsO2@<^hEkM^$V?Orw98(j{Y z2`qIR?Hyd*H-t5}qikbAD~G#=c#2N+f=habcy?*Ddremq<6>+2RB-Rm&OyBkY%g7hA<0>gOJ2fOmM}jVW8Huw3}xyQFQ52_P~eVWxd0g6Tfst ztatE)g>z>wZU}|oF?4BcsBdr>uTM*3tA^1w@Xt#7IDAtgrKLl?tZQX=*C5NT?Crf! zesBs)hkJR_!_td}`i6V0xJa>kc^6Kmf5oyeoRSW7^`my;w|AgBcCq?h*^85ot+)s~ z$p>dcMdFN5bVyDA;9p(9l7p2-eC5};G*{wNc9;APpa}SHP65BFJgrP2sJ|B%1HXeN X&L9i-T-@J-&{Y>iFX$WO3rGJA*406M literal 0 HcmV?d00001 diff --git a/include/pxi_daq_lib_v.2.1/asic.c b/include/pxi_daq_lib_v.2.1/asic.c new file mode 100755 index 0000000..e12e5cf --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/asic.c @@ -0,0 +1,93 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.c +Goal : Functions of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_C +#define ASIC_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/05/2010 +Doc date : 22/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ASIC__FPrintFrameStatus ( ASIC__TFrameStatus* PtFrStatus ) { + + err_retnull ( PtFrStatus, (ERR_OUT,"PtFrStatus = NULL") ); + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "-----------------------------------------------------" )); + msg (( MSG_OUT, "AsicNo = %d", PtFrStatus->AsicNo )); + msg (( MSG_OUT, "AcqNo = %d", PtFrStatus->AcqNo )); + msg (( MSG_OUT, "FrameNoInAcq = %d", PtFrStatus->FrameNoInAcq )); + msg (( MSG_OUT, "FrameNoInRun = %d", PtFrStatus->FrameNoInRun )); + msg (( MSG_OUT, "HitCnt = %d", PtFrStatus->HitCnt )); + msg (( MSG_OUT, "ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = %d", PtFrStatus->ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] )); + msg (( MSG_OUT, "ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = %d", PtFrStatus->ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] )); + msg (( MSG_OUT, "ATrigRes[ASIC__MI26_TRIG_RES__LINE] = %d", PtFrStatus->ATrigRes[ASIC__MI26_TRIG_RES__LINE] )); + msg (( MSG_OUT, "ATrigRes[ASIC__MI26_TRIG_TOT_NB] = %d", PtFrStatus->ATrigRes[ASIC__MI26_TRIG_TOT_NB] )); + msg (( MSG_OUT, "-----------------------------------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/asic.def b/include/pxi_daq_lib_v.2.1/asic.def new file mode 100755 index 0000000..9ebc738 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/asic.def @@ -0,0 +1,238 @@ + + +/******************************************************************************* +File : x:\lib\com\asic\asic.def +Goal : Macros definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_DEF +#define ASIC_DEF + + + + +/* ============== */ +/* */ +/* ============== */ +// 30/04/2014 - MS - upg FSBB0 + +typedef enum { + + ASIC__NONE, // 0 + ASIC__MI26, // 1 + ASIC__ULT1, // 2 + ASIC__SUZE02, // 3 + ASIC__FSBB0, // 4 + ASIC__NB + +} ASIC__TEAsicName; + + +/* ============== */ +/* */ +/* ============== */ + +// 12/12/13 GC - Upg AROM1D : +// ASIC_ARM_... => ARM stand for Asic & Read Mode +// 05/05/2014 - MS - Upg FSBB0 : +// added ASIC__ARM_FSBB0_A_416 , ASIC__ARM_FSBB0_A_420 , ASIC__ARM_FSBB_M0_D_416L , ASIC__ARM_FSBB0_D_420 , // + +typedef enum { + + ASIC__ARM_NONE, // 0 + ASIC__ARM_SIS_REF, // Silicon Strip Reference detectors + ASIC__ARM_MI1, // + ASIC__ARM_MI2, // + ASIC__ARM_MI3, // + ASIC__ARM_MI4 , // + ASIC__ARM_MI5 , // + ASIC__ARM_MI6A , // + ASIC__ARM_MI6D , // + ASIC__ARM_MI7A , // + ASIC__ARM_MI7D , // + ASIC__ARM_MI8A , // + ASIC__ARM_MI8D , // + ASIC__ARM_MI9 , // + ASIC__ARM_MI10 , // + ASIC__ARM_MI11 , // + ASIC__ARM_MI12 , // + ASIC__ARM_MI13 , // + ASIC__ARM_MI14 , // + ASIC__ARM_MI15 , // + ASIC__ARM_MI16 , // + ASIC__ARM_MI17 , // + ASIC__ARM_MI18, // + ASIC__ARM_MI19 , // + + // ASIC__ARM_MI20_PH1_A_640L , // + // ASIC__ARM_MI20_PH1_A_642L , // + // ASIC__ARM_MI20_PH1_D_640L , // + // ASIC__ARM_MI20_PH1_D_642L , // + + ASIC__ARM_MI20_MSTAR3_A_320L , // + ASIC__ARM_MI20_MSTAR3_D_320L , // + + + ASIC__ARM_MI21 , // + + ASIC__ARM_MI22_A_576L , // + ASIC__ARM_MI22_A_578L , // + ASIC__ARM_MI22_D_576L , // + ASIC__ARM_MI22_D_578L , // + + ASIC__ARM_MI22_THRA_A_320L , // + ASIC__ARM_MI22_THRA_A_322L , // + ASIC__ARM_MI22_THRA_D_320L , // + ASIC__ARM_MI22_THRA_D_322L , // + + ASIC__ARM_MI22_THRB_A_64L , // + ASIC__ARM_MI22_THRB_A_66L , // + ASIC__ARM_MI22_THRB_D_64L , // + ASIC__ARM_MI22_THRB_D_66L , // + + ASIC__ARM_MI23_PH1_A_640L , // + ASIC__ARM_MI23_PH1_A_642L , // + ASIC__ARM_MI23_PH1_D_640L , // + ASIC__ARM_MI23_PH1_D_642L , // + + ASIC__ARM_MI24 , // + ASIC__ARM_MI25 , // + + ASIC__ARM_MI26_A_576L , // + ASIC__ARM_MI26_A_578L , // + ASIC__ARM_MI26_D_576L , // + ASIC__ARM_MI26_D_578L , // + + ASIC__MI27 , // + + ASIC__ARM_MI28_A_928L , // + ASIC__ARM_MI28_A_930L , // + ASIC__ARM_MI28_D_928L , // + ASIC__ARM_MI28_D_930L , // + + ASIC__MI29, // + + ASIC__ARM_MI30S_A_256L , // + ASIC__ARM_MI30S_A_258L , // + ASIC__ARM_MI30S_D_256L , // + ASIC__ARM_MI30S_D_258L , // + + ASIC__ARM_MI30E_A_64L , // + ASIC__ARM_MI30E_A_66L , // + ASIC__ARM_MI30E_D_64L , // + ASIC__ARM_MI30E_D_66L , // + + ASIC__ARM_MI31 , // + ASIC__ARM_MI32_A , // + ASIC__ARM_MI32_D , // + ASIC__ARM_MI33 , // + ASIC__ARM_MI34 , // + ASIC__ARM_AROM0 , // + + ASIC__ARM_AROM1_A_64L , // + ASIC__ARM_AROM1_A_68L , // + ASIC__ARM_AROM1_D_64L , // + ASIC__ARM_AROM1_D_68L , // + + ASIC__ARM_SUZE02, // + + ASIC__ARM_FSBB_M0_A_416L , // + ASIC__ARM_FSBB_M0_A_420L , // + ASIC__ARM_FSBB_M0_D_416L , // + ASIC__ARM_FSBB_M0_D_420L , // + + ASIC__ARM_FSBB_A0_A_416L , // + ASIC__ARM_FSBB_A0_A_420L , // + ASIC__ARM_FSBB_A0_D_416L , // + ASIC__ARM_FSBB_A0_D_420L , // + + ASIC__ARM_NB // + +} ASIC__TEAsicReadMode; + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__MI26_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__MI26_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__MI26_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__MI26_TRIG_TOT_NB // Total number of triggers + +} ASIC__MI26_TETrigRes; + + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__ULT1_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__ULT1_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__ULT1_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__ULT1_TRIG_TOT_NB // Total number of triggers + +} ASIC__ULT1_TETrigRes; + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__FSBB0_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__FSBB0_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__FSBB0_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__FSBB0_TRIG_TOT_NB // Total number of triggers + +} ASIC__FSBB0_TETrigRes; +#define ASIC__ENUM_TRIG_RES_NB 4 + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/asic.h b/include/pxi_daq_lib_v.2.1/asic.h new file mode 100755 index 0000000..ebaf2a6 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/asic.h @@ -0,0 +1,39 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.h +Goal : Functions prototypes of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef ASIC_H + #define ASIC_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/asic.typ b/include/pxi_daq_lib_v.2.1/asic.typ new file mode 100755 index 0000000..51d7703 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/asic.typ @@ -0,0 +1,51 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.typ +Goal : Types definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_TYP +#define ASIC_TYP + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + SInt8 AsicNo; // Index of Asic <0..N-1> in case more than one is acquired + SInt32 AcqNo; // Index of current acquisition + SInt32 FrameNoInAcq; // Index of frame in acquisition <0..AcqFrameNb-1> + SInt32 FrameNoInRun; // Index of frame in run <0..TotEventNb-1> + + SInt32 HitCnt; // Counter of hits in frame + // Used for monitoring, may be not set, therefore HitCnt = -1 + + + SInt32 ATrigRes[ASIC__ENUM_TRIG_RES_NB]; // Information about trigger, see ASIC__MI26_TETrigRes in asic.def + // Parameters list index is + // ASIC__MI26_TRIG_RES__SIG_LINE + // ASIC__MI26_TRIG_RES__SIG_CLK + // ASIC__MI26_TRIG_RES__LINE + // ASIC__MI26_TRIG_TOT_NB + +} ASIC__TFrameStatus; + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/asic.var b/include/pxi_daq_lib_v.2.1/asic.var new file mode 100755 index 0000000..452512e --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/asic.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.var +Goal : Variables definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_VAR +#define ASIC_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN VAR_STATIC SInt8 ASIC__VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/backup.c b/include/pxi_daq_lib_v.2.1/backup.c new file mode 100755 index 0000000..98ca927 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/backup.c @@ -0,0 +1,412 @@ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + + + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Init frame pointer on first elt of list & reset frame counter ( for acquistion ) + + VPtFrame = VPtFrList->AFramePtr[0]; + + VPtFrList->TotFrameNb = 0; + + // Check if pointer is valid + + err_retnull ( VPtFrame, (ERR_OUT,"Abort : No valid buffer for frame [%d]", VPtFrList->TotFrameNb ) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // err_error (( ERR_OUT, "TRACE => VEmptyTrigRecSz = %d", VEmptyTrigRecSz )); + // err_error (( ERR_OUT, "TRACE => VEmptyFrameRecSz = %d", VEmptyFrameRecSz )); + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Mark first three frames as frames with trigger + + VFrameWithTrigCnt = 3; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + VPtFrameWithTrigList[0] = 0; + VPtFrameWithTrigList[1] = 1; + VPtFrameWithTrigList[2] = 2; + + for ( VFrameId=3; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + // for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb > 0 ) { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // err_error (( ERR_OUT, "TRACE : Set pointer frame %d - pointer = %d [D]", VPtFrList->TotFrameNb, VPtFrList->AFramePtr[VPtFrList->TotFrameNb] )); + } + + VPtFrame->Tag = 0x55550000; + + VPtFrame->Header.Tag = 0x00000001; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + VPtFrame->Data.Tag = 0x00000002; + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + // err_error (( ERR_OUT, "TRACE -> Before loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + // err_error (( ERR_OUT, "TRACE -> After loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + VPtTmpTrigRec->Tag = 0x00000003; + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + + return (VFrameWithTrigCnt); + } + \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/cc.def b/include/pxi_daq_lib_v.2.1/cc.def new file mode 100755 index 0000000..876fa2f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/cc.def @@ -0,0 +1,33 @@ + +/************************************************************* +File : /dd/sdev_src/c/work/common/include/cc.def +Goal : Set conditional compilation options common for + : all softwares. +Prj date : 2000 - 2002 +File date : 01/01/2002 +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef CC_DEF +#define CC_DEF + + #undef APP_VFAS_DONT_CARE_READ_MODE + #define GC_CASCADE + + #define CC_MAX_BOARDS_NB 5 // 10 EUDET demo - 5 DAQ APP + + // #define CC_COMPILER_CPPB_4 + #define CC_COMPILER_CPPB_6 + + #define CC_LIB_JTAG_BEFORE_090608 // Must be defined to compil with JTAG lib prior to 09/06/2008 + + // #define CC_IMG_FW__MAX_CYCLE_24_BITS // New imager board fw of september 2008 + +#endif + + + diff --git a/include/pxi_daq_lib_v.2.1/com.def b/include/pxi_daq_lib_v.2.1/com.def new file mode 100755 index 0000000..c3c5437 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com.def @@ -0,0 +1,36 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com/ +Goal : Constants ( Macros ) definitions common to com_pc & com_uc units. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef COM_DEF +#define COM_DEF + +#define COM_STR_CMD_SZ 50 /* Size of command string ( used for human ) */ + +/* FSendCmd return modes */ + +#define COM_CMD_RET_MODE_WAIT 0 /* Wait answer of receiver */ +#define COM_CMD_RET_MODE_NO_WAIT 1 /* Return */ + +/* Commands types and subtypes */ + +/* System commands type */ + +#define COM_CMD_TYPE_SYS 1 + +#define COM_CMD_STYPE_SYS_HELLO 1 + +#define COM_CMD_STYPE_SYS_USB_LISTEN 2 + + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com.typ b/include/pxi_daq_lib_v.2.1/com.typ new file mode 100755 index 0000000..b680022 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com.typ @@ -0,0 +1,32 @@ +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com/ +Goal : Types definition common to com_pc & com_uc units. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef COM_TYP +#define COM_TYP + + +typedef struct { + SInt32 Index; + SInt32 TotSz; /* Header + parameters */ + SInt32 Type; + SInt32 SubType; + SInt32 RetMode; + SInt32 RetSz; + SInt32 ParamSz; + SInt8* PtRetBuff; + char StrCmd[COM_STR_CMD_SZ]; + SInt32 ParamBuff; +} COM_TCommand; + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_pc.c b/include/pxi_daq_lib_v.2.1/com_pc.c new file mode 100755 index 0000000..fb21d95 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_pc.c @@ -0,0 +1,542 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_pc/ +Goal : Functions of com_pc unit. +Prj date : 26/03/2003 +File date : 27/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef COM_PC_C +#define COM_PC_C + +/******************************************************************************* +Prototype : CPC_FBegin ( SInt8 ObjId, SInt32 ComMedia, SInt32 ComId, + : SInt32 SendBuffSz, PIP_TSendFunc PtSendFunc, + : SInt32 RecBuffSz, PIP_TGetFunc PtGetFunc ) + : +Goal : Initialize com_pc unit, must be called at beginning before + : any other unit function. + : +Inputs : ObjId - object identifier + : ComMedia - the communication media ( USB, RPC etc ) + : ComdId - the communication identifier ( 1, 2 ... ) + : SendBuffSz - the sender block size ( max value ) + : PtSendFunc - a pointer to low level sender function + : RecBuffSz - the receiver block size ( max value ) + : PtGetFunc - a pointer to low level receiver function + : +Ouputs : 0 if ok, negative value if initialization fail. +Globals : +Remark : +Level : This is a user level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_FBegin ( SInt8 ObjId, SInt32 ComMedia, SInt32 ComId, SInt32 SendBuffSz, PIP_TSendFunc PtSendFunc, SInt32 RecBuffSz, PIP_TGetFunc PtGetFunc ) { + + SInt32 VRet; + CPC_TContext* VPt; + + VPt = &CPC_VGContext[ObjId]; + + CPC_CHK_OBJ_ID (ObjId); + + VPt->ComMedia = ComMedia; + VPt->ComId = ComId; + + VRet = PIP_FBegin ( ObjId, + ComId, SendBuffSz, PtSendFunc, + ComId + 1000, RecBuffSz, PtGetFunc ); + + err_retfail ( VRet, (ERR_OUT,"PIP_FBegin fail => return %d ", VRet) ); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : SInt32 CPC_FEnd ( SInt8 ObjId ) +Goal : Close the com_pc unit ( free memory ), must be called at end of program. +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_FEnd ( SInt8 ObjId ) { + + CPC_TContext* VPt; + + CPC_CHK_OBJ_ID (ObjId); + + VPt = &CPC_VGContext[ObjId]; + + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : SInt32 CPC_FPutDatas ( SInt8 ObjId, SInt8 MultiExec, + : UInt8 *PtSrc, SInt32 BlkSz, UInt32 TotSz ) +Goal : Send datas. + : +Inputs : ObjId - object identifier + : MultiExec - if 0 the function will send all datas and return + : - if 1, it will send one block and return, the you need + : - to call it until it returns 1 + : PtSrc - pointer to source buffer + : BlkSz - size of block ( the datas will be splitted ) + : TotSz - total size to send + : +Ouputs : 0 if block send ( MultiExec mode - should not happen otherwise ) + : 1 if end of transaction reached with success + : negative value in case of error +Globals : +Remark : +Level : This is a user level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_FPutDatas ( SInt8 ObjId, SInt8 MultiExec, UInt8 *PtSrc, SInt32 BlkSz, UInt32 TotSz ) { + + SInt32 VRet; + CPC_TContext* VPt; + + CPC_CHK_OBJ_ID (ObjId); + + VPt = &CPC_VGContext[ObjId]; + + VRet = PIP_FPutDatas ( ObjId, MultiExec, PIP_TRANS_MSG_TYPE_DATA, PtSrc, BlkSz, TotSz ); + + return (VRet); +} + +/******************************************************************************* +Prototype : SInt32 CPC_FGetDatas ( SInt8 ObjId, SInt8 MultiExec, + : UInt8 *PtDest, UInt32 MaxDestSz, UInt32* PtGetDataSz ) + : +Goal : Get datas. +Inputs : ObjId - the object identifier + : MultiExec - if 0 the function will read all blocks and return + : - at end of transaction + : - if 1 the function will read one block and return, + : - you will need to call it until it return 1 + : PtDest - the destination buffer pointer + : MaxDestSz - the destination buffer size ( to avoid gardening ... ) + : PtGetTotDataSz - the variable pointed will be set with transaction size + : +Ouputs : The function returns + : 0 if one block received + : 1 if transaction if finished ( last block received ) + : -1 => error + : -2 => there is nothing to read ( no block available ) +Globals : +Remark : +Level : This is a user level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_FGetDatas ( SInt8 ObjId, SInt8 MultiExec, UInt8 *PtDest, UInt32 MaxDestSz, UInt32* PtGetDataSz ) { + + SInt32 VRet; + CPC_TContext* VPt; + + CPC_CHK_OBJ_ID (ObjId); + + VPt = &CPC_VGContext[ObjId]; + + VRet = PIP_FGetDatas ( ObjId, MultiExec, PtDest, MaxDestSz, PtGetDataSz ); + + return (VRet); +} + +/******************************************************************************* +Prototype : SInt32 CPC_PRIV_FGetNewCmd ( SInt8 ObjId, + : UInt32 ParamSz, COM_TCommand** PtCommand ) + : +Goal : Return a free command structure to be filled by a send command function. + : +Inputs : ObjId - object identifier + : ParamSz - size of command parameters + : PtCommand - pointer to pointer to command parameters structure + : +Ouputs : The command index if success ( positive value ) + : a negative value in case of error +Globals : +Remark : NOW RETURN ALWAYS 0 ( index ) => single command mode +Level : This is a UNIT PRIVATE level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_PRIV_FGetNewCmd ( SInt8 ObjId, UInt32 ParamSz, COM_TCommand** PtCommand ) { + + SInt32 VRet; + CPC_TContext* VPt; + COM_TCommand* VPtCommand; + UInt32 VTotCmdSz; + + CPC_CHK_OBJ_ID (ObjId); + + VPt = &CPC_VGContext[ObjId]; + + /* Find free cell in CPC_VGCommandsInf */ + /* Now always return first cell */ + + VTotCmdSz = sizeof (COM_TCommand) + ParamSz; /* Record will exced required size from 4 bytes => because of field ParamBuff */ + + VPtCommand = (COM_TCommand*) malloc ( VTotCmdSz ); + + if ( VPtCommand == NULL ) { + err_retfail ( -1, (ERR_OUT,"Cannot alloc command record - %d bytes", VTotCmdSz ) ); + } + + VPtCommand->TotSz = VTotCmdSz; + + CPC_VGCommandsPt[ObjId][0 /*CPC_CMD_REC_NB */] = VPtCommand; + *PtCommand = VPtCommand; + + return (0); /* Return command index !!! - NOW it's always 0 */ +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : NOW - CmdId IS NOT handled => Only default CmdId = 0 is used. +Level : This is a user level function. +Date : 12/01/2008 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_PRIV_FFreeCmd ( SInt8 ObjId, SInt8 CmdId ) { + + CmdId = 0; // => Force CmdId to 0 + + err_retfailnull ( CPC_VGCommandsPt[ObjId][CmdId], (ERR_OUT,"Pt Cmd Record Id=%d == NULL", CmdId) ); + + free ( CPC_VGCommandsPt[ObjId][CmdId] ); + + return (0); +} + +/******************************************************************************* +Prototype : SInt32 CPC_FSendCmd ( SInt8 ObjId, + : SInt32 CmdType, SInt32 CmdSubType, + : SInt32 CmdRetMode, SInt32 CmdRetSz, + : char* CmdStr, + : UInt8 *PtParam, UInt32 ParamSz ) { + : +Goal : Send a command. + : +Inputs : ObjId - object identifier + : CmdType - the type of command, ex : COM_CMD_TYPE_SYS + : CmdSubType - the sub type of command, ex : COM_CMD_STYPE_SYS_USB_LISTEN + : CmdRetMode - the answer mode + : COM_CMD_RET_MODE_WAIT => the function wait for answer + : COM_CMD_RET_MODE_NO_WAIT => the function returns, you must + : call CPC_FGetCmdRes with command index as paramter to get the answer. + : CmdRetSz - the size of command answer + : CmdStr - a string to identify the command for human ( debug ) + : PtParam - pointer to command parameters + : ParamSz - command parameters size + : +Ouputs : Command index if ok, negative value in case of error. +Globals : +Remark : +Level : This is a user level function. +Date : 27/03/2003 +Rev : 09/01/2008 + : - Return CmdIndex if ok + : 12/01/2008 + : - Bug correction => Add CPC_PRIV_FFreeCmd call if PIP_FPutDatas failed +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_FSendCmd ( SInt8 ObjId, SInt32 CmdType, SInt32 CmdSubType, SInt32 CmdRetMode, SInt32 CmdRetSz, char* CmdStr, UInt8 *PtParam, UInt32 ParamSz ) { + + SInt32 VRet; + COM_TCommand* VPtCommand; + SInt32 VCmdIndex; + SInt32* VPtCmdParam; + CPC_TContext* VPt; + + CPC_CHK_OBJ_ID (ObjId); + + VPt = &CPC_VGContext[ObjId]; + + /* Try to get a command structure */ + + VCmdIndex = CPC_PRIV_FGetNewCmd ( ObjId, ParamSz, &VPtCommand ); + + err_retfail ( VCmdIndex, (ERR_OUT,"No free command record") ); + + /* Set command type & parameters */ + + VPtCommand->Index = VCmdIndex; /* Always 0 at the moment */ + VPtCommand->Type = CmdType; + VPtCommand->SubType = CmdSubType; + VPtCommand->RetMode = CmdRetMode; + VPtCommand->RetSz = CmdRetSz; + VPtCommand->PtRetBuff = NULL; + VPtCommand->ParamSz = ParamSz; + + sprintf ( VPtCommand->StrCmd, "%s", CmdStr ); + + memcpy ( &VPtCommand->ParamBuff, PtParam, ParamSz ); + + VRet = PIP_FPutDatas ( ObjId, 0 /* MultiExec */ , PIP_TRANS_MSG_TYPE_COMMAND, (UInt8*) VPtCommand, CPC_OBJ_CMD_BLK_SZ /* -1 => use default BlkSz */, VPtCommand->TotSz ); + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( ObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"CPC_FPutDatas fail => return %d ",VRet) ); + } + + return (VCmdIndex); +} + +/******************************************************************************* +Prototype : UInt32 CPC_FGetCmdRes ( SInt8 ObjId, SInt32 CmdIndex, UInt8** PtPtRes ) +Goal : Get the answer to a command send by CPC_FSendCmd. + : +Inputs : ObjId - object identifier + : CmdIndex - index of command send ( this the way to link command to answer ) + : PtPtRes - this pointer parameter will point to the answer structure. + : +Ouputs : 0 if ok, negative value in case of error. +Globals : +Remark : +Level : This is a user level function. +Date : 28/03/2003 +Rev : 10/01/2008 + : - Bug correction => +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +UInt32 CPC_FGetCmdRes ( SInt8 ObjId, SInt32 CmdIndex, UInt8** PtPtRes ) { + + SInt32 VRet; + UInt32 VGetDataSz; + COM_TCommand* VPtCommand; + CPC_TContext* VPt; + + CPC_CHK_OBJ_ID (ObjId); + + VPt = &CPC_VGContext[ObjId]; + + + err_retnull ( PtPtRes, (ERR_OUT,"PtPtRes == NULL") ); + + VPtCommand = CPC_VGCommandsPt[ObjId][CmdIndex]; + + /* Set PtRes to NULL by default - overwrite it later if succeed */ + + *PtPtRes = NULL; + + if ( VPtCommand == NULL ) { + err_retfail ( -1, (ERR_OUT,"No command of %d index registered !", CmdIndex) ); + } + + VPtCommand->PtRetBuff = (SInt8*) malloc ( VPtCommand->RetSz ); + + if ( VPtCommand->PtRetBuff == NULL ) { + err_retfail ( -1, (ERR_OUT,"Malloc of RetBuffer %d bytes fail", VPtCommand->RetSz ) ); + } + + *PtPtRes = (UInt8*) VPtCommand->PtRetBuff; + + VRet = CPC_FGetDatas ( ObjId, 0 /* MultiExec */, (UInt8*) VPtCommand->PtRetBuff, VPtCommand->RetSz, &VGetDataSz ); + + if ( VRet == 1 ) { + + if ( VPtCommand->RetSz != VGetDataSz ) { + err_retfail ( -1, (ERR_OUT,"Ask return sz = %d <> return sz = %d", VPtCommand->RetSz, VGetDataSz) ); + } + + } + + else { + + if ( VRet == -2 ) { + err_trace (( ERR_OUT, "CPC_FGetDatas (...) Ret=-1 => No block to read" )); + return (-1); + } + + else { + err_retfail ( -1, (ERR_OUT,"CPC_FGetDatas (...) failed => Ret=%d", VRet) ); + } + + } + + + err_retok (( ERR_OUT, "" )); +} + + + +/* ------------------ USB & VME command set ------------------ */ + +/******************************************************************************* +Prototype : SInt32 CPC_FUsbCmdListenRq ( SInt8 ObjId ) +Goal : Send the USB listen command. +Inputs : ObjId - object identifier +Ouputs : 0 if ok, negative value if fail. +Globals : +Remark : Should be checked, answer / return value / error code +Level : +Date : 13/04/2003 +Doc date : 13/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_FCmdHello ( SInt8 ObjId ) { + + SInt32 VRet; + SInt32 VCmdIndex; + UInt8* VPtRes; + CPC_TContext* VPt; + + CPC_CHK_OBJ_ID (ObjId); + + VPt = &CPC_VGContext[ObjId]; + + VCmdIndex = CPC_FSendCmd ( ObjId, + COM_CMD_TYPE_SYS, + COM_CMD_STYPE_SYS_HELLO, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + 4 /* CmdRetSz */, + "Hello world" /* CmdStr */, + NULL /* PtParam */, + 0 /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + VRet = CPC_FGetCmdRes ( ObjId, VCmdIndex, &VPtRes ); + + free ( VPtRes ); + + err_retfail ( VRet, (ERR_OUT,"FGetCmdResfail => return %d", VRet) ); + + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : SInt32 CPC_FUsbCmdListenRq ( SInt8 ObjId ) +Goal : Send the USB listen command. +Inputs : ObjId - object identifier +Ouputs : 0 if ok, negative value if fail. +Globals : +Remark : Should be checked, answer / return value / error code +Level : +Date : 28/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CPC_FUsbCmdListenRq ( SInt8 ObjId ) { + + SInt32 VRet; + SInt32 VCmdIndex; + UInt8* VPtRes; + CPC_TContext* VPt; + + CPC_CHK_OBJ_ID (ObjId); + + VPt = &CPC_VGContext[ObjId]; + + VCmdIndex = CPC_FSendCmd ( ObjId, + COM_CMD_TYPE_SYS, + COM_CMD_STYPE_SYS_USB_LISTEN, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + 4 /* CmdRetSz */, + "Listen request" /* CmdStr */, + NULL /* PtParam */, + 0 /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + VRet = CPC_FGetCmdRes ( ObjId, VCmdIndex, &VPtRes ); + + free ( VPtRes ); + + err_retfail ( VRet, (ERR_OUT,"FGetCmdResfail => return %d", VRet) ); + + err_retok (( ERR_OUT, "" )); +} + +SInt32 CPC_FCUsbCmdDataTrfRq () { + return (0); +} + +SInt32 CPC_FUsbCmdLoadEepromRq () { + return (0); +} + +SInt32 CPC_FUsbCmdLoadEepromExec ( char *SrcSvfFile ) { + return (0); +} + +SInt32 CPC_FCmdUsbLoadEepromAbort () { + return (0); +} + +SInt32 CPC_FUsbCmdLoadEepromDone () { + return (0); +} + +SInt32 CPC_FUsbCmdJtagWriteRq () { + return (0); +} + +SInt32 CPC_FUsbCmdJtagReadRq () { + return (0); +} + + + +/* !!! How to send back debug information from uC to PC ? */ + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_pc.def b/include/pxi_daq_lib_v.2.1/com_pc.def new file mode 100755 index 0000000..9b57125 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_pc.def @@ -0,0 +1,31 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_pc/ +Goal : Constants ( Macros ) definitions of com_pc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef COM_PC_DEF +#define COM_PC_DEF + +#define CPC_OBJ_NB 4 +#define CPC_OBJ_0 0 + +#define CPC_CMD_REC_NB 10 + +#define CPC_CHK_OBJ_ID(ObjId) { \ + if ( ObjId >= CPC_OBJ_NB ) { \ + err_retfail ( -1, (ERR_OUT,"ObjId=%d >= CPC_OBJ_NB=%d", ObjId, CPC_OBJ_NB ) ); \ + } \ +} + + +#define CPC_OBJ_CMD_BLK_SZ 512 +#define CPC_OBJ_CMD_RES_BLK_SZ 512 + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_pc.h b/include/pxi_daq_lib_v.2.1/com_pc.h new file mode 100755 index 0000000..15c417a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_pc.h @@ -0,0 +1,18 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_pc/ +Goal : Functions prototypes of com_pc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef COM_PC_H +#define COM_PC_H + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_pc.typ b/include/pxi_daq_lib_v.2.1/com_pc.typ new file mode 100755 index 0000000..752f17f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_pc.typ @@ -0,0 +1,26 @@ +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_pc/ +Goal : Types definition of com_pc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef COM_PC_TYP +#define COM_PC_TYP + + +typedef struct CPC_TContext { + + SInt32 ComMedia; + SInt32 ComId; + +} CPC_TContext; + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_pc.var b/include/pxi_daq_lib_v.2.1/com_pc.var new file mode 100755 index 0000000..9a2c84f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_pc.var @@ -0,0 +1,20 @@ +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_pc/ +Goal : Variables definition of com_pc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef COM_PC_VAR +#define COM_PC_VAR + + + CPC_TContext CPC_VGContext[CPC_OBJ_NB]; + COM_TCommand* CPC_VGCommandsPt[CPC_OBJ_NB][CPC_CMD_REC_NB]; + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_uc.c b/include/pxi_daq_lib_v.2.1/com_uc.c new file mode 100755 index 0000000..5441949 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_uc.c @@ -0,0 +1,290 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_uc/ +Goal : Functions of com_uc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef COM_UC_C +#define COM_UC_C + +/******************************************************************************* +Prototype : SInt32 CUC_FBegin ( SInt8 ObjId ) +Goal : Initialize com_uc unit, must be called before any other unit function. +Inputs : ObjId - object identifier. +Ouputs : 0 if ok, negative value in case of error. +Globals : +Remark : => doc must be updated +Level : This is a user level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CUC_FBegin ( SInt8 ObjId, SInt32 ComMedia, SInt32 ComId, SInt32 SendBuffSz, PIP_TSendFunc PtSendFunc, SInt32 RecBuffSz, PIP_TGetFunc PtGetFunc ) { + + SInt32 VRet; + CUC_TContext* VPt; + + VPt = &CUC_VGContext[ObjId]; + + CUC_CHK_OBJ_ID (ObjId); + + VPt->ComMedia = ComMedia; + VPt->ComId = ComId; + + VRet = PIP_FBegin ( ObjId, + ComId + 1000, SendBuffSz, PtSendFunc, + ComId, RecBuffSz, PtGetFunc ); + + err_retfail ( VRet, (ERR_OUT,"PIP_FBegin fail => return %d ", VRet) ); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : SInt32 CUC_FEnd ( SInt8 ObjId ) +Goal : Close the com_uc unit ( free mem, ... ), must be called at end of program. +Inputs : ObjId - object identifier +Ouputs : 0 if ok, negative value in cas eof error. +Globals : +Remark : +Level : This is a user level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CUC_FEnd ( SInt8 ObjId ) { + + CUC_TContext* VPt; + + VPt = &CUC_VGContext[ObjId]; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : SInt32 CUC_FPutDatas ( SInt8 ObjId, SInt8 MultiExec, + : UInt8 *PtSrc, SInt32 BlkSz, UInt32 TotSz ) +Goal : Send datas. + : +Inputs : ObjId - object identifier + : MultiExec - if 0 the function will send all datas and return + : - if 1, it will send one block and return, the you need + : - to call it until it returns 1 + : PtSrc - pointer to source buffer + : BlkSz - size of block ( the datas will be splitted ) + : TotSz - total size to send + : +Ouputs : 0 if block send ( MultiExec mode - should not happen otherwise ) + : 1 if end of transaction reached with success + : negative value in case of error +Globals : +Remark : +Level : This is a user level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CUC_FPutDatas ( SInt8 ObjId, SInt8 MultiExec, UInt8 *PtSrc, SInt32 BlkSz, UInt32 TotSz ) { + + SInt32 VRet; + CUC_TContext* VPt; + + CUC_CHK_OBJ_ID (ObjId); + + VPt = &CUC_VGContext[ObjId]; + + VRet = PIP_FPutDatas ( ObjId, MultiExec, PIP_TRANS_MSG_TYPE_DATA, PtSrc, BlkSz, TotSz ); + + return (VRet); +} + +/******************************************************************************* +Prototype : SInt32 CUC_FGetDatas ( SInt8 ObjId, SInt8 MultiExec, + : UInt8 *PtDest, UInt32 MaxDestSz, UInt32* PtGetDataSz ) + : +Goal : Get datas. +Inputs : ObjId - the object identifier + : MultiExec - if 0 the function will read all blocks and return + : - at end of transaction + : - if 1 the function will read one block and return, + : - you will need to call it until it return 1 + : PtDest - the destination buffer pointer + : MaxDestSz - the destination buffer size ( to avoid gardening ... ) + : PtGetTotDataSz - the variable pointed will be set with transaction size + : +Ouputs : The function returns + : 0 if one block received + : 1 if transaction if finished ( last block received ) + : -1 => error + : -2 => there is nothing to read ( no block available ) +Globals : +Remark : +Level : This is a user level function. +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CUC_FGetDatas ( SInt8 ObjId, SInt8 MultiExec, UInt8 *PtDest, UInt32 MaxDestSz, UInt32* PtGetDataSz ) { + + SInt32 VRet; + CUC_TContext* VPt; + + CUC_CHK_OBJ_ID (ObjId); + + VPt = &CUC_VGContext[ObjId]; + + VRet = PIP_FGetDatas ( ObjId, MultiExec, PtDest, MaxDestSz, PtGetDataSz ); + + return (VRet); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : 2 => a data message is ready + : 1 => a command message is ready + : -1 => an error occurs + : -2 => there is nothing to read +Globals : +Remark : +Level : +Date : 13/04/2003 +Doc date : 13/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CUC_FCmdInterpreter ( SInt8 ObjId, char* StrStatus, COM_TCommand** PtPtCmd, UInt8** PtPtData ) { + + COM_TCommand* VPtCommand; + UInt32 VRecSz; + SInt32 VStatus; + SInt32 VMsgType; + SInt32 VRet; + CUC_TContext* VPt; + + CUC_CHK_OBJ_ID (ObjId); + + VPt = &CUC_VGContext[ObjId]; + + VStatus = CUC_FGetDatas ( ObjId, 1 /* MultiExec */, (UInt8*) &CUC_VGRecBuffer[ObjId][0], CUC_REC_BUFF_SZ /* MaxDestSz */, &VRecSz ); + + if ( VStatus == -1 ) { + sprintf ( StrStatus, "Error" ); + err_error (( ERR_OUT, "CPC_FGetDatas fail !" )); + } + + if ( VStatus == -2 ) { + sprintf ( StrStatus, "Nothing to do" ); + return (0); + } + + if ( VStatus == 0 ) { + return (0); + } + + VMsgType = PIP_FGetRecMsgType ( ObjId ); + + if ( VMsgType == PIP_TRANS_MSG_TYPE_DATA ) { + sprintf ( StrStatus, "Data message received" ); + + if ( PtPtData != NULL ) { + *PtPtData = (UInt8*) &CUC_VGRecBuffer[ObjId][0]; + } + + return (2); + } + + if ( VMsgType == PIP_TRANS_MSG_TYPE_COMMAND ) { + + VPtCommand = (COM_TCommand*) &CUC_VGRecBuffer[ObjId][0]; + + if ( PtPtCmd != NULL ) { + *PtPtCmd = VPtCommand; + } + + sprintf ( StrStatus, "Command received - %s", VPtCommand->StrCmd ); + + return (1); + } + + return (0); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 13/04/2003 +Doc date : 13/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +char* CUC_FGetDataPtr ( SInt8 ObjId ) { + + CUC_TContext* VPt; + + if ( ObjId >= CUC_OBJ_NB ) { + err_error (( ERR_OUT, "ObjId=%d >= CUC_OBJ_NB=%d", ObjId, CUC_OBJ_NB )); + return (NULL); + } + + VPt = &CUC_VGContext[ObjId]; + + return ( &CUC_VGRecBuffer[ObjId][0] ); + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 27/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 CUC_FLoadProm () { + return (0); +} + +/* !!! How to send back debug information from uC to PC ? */ + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_uc.def b/include/pxi_daq_lib_v.2.1/com_uc.def new file mode 100755 index 0000000..c6153a6 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_uc.def @@ -0,0 +1,27 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_uc/ +Goal : Constants ( Macros ) definitions of com_uc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef COM_UC_DEF +#define COM_UC_DEF + +#define CUC_OBJ_NB 4 +#define CUC_OBJ_0 0 + +#define CUC_REC_BUFF_SZ (1024*4) + +#define CUC_CHK_OBJ_ID(ObjId) { \ + if ( ObjId >= CUC_OBJ_NB ) { \ + err_retfail ( -1, (ERR_OUT,"ObjId=%d >= CUC_OBJ_NB=%d", ObjId, CUC_OBJ_NB ) ); \ + } \ +} + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_uc.h b/include/pxi_daq_lib_v.2.1/com_uc.h new file mode 100755 index 0000000..52e76fc --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_uc.h @@ -0,0 +1,18 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_uc/ +Goal : Functions prototypes of com_uc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef COM_UC_H +#define COM_UC_H + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_uc.typ b/include/pxi_daq_lib_v.2.1/com_uc.typ new file mode 100755 index 0000000..b2526f4 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_uc.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_uc/ +Goal : Types definition of com_uc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef COM_UC_TYP +#define COM_UC_TYP + + +typedef struct CUC_TContext { + + SInt32 ComMedia; + SInt32 ComId; + + +} CUC_TContext; + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/com_uc.var b/include/pxi_daq_lib_v.2.1/com_uc.var new file mode 100755 index 0000000..192255d --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/com_uc.var @@ -0,0 +1,21 @@ +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/com_uc/ +Goal : Variables definition of com_uc unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef COM_UC_VAR +#define COM_UC_VAR + + + CUC_TContext CUC_VGContext[CUC_OBJ_NB]; + + char CUC_VGRecBuffer[CUC_OBJ_NB][CUC_REC_BUFF_SZ]; + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/daq_lib.c b/include/pxi_daq_lib_v.2.1/daq_lib.c new file mode 100755 index 0000000..fbef6a5 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/daq_lib.c @@ -0,0 +1,1142 @@ +// Include file for linking the whole daq library to PXIeBoardReader +// It is enough to include this file in PXIeBoardReader.c +// along with +// +// Originally written by Gille Claus +// Few additions: +// 2014/10/15, JB: Conditional directives on LIB CONFIGURATIO +// 2014/10/15, JB: addition of global var: VAcqNo, VFrNo, VPtFrame + +/******************************************************************************* +File : X:\prj\unix\read_daq_files\flex_rio_2011\main.c +Goal : Demonstration program for Mi26 Flex RIO DAQ run file loading under Linux +Prj date : 19/02/2011 +File date : 19/02/2011 +Doc date : 19/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +/* ======================= */ +/* Standard C header files */ +/* ======================= */ + + +#define _FILE_OFFSET_BITS 64 // Mandatory for large files ( > 2 GB ) handling + // MUST be set before standard C header files + +#include +#include +#include // types +#include +#include +#include + +/* ========================================= */ +/* Conditional compilation for DAQ sources */ +/* ========================================= */ + +#define ROOT_ROOT // Disable code parts which can't compile under ROOT +#define CC_UNIX // Specify operating system + +#define CC_64B // Mandatory for 64bits machine + +#define INT_MAX 128 + + + + +#define EFRIO_FSBB0 + + +//********************************** +// LIB CONFIGURATION +//********************************** +// Made in the "pxi_daq_lib_config.h" file +//********************************** +// JB 2014/10/15 +// The following include replaces definitions originally done here +#include "pxi_daq_lib_config.h" + +// test to check if configuration in "pxi_daq_lib_config.h" is well done +// (is one of the APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1 variable defined ?) +#ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + #error in pxi_daq_lib_v.1.2 (daq_lib.h) : bad configuration for DATA_FORMAT_CC1 in file include/pxi_daq_lib_config.h + #endif + #endif +#endif + +#ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + #error in pxi_daq_lib_v.1.2 (daq_lib.h) : bad configuration for DATA_FORMAT_CC2 in file include/pxi_daq_lib_config.h + #endif +#endif + +/* ========================================= */ +/* DAQ commun files -> types & constants */ +/* ========================================= */ + + +#include "globals.def" +#include "globals_root.def" +#include "types.def" +#include "types.typ" + +/* ================================================================ */ +/* Definition of WIndows types & constant not available under Linux */ +/* ---------------------------------------------------------------- */ +/* Work like this now = allow to compile program, but should be */ +/* done in a better way later !!!!!!!!! */ +/* ================================================================ */ + +#define HANDLE UInt32 +#define DWORD UInt32 +#define WINAPI +#define LPVOID void* +#define INVALID_HANDLE_VALUE 0xFFFFFFFF + + +/* ========================================= */ +/* Macros needed to compile DAQ sources */ +/* ========================================= */ + +#define EXTERN +#define VAR_STATIC +#define VAR_INIT(x) =x +#define VAR_INIT_A2(x,y) ={x,y} +#define VAR_DCL(Extern,Static,Var) Extern Static Var; +#define VAR_DCL_INIT(Extern,Static,Var,Init) Extern Static Var VAR_INIT (Init); +#define VAR_DCL_INIT_A2(Extern,Static,Var,Init0,Init1) Extern Static Var VAR_INIT_A2 (Init0,Init1); + + +/* ========================================= */ +/* Includes DAQ source files */ +/* ========================================= */ + +// Errors messages logging library interface + +#include "errors.def" +#include "errors.typ" +#include "errors.var" + +// General messages logging library interface + +#include "msg.def" +#include "msg.typ" +#include "msg.var" + +// ASIC library interface + +#include "asic.def" +#include "asic.typ" +#include "asic.var" + +// MAPS library interface + +#include "maps.def" +#include "maps.typ" +#include "maps.var" + +// Time library interface + +#include "time.def" +#include "time.typ" +#include "time.var" + + +// Files library interface + +#include "files.def" +#include "files.typ" +#include "files.var" + + +// Math library interface + +#include "math.def" +#include "math.typ" +#include "math.var" + + + +// Mimosa 26 library interface + +#include "mi26_usr.def" +#include "mi26_usr.typ" + +// Ultimate 1 library interface + +#include "ult1_usr.def" +#include "ult1.def" +#include "ult1_usr.typ" +#include "ult1.typ" + +// FSBB 0 library interface + +#include "fsbb0_usr.def" +#include "fsbb0.def" +#include "fsbb0_usr.typ" +#include "fsbb0.typ" + + +// Eudet flex rio DAQ library interface + +#include "eudet_frio.def" +#include "eudet_frio.typ" +#include "eudet_frio.var" +#include "eudet_frio_usr.def" +#include "eudet_frio_usr.typ" +#include "eudet_frio_usr.var" + +// Libraries C source files + +#include "errors.c" +#include "msg.c" +#include "time.c" +#include "math.c" +#include "files.c" +#include "math.c" + + +#include "eudet_frio_fsbb0.c" +#include "eudet_frio_print.c" + + + +/* ========================== */ +/* Application constants */ +/* ========================== */ + +#define APP_ERR_LOG_FILE "./Results/errors.txt" +#define APP_MSG_LOG_FILE "./Results/msg.txt" + +/* ========================== */ +/* Application macros */ +/* ========================== */ + +#define APP__READ_CR { while ( getchar () != '\n' ); }; + + +/* ============================= */ +/* Application context type */ +/* ============================= */ + + +typedef struct { + + // Parameters + + char ParRunDir[GLB_FILE_PATH_SZ]; // Run directory + char ParFileNamePrefix[20]; // Run file prefix, eg : RUN_666 => RUN_ is the prefix + SInt32 ParRunNo; + + SInt32 ParFrameNbPerAcq; // Nb of frame in the acquisition ( get from run file ) + SInt32 ParAcqNo; // Index of acquisition to select ( get from GUI ) + SInt32 ParFrameNo; // Index of frame to get + + // Intermediate variables + + char InfRunParFile[GLB_FILE_PATH_SZ]; // File which contains run parameters *.par + char InfRunDataFile[GLB_FILE_PATH_SZ]; // File which contains run data *.bin + SInt32 InfMaxFrameSz; // Maximal size of one frame = total size for N Mimosa 26 + + // Results + + SInt8 ResRunLoaded; // Flag indicates run state : -1 not loaded, +1 loaded + + EFRIO__TRunCont ResRunCont; // Run context record = run parameter + additional info + // Loaded from file RUN*.par + + EFRIO__TFrameList ResFramesList; // List of frames + +} APP__TContext; + + +/* ============================= */ +/* Application global variables */ +/* ============================= */ + + +// Error messages logging level ( file errors.txt ) , can be +// - ERR_LOG_LVL_NONE +// - ERR_LOG_LVL_ALL +// - ERR_LOG_LVL_WARNINGS_ERRORS +// - ERR_LOG_LVL_ERRORS + + +SInt32 APP_VGErrFileLogLvl = ERR_LOG_LVL_ALL; // Log level for log file +SInt32 APP_VGErrUserLogLvl = ERR_LOG_LVL_ALL; // Log level for user print function => not used + +// General messages logging level ( file msg.txt ), 127 => log all messages + +SInt32 APP_VGMsgFileLogLvl = 127; // Log level for log file +SInt32 APP_VGMsgUserLogLvl = 127; // Log level for user print function => not used + +// Class to read run file +// - APP__VGRunConfFile for run conf file = RUN*.par +// - APP__VGRunDataFile for run data file = RUN*.bin (data) and RUN*.bin.inf (index file) + +FIL__TCBinFile APP__VGRunConfFile ( "./err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); +FIL__TCStreamFile APP__VGRunDataFile ( "./err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); + + +// Application context record +// - Contains all global variables needed => easier to move to an object +// - Should also include errors and messages log variables ( APP_VGErrFileLogLvl, etc ... ), not done now + +APP__TContext APP__VGContext; + +// Addition for PXIeBoardReader, JB 2014/10/15 +SInt32 VAcqNo; // current acquisition number +SInt32 VFrNo; // current frame number +EFRIO__TFrame* VPtFrame; // pointer to the current frame + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 19/02/2011 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FIsLittleEndian () + : +Goal : Test is CPU is little endian, return 1 in this case, 0 otherwise. + : +Inputs : None + : +Ouputs : The function returns + : 0 - CPU is not little endian + : 1 - CPU is little endian + : +Globals : None + : +Remark : One + : +Level : +Date : 19/02/2011 +Doc date : 19/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FIsLittleEndian () { + + SInt32 VTest = 0x11223344; + char* VPt; + + VPt = (char*) &VTest; + + if ( (VPt[0] == 0x11) && (VPt[1] == 0x22) && (VPt[2] == 0x33) && (VPt[3] == 0x44) ) { + return (0); + } + + else { + return (1); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 19/02/2011 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FPrintRecSzChkAlign ( char* Os ) { + + // In the logfile + // Change Antonin Maire, based on an idea by Gilles Claus, Alejandro Perez (16 oct 2014) + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "= Print records size for alignment checking Windows / Unix =" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "= System = %s ", Os )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "sizeof(int*) = %d", sizeof(int*) )); + msg (( MSG_OUT, "sizeof(int) = %d", sizeof(int) )); + msg (( MSG_OUT, "sizeof(unsigned) = %d", sizeof(unsigned) )); + msg (( MSG_OUT, "sizeof(unsigned int) = %d", sizeof(unsigned int) )); + msg (( MSG_OUT, "sizeof(unsigned long int) = %d", sizeof(unsigned long int) )); + msg (( MSG_OUT, "sizeof(unsigned long) = %d", sizeof(unsigned long) )); + msg (( MSG_OUT, "sizeof(unsigned short) = %d", sizeof(unsigned short) )); + msg (( MSG_OUT, "sizeof(long int) = %d", sizeof(long int) )); + msg (( MSG_OUT, "sizeof(size_t) = %d", sizeof(size_t) )); + msg (( MSG_OUT, "sizeof(uint32_t) = %d", sizeof(uint32_t) )); + msg (( MSG_OUT, "sizeof(uint64_t) = %d", sizeof(uint64_t) )); + msg (( MSG_OUT, "sizeof(int64_t) = %d", sizeof(int64_t) )); + + msg (( MSG_OUT, "sizeof(float) = %d", sizeof(float) )); + msg (( MSG_OUT, "sizeof(double) = %d", sizeof(double) )); + msg (( MSG_OUT, "============================================================\n" )); + msg (( MSG_OUT, "" )); + + msg (( MSG_OUT, "FIL__TCStreamFile_TBlocInf = %d ", sizeof (FIL__TCStreamFile_TBlocInf) )); + msg (( MSG_OUT, "FIL__TCStreamFile_TRecInfFile = %d ", sizeof (FIL__TCStreamFile_TRecInfFile) )); + msg (( MSG_OUT, "EFRIO__TRunCont = %d ", sizeof (EFRIO__TRunCont) )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EFRIO__TFrame = %d ", sizeof (EFRIO__TFrame) )); + msg (( MSG_OUT, "EFRIO__TFrameHeader = %d ", sizeof (EFRIO__TFrameHeader) )); + msg (( MSG_OUT, "EFRIO__TFrameData = %d ", sizeof (EFRIO__TFrameData) )); + msg (( MSG_OUT, "EFRIO__TTriggerRec = %d ", sizeof (EFRIO__TTriggerRec) )); + + msg (( MSG_OUT, "" )); + + // On stdout. + // Change Antonin Maire, based on an idea by Gilles Claus, Alejandro Perez (16 oct 2014) + // Check the size in terms of bytes of the different type on the current system. + // Very important to know, in order to read properly the words of the C struct of the written frame. + // Very likely the writing is done under a Windows 32 bits system, + // while the analysis treatment is done under Mac/Linux 64 bits. + printf("============================================================\n" ); + printf("= Print records size for alignment checking Windows / Unix =\n" ); + printf("------------------------------------------------------------\n" ); + printf("= System = %s ", Os ); + printf("-------------------------------\n" ); + printf("sizeof(int*) = %d \n", sizeof(int*) ); + printf("sizeof(int) = %d \n", sizeof(int) ); + printf("sizeof(unsigned) = %d \n", sizeof(unsigned) ); + printf("sizeof(unsigned int) = %d \n", sizeof(unsigned int) ); + printf("sizeof(unsigned long int) = %d \n", sizeof(unsigned long int) ); + printf("sizeof(unsigned long) = %d \n", sizeof(unsigned long) ); + printf("sizeof(unsigned short) = %d \n", sizeof(unsigned short) ); + printf("sizeof(long int) = %d \n", sizeof(long int) ); + printf("sizeof(size_t) = %d \n", sizeof(size_t) ); + printf("sizeof(uint32_t) = %d \n", sizeof(uint32_t) ); + printf("sizeof(uint64_t) = %d \n", sizeof(uint64_t) ); + printf("sizeof(int64_t) = %d \n", sizeof(int64_t) ); + + printf("sizeof(float) = %d \n", sizeof(float) ); + printf("sizeof(double) = %d \n", sizeof(double) ); + printf("============================================================\n" ); + printf(" "); + + printf("FIL__TCStreamFile_TBlocInf = %d \n", sizeof (FIL__TCStreamFile_TBlocInf) ); + printf("FIL__TCStreamFile_TRecInfFile = %d \n", sizeof (FIL__TCStreamFile_TRecInfFile) ); + printf("EFRIO__TRunCont = %d \n", sizeof (EFRIO__TRunCont) ); + printf("------------------------------------------------------------\n" ); + printf("EFRIO__TFrame = %d \n", sizeof (EFRIO__TFrame) ); + printf("EFRIO__TFrameHeader = %d \n", sizeof (EFRIO__TFrameHeader) ); + printf("EFRIO__TFrameData = %d \n", sizeof (EFRIO__TFrameData) ); + printf("EFRIO__TTriggerRec = %d \n", sizeof (EFRIO__TTriggerRec) ); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) + : +Goal : Load a run file = configure lib for this run but the run is not loaded + : in memory. + : +Inputs : RunDir - Run directory without \ at end + : RunPrefix - Run file prefix, eg : "RUN_" + : RunNo - Run no + : +Ouputs : The function returns + : Number of acquisitions in run file + : -1 if an error occurs + : +Globals : Update APP__VGContext fields + : +Remark : None + : +Level : +Date : 19/02/2011 +Rev : 06/07/2011 + : - Bug fix => VRet is used via a "OR" to cumlate errors and was not set to 0 ! +Doc date : 19/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqNb; + SInt32 VRet = 0; + + + // ----------------------------- + // Reset run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = -1; + + // ----------------------------- + // Set run parameters + // ----------------------------- + + sprintf ( VPtCont->ParRunDir , "%s", RunDir ); + sprintf ( VPtCont->ParFileNamePrefix, "%s", RunPrefix ); + + VPtCont->ParRunNo = RunNo; + + // Calculate run par file & run data file names + + sprintf ( VPtCont->InfRunDataFile, "%s/%s%d.bin", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + sprintf ( VPtCont->InfRunParFile , "%s/%s%d.par", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + + // Print run par file & run data file names for debugging + + msg (( MSG_OUT, "Run data file name = %s", VPtCont->InfRunDataFile )); + msg (( MSG_OUT, "Run par file name = %s", VPtCont->InfRunParFile )); + + + // ----------------------------- + // Read run param file + // ----------------------------- + + // Init & conf TCBinFile class to do the job + + // Fix to adapt the structure size from 32 to 64 bits machine + // Data are taken on a 32 bits processor with EFRIO__TRunCont = 1628 + // However on 64 bits processor, EFRIO__TRunCont = 1758 + // JB 2012/10/16 + SInt32 sizeof_EFRIO__TRunCont = 1628; + + printf(" FLoadRun: reading param file with sizeof_EFRIO__TRunCont %d\n", sizeof_EFRIO__TRunCont); + +// VRet = VRet | APP__VGRunConfFile.PubFConf ( VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont), 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunConfFile.PubFConf ( VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof_EFRIO__TRunCont, sizeof_EFRIO__TRunCont, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + printf(" FLoadRun: After param:PubFConf ret %d\n", VRet); + VRet = VRet | APP__VGRunConfFile.PubFOpen (); + printf(" FLoadRun: After param:PubFOpen ret %d\n", VRet); +// VRet = VRet | APP__VGRunConfFile.PubFSeqRead ( &VPtCont->ResRunCont, sizeof_EFRIO__TRunCont, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont) ); + VRet = VRet | APP__VGRunConfFile.PubFSeqRead ( &VPtCont->ResRunCont, sizeof_EFRIO__TRunCont, sizeof_EFRIO__TRunCont ); + printf(" FLoadRun: After param:PubFSeqRead ret %d\n", VRet); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Load run parameter file = %s failed !", VPtCont->InfRunParFile ) ); + + // ----------------------------- + // Open run data file + // ----------------------------- + + // Init & conf TCStreamFile class to do the job + + printf(" FLoadRun: opening bin file with max_bloc_sz %d\n", EFRIO__MAX_DATA_FILE_BLOC_SZ); + + VRet = VRet | APP__VGRunDataFile.PubFConf ( &APP__VGRunDataFile, 0 /* UseThread */, VPtCont->InfRunDataFile, FIL__TCBinFile_RWB_MODE_READ, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + printf(" FLoadRun: After data:PubFConf ret %d\n", VRet); + VRet = VRet | APP__VGRunDataFile.PubFOpen (); + printf(" FLoadRun: After data:PubFOpen ret %d\n", VRet); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Open run data file %s failed !", VPtCont->InfRunDataFile ) ); + + + // ----------------------------- + // Set run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = 1; + + // ----------------------------- + // Return number of acq in file + // ----------------------------- + + VAcqNb = APP__VGRunDataFile.PubFGetBlocNb (); + + err_retval ( VAcqNb, ( ERR_OUT, "Run %d loaded => Contains %d acquistions", RunNo, VAcqNb ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FAllocAcqBuffer ( ) + : +Goal : Allocates the buffer for one acqusition. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Read informations from APP__VGContext and set pointer to buffer. + : +Remark : None + : +Level : +Date : 19/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FAllocAcqBuffer () { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + + // ---------------------- + // Calculates sizes + // ---------------------- + + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + VPtCont->ResRunCont.InfFrameBuffSz = VPtCont->ResRunCont.ParFrameNbPerAcq * VPtCont->InfMaxFrameSz; + + // ---------------------- + // Print results + // ---------------------- + + msg (( MSG_OUT, "==========================================" )); + msg (( MSG_OUT, "InfMaxFrameSz = %d", VPtCont->InfMaxFrameSz )); + msg (( MSG_OUT, "ResRunCont.InfFrameBuffSz = %d", VPtCont->ResRunCont.InfFrameBuffSz )); + msg (( MSG_OUT, "EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB = %d", EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + msg (( MSG_OUT, "EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ = %d", EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ )); + msg (( MSG_OUT, "==========================================" )); + + + // ---------------------- + // Allocate acq buffer + // ---------------------- + + // Free if already allocated + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + } + + // Try to allocate + + VPtCont->ResRunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->ResRunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->ResRunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->ResRunCont.ParFrameNbPerAcq) ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FFreeAcqBuffer () + : +Goal : Free acquisition buffer + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Read informations from APP__VGContext and set buffer pointer to NULL. + : +Remark : None + : +Level : +Date : 19/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FFreeAcqBuffer ( ) { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Free buffer + // ------------------------------- + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + VPtCont->ResRunCont.PtFrame = NULL; + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : +Goal : Build the frame list for one acquisition + : +Inputs : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : This function is the copy of EFRIO__FBuildFrameListFromAcq for application + : program demo. + : + : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : +Level : +Date : 06/11/2010 +Rev : 19/02/2011 + : - Moved from eudet_fio.c + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) + : +Goal : Load AcqNo in memory + : +Inputs : AcqNo - No of acquisition to load + : PtFrameNb - Pointer to a variable which will be set with frames nb in AcqNo + : - Set it to NULL if you don't need it + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Read information from APP__VGContext. + : +Remark : None. + : +Level : +Date : 19/02/2011 +Rev : 07/03/2011 + : - New " spare W32 info " format +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqInfFormat; + EFRIO__TFileSpareW32Info VAcqInf; + SInt32 VRet; + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + // ----------------------------------- + // Load acquisition in memory + // ----------------------------------- + + // Load from run file + + // Before 07/03/2011 + // VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VFrameNb ); + + VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VAcqInfFormat, sizeof (VAcqInf) / 4 /* MaxSpareW32InfoNb */, (SInt32*) &VAcqInf ); + + err_retfail ( VRet, (ERR_OUT, "Goto acquisition No %d failed !", AcqNo ) ); + + // Build frame list = array of pointer to access frames one by one + + VRet = APP__FBuildFrameListFromAcq ( VAcqInf.TotFrameNb, VPtCont->ResRunCont.PtFrame, &VPtCont->ResFramesList ); + + err_retfail ( VRet, (ERR_OUT,"Build frames list for acquisition No %d failed !", AcqNo ) ); + + // ----------------------------------- + // Update frame nb parameter + // ----------------------------------- + + if ( PtFrameNb != NULL ) { + *PtFrameNb = VAcqInf.TotFrameNb; + } + + err_retok (( ERR_OUT, "Acquisiton No %d loaded in memory - Contains %d frames", AcqNo, VAcqInf.TotFrameNb )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) + : +Goal : Return a pointer to one frame of the acquisition which is loaded in memory. + : +Inputs : FrameIdInAcq - The no of the frame + : +Ouputs : The function returns + : A valid pointer to the frame + : A NULL pointer if the operation failed + : +Globals : Read information from APP__VGContext. + : +Remark : None + : +Level : +Date : 19/02/2011 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) { + + APP__TContext* VPtCont = &APP__VGContext; + EFRIO__TRunCont* VPtRunCont = &VPtCont->ResRunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->ResFramesList; + + + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"No frame=%d in list => Pointer NULL", FrameIdInAcq) ); + } + + return ( VPtFrList->AFramePtr[FrameIdInAcq] ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : int main () +: +Goal : Demonstration function + : - read run + : - move between acquisitions and frames + : - print frames information ( header, data, trigger ) in messages file + : +Inputs : None + : +Ouputs : Always 0 + : +Globals : All + : +Remark : None + : +Level : +Date : 19/02/2011 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +int main () +{ + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VMyVar = 10; + SInt32 VRet = 0; // Variable to store error code of functions called + EFRIO__TFrame* VPtFrame; + SInt32 VAcqNo; + SInt32 VFrNo; + + + /* ----------------------------------------- */ + /* Init application errors messages handling */ + /* ----------------------------------------- */ + + ERR_FBegin ( ( APP_VGErrFileLogLvl != 0 ) /* Enable */, APP_ERR_LOG_FILE ); + ERR_FSetFileLogLevel ( APP_VGErrFileLogLvl ); + ERR_FSetUserLogLevel ( APP_VGErrUserLogLvl ); + // ERR_FSetUserErrorFunc ( APP_FUserErrorFunc ); + + /* ------------------------------------------ */ + /* Init application general messages handling */ + /* ------------------------------------------ */ + + MSG_FBegin ( (APP_VGMsgFileLogLvl != 0) /* Enable */, APP_MSG_LOG_FILE ); + MSG_FSetFileLogLevel ( APP_VGMsgFileLogLvl ); + MSG_FSetUserLogLevel ( APP_VGMsgUserLogLvl ); + // MSG_FSetUserMsgFunc ( APP_FUserMsgFunc ); + + + /* ------------------------------------------ */ + /* Print records sise */ + /* ------------------------------------------ */ + + APP__FPrintRecSzChkAlign ( "Linux" ); + + /* ------------------------------------------ */ + /* Reset application context record */ + /* ------------------------------------------ */ + + memset ( VPtCont, 0, sizeof (APP__TContext) ); + + VPtCont->ResRunLoaded = -1; // No run loaded + + + /* ------------------------------------------ */ + /* Test if CPU is little / big endian */ + /* ------------------------------------------ */ + + printf ( "========================================================= \n" ); + printf ( "Little endian = %d \n", APP__FIsLittleEndian () ); + printf ( "========================================================= \n" ); + + /* ------------------------------------------ */ + /* Error logging macros demo */ + /* ------------------------------------------ */ + + err_trace (( ERR_OUT, "This is a trace message - VMyVar=%d", VMyVar )); + err_warning (( ERR_OUT, "This is a warning message - VMyVar=%d", VMyVar )); + err_error (( ERR_OUT, "This is an error message - VMyVar=%d", VMyVar )); + + /* ------------------------------------------ */ + /* Messages logging macros demo */ + /* ------------------------------------------ */ + + msg (( MSG_OUT, "This is a general message - with default LogLvl = 1 - VMyVar=%d", VMyVar )); + msg (( MSG_OUT, "sizeof (EFRIO__TRunCont) = %d", sizeof (EFRIO__TRunCont) )); + + + // -------------------------------------------------------------- + // Printf records size for alignment checking Unix / Windows + // -------------------------------------------------------------- + + // APP__FPrintRecSzChkAlign ( "Linux" ); + + // ----------------------------- + // Load run + // ----------------------------- + + printf ( "Try to load run \n" ); + + + +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/286000" /* RunDir */, "RUN_" /* RunPrefix */, 286000 /* RunNo */ ); +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/288000" /* RunDir */, "RUN_" /* RunPrefix */, 288000 /* RunNo */ ); +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/286001" /* RunDir */, "RUN_" /* RunPrefix */, 286001 /* RunNo */ ); +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/288001" /* RunDir */, "RUN_" /* RunPrefix */, 288001 /* RunNo */ ); + +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/288001" /* RunDir */, "RUN_" /* RunPrefix */, 288001 /* RunNo */ ); + VRet = APP__FLoadRun ( "/Users/jeromeb/Data/cmos/fsbb/35400" /* RunDir */, "RUN_" /* RunPrefix */, 35400 /* RunNo */ ); + + printf ( "Run loaded => Contains %d acquistions \n", VRet ); + + // -------------------------------------------------------------- + // Printf run context record = run paramters from file RUN*.par + // -------------------------------------------------------------- + + EFRIO__FPrintRunContRec ( &VPtCont->ResRunCont ); + + + // ----------------------------- + // Allocate acquisition buffer + // ----------------------------- + + APP__FAllocAcqBuffer (); + + + + EFRIO__FPrintRunContRec ( &VPtCont->ResRunCont ); // DBG 07/02/14 + + + // ----------------------------- + // Goto acq & print frame record + // ----------------------------- + + VAcqNo = 0; + + while ( VAcqNo >= 0 ) { + + // Print " menu " + + printf ( "\n" ); + printf ( "-------------------------------------------------------------------------- \n" ); + printf ( "Goto acquisition No, Frame No => print record in messages logfile \n" ); + printf ( "Set Acq No & Frame No to -1 in order to exit \n" ); + printf ( "Acquisition No ? " ); + scanf ( "%d", &VAcqNo ); + APP__READ_CR; + printf ( "Frame No ? " ); + scanf ( "%d", &VFrNo ); + APP__READ_CR; + + // User wants to stop frames scanning + + if ( VAcqNo == -1 ) { + break; + } + + // Load acquisition in memory and get pointer on frame + + VRet = APP__FGotoAcq ( VAcqNo /* AcqNo */, NULL /* PtFrameNb */ ); + + VPtFrame = APP__FGetFramePt ( VFrNo /* FrameIdInAcq */ ); + + // Check if frame is available => Jump to menu in case of error + + if ( (VRet < 0) || (VPtFrame == NULL) ) { + printf ( "Goto acquistion %d frame %d failed ! \n", VAcqNo, VFrNo ); + continue; + } + + // Acquistion loaded and frame found + + printf ( "Goto acquisition %d frame %d done => Result in messages logfile \n", VAcqNo, VFrNo ); + + // Print frame record, information type depend on PrintLevel parameter + // You can look at EFRIO__FPrintFrameRec to see how to access to all frame fields + + // PrintLevel - 0 -> Print nothing + // - 1 -> Print AcqId & FrId + // - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + // - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + // - 4 -> Print trigger list + + + EFRIO__FPrintFrameRecFsbb0 ( VPtFrame, 3 /* PrintLevel */ ); + + } // End while (1) + + + // ----------------------------- + // Close run class + // ----------------------------- + + APP__VGRunDataFile.PubFClose (); + APP__VGRunConfFile.PubFClose (); + + + // ----------------------------- + // Free acquisition buffer + // ----------------------------- + + APP__FFreeAcqBuffer (); + + return 0; +} + + + +//--------------------------------------------------------------------------- diff --git a/include/pxi_daq_lib_v.2.1/dbg_log.def b/include/pxi_daq_lib_v.2.1/dbg_log.def new file mode 100755 index 0000000..8cce066 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/dbg_log.def @@ -0,0 +1,69 @@ +/******************************************************************************* +File : x:\lib\win\dbg_log\dbg_log.def +Goal : Macros definition of Windows GUI user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 15/01/2004, but split in files + : .def, .typ, .var, .h, .c was done on 20/02/2005. +Author : Gilles CLAUS +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef DBG_LOG_DEF +#define DBG_LOG_DEF + +#define DBGL_MAX_CHAN_NB 10 +#define DBGL_MSG_SZ MSG_CMT_SZ + +#define DBGL_OUT DBGL_VOutStr + +#ifdef CC_APP_WINDOWS + + #define DBGL_SET_OUTPUT(Memo) { \ + DBGL_FSetOutput ( 0 /* Chan */, Memo ); \ + } \ + + #define log(Msg) DBGL_LOG(Msg) + +#define DBGL_LOG(Msg) { \ +sprintf Msg; \ + DBGL_FGenMsg (0 /* Chan */, 0 /* SendToErr */ ); \ + } \ + +#define DBGL_LOG_CHAN(Chan,SendToErr,Msg) { \ + sprintf Msg; \ + DBGL_FGenMsg ( Chan, SendToErr ); \ + } \ + + + +#else + + + #define DBGL_SET_OUTPUT(Memo) + + #define log(Msg) DBGL_LOG(Msg) + + #define DBGL_LOG(Msg) { \ + \ + sprintf Msg; \ + printf ("%s \n", DBGL_OUT ); \ + } \ + + + #define DBGL_LOG_CHAN(Chan,SendToErr,Msg) DBGL_LOG(Msg) + +#endif + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/dbg_log.typ b/include/pxi_daq_lib_v.2.1/dbg_log.typ new file mode 100755 index 0000000..6ee4651 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/dbg_log.typ @@ -0,0 +1,25 @@ +/******************************************************************************* +File : x:\lib\win\dbg_log\dbg_log.typ +Goal : Types definition of Windows GUI user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 15/01/2004, but split in files + : .def, .typ, .var, .h, .c was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef DBG_LOG_TYP +#define DBG_LOG_TYP + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/dbg_log.var b/include/pxi_daq_lib_v.2.1/dbg_log.var new file mode 100755 index 0000000..937d654 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/dbg_log.var @@ -0,0 +1,31 @@ +/******************************************************************************* +File : x:\lib\win\dbg_log\dbg_log.var +Goal : Variables definition of Windows GUI user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 15/01/2004, but split in files + : .def, .typ, .var, .h, .c was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef DBG_LOG_VAR +#define DBG_LOG_VAR + +#ifdef CC_APP_WINDOWS + EXTERN VAR_STATIC TMemo* DBGL_VGPtMemoOut[DBGL_MAX_CHAN_NB] VAR_INIT_A5(NULL,NULL,NULL,NULL,NULL); +#endif + +EXTERN VAR_STATIC char DBGL_VOutStr[DBGL_MSG_SZ]; + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/errors.c b/include/pxi_daq_lib_v.2.1/errors.c new file mode 100755 index 0000000..d3aff27 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/errors.c @@ -0,0 +1,360 @@ + +/******************************************************************************* +File : x:\lib\com\errors\errors.c +Goal : Implement errors messages print ( screen ) or log ( file ) functions. + : Each function use " errors macros " to log errors and return code. + : +Remark : The way it works is controlled by 3 globals variables + : ERR_VGLogClosed = 0 ( disable ) / 1 ( enable ) errors messages + : ERR_VGLogPath = '/tmp/errors.txt' = path of error logfile + : ERR_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_C +#define ERRORS_C + + +#ifdef CC_APP_OS9 + +char* strerror ( SInt32 errno ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + sprintf ( VMsgStr, "Not avalibale under OS9" ); + + return (VMsgStr); +} + +#endif + +#ifndef CC_APP_WINDOWS + + +char *_strerror ( char* UsrStr ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + #ifdef APP_ROOT + sprintf ( VMsgStr, "%s : No errno str because not supported by ROOT", UsrStr ); + #else + strncpy ( VMsgStr, UsrStr, ERR_USR_MSG_SZ-10 ); + strcat ( VMsgStr, " : " ); + strncat ( VMsgStr, strerror ( errno ), ERR_SYS_MSG_SZ-10 ); + #endif + + + return (VMsgStr); +} + + +#endif + +SInt32 ERR_FEnableLog ( SInt8 Enable ) { + + ERR_VGLogClosed = Enable; + ERR_VGFileLogEnable = Enable; + ERR_VGUserLogEnable = Enable; + + return (0); +} + +SInt32 ERR_EnableLog ( SInt8 Enable ) { + return ( ERR_FEnableLog ( Enable) ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetFileLogEnabled () { + return ( ERR_VGFileLogEnable ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetUserLogEnabled () { + return ( ERR_VGUserLogEnable ); +} + + +SInt32 ERR_FSetLogFilePath ( char* LogFilePath ) { + sprintf ( ERR_VGLogPath, "%s", LogFilePath ); + return (0); +} + +char* ERR_FGetLogFilePath () { + return ( ERR_VGLogPath ); +} + +SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath ) { + ERR_FEnableLog ( Enable ); + ERR_FSetLogFilePath ( FilePath ); + + return (0); +} + + +SInt32 ERR_FEnd () { + return (0); +} + + +SInt32 ERR_FStopLog ( SInt8 Stop ) { + ERR_VGFileDontLog = Stop; + return (0); +} + +/* 11/06/2005 */ + +SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel ) { + ERR_VGFileLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetFileLogLevel () { + return ( ERR_VGFileLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FLogLevel2Str ( SInt8 Lvl ) { + + static char VStr[GLB_CMT_SZ+1]; + + switch ( Lvl ) { + + case ERR_LOG_LVL_NONE : { + sprintf ( VStr, "ERR_LOG_LVL_NONE" ); + break; } + + case ERR_LOG_LVL_ALL : { + sprintf ( VStr, "ERR_LOG_LVL_ALL" ); + break; } + + case ERR_LOG_LVL_WARINGS_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_WARINGS_ERRORS" ); + break; } + + case ERR_LOG_LVL_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_ERRORS" ); + break; } + + default : { + sprintf ( VStr, "Unknow error level = %d", Lvl ); + break; } + + } + + return ( VStr ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetFileLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGFileLogLevel ) ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel ) { + ERR_VGUserLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetUserLogLevel () { + return ( ERR_VGUserLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FGetUserLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGUserLogLevel ) ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetErrLogConfStr () { + + static char VStr[GLB_CMT_SZ+1]; + + sprintf ( VStr, "Error log configuration \n\n - File log enabled = %d \n - File log level = %s \n - File stop log =%d \n - Log file name = %s \n - User log enabled = %d \n - User log level = %s \n - User stop log =%d \n\n", ERR_VGFileLogEnable, ERR_FGetFileLogLevelStr (), ERR_VGFileDontLog, ERR_VGLogPath, ERR_VGUserLogEnable, ERR_FGetUserLogLevelStr (), ERR_VGUserDontLog ); + + return (VStr); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FUserStopLog ( SInt8 Stop ) { + ERR_VGUserDontLog = Stop; + return (0); +} + +/* 10/06/2005 */ + +SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func ) { + + ERR_VGUserErrorFunc = Func; + + return (0); +} + +SInt32 ERR_FGenError ( char MsgType ) { + + static char VErrMsg[ERR_TOT_MSG_SZ]; + + ERR_VGLastErrMsg = VErrMsg; + + /* ERR_VGLogLevel */ + /* == ERR_LOG_LVL_NONE => No log */ + /* == ERR_LOG_LVL_ALL => Log 'T', 'W', 'E' */ + /* == ERR_LOG_LVL_WARINGS_ERRORS => Log 'W', 'E' */ + /* == ERR_LOG_LVL_ERRORS => Log 'E' */ + + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_NONE) && (ERR_VGUserLogLevel == ERR_LOG_LVL_NONE) ) { + return (0); + } + + sprintf ( VErrMsg, "%s%s \n", ERR_VGStrLocationMsg , ERR_OUT ); + + /* File log handling */ + + while (1) { + + if ( ERR_VGFileLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Write error message to file */ + + if ( ERR_VGLogClosed && (ERR_VGLogFile != stdout) && (ERR_VGLogFile != stderr) ) { + ERR_VGLogClosed = 0; + + // + // 29/10/10 => Don't open log file in append mode but overwrite it + // + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + + // 02/06/12 => Enable again open in append mode for strip analysis LIB / DLL debug + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + + + ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); + } + + if ( (ERR_VGFileDontLog == 0) && (ERR_VGLogFile != NULL) ) { + fprintf ( ERR_VGLogFile, VErrMsg ); + fflush ( ERR_VGLogFile ); + } + + break; + } + + /* User log handling */ + + while (1) { + + if ( ERR_VGUserLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Call user error function */ + + if ( (ERR_VGUserDontLog == 0) && (ERR_VGUserErrorFunc != NULL) ) { + ERR_VGUserErrorFunc ( MsgType, ERR_VGStrLocationMsg , ERR_OUT, VErrMsg ); + } + + break; + } + + + + + + + return (0); +} + + + +char* ERR_FGetLastErrMsg () { + + return (ERR_VGLastErrMsg); + +} + + + +void FPrint ( void ) +{ + printf ( "%s \n", VGOut ); +} + + +// 01/03/2012 + +SInt32 ERR_FGetEnumSz () { + + SInt32 VSz; + + typedef enum EEnumTest { FIRST, PREC, NEXT, LAST } TEnumTest; + + VSz = sizeof ( TEnumTest ); + + err_trace (( ERR_OUT, "Enum size = %d Bytes", VSz )); + + return (VSz); +} + + + +//========================================================================================= + + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.2.1/errors.def b/include/pxi_daq_lib_v.2.1/errors.def new file mode 100755 index 0000000..40969a2 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/errors.def @@ -0,0 +1,153 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.def +Goal : Macros definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef ERRORS_DEF +#define ERRORS_DEF + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + + +#ifdef CC_APP_WINDOWS + + #ifndef __FUNCTION__ + + #ifdef CC_COMPILER_CPPB_4 + #define __FUNCTION__ "? Not available" + #endif + + #ifdef CC_COMPILER_CPPB_6 + #define __FUNCTION__ __FUNC__ + #endif + + #endif + +#endif +// ms 24 11 2009 changed size from 100 to 256 +#define ERR_USR_MSG_SZ 256 +#define ERR_SYS_MSG_SZ 256 +#define ERR_TOT_MSG_SZ (ERR_USR_MSG_SZ + ERR_SYS_MSG_SZ) + + +/* 07/04/2007 ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ +/* #define ERR_OUT ERR_VGStrUserMsg */ + + +/* 07/04/2007 - Use a local variable in each function because __FUNCTION__ IS NOT handled by CNT ... */ +/* __LINE__ is replaced by 0 because __LINE__ because ... __LINE__ is not handled file by file ... */ + +#ifdef APP_ROOT + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,VFuncName, 0 /* __LINE__ */ );} +#else + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,__FUNCTION__,__LINE__ );} +#endif + + + +#define ERR_WARNING(Msg) { sprintf Msg; ERR_LOCATION ('W'); ERR_FGenError ('W'); } + +#define ERR_ERROR(Msg) { sprintf Msg; ERR_LOCATION ('E'); ERR_FGenError ('E'); } + +#define ERR_TRACE(Msg) { sprintf Msg; ERR_LOCATION ('T'); ERR_FGenError ('T'); } + + +#define ERR_RET(Code,MsgOk,MsgFail) { \ + if ((Code)<0) ERR_ERROR (MsgFail) \ + else ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_RET_FAIL(Code,MsgFail) { \ + if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (Code); } \ + } + + + +#define ERR_RET_FAIL_NULL(Code,MsgFail) { \ +if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (NULL); } \ + } + + + +#define ERR_RET_NULL(Ptr,MsgFail) { \ +if ((void*)(Ptr)==NULL) { ERR_ERROR (MsgFail) return (-1); } \ + } + + + +#define ERR_RET_OK(MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (0); \ + } + + + +#define ERR_RET_VAL(Code,MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_TYPE_ID(Id) ( 0x5A00 | Id ) + +#define ERR_TYPE_CHK(Pt,TypeId) { \ +if ( *( (UInt16*) (Pt) ) != ERR_TYPE_ID(TypeId) ) { \ + err_retfail ( -1, (ERR_OUT,"Bad type used Type Id = %x MUST be %x => Check the function call parameters in your source code", *( (UInt8*) (Pt) ) , TypeId ) ); \ + } \ + } + + +#define err_trace(Msg) ERR_TRACE(Msg) +#define err_tracel(Lvl,Msg) ERR_TRACE(Msg) +#define err_warning(Msg) ERR_WARNING(Msg) +#define err_error(Msg) ERR_ERROR(Msg) + +#define err_ret(Code,MsgOk,MsgFail) ERR_RET(Code,MsgOk,MsgFail) +#define err_retok(MsgOk) ERR_RET_OK(MsgOk) +#define err_retval(Code,MsgOk) ERR_RET_VAL(Code,MsgOk) +#define err_retfail(Code,MsgFail) ERR_RET_FAIL(Code,MsgFail) +#define err_retfailnull(Code,MsgFail) ERR_RET_FAIL_NULL(Code,MsgFail) +#define err_retnull(Ptr,MsgFail) ERR_RET_NULL(Ptr,MsgFail) + +#define err_typechk(Pt,TypeId) ERR_TYPE_CHK(Pt,TypeId) + +#define PRINT(msg) { sprintf (VGOut, "%s",msg); FPrint (); } +#define RETURN_ERROR(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (FALSE); } +#define RETURN_ERROR_2(msg1,msg2) { sprintf (VGOut, "%s %s",msg1,msg2); FPrint (); return (FALSE); } + +#define RETURN_ERROR_NULL(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (NULL); } +#define RETURN_OK { return (TRUE);} + + + + +#endif + + +// trace (( ERR_OUT, "", par )); +// retfail ( Code, (ERR_OUT,"MsgFail",par) ); +// retnull ( Code, (ERR_OUT,"MsgFail",par) ); // Pointer == NULL => Ret -1 +// error (( ERR_OUT, "", par )); + + diff --git a/include/pxi_daq_lib_v.2.1/errors.h b/include/pxi_daq_lib_v.2.1/errors.h new file mode 100755 index 0000000..5325c9f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/errors.h @@ -0,0 +1,71 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.h +Goal : Functions prototypes definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef ERRORS_H + +#include "func_header.def" + + +#include "errors.def" +#include "errors.typ" + + +FHEAD (SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath );) +FHEAD (SInt32 ERR_FEnableLog ( SInt8 Enable );) +FHEAD (SInt32 ERR_EnableLog ( SInt8 Enable );) +FHEAD (SInt32 ERR_FSetLogFilePath ( char* LogFilePath );) +FHEAD (SInt32 ERR_FStopLog ( SInt8 Stop );) +FHEAD (SInt32 ERR_FGenError ( char MsgType );) +FHEAD (SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func );) +FHEAD (SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel );) +FHEAD (SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel );) + +FHEAD (SInt32 ERR_FGetFileLogEnabled ();) +FHEAD (SInt8 ERR_FGetFileLogLevel ();) +FHEAD (char* ERR_FGetFileLogLevelStr ();) + +FHEAD (SInt32 ERR_FGetUserLogEnabled ();) +FHEAD (SInt8 ERR_FGetUserLogLevel ();) +FHEAD (char* ERR_FGetUserLogLevelStr ();) + +FHEAD (char* ERR_FGetLogFilePath ();) + +FHEAD (char* ERR_FGetErrLogConfStr ();) + + + +#ifndef CC_APP_WINDOWS + FHEAD (char *_strerror ( char* UsrStr );) +#endif + + +FHEAD (void FPrint ( void );) + +// FHEAD (;) + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef ERRORS_H + #define ERRORS_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/errors.txt b/include/pxi_daq_lib_v.2.1/errors.txt new file mode 100755 index 0000000..585a756 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/errors.txt @@ -0,0 +1,73 @@ +0010 #T - main.c - APP__FPrintRecSzChkAlign - 0397 = +0011 #T - main.c - main - 0916 = This is a trace message - VMyVar=10 +0012 #W - main.c - main - 0917 = This is a warning message - VMyVar=10 +0013 #E - main.c - main - 0918 = This is an error message - VMyVar=10 +0014 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFConf - 1402 = +0015 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFOpen - 1645 = +0016 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFSeqRead - 1773 = +0017 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFConf - 2659 = RequestedBlocSz=227008800 - BlocSz=227009024 +0018 #W - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFConf - 2669 = ProParMaxBlocSz=0 must be adjusted -> Set to ProParBlocSz=227009024 +0019 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFConf - 2758 = Info file=/Users/jeromeb/Data/cmos/fsbb/35400/RUN_35400.bin.inf read +0020 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFPrintInfFile - 3031 = +0021 #W - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFConf - 2777 = Requested bloc sz=227008800 <> Info file bloc sz=32727040 => Use Info file bloc sz +0022 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFConf - 2858 = +0023 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFOpen - 3241 = +0024 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFGetBlocNb - 3137 = File /Users/jeromeb/Data/cmos/fsbb/35400/RUN_35400.bin contains 30 blocs +0025 #T - main.c - APP__FLoadRun - 0503 = Run 35400 loaded => Contains 30 acquistions +0026 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_print.c - EFRIO__FPrintRunContRec - 0198 = +0027 #T - main.c - APP__FAllocAcqBuffer - 0578 = +0028 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_print.c - EFRIO__FPrintRunContRec - 0198 = +0029 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFGotoBloc - 3792 = +0030 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFSeqRead - 3634 = +0031 #T - main.c - APP__FBuildFrameListFromAcq - 0709 = +0032 #T - main.c - APP__FGotoAcq - 0782 = Acquisiton No 0 loaded in memory - Contains 1500 frames +0033 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0034 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0035 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0036 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0037 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0038 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0039 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFGotoBloc - 3792 = +0040 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFSeqRead - 3634 = +0041 #T - main.c - APP__FBuildFrameListFromAcq - 0709 = +0042 #T - main.c - APP__FGotoAcq - 0782 = Acquisiton No 1 loaded in memory - Contains 1500 frames +0043 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0044 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0045 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0046 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0047 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0048 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0049 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFGotoBloc - 3792 = +0050 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFSeqRead - 3634 = +0051 #T - main.c - APP__FBuildFrameListFromAcq - 0709 = +0052 #T - main.c - APP__FGotoAcq - 0782 = Acquisiton No 10 loaded in memory - Contains 1500 frames +0053 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0054 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0055 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0056 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0057 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0058 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0059 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFGotoBloc - 3792 = +0060 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFSeqRead - 3634 = +0061 #T - main.c - APP__FBuildFrameListFromAcq - 0709 = +0062 #T - main.c - APP__FGotoAcq - 0782 = Acquisiton No 25 loaded in memory - Contains 1500 frames +0063 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0064 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0065 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0066 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0067 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0068 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0069 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFGotoBloc - 3792 = +0070 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFSeqRead - 3634 = +0071 #T - main.c - APP__FBuildFrameListFromAcq - 0709 = +0072 #T - main.c - APP__FGotoAcq - 0782 = Acquisiton No 25 loaded in memory - Contains 1500 frames +0073 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0074 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0075 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0076 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0077 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0078 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/eudet_frio_fsbb0.c - EFRIO__FSBB0_FMatDiscriPrintHit - 0084 = +0079 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - ProFUpdateIndexTable - 4113 = +0080 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFClose - 4261 = +0081 #T - /Users/jeromeb/Documents/techdoc/daq/fsbb_daq_library_15102014/pxi_daq_lib_v2.1/files.c - PubFClose - 2029 = +0082 #T - main.c - APP__FFreeAcqBuffer - 0620 = diff --git a/include/pxi_daq_lib_v.2.1/errors.typ b/include/pxi_daq_lib_v.2.1/errors.typ new file mode 100755 index 0000000..983ef79 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/errors.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.typ +Goal : Types definition if error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_TYP +#define ERRORS_TYP + +typedef SInt32 (*ERR_TUserErrorFunc) ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ); + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/errors.var b/include/pxi_daq_lib_v.2.1/errors.var new file mode 100755 index 0000000..a0d8944 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/errors.var @@ -0,0 +1,79 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.var +Goal : Variables definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_VAR +#define ERRORS_VAR + + +/* + +EXTERN VAR_STATIC SInt8 ERR_VGLogClosed VAR_INIT (0); // Set to 1 to allow error loggin +EXTERN VAR_STATIC SInt8 ERR_VGFileDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogLevel VAR_INIT (ERR_LOG_LVL_ALL); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogLevel VAR_INIT (ERR_LOG_LVL_ALL); + +EXTERN VAR_STATIC char ERR_VGLogPath[GLB_FILE_PATH_SZ] VAR_INIT ("/dd/tmp/pc/errors.txt"); +EXTERN VAR_STATIC FILE *ERR_VGLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC FILE *ERR_VGTmpLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC SInt32 ERR_VGMsgCnt VAR_INIT (0); +EXTERN VAR_STATIC ERR_TUserErrorFunc ERR_VGUserErrorFunc VAR_INIT (NULL); +EXTERN VAR_STATIC char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ]; +EXTERN VAR_STATIC char ERR_VGStrUserMsg[ERR_TOT_MSG_SZ]; + +EXTERN VAR_STATIC char VGOut[255]; + +*/ + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogEnable , 1); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_VGLogPath[GLB_FILE_PATH_SZ] , "c:\\tmp\\errors.txt"); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGTmpLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt32 ERR_VGMsgCnt , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, ERR_TUserErrorFunc ERR_VGUserErrorFunc , NULL); +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ] ); + +/* 07/04/2007 - ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ + +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + +VAR_DCL ( EXTERN, VAR_STATIC, char VGOut[255] ); + +// 21/12/2010 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char *ERR_VGLastErrMsg, "NULL"); + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio.c b/include/pxi_daq_lib_v.2.1/eudet_frio.c new file mode 100755 index 0000000..a8994ce --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio.c @@ -0,0 +1,13478 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr + +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_C +#define EUDET_FRIO_C + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: Acquisition size if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 15/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FCpyAcq ( UInt8* PtDest, SInt32 MaxDestSz, SInt32 AcqSz ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + UInt32* VPtDest; + SInt32 VTotSz; + + // Check destination buffer + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + // Calculate total size + // = AcqSz + 4 because first W32 is used to store size of acquistion + + VTotSz = AcqSz + 4; + + // Test buffer size + + if ( VTotSz > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Destination buffer is too small => VTotSz=%d > MaxDestSz=%d", VTotSz, MaxDestSz ) ); + } + + // ----------------------------------------------- + // Copy data + // ----------------------------------------------- + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Add size on first elt + + VPtDest = (UInt32*) PtDest; + + *VPtDest = VTotSz; + + ++VPtDest; + + // Copy + + memcpy ( VPtDest, VPtRun->PtFrame, AcqSz ); + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotSz); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : MapsName - Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 +Rev : 11/05/2011 + : - Handle version information -> majour, minor, comment + : + : 12/05/2011 + : - JTAG version Mi26 / Ult1 handling + : + : 19/05/2011 + : - Dma host size calculated for Ultimate because we don't know at this step which + : MAPS will be used and memory size for Ultimate is > the one for Mimosa 26 + : + : 25/05/2011 + : - Renamed in EFRIO__FBeginExt + : - Add parameter MapsName + : - Create a new EFRIO__FBegin (...) which call EFRIO__FBeginExt ( ASIC__MI26, ... ) + : This will keep compatibility with previous sw (EUDET), because EFRIO__FBegin call + : will configure Mimosa 26 as ASIC as it was done for first version of EUDET library. + : + : 28/09/2011 + : - Update code because EFRIO_VGJtagMi26.get_Info (...) has changed => returns one more param = SW version now + : + : 26/03/2013 + : - Add EFRIO__USR_VGContext.ParCrIndexFile handling + : + : 29/10/2013 - Lib V3.0 + : - Add COM SPI interface to clk dirstib board SP + : - ONLY on version V3.0 defined by CC => EFRIO__V30 in the DLL cpp file + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + SInt32 VRet; + SInt8 VEnableErrLog; + SInt8 VEnableMsgLog; + WideString VWsJtagStatus; + WideString VWsSwVersion; + +#ifdef EFRIO__INCLUDE_PARA_PORT + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // Select JTAG Mi26 or Ultimate + + switch ( MapsName ) { + + case ASIC__MI26 : { + EFRIO__VGJtagChip = EFRIO__JTAG_MI26; // 0 => Mi26, 1 => Ultimate + break; } + + case ASIC__ULT1 : { + EFRIO__VGJtagChip = EFRIO__JTAG_ULT1; // 0 => Mi26, 1 => Ultimate + break; } + + case ASIC__FSBB0:{ + EFRIO__VGJtagChip = EFRIO__JTAG_FSBB0; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + }/* end switch MapsName */ + +#endif + + // Reset lib context record => Set all field to 0 + // BUT ! Set CmdRun to -1 + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + VPtCont->RunCont.CmdRun = -1; + + // Set version information ( only for version >= 2.0 ) + + #ifdef EFRIO__V20_AND_LATER + + #ifdef EFRIO__V20 + VPtCont->VersionMajor = 2; + VPtCont->VersionMinor = 0; + + sprintf ( VPtCont->VersionCmt, "Extension of V1.0 to Ultimate 1" ); + #endif + + // 28/10/13 + + #ifdef EFRIO__V30 + VPtCont->VersionMajor = 3; + VPtCont->VersionMinor = 0; + + sprintf ( VPtCont->VersionCmt, "Extension of V2.0 to SALAT (COM interface / SPI clk distri)" ); + #endif + + + #endif + + + // Conf errors logging + + VEnableErrLog = ( ErrorLogLvl != 0 ); + + VRet = ERR_FBegin ( VEnableErrLog, ErrorLogFile ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FBegin failed !" ) ); + + VRet = ERR_FSetFileLogLevel ( ErrorLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FSetFileLogLevel failed !" ) ); + + // Conf messages logging + + VEnableMsgLog = ( MsgLogLvl != 0 ); + + VRet = MSG_FBegin ( VEnableMsgLog, MsgLogFile ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FBegin failed !" ) ); + + VRet = MSG_FSetFileLogLevel ( MsgLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FSetFileLogLevel failed !" ) ); + + // Init // port + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FBegin ( VEnableErrLog, ErrorLogFile ); + PPO_FOpen ( 0x378 /* BaseAdr */, 0 /* Id */ ); + PPO_FEnableReadDataOutPortBeforeWrite ( 0 /* Id */, 1 /* Enable */ ); + #endif + + // Set default values to first board conf in order to get DmaHostSize initialized BEFORE fw loading + + VPtBoard->AsicNb = EFRIO__MAX_ASIC_NB; // Max possible number + VPtBoard->FrameNbPerAcq = EFRIO__MAX_FRAME_NB_PER_ACQ; // "Nominal" value + + // DMA host size is the memory size allocated for DMA on CPU side + // It must be equal AT LEAST to the size of one acquisition and higher value are not useful + // VPtBoard->AsicNb + 1 => + 1 for extra channel + + // 25/05/2011 => Calculate DMA host size in function of ASIC name + + switch ( MapsName ) { + + case ASIC__MI26 : { + VPtBoard->DmaHostSz = ((MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + + case ASIC__ULT1 : { + VPtBoard->DmaHostSz = ((ULT1__ZS_FFRAME_MODE_2X160MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + case ASIC__FSBB0 : { + VPtBoard->DmaHostSz = 0;//((FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + + + // Set default values of Header & Trailer for DQ emulation + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x8000800; + + VPtAcqEmul->ParATrailer[0] = 0xAAAAAAAA; + VPtAcqEmul->ParATrailer[1] = 0xBBBBBBBB; + VPtAcqEmul->ParATrailer[2] = 0xCCCCCCCC; + VPtAcqEmul->ParATrailer[3] = 0xDDDDDDDD; + VPtAcqEmul->ParATrailer[4] = 0xEEEEEEEE; + VPtAcqEmul->ParATrailer[5] = 0xFFFFFFFF; + + +#ifdef EFRIO__INCLUDE_JTAG + + +#ifdef OLD_COM_JTAG_CODE + + // Init JTAG + + if( ! EFRIO_VGJtagMi26.IsBound()) { + OleCheck(CoMI26MasterConf::Create(EFRIO_VGJtagMi26)); + } + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + // Init JTAG end + + +#else + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + + switch (EFRIO__VGJtagChip){ + case EFRIO__JTAG_MI26:{ + VHrComErr = CoMI26MasterConf::Create( EFRIO_VGJtagMi26 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + // 28/09/2011 + // => Update code because EFRIO_VGJtagMi26.get_Info (...) has changed => returns one more param = SW version now + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsSwVersion, &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => Version %s - Status %s", TOOLS__FWideString2CStr (VWsSwVersion, NULL, 0), TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + break; + } + case EFRIO__JTAG_ULT1:{ + VHrComErr = CoMI28COM::Create( EFRIO_VGJtagUlt1 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI28COM::Create failed !" ) ); + } + + if ( EFRIO_VGJtagUlt1.IsBound () ) { + OleCheck ( EFRIO_VGJtagUlt1.Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + break; + } + case EFRIO__JTAG_FSBB0:{ + VHrComErr = CoFSBBM0COM::Create( EFRIO_VGJtagFsbb0 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI28COM::Create failed !" ) ); + } + + if ( EFRIO_VGJtagFsbb0.IsBound () ) { + OleCheck ( EFRIO_VGJtagFsbb0.Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + break; + } + + } + + + + + // Init JTAG end + +#endif + + + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + +#ifdef EFRIO__V30 + SPICD_FBegin ( (SInt8) ErrorLogLvl, ErrorLogFile ); + SPICD_FStartCom (); + Sleep ( 1000 ); + SPICD_FSendConf (); + Sleep ( 1000 ); + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); // Stop clock +#endif + + VPtCont->InfInitDone = 0; + + +#ifndef EFRIO__V20_AND_LATER + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "EUDET Flex RIO DLL compiled on %s at %s", __DATE__, __TIME__ )); + err_error (( ERR_OUT, "******************************************************************" )); + +#else + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "- EUDET Flex RIO DLL V%d.%d compiled on %s at %s", VPtCont->VersionMajor, VPtCont->VersionMinor, __DATE__, __TIME__ )); + err_error (( ERR_OUT, "------------------------------------------------------------------" )); + err_error (( ERR_OUT, "%s", VPtCont->VersionCmt )); + + err_error (( ERR_OUT, "------------------------------------------------------------------" )); + err_error (( ERR_OUT, "Max Acq Nb = %d", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE )); + err_error (( ERR_OUT, "------------------------------------------------------------------" )); + + + #ifdef EFRIO__FREE_MI26_NB + err_error (( ERR_OUT, "----------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! Mi26 number is free ( mode EUDET 2 & EUDET 3 ) = Not limited to 1, 5, 6, 8" )); + err_error (( ERR_OUT, "! BUT current implementation will slow down acquisition !" )); + #else + err_error (( ERR_OUT, "----------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! Mi26 number can be ONLY 1, 5, 6, 8" )); + err_error (( ERR_OUT, "! Because data demultiplexing is hard coded, in order to achieve the shortest execution time" )); + #endif + + + #ifdef EFRIO__CREATE_INDEX_FILE + + if ( VPtUsrCont->ParCrIndexFile ) { + err_error (( ERR_OUT, "" )); + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! Index file (needed for DUT DAQ interface) is ENABLED by line cmd param !" )); + err_error (( ERR_OUT, "! It will slow down the acquisition !" )); + err_error (( ERR_OUT, "! Maximum trigger rate (6 x Mimosa 26 saturated) without loosing frames : !" )); + err_error (( ERR_OUT, "! - Saving data on RAID => FTrig max = 1 KHz !" )); + err_error (( ERR_OUT, "! - Saving data on CPU disk => FTrig max ~ 500 Hz !" )); + } + + else { + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! Index file (needed for DUT DAQ interface) is DISABLED by line cmd param !" )); + err_error (( ERR_OUT, "! Maximum trigger rate (6 x Mimosa 26 saturated) without loosing frames : !" )); + err_error (( ERR_OUT, "! - Saving data on RAID => FTrig max > 8 KHz (100 KHz & 1 MHz tested) !" )); + err_error (( ERR_OUT, "! - Saving data on CPU disk => FTrig max ~ 500 Hz !" )); + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + } + + + + #else + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "! This DAQ version DOESN'T create the index file needed for DUT DAQ interface !" )); + err_error (( ERR_OUT, "! Maximum trigger rate (6 x Mimosa 26 saturated) without loosing frames : !" )); + err_error (( ERR_OUT, "! - Saving data on RAID => FTrig max > 8 KHz (100 KHz & 1 MHz tested) !" )); + err_error (( ERR_OUT, "! - Saving data on CPU disk => FTrig max ~ 500 Hz !" )); + err_error (( ERR_OUT, "-------------------------------------------------------------------------------" )); + #endif + + + err_error (( ERR_OUT, "******************************************************************" )); + +#endif + + msg (( MSG_OUT, "EFRIO__FBeginExt end" )); + + err_retok (( ERR_OUT, "end" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 +Rev : 11/05/2011 + : - Handle version information -> majour, minor, comment + : + : 12/05/2011 + : - JTAG version Mi26 / Ult1 handling + : + : 19/05/2011 + : - Dma host size calculated for Ultimate because we don't know at this step which + : MAPS will be used and memory size for Ultimate is > the one for Mimosa 26 + : + : 25/05/2011 + : - Body of function is " empty " => it has been moved in EFRIO__FBeginExt (...) + : - Call EFRIO__FBeginExt ( ASIC__MI26, ... ) + : - EFRIO__FBeginExt (...) handles MapsName parameter ( Mi26 / Ultimate / ... ) + : EFRIO__FBegin still configure Mimosa 26 as it was done in first version of lib. + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + err_error (( ERR_OUT, "TRACE => Init done" )); + + return ( EFRIO__FBeginExt ( ASIC__FSBB0, ErrorLogLvl, ErrorLogFile, MsgLogLvl, MsgLogFile ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEnd () + : +Goal : Terminate lib + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 05/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEnd () { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FEnd (); + #endif + + // Close JTAG COM classe + // Avoid "assertion message" when LabView is stop and then restarted + + err_error (( ERR_OUT, "1" )); + +#ifdef EFRIO__INCLUDE_JTAG + + + // JTAG Mi26 + + if ( EFRIO__VGJtagChip == 0 ) { + EFRIO_VGJtagMi26.Unbind(); + } + + else { + EFRIO_VGJtagUlt1.Unbind(); + } + + +#endif + + +#ifdef EFRIO__V30 + SPICD_FEnd (); +#endif + + // Free frames buffer if allocated + + err_error (( ERR_OUT, "2" )); + + if ( VPtCont->RunCont.PtZsFFrameRaw !=NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + // Reset context record + + err_error (( ERR_OUT, "3" )); + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : +Goal : Build the frame list for one acquisition + : +Inputs : AcqStatus - ACquisition status ( < 0 -> HW error, 0 -> OK, > 0 -> Frame nb lost ) + : TrigStatus - No meaning now, reserved for future use + : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : +Level : +Date : 06/11/2010 +Rev : 24/02/2011 + : - Add parameters AcqStatus, TrigStatus to field new fields of EFRIO__TFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->AcqStatus = AcqStatus; + PtList->TrigStatus = TrigStatus; + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) + : +Goal : Init DAQ emulation either in standalone DAQ emulation application ( without + : HW ) or in LabView DAQ application. Selection done by RunInLabview parameter. + : +Inputs : RunInLabview = 0 => Run in C++ Builder DAQ emulation application + : = 1 => Run in Labview DAQ + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : If emulation is running under Labview ( RunInLabview = 1 ), frames emulation + : function overwite memory already allocated for Flew RIO board. In case emulation + : is runing in a standalone application ( RunInLabview = 0 ), this function allocates + : memory in PC DRAM to emulate Flex RIO RAM. + : + : This function sets default values of DAQ emulation parameters. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// RunInLabview = 0 => Run in C++ Builder DAQ emulation application +// RunInLabview = 1 => Run in Labview DAQ + +SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + // Reset context records + + memset ( VPtAcqEmul, 0, sizeof (EFRIO__TAcqEmul) ); + + memset ( VPtFrChk , 0, sizeof (EFRIO__TFrCheck) ); + + // Set default value of DAQ emulation parameters => Mainly for Labview which will not control all of them + + VPtAcqEmul->ParAcqCycleMs = 200; + VPtAcqEmul->ParEmuleDRamReadMs = 0; + VPtAcqEmul->ParEmuleFunctNo = 0; + VPtAcqEmul->ParRandomDataSz = 0; + VPtAcqEmul->ParSetMaxDataSzOnOneMaps = 1; + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x80008006; + + VPtAcqEmul->ParATrailer[0] = 0xAAAA0001; + VPtAcqEmul->ParATrailer[1] = 0xAAAA0002; + VPtAcqEmul->ParATrailer[2] = 0xAAAA0003; + VPtAcqEmul->ParATrailer[3] = 0xAAAA0004; + VPtAcqEmul->ParATrailer[4] = 0xAAAA0005; + VPtAcqEmul->ParATrailer[5] = 0xAAAA0006; + + VPtAcqEmul->ParTrigNbPerFrame = 0; + VPtAcqEmul->ParTrigOnOneFrameOverN = 1; + VPtAcqEmul->ParTrigOnNConsecutiveFrames = 1; + + VPtAcqEmul->ParATrig[0] = 10; + VPtAcqEmul->ParATrig[1] = 20; + VPtAcqEmul->ParATrig[2] = 30; + VPtAcqEmul->ParATrig[3] = 40; + + VPtAcqEmul->ParATS[0] = 100; + VPtAcqEmul->ParATS[1] = 200; + VPtAcqEmul->ParATS[2] = 300; + VPtAcqEmul->ParATS[3] = 400; + + + // Set Mi26 nb + + VPtFrChk->InfMi26Nb = VPtRunCont->ParMi26Nb; + + // Extra channel or not ? + + if ( (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtAcqEmul->InfExtraChan = 1; + } + + else { + VPtAcqEmul->InfExtraChan = 0; + } + + if ( RunInLabview == 0 ) { + + // Calculate DRAM size + + VPtAcqEmul->InfDRamSz = (VPtRunCont->ParMi26Nb + VPtAcqEmul->InfExtraChan) * VPtRunCont->ParFrameNbPerAcq * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 4; + + VPtAcqEmul->InfDRamSzMb = VPtAcqEmul->InfDRamSz / (1024 * 1024); + + // Alloc RAM to emulate Flex RIO DRAM + + VPtAcqEmul->InfDRamPtr = (UInt32*) malloc ( VPtAcqEmul->InfDRamSz ); + + err_retnull ( VPtAcqEmul->InfDRamPtr, (ERR_OUT,"Allocation of %d bytes for Flex RIO DRAM emulation failed !", VPtAcqEmul->InfDRamSz) ); + + } // End if ( RunInLabview == 0 ) + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleEnd ( ) + : +Goal : Terminate DAQ emulation + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Free DRAM if allocated in PC to emulate Flex RIO DRAM. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEmuleEnd ( ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + if ( VPtAcqEmul->InfDRamPtr != NULL ) { + free ( VPtAcqEmul->InfDRamPtr ); + } + + err_retok (( ERR_OUT, "" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) + : +Goal : Emulate Flex RIO DRAM read + : +Inputs : Cmd - 0 => Do nothing + : - 1 => Fill memory with zero + : +Ouputs : A pointer to DRAM or NULL if not allocated + : +Globals : + : +Remark : A delay should also be added here later to emulate Flex RIO DRAM access time + : configured by field ParEmuleDRamReadMs of EFRIO__TAcqEmul. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + + + if ( Cmd == 1 ) { + memset ( VPtAcqEmul->InfDRamPtr, 0, VPtAcqEmul->InfDRamSz ); + } + + Sleep ( VPtAcqEmul->ParEmuleDRamReadMs ); + + return ( VPtAcqEmul->InfDRamPtr ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) + : +Goal : Used for DAQ emulation. + : Set the FrameId fields ( TLU & Flex RIO triggers ) of all triggers info in + : the record used to emulate triggers + : +Inputs : FrameId - The value of frame id to set in all triggers info + : TrigNb - The number of trigger info to set in record + : PtRec - Pointer to destination record + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : The field set are + : - for TLU trigger => F.FrameIdInAcq ( see record EFRIO__TTluTrigger in *.typ ) + : - for Flex RIO trigger => F.Mi26Frame ( see record EFRIO__TFlexRioTimeStamp1 in *.typ ) + : +Level : +Date : 03/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) { + + SInt32 ViTrig; + EFRIO__TTluTrigger* VPtTrig; + EFRIO__TFlexRioTimeStamp1* VPtTs; + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + if ( TrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"TrigNb=%d > Max=%d", TrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) ); + } + + for ( ViTrig=0; ViTrig < TrigNb; ViTrig++ ) { + + VPtTrig = (EFRIO__TTluTrigger*) &PtRec->ATrig[2 * ViTrig]; + VPtTs = (EFRIO__TFlexRioTimeStamp1*) &PtRec->ATrig[(2 * ViTrig)+1]; + + VPtTrig->F.FrameIdInAcq = FrameId; + VPtTs->F.Mi26Frame = FrameId; + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) + : +Goal : Function used to avoid data copy while transfering data from one Vi to + : another under Labview. Because sometimes, it seems that Labview use pointers + : but it's not the case, a copy of data is done, and execution time is lost ... + : +Inputs : CmdGetPtrCpyAlloc = 0 => return buffer pointer + : = 1 => store PtSrcW32 but NO copy of data + : = 2 => copy src to buffer + : = 3 => alloc buffer + : + : AllocW32Sz - Memory size to alloc in W32 ( if CmdGetPtrCpyAlloc = 3 ) + : PtSrcW32 - Pointer to source data to copy to buffer + : SrcW32Sz - Size of source data to copy to buffer + : +Ouputs : A pointer on the buffer or NULL if not allocated. + : +Globals : + : +Remark : It's mainly used to passe a pointer on board DRAM to DLL ( CmdGetPtrCpyAlloc = 1 ) + : +Level : +Date : 07/09/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) { + + static UInt32* VPtBuff = NULL; + static UInt32 VAllocW32Sz = 0; + UInt32 VAllocSz; + SInt32 Vi; + + // Get pointer request + + if ( CmdGetPtrCpyAlloc == 0 ) { + return (VPtBuff); + } + + // Store pointer request + + if ( CmdGetPtrCpyAlloc == 1 ) { + VPtBuff = PtSrcW32; + return (VPtBuff); + } + + // Copy request + + if ( CmdGetPtrCpyAlloc == 2 ) { + + if ( (VPtBuff == NULL) || (SrcW32Sz > VAllocW32Sz) ) { + err_error (( ERR_OUT, "VPtBuff = %x = NULL ? / SrcW32Sz=%d > VAllocW32Sz=%d", VPtBuff, SrcW32Sz, VAllocW32Sz )); + return (NULL); + } + + for ( Vi=0; Vi < SrcW32Sz; Vi++ ) { + VPtBuff[Vi] = PtSrcW32[Vi]; + } + + return (VPtBuff); + } + + + // Allocation request + + if ( CmdGetPtrCpyAlloc == 3 ) { + + // Free mem if already allocated + + if ( VPtBuff != NULL ) { + free ( VPtBuff ); + VPtBuff = NULL; + } + + // Alloc new mem + + VAllocW32Sz = AllocW32Sz; + VAllocSz = VAllocW32Sz * 4; + + VPtBuff = (UInt32*) malloc ( VAllocSz ); + + // If allocation failed => error message + ret NULL + + if ( VPtBuff == NULL ) { + err_error (( ERR_OUT, "Allocation of %d bytes failed !", VAllocSz )); + return (NULL); + } + + // If allocation OK => ret buffer pointer + + return (VPtBuff); + } + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 + : EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : Mi26Nb - Mimosa 26 number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 => Creation with all job done in function body + : +Rev : 12/05/2011 + : - Code moved to EFRIO__FConfRunExt (...) + : - Call EFRIO__FConfRunExt ( ASIC__MI26, ... ) + : + : +Doc date : 12/05/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent, char* JtagFileName ) { + + SInt32 VRet; + + VRet = EFRIO__FConfRunExt ( ASIC__FSBB0, Mi26Nb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DataTransferMode, TrigMode, DestDir, FileNamePrefix, SaveToDisk, SendOnEth, SendOnEthPCent, JtagFileName ); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, + : SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : MapsName - Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + : MapsNb - MAPS number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 -> Creation of EFRIO__FConfRun (...) + : 12/05/2011 -> Change name from EFRIO__FConfRun to EFRIO__FConfRunExt and add MapsName parameter + : See " Rev 12/05/2011 " + ; + : +Rev : 04/11/2010 + : - Save to disk + : + : 21/02/2011 + : - Set new fields ( ParDaqVersion, ParMapsName ) + : + : 12/05/2011 + : - A new parameter MapsName must be added, in order to keep compatibility with EUDET lib : + : -> This function has been renamed EFRIO__FConfRunExt ( it was EFRIO__FConfRun before ) + : -> The new parameter MapsName had been added + : -> The former EFRIO__FConfRun call now EFRIO__FConfRunExt with MapsName param = ASIC__MI26 + : + : 10/07/2012 + : - Run index file path creation + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent, char* JtagFileName ) { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + SInt32 VMaxFrameSz; + SInt32 VRet; + + + // Check function parameters + + err_retnull ( DestDir , (ERR_OUT,"Abort : DestDir == NULL !") ); + err_retnull ( FileNamePrefix, (ERR_OUT,"Abort : FileNamePrefix == NULL !") ); + + // Debug print function parameters + + err_error (( ERR_OUT, "Call with : MapsNb=%d - RunNo=%d - TotEvNb=%d - EvNbPerFile=%d - FrameNbPerAcq=%d - DestDir=%s - FileNamePrefix=%s", MapsNb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DestDir, FileNamePrefix )); + + // Set hard coded parameters + + VPtCont->RunCont.ParMeasDataRate = 1; // Enable data rate measurement + VPtCont->RunCont.ParAcqNbToMeasDataRate = 10; // Uses 10 acquistions to measure data rate + + // Set default values to new fields + + VPtCont->RunCont.ParDaqVersion = 0; + + // Copy run parameters to run context record + + VPtCont->RunCont.ParMapsName = MapsName; + VPtCont->RunCont.ParMi26Nb = MapsNb; + VPtCont->RunCont.ParRunNo = RunNo; + VPtCont->RunCont.ParTotEvNb = TotEvNb; + VPtCont->RunCont.ParEvNbPerFile = EvNbPerFile; + VPtCont->RunCont.ParFrameNbPerAcq = FrameNbPerAcq; + VPtCont->RunCont.ParDataTransferMode = DataTransferMode; + VPtCont->RunCont.ParTrigMode = TrigMode; + + VPtCont->RunCont.ParSaveOnDisk = SaveToDisk; + VPtCont->RunCont.ParSendOnEth = SendOnEth; + VPtCont->RunCont.ParSendOnEthPCent = SendOnEthPCent; + + sprintf ( VPtCont->RunCont.ParDestDir , "%s", DestDir ); + sprintf ( VPtCont->RunCont.ParFileNamePrefix, "%s", FileNamePrefix ); + sprintf ( VPtCont->RunCont.ParJtagFileName , "%s", JtagFileName ); + + + + sprintf ( VPtCont->RunCont.InfDataFileName , "%s\\%s%d.bin" , VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + #ifdef EFRIO__CREATE_INDEX_FILE + if ( VPtUsrCont->ParCrIndexFile ) { + sprintf ( VPtCont->RunCont.InfIndexFileName, "%s\\%s%d_index.bin", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + } + #endif + + sprintf ( VPtCont->RunCont.InfConfFileName, "%s\\%s%d.par", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + VPtCont->RunCont.InfSaveDataOnDiskRunning = 0; + + // Compare run conf paramters to the max parameters used to calculate DmaHostSz in FBegin + // If they have higher values => DmaHostSz send to board at fw loading is bad => Abort + + if ( (VPtCont->RunCont.ParMi26Nb > EFRIO__MAX_ASIC_NB) || (VPtCont->RunCont.ParFrameNbPerAcq > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_error (( ERR_OUT, "Bad Mi26 nb ? Run conf = %d - Max = %d", VPtCont->RunCont.ParMi26Nb, EFRIO__MAX_ASIC_NB )); + err_error (( ERR_OUT, "Bad frame nb per acq ? Run conf = %d - Max = %d", VPtCont->RunCont.ParFrameNbPerAcq, EFRIO__MAX_FRAME_NB_PER_ACQ )); + err_retfail ( -1, (ERR_OUT,"Abort : Bad value of AsicNb=%d or FrameNbPerAcq=%d", VPtCont->RunCont.ParMi26Nb, VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // Update monitor context fields + + VPtCont->MonCont.InfFrameNbToSend = (SInt32) ( (float) FrameNbPerAcq * (float) ( (float) SendOnEthPCent / (float) 100 )); + + VPtCont->MonCont.InfSzToSend = 0; // Because it's not known at this step + + err_error (( ERR_OUT, "TRACE => InfFrameNbToSend = %d", VPtCont->MonCont.InfFrameNbToSend )); + + // Overwrite default values of AsicNb & FrameNbPerAcq + + VPtBoard->AsicNb = VPtCont->RunCont.ParMi26Nb; + VPtBoard->FrameNbPerAcq = VPtCont->RunCont.ParFrameNbPerAcq; + + // DMA host size => Already initialized in FBegin function + // VPtBoard->DmaHostSz = (MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * VPtBoard->AsicNb * VPtBoard->FrameNbPerAcq) / (1024 * 1024); + + // Configure others board conf parameters + + VPtBoard->BoardId = 0; + // 30/09/2014 - MS : changed the setting of the AsicName + switch ( MapsName ) { + + case ASIC__MI26 : { + sprintf ( VPtBoard->AsicName, "%s", "Mimosa 26" ); + VPtBoard->DataClkFrequency = 80; // 80 MHz + break; } + + case ASIC__ULT1 : { + sprintf ( VPtBoard->AsicName, "%s", "Ultimate 1" ); + VPtBoard->DataClkFrequency = 80; // 80 MHz + break; } + + case ASIC__FSBB0:{ + sprintf ( VPtBoard->AsicName, "%s", "FSBB 0" ); + VPtBoard->DataClkFrequency = 160; // 160 MHz + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + }/* end switch MapsName */ + + VPtBoard->ReadoutMode = 0; // Reserved for future use + + if ( (DataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (DataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtBoard->EnableExtraChannel = 1; // Yes + } + + else { + VPtBoard->EnableExtraChannel = 0; // No + } + + err_trace (( ERR_OUT, "EnableExtraChannel=%d", VPtBoard->EnableExtraChannel )); + + VPtBoard->TriggerMode = 0; // Trigger mode -> disabled + VPtBoard->TriggerDetectTimeWindow = 0; // Trigger mode -> Window during which we count triggers to detect beginning of spill + VPtBoard->TriggerDetectOccurNb = 0; // Trigger mode -> Number of trigger required during "TriggerDetectTimeWindow" to decide that spill has begun + VPtBoard->AcqNbPerTrig = 0; // Trigger mode -> Number of consecutive Acq stored after beginning of spill detection + + VPtBoard->EnableTimeStamping = 0; // On board time stamping -> disabled + VPtBoard->TimeStampRes = 0; // On board time stamp resolution in [ns] + + VPtBoard->EnableTrigCnt = 0; // On board trigger counter + + VPtBoard->TagEventsStoredByDUT = 0; // Tag events taken dy DUT -> disabled + VPtBoard->ReadTluTrigCntEachNTrig = 0; // Read event counter provided by TLU -> disabled + + + + // Allocate memory + + // IPHC data transfer mode + + if ( DataTransferMode == EFRIO__TRF_MODE_IPHC ) { + + // Free tmp trigger record if allocated + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + // Free EUDET mode buffer + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.PtFrame = NULL; + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Alloc IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + + VPtCont->RunCont.InfZsFFrameRawBuffSz = VPtCont->RunCont.ParMi26Nb * (VPtCont->RunCont.ParFrameNbPerAcq + 200) * sizeof (MI26__TZsFFrameRaw); + + VPtCont->RunCont.PtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + err_retnull ( VPtCont->RunCont.PtZsFFrameRaw, (ERR_OUT,"Allocation of IPHC buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // EUDET data transfer mode + + else { + + // Alloc tmp trigger record + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + VPtCont->PtTmpTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtCont->PtTmpTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Free IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + VPtCont->RunCont.InfZsFFrameRawBuffSz = 0; + + // Reset frame list + + memset ( VPtCont->AAcqFrameList, 0, sizeof (EFRIO__TFrameList) ); + + // Alloc + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Upgrade for Ultimate + + // VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VPtCont->RunCont.InfFrameBuffSz = VPtCont->RunCont.ParFrameNbPerAcq * VMaxFrameSz; + + VPtCont->RunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->RunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->RunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq) ); + + err_error (( ERR_OUT, "TRACE => Frames buffer sz = %d Bytes", VPtCont->RunCont.InfFrameBuffSz )); + err_error (( ERR_OUT, "TRACE => Frames buffer sz = %d MBytes", VPtCont->RunCont.InfFrameBuffSz / (1024 * 1024) )); + } + + + // Reset run context results fields + + VPtCont->RunCont.ResAcqCnt = 0; + VPtCont->RunCont.ResFrameCnt = 0; + VPtCont->RunCont.ResEventCnt = 0; + + // Set status conf done + + VPtCont->ABoardsStatus[0].ConfDone = 1; + + // Set flag init done + + VPtCont->InfInitDone = 1; + + // Init for Labview because some emulation parameters are not controlled by GUI + + #ifdef APP_DLL + EFRIO__FEmuleBegin ( 1 /* RunInLabview */ ); + #endif + + + err_retok (( ERR_OUT, "end" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 07/03/2011 + : - Get disk sector size from OS + : + : 20/05/2011 + : - Use run param to calculate TCStreamFile max buffer size + : + : 13/10/2011 + : - Add creation of a copy of run conf file in x:\log ( VInfConfFileNameCpy ). + : + : 10/07/2012 + : - Create run index file + : + : 09/11/2012 + : - Automatic creation of run directory + : + : 26/03/2013 + : - Add EFRIO__USR_VGContext.ParCrIndexFile handling + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStartSavingOnFile () { + + SInt32 VRet; + char VDiskDrive[3]; + SInt32 VDiskSectorSz; + SInt8 VUseThread; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + EFRIO__TFrame* VPtFrame; + SInt32 VStreamFileMaxBlocSz; + char VInfConfFileNameCpy[GLB_FILE_PATH_SZ]; // Copy in x:\log of the run conf file + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + + VRet = 0; + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + // Debug + + msg (( MSG_OUT, "EFRIO__FStartSavingOnFile () => Run No = %d", VPtRunCont->ParRunNo )); + + msg (( MSG_OUT, "EFRIO__FStartSavingOnFile () => Dest dir = %s", VPtRunCont->ParDestDir )); + + // 09/11/12 + + if ( DirectoryExists ( VPtRunCont->ParDestDir ) == True ) { + msg (( MSG_OUT, "Dest dir = %s already exists", VPtRunCont->ParDestDir )); + } + + else { + msg (( MSG_OUT, "Dest dir = %s doesn't exist => Try to create it", VPtRunCont->ParDestDir )); + + err_retfail ( FIL_FMkDir ( VPtRunCont->ParDestDir ), (ERR_OUT,"Abort : Directory %s creation failed !", VPtRunCont->ParDestDir ) ); + } + + + // Create & write conf file + + // msg (( MSG_OUT, "VPtRunCont->ResConfFileName=%s", VPtRunCont->ResConfFileName )); + + // Set pointer to 0 before saving and restor them afer + + VPtZsFFrameRaw = VPtRunCont->PtZsFFrameRaw; + VPtFrame = VPtRunCont->PtFrame; + + VPtRunCont->PtZsFFrameRaw = NULL; + VPtRunCont->PtFrame = NULL; + + VRet = VRet | EFRIO__VGRunConfFile.PubFConf ( VPtRunCont->InfConfFileName, FIL__TCBinFile_RWB_MODE_WRITE, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont), 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunConfFile.PubFCreate (); + VRet = VRet | EFRIO__VGRunConfFile.PubFSeqWrite ( VPtRunCont, sizeof (EFRIO__TRunCont) ); + VRet = VRet | EFRIO__VGRunConfFile.PubFClose (); + + VPtRunCont->PtZsFFrameRaw = VPtZsFFrameRaw; + VPtRunCont->PtFrame = VPtFrame; + + err_retfail ( VRet, (ERR_OUT,"Run config file = %s creation failed !", VPtRunCont->InfConfFileName) ); + + // Make a copy of run info file + + sprintf ( VInfConfFileNameCpy, "x:\\log\\%s%d.par", VPtRunCont->ParFileNamePrefix, VPtRunCont->ParRunNo ); // 13/10/2011 + + VRet = FIL_FCpyFile ( VPtRunCont->InfConfFileName, VInfConfFileNameCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT, "Copy of info = %s file i, %s failed !", VPtRunCont->InfConfFileName, VInfConfFileNameCpy )); + err_error (( ERR_OUT, "Copy of info = %s file i, %s failed !", VPtRunCont->InfConfFileName, VInfConfFileNameCpy )); + } + + // Create data file + + if ( VPtRunCont->ParSaveOnDisk == 1 ) { + VUseThread = 1; + } + + else { + VUseThread = 0; + } + + + // Get disk sector size + + strncpy ( VDiskDrive, VPtRunCont->InfDataFileName, 2 ); + + VDiskDrive[2] = 0; + + VDiskSectorSz = FIL_FGetDiskSectorSz ( VDiskDrive ); + + err_retfail ( VDiskSectorSz, (ERR_OUT,"Abort => Unable to get drive %s sector size !", VDiskDrive ) ); + + msg (( MSG_OUT, "Disk sector sz = %d Bytes", VDiskSectorSz )); + + // Set TCStreamFile disk sector size + + VRet = VRet | EFRIO__VGRunDataFile.PubFSetDiskSectorSz ( VDiskSectorSz ); + + // Conf TCStreamFile + + // VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + // VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + // 20/05/2011 + + VStreamFileMaxBlocSz = ( VPtRunCont->ParFrameNbPerAcq * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ); + + err_error (( ERR_OUT, "TRACE => Calc TCStreamFile max bloc sz - %d Fr/Acq - Bloc Sz = %d MB", VPtRunCont->ParFrameNbPerAcq, VStreamFileMaxBlocSz / (1024 * 1024) )); + + VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, VStreamFileMaxBlocSz /* Max */, VStreamFileMaxBlocSz /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + err_retfail ( VRet, (ERR_OUT,"Run data file = %s creation failed !", VPtRunCont->InfDataFileName) ); + + // Create index file + + #ifdef EFRIO__CREATE_INDEX_FILE + if ( VPtUsrCont->ParCrIndexFile ) { + VRet = FIL_FIndexFileTelCreate ( VPtRunCont->InfIndexFileName ); + err_retfail ( VRet, (ERR_OUT,"Index file %s creation failed => %s", VPtRunCont->InfIndexFileName, _strerror ( "System says :" ) )); + } + #endif + + // + + VPtRunCont->InfSaveDataOnDiskRunning = 1; + + } + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 16/02/2011 + : - Test if ParTotEvNb reached, if yes => call EFRIO__FStopSavingOnFile () + : + : 24/02/2011 + : - Handle SpareW32Par as an array ASpareW32Par now + : + : 10/07/2012 + : - Create run index file + : + : 26/03/2013 + : - Add EFRIO__USR_VGContext.ParCrIndexFile handling + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSaveAcqOnFile () { + + SInt32 VRet; + SInt32 ViFr; + static SInt32 ViEv = 0; + SInt8 VUseThread; + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TFileSpareW32Info VSpareW32Info; + + + VRet = 0; + + if ( VPtRunCont->InfSaveDataOnDiskRunning == 0 ) { + return (0); + } + + if ( VPtRunCont->ResEventCnt > VPtRunCont->ParTotEvNb ) { + EFRIO__FStopSavingOnFile (); + err_error (( ERR_OUT, "TRACE => End of run reached : %d events saved on disk", VPtRunCont->ResEventCnt )); + return (0); + } + + // Save acq on file if + // - Run conf "save on disk" parameter is set + // - There is something to save => ResAcqFunctRetCode = acquisition size <> 0 + + if ( (VPtRunCont->ParSaveOnDisk > 0) && (VPtRunCont->ResAcqFunctRetCode > 0) ) { + + VSpareW32Info.AcqStatus = VPtFrList->AcqStatus; + VSpareW32Info.TrigStatus = VPtFrList->TrigStatus; + VSpareW32Info.TotFrameNb = VPtFrList->TotFrameNb; + VSpareW32Info.DiskSectorSz = EFRIO__VGRunDataFile.PubFGetDiskSectorSz (); + + VRet = EFRIO__VGRunDataFile.PubFSeqWrite ( VPtRunCont->PtFrame, VPtRunCont->ResAcqFunctRetCode /* Acq sz */, VPtRunCont->ResEventCnt - 1 /* DbgCallPar */, 1 /* SpareW32InfoFormat */, (SInt32*) &VSpareW32Info, sizeof (VSpareW32Info) / 4 /* SpareW32InfoNb */ ); + +// err_error (( ERR_OUT, "***********************************************" )); +// err_error (( ERR_OUT, "TRACE => Saving AcqId=%d - %d Frames", VPtRunCont->ResAcqCnt, VPtFrList->TotFrameNb )); +// err_error (( ERR_OUT, "***********************************************" )); + + if ( VPtRunCont->ResAcqCnt == 1 ) { + ViEv = 0; + } + + for ( ViFr=0; ViFr < VPtFrList->TotFrameNb; ViFr++ ) { + +// err_error (( ERR_OUT, "EvId=%d - AcqId=%d - Fr=%d : Header=%x [H] - FrCnt=%d", ViEv, VPtRunCont->ResAcqCnt - 1, ViFr, VPtFrList->AFramePtr[ViFr]->Header.AMapsHeader[0], VPtFrList->AFramePtr[ViFr]->Header.AMapsFrameCnt[0] )); + + #ifdef EFRIO__CREATE_INDEX_FILE + if ( VPtUsrCont->ParCrIndexFile ) { + FIL_FIndexFileTelAddEv ( ViEv /* EvId */, VPtRunCont->ResAcqCnt - 1 /* AcqId */, ViFr /* FrId */, VPtFrList->AFramePtr[ViFr]->Header.AMapsFrameCnt[0] /* EvTag */, VPtFrList->AFramePtr[ViFr]->Header.AMapsTrigInfo[0], VPtFrList->AFramePtr[ViFr]->Header.AMapsTrigInfo[1], VPtFrList->AFramePtr[ViFr]->Header.AMapsTrigInfo[2], VPtFrList->AFramePtr[ViFr]->Header.TriggerNb, 0 /* SpareU32 */ ); + } + #endif + + ++ViEv; + } + + } + + err_retfail ( VRet, (ERR_OUT,"Saving Acq=%d of %d bytes on file %s failed", VPtRunCont->ResAcqCnt - 1, VPtRunCont->ResAcqFunctRetCode, VPtRunCont->InfDataFileName ) ); + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStopSavingOnFile () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + VRet = 0; + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_IPHC ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__TRF_MODE_IPHC not hanlded") ); + } + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + VPtRunCont->InfSaveDataOnDiskRunning = 0; + + VRet = VRet | EFRIO__VGRunDataFile.PubFFlush (); + VRet = VRet | EFRIO__VGRunDataFile.PubFClose (); + + err_retfail ( VRet, (ERR_OUT,"Error while closing data file = %s", VPtRunCont->InfDataFileName) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +#undef COMPIL_FTluTrigger2Str +#ifdef COMPIL_FTluTrigger2Str + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert TLU trigger info record to string for print or display + : +Inputs : Trig - Source trigger record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display + : +Inputs : Ts - Source time stamp record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger / timestamp as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in IPHC data transfer mode. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + SInt32 VNiFrame; + SInt32 VNiFramePMi26; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[0]; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VNiFrame = ViFrame * VPtRunCont->ParMi26Nb; + + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + VNiFramePMi26 = VNiFrame + ViMi26; + + if ( VPtFrame[VNiFramePMi26].Header != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Header, VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFrame[VNiFramePMi26].Trailer != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Trailer, VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFrame[VNiFramePMi26].FrameCnt; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFrame[VNiFramePMi26].FrameCnt != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].FrameCnt, VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in EUDET 1,2,3 data transfer modes. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +UInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrame* VPtFr; + SInt32 ViFrame; + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VPtFr = VPtFrList->AFramePtr[ViFrame]; + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + if ( VPtFr->Header.AMapsHeader[ViMi26] != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsHeader[ViMi26], VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFr->Header.AMapsTrailer[ViMi26] != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsTrailer[ViMi26], VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFr->Header.AMapsFrameCnt[ViMi26]; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFr->Header.AMapsFrameCnt[ViMi26] != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFr->Header.AMapsFrameCnt[ViMi26], VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/04/2011 ( DPXI version of 20/08/2009 moved here ) + : +Rev : 15/05/2013 + : - Modification of frame counter test, the test Fr(n+1) = Fr(n) + 1 has been + : removed because in beam test (EUDET3 mode) the frames in one acquisition are + : not all consecutives, there it detects fake errors. Now the test is only done + : by a comparison of all Mimosa 28 frame couters frame by frame. + : + : 08/11/2013 + : - Update test context field ResErrOnCurrentAcq with errors count + : +Doc date : 20/08/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FChkFrameLight ( SInt16 FuncId, SInt32 CurFrame, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // Debug tool + + if ( VPtTestCont->ParPrintLvl == -1 ) { + msg (( MSG_OUT, "Nb Mi26 to test : %d", VMi26Nb )); + } + + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 26 frame counters to the one of Mimosa26 [0] + // This is done frame by frame = doesn't care about previous frame counter value - 15/05/2013 + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "B - Frame cnt error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Header error [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Trailer error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 08/11/2013 + + VPtTestCont->ResErrOnCurrentAcq = VErrors; + + return (VErrors); +} + + +SInt32 EFRIO__MI26_FPrintFrameExtraTrig ( SInt32 AcqId, SInt32 CurFrame, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + EFRIO__TFrameData* VPtData; + UInt32* VPtAW32; + SInt8 ViMi26ExtraTrig; + SInt32 VOneMapsW32Sz; + SInt32 VExtraTrigW32DataOffset; + SInt32 ViDataW32; + SInt32 VTrig1Cnt; + SInt32 VTrig2Cnt; + + + // msg (( MSG_OUT, "------------------- EFRIO__MI26_FPrintFrameExtraTrig -------------------" )); + + // Check MAPS nb + + if ( Mi26Nb < 2 ) { + err_retfail ( -1, (ERR_OUT,"Mi26Nb=%d => Abort, no extra trig channel", Mi26Nb )); // Check MAPS nb to test + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + VTrig1Cnt = 0; + VTrig2Cnt = 0; + + // Get index of Mi26 used as extra trigger channel + + ViMi26ExtraTrig = Mi26Nb - 1; + + // Init ptr + + VPtFrHd = &PtFrame->Header; + VPtData = &PtFrame->Data; + + VOneMapsW32Sz = VPtData->OneMapsSz / 4; + VExtraTrigW32DataOffset = ViMi26ExtraTrig * VOneMapsW32Sz; + + VPtAW32 = &PtFrame->Data.ADataW32[VExtraTrigW32DataOffset]; + + // Debug print + + // msg (( MSG_OUT, "Frame [%d] : TotSz=%d W8 - OneMapsSz=%d W8 - VExtraTrigW32DataOffset=%d", CurFrame, VPtData->TotSz, VPtData->OneMapsSz, VExtraTrigW32DataOffset )); + + + // List trigger accepted by Mi32 received on D00 + + if ( (VPtFrHd->AMapsHeader[ViMi26ExtraTrig] & 0x0000FFFF) != 0 ) { + ++VTrig1Cnt; + msg (( MSG_OUT, "##Mi32 Trig Line 0 Header=%X", VPtFrHd->AMapsHeader[ViMi26ExtraTrig] )); + } + + if ( (VPtFrHd->AMapsFrameCnt[ViMi26ExtraTrig] & 0x0000FFFF) != 0 ) { + ++VTrig1Cnt; + msg (( MSG_OUT, "##Mi32 Trig Line 1 FrCnt=%X", VPtFrHd->AMapsFrameCnt[ViMi26ExtraTrig] )); + } + + if ( (VPtFrHd->AMapsDataLength[ViMi26ExtraTrig] & 0x0000FFFF) != 0 ) { + ++VTrig1Cnt; + msg (( MSG_OUT, "##Mi32 Trig Line 2 DataLength=%X", VPtFrHd->AMapsDataLength[ViMi26ExtraTrig] )); + } + + if ( (VPtFrHd->AMapsTrailer[ViMi26ExtraTrig] & 0x0000FFFF) != 0 ) { + ++VTrig1Cnt; + msg (( MSG_OUT, "##Mi32 Trig Line 573 Trailer=%X", VPtFrHd->AMapsTrailer[ViMi26ExtraTrig] )); + } + + // Search in data + + for ( ViDataW32=0; ViDataW32 < VOneMapsW32Sz; ViDataW32++ ) { + + if ( (VPtAW32[ViDataW32] & 0x0000FFFF) != 0 ) { + ++VTrig1Cnt; + msg (( MSG_OUT, "##Mi32 Trig Line %d - Data[%.4d]=%X", 3 + ViDataW32, ViDataW32, VPtAW32[ViDataW32] )); + } + + } + + // List trigger from scintillator received on D01 + + if ( (VPtFrHd->AMapsHeader[ViMi26ExtraTrig] & 0xFFFF0000) != 0 ) { + ++VTrig2Cnt; + msg (( MSG_OUT, "##Tot Trig Line 0 Header=%X", VPtFrHd->AMapsHeader[ViMi26ExtraTrig] )); + } + + if ( (VPtFrHd->AMapsFrameCnt[ViMi26ExtraTrig] & 0xFFFF0000) != 0 ) { + ++VTrig2Cnt; + msg (( MSG_OUT, "##Tot Trig Line 1 FrCnt=%X", VPtFrHd->AMapsFrameCnt[ViMi26ExtraTrig] )); + } + + if ( (VPtFrHd->AMapsDataLength[ViMi26ExtraTrig] & 0xFFFF0000) != 0 ) { + ++VTrig2Cnt; + msg (( MSG_OUT, "##Tot Trig Line 2 DataLength=%X", VPtFrHd->AMapsDataLength[ViMi26ExtraTrig] )); + } + + if ( (VPtFrHd->AMapsTrailer[ViMi26ExtraTrig] & 0xFFFF0000) != 0 ) { + ++VTrig2Cnt; + msg (( MSG_OUT, "##Tot Trig Line 573 Trailer=%X", VPtFrHd->AMapsTrailer[ViMi26ExtraTrig] )); + } + + // Search in data + + for ( ViDataW32=0; ViDataW32 < VOneMapsW32Sz; ViDataW32++ ) { + + if ( (VPtAW32[ViDataW32] & 0xFFFF0000) != 0 ) { + ++VTrig2Cnt; + msg (( MSG_OUT, "##Tot Trig Line %d - Data[%.4d]=%X", 3 + ViDataW32, ViDataW32, VPtAW32[ViDataW32] )); + } + + } + + + if ( (VTrig1Cnt != 0) || (VTrig2Cnt != 0) ) { + msg (( MSG_OUT, "AcqId=%d Frame [%d] : %d Mi32 Accepted triggers - %d Total triggers ", AcqId, CurFrame, VTrig1Cnt, VTrig2Cnt )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + } + + + + return (0); +} + + + +#ifndef NO_MI26 + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 02/02/2010 +Rev : 07/05/2010 + : - Trigger calculation + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // msg (( MSG_OUT, "==> DPXI__MI26_FFRioAcqDeserData1Mi26 : Mi26NbToRead=%d - EltNb=%d - TotAnsSz=%d", VPtServ->PtParAcqReqFunc->AsicNbToRead, EltNb, PtAcq->InfTotAnsSz )); + + // Copy Acq inf pointers to local pointers + + // $$$ VPtAcqData = PtAcq->InfPtAcqData; + // $$$ VptZsFFrameRaw = PtAcq->InfPtZsFFrameRaw; + // $$$ msg (( MSG_OUT, "DPXI__MI26_FFRioAcqDeserData1Mi26 => AcqReqFuncSz=%d - MaxDataSz=%d - VTotAnsSz=%d", PtAcq->InfParAcqReqFuncSz, VPtServ->PtParAcqReqFunc->MaxDataSz, PtAcq->InfTotAnsSz )); + // $$$ memset ( VPtAcqData, 0, PtAcq->InfTotAnsSz ); + // $$$ err_trace (( ERR_OUT, "Start extract data for FrameNb=%d", VPtServ->PtParAcqReqFunc->FrameNb )); + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // $$$ VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VptZsFFrameRaw[ViFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[ViFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + VptZsFFrameRaw[ViFrame].DataLength = VDataLengthField; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32 = (UInt32*) VptZsFFrameRaw[ViFrame].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[ViFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + VptZsFFrameRaw[ViFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + VptZsFFrameRaw[ViFrame].Zero2 = VZero2; + ++ViSrcW32; + + // $$$ DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + VptZsFFrameRaw[ViFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[ViFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[ViFrame].SStatus.HitCnt = -1; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 09/03/2010 +Rev : 06/05/2010 + : - Add trigger extract + : Warning ! Copy Zero & Zero2 fields of frame chip No 0 to ALL others chips ! + : All fields Zero & Zero2 are equals to the fields of first chip + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + SInt32 V6iFrameP1; + SInt32 V6iFrameP2; + SInt32 V6iFrameP3; + SInt32 V6iFrameP4; + SInt32 V6iFrameP5; + UInt32 VADataLengthField[6]; + UInt16 VADataLengthW16[6]; + UInt16 VADataLengthW32[6]; + UInt16 VDataLengthW32Max; + register SInt32 ViSrcW32; + register SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get AcqId + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // err_warning (( ERR_OUT, "TRACE : Memset buffer")); + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + V6iFrameP1 = V6iFrame + 1; + V6iFrameP2 = V6iFrame + 2; + V6iFrameP3 = V6iFrame + 3; + V6iFrameP4 = V6iFrame + 4; + V6iFrameP5 = V6iFrame + 5; + + + VptZsFFrameRaw[V6iFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VptZsFFrameRaw[V6iFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + + VptZsFFrameRaw[V6iFrame].DataLength = VADataLengthField[0]; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VptZsFFrameRaw[V6iFrameP1].DataLength = VADataLengthField[1]; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + + VptZsFFrameRaw[V6iFrameP2].DataLength = VADataLengthField[2]; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VptZsFFrameRaw[V6iFrameP3].DataLength = VADataLengthField[3]; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VptZsFFrameRaw[V6iFrameP4].DataLength = VADataLengthField[4]; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VptZsFFrameRaw[V6iFrameP5].DataLength = VADataLengthField[5]; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + // Find max data length of the six Mi26 + + VDataLengthW32Max = MATH_FUInt16Max ( VADataLengthW32, 6 ); + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32Chip0 = (UInt32*) VptZsFFrameRaw[V6iFrame].ADataW16; + VPtDataW32Chip1 = (UInt32*) VptZsFFrameRaw[V6iFrameP1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VptZsFFrameRaw[V6iFrameP2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VptZsFFrameRaw[V6iFrameP3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VptZsFFrameRaw[V6iFrameP4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VptZsFFrameRaw[V6iFrameP5].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip1[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip2[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip3[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip4[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip5[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VptZsFFrameRaw[V6iFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + ++ViSrcW32; + + // DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + + VptZsFFrameRaw[V6iFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrame].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP1].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 1 + 18 + (6 * VADataLengthW32[1])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP1].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP1].SStatus.AsicNo = 1; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP1].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP2].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 2 + 18 + (6 * VADataLengthW32[2])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP2].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP2].SStatus.AsicNo = 2; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP2].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP3].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 3 + 18 + (6 * VADataLengthW32[3])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP3].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP3].SStatus.AsicNo = 3; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP3].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP4].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 4 + 18 + (6 * VADataLengthW32[4])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP4].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP4].SStatus.AsicNo = 4; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP4].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP5].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 5 + 18 + (6 * VADataLengthW32[5])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP5].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP5].SStatus.AsicNo = 5; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP5].SStatus.HitCnt = -1; + + + + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 6 /* Mi26Nb */ ); + // PtAcq->ResAsicErrorsRejCurAcq = 0; + + // if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 25/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 27/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointers + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // If length > max possible => Set it to 0 + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode5Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/08/2012 + : Copy EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 to create EFRIO__MI26_FFRioAcqDeserDataEudet2Mode5Mi26. +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode5Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[5]; + UInt32 VADataLengthW8[5]; + UInt16 VADataLengthW16[5]; + UInt32 VADataLengthW32[5]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[5]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // Divide by 6 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + // err_error (( ERR_OUT, "$$$ Header [0]=%x - [1]=%x - [2]=%x - [3]=%x - [4]=%x", VPtFrame->Header.AMapsHeader[0], VPtFrame->Header.AMapsHeader[1], VPtFrame->Header.AMapsHeader[2], VPtFrame->Header.AMapsHeader[3], VPtFrame->Header.AMapsHeader[4] )); + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + + // err_error (( ERR_OUT, "### Data length [0]=%d - [1]=%d - [2]=%d - [3]=%d - [4]=%d", VADataLengthW16[0], VADataLengthW16[1], VADataLengthW16[2], VADataLengthW16[3], VADataLengthW16[4] )); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 5 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 5; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 5 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 5 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 5 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 5; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 5; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 5; // Bypass Mi26 x 5 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 6; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + // err_error (( ERR_OUT, "$$$ Trailer [0]=%x - [1]=%x - [2]=%x - [3]=%x - [4]=%x", VPtFrame->Header.AMapsTrailer[0], VPtFrame->Header.AMapsTrailer[1], VPtFrame->Header.AMapsTrailer[2], VPtFrame->Header.AMapsTrailer[3], VPtFrame->Header.AMapsTrailer[4] )); + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 5 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 29/10/2010 version handling 6 Mi26 ) +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V9iFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V9iFrame = 9 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 9 = 9 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; // 18 = 9 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + +// Mode 2 - 12 x Mi26 +// 23/11/2011 +// $$ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode12Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V13iFrame; + UInt32 VADataLengthField[12]; + UInt32 VADataLengthW8[12]; + UInt16 VADataLengthW16[12]; + UInt32 VADataLengthW32[12]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[12]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode12Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 13; // Divide by 13 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V13iFrame = 13 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + VADataLengthW16[8] = (VADataLengthField[8] & 0x0000FFFF) + ((VADataLengthField[8] & 0xFFFF0000) >> 16); + VADataLengthW16[9] = (VADataLengthField[9] & 0x0000FFFF) + ((VADataLengthField[9] & 0xFFFF0000) >> 16); + VADataLengthW16[10] = (VADataLengthField[10] & 0x0000FFFF) + ((VADataLengthField[10] & 0xFFFF0000) >> 16); + VADataLengthW16[11] = (VADataLengthField[11] & 0x0000FFFF) + ((VADataLengthField[11] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 12 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 12; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 12 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 12 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 12 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 12; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + VPtFrame->Header.AMapsDataLength[8] = VADataLengthW8[8]; + VPtFrame->Header.AMapsDataLength[9] = VADataLengthW8[9]; + VPtFrame->Header.AMapsDataLength[10] = VADataLengthW8[10]; + VPtFrame->Header.AMapsDataLength[11] = VADataLengthW8[11]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 12; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + VAPtCpyDestW32[8] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 8 * VDataLengthW32Max ) ); + VAPtCpyDestW32[9] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 9 * VDataLengthW32Max ) ); + VAPtCpyDestW32[10] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 10 * VDataLengthW32Max ) ); + VAPtCpyDestW32[11] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 11 * VDataLengthW32Max ) ); + + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[8] = *VPtCpySrcW32; + ++VAPtCpyDestW32[8]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[9] = *VPtCpySrcW32; + ++VAPtCpyDestW32[9]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[10] = *VPtCpySrcW32; + ++VAPtCpyDestW32[10]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[11] = *VPtCpySrcW32; + ++VAPtCpyDestW32[11]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 12; // Bypass Mi26 x 12 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 13; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (13 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * VADataLengthW32[0])]; // 39 = 13 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 1 + (13 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 2 + (13 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 3 + (13 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 4 + (13 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 5 + (13 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 6 + (13 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 7 + (13 * VADataLengthW32[7])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[8] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 8 + (13 * VADataLengthW32[8])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[9] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 9 + (13 * VADataLengthW32[9])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[10] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 10 + (13 * VADataLengthW32[10])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[11] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 11 + (13 * VADataLengthW32[11])]; + ++ViSrcW32; + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * MI26__ZS_FFRAME_RAW_MAX_W32) + 13]; // 13 = 13 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * MI26__ZS_FFRAME_RAW_MAX_W32) + 26]; // 26 = 13 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 26; // 13 times 2 zero fields = 26 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 12 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +// Mode 2 - N x Mi26 +// 17/11/2011 +// $$ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[16]; + UInt32 VADataLengthW8[16]; + UInt16 VADataLengthW16[16]; + UInt32 VADataLengthW32[16]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[16]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + SInt8 VMi26NbP1; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 (Mi26Nb=%d, P=%x, EltNb=%d)", Mi26Nb, PtSrcW32, EltNb )); + + // Mi26 nb check + + if ( (Mi26Nb < 0) || (Mi26Nb > 16) ) { + err_retfail ( -1, (ERR_OUT,"Bad Mi26 Nb = %d => Out of range [0..16]", Mi26Nb) ); + } + + VMi26NbP1 = Mi26Nb + 1; + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / VMi26NbP1; // Divide by 7 because of extral channel + + // VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = VMi26NbP1 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsHeader[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsFrameCnt[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthField[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthW16[ViMi26] = (VADataLengthField[ViMi26] & 0x0000FFFF) + ((VADataLengthField[ViMi26] & 0xFFFF0000) >> 16); + } + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, Mi26Nb ); + + /* + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + */ + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < Mi26Nb /* 6 */; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + + for ( ViMi26=0; ViMi26 < Mi26Nb /* 6 */; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsDataLength[ViMi26] = VADataLengthW8[ViMi26]; + } + + /* + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + */ + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * Mi26Nb; + + // VDataLengthW32ToCpy = VDataLengthW32Max * 6; + + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VAPtCpyDestW32[ViMi26] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + (ViMi26 * VDataLengthW32Max) ); + } + + + /* + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + */ + + + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + *VAPtCpyDestW32[ViMi26] = *VPtCpySrcW32; + ++VAPtCpyDestW32[ViMi26]; + ++VPtCpySrcW32; + } + + /* + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += Mi26Nb; // Bypass Mi26 x 6 data + + // VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + + VPtEChanSrcW32 += VMi26NbP1; + + // VPtEChanSrcW32 += 7; + + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32); + + // ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsTrailer[ViMi26] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + ViMi26 + (VMi26NbP1 * VADataLengthW32[ViMi26])]; + ++ViSrcW32; + } + + + + // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + /* + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + */ + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + (2 * VMi26NbP1)]; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += (2 * VMi26NbP1); // 7 times 2 zero fields = 14 + + // ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, Mi26Nb ); + + // EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode5Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/08/2012 + : => Cpy of EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 to make EFRIO__MI26_FFRioAcqDeserDataEudet3Mode5Mi26 + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 28/08/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode5Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V6FrameId; + UInt32 VADataLengthField[5]; + UInt32 VADataLengthW8[5]; + UInt16 VADataLengthW16[5]; + UInt32 VADataLengthW32[5]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[5]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // Divide by 6 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V6FrameId = 6 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 6 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V6FrameId = 6 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 5 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 5 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 5 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 5 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 5; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 5; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 5; // Bypass Mi26 x 5 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 6; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6FrameId) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 5 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 03/11/2010 version handling 6 Mi26 ) + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 9 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = 9 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + /* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + + */ + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for N Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : + : + : Mi26Nb - Mi26 number + : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/08/2012 +Rev : + : +Doc date : 28/08/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[16]; + UInt32 VADataLengthW8[16]; + UInt16 VADataLengthW16[16]; + UInt32 VADataLengthW32[16]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[16]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + SInt8 VMi26NbP1; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 (Mi26Nb=%d, P=%x, EltNb=%d)", Mi26Nb, PtSrcW32, EltNb )); + + // Mi26 nb check + + if ( (Mi26Nb < 0) || (Mi26Nb > 16) ) { + err_retfail ( -1, (ERR_OUT,"Bad Mi26 Nb = %d => Out of range [0..16]", Mi26Nb) ); + } + + VMi26NbP1 = Mi26Nb + 1; + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / VMi26NbP1; // Divide by 9 because of extral channel + + // VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = VMi26NbP1 * VFrameId; + + // V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (VMi26NbP1 * 3) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // if ( TrigStatus == 0 ) { + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + // } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (VMi26NbP1 * 3) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + VZero = (TrigStatus << 16); + } + + // else { + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + // VZero = (TrigStatus << 16); + // } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * VMi26NbP1 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = VMi26NbP1 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsHeader[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsFrameCnt[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthField[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthW16[ViMi26] = (VADataLengthField[ViMi26] & 0x0000FFFF) + ((VADataLengthField[ViMi26] & 0xFFFF0000) >> 16); + } + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, Mi26Nb ); + + /* + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + */ + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < Mi26Nb /* 8 */; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsDataLength[ViMi26] = VADataLengthW8[ViMi26]; + } + + /* + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + */ + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * Mi26Nb /* 8 */; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VAPtCpyDestW32[ViMi26] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + (ViMi26 * VDataLengthW32Max) ); + } + + /* + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + */ + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + *VAPtCpyDestW32[ViMi26] = *VPtCpySrcW32; + ++VAPtCpyDestW32[ViMi26]; + ++VPtCpySrcW32; + } + + /* + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + + VPtEChanSrcW32 += Mi26Nb; // Bypass Mi26 x 8 data + + // VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + + VPtEChanSrcW32 += VMi26NbP1; + + // VPtEChanSrcW32 += 9; + + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32); + + // ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsTrailer[ViMi26] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + ViMi26 + (VMi26NbP1 * VADataLengthW32[ViMi26])]; + ++ViSrcW32; + } + + + // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + /* + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + */ + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + // // 9 = 9 x 1 Trailer + + } + + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + (2 * VMi26NbP1)]; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + + ViSrcW32 += (2 * VMi26NbP1); // 9 times 2 zero fields = 18 + + // ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +// 14/06/13 + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26ExtaTrigInfo ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[17]; + UInt32 VADataLengthW8[17]; + UInt16 VADataLengthW16[17]; + UInt32 VADataLengthW32[17]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[17]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + SInt8 VMi26NbP1; + SInt8 VMi26NbM1; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 (Mi26Nb=%d, P=%x, EltNb=%d)", Mi26Nb, PtSrcW32, EltNb )); + + // Mi26 nb check + + if ( (Mi26Nb < 0) || (Mi26Nb > 16) ) { + err_retfail ( -1, (ERR_OUT,"Bad Mi26 Nb = %d => Out of range [0..16]", Mi26Nb) ); + } + + VMi26NbM1 = Mi26Nb - 1; + VMi26NbP1 = Mi26Nb + 1; + + + // msg (( MSG_OUT, "-------------------------------------------------------------------------" )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / VMi26NbP1; // Divide by 9 because of extral channel + + // VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = VMi26NbP1 * VFrameId; + + // V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (VMi26NbP1 * 3) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // if ( TrigStatus == 0 ) { + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + // } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (VMi26NbP1 * 3) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + VZero = (TrigStatus << 16); + } + + // else { + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + // VZero = (TrigStatus << 16); + // } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * VMi26NbP1 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = VMi26NbP1 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsHeader[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsFrameCnt[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthField[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthW16[ViMi26] = (VADataLengthField[ViMi26] & 0x0000FFFF) + ((VADataLengthField[ViMi26] & 0xFFFF0000) >> 16); + } + + // 14/06/13 : Search max size on Mi26Nb - 1 because last one is the extra trigger info + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, VMi26NbM1 ); + + // msg (( MSG_OUT, "VDataLengthW16Max [0..%d]=%d", VMi26NbM1 - 1, VDataLengthW16Max )); + + /* + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + */ + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // Test done before 14/06/13 "if ( VDataLengthW16Max > 2304 ) {" => Don't remember why 2304, should be 1140 W16 => ??? + // Rq : 2304 = 1152 W16 x 2 = Total size (including non data fields) in W8 => It may be the explanation + // but it confirms that it's not the good value + + // 14/06/13 : Modify the test => use the good Max W16 value + // + // If one Mi26 data field is out of normal range => Force all of them to 0 in order to + // - avoid SW crash during frame processing with corrupted data + // - indicate that there is a problem with this event => data size set to 0 => event not processed + + if ( VDataLengthW16Max > 1140 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, Mi26Nb /* 8 */ * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + // 14/06/13 + // If data size fields of Mi26Nb connected to DAQ (Mi26Nb - 1) is OK + // => Set maximum data size variable to MAXIMUM possible value + // => Real data size (from Mi26 data size fields) to Mi26 0 to Mi26 nb - 1 + // => Set data size to MAXIMUM possible value for the last Mi26 which is extra trigger channel + // because for extra trigger acquisition, we must process the full frame + + else { + + // Set maximum size variable to MAXIMUM possible size + + VDataLengthW16Max = 1140; + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + + // Set size of Mi26 No 0 to NbMax - 1 + + for ( ViMi26=0; ViMi26 < VMi26NbM1 /* 8 */; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + + // msg (( MSG_OUT, "VADataLengthW16[%d]=%d", ViMi26, VADataLengthW16[ViMi26] )); + } + + // Set size of last Mi26 = extra trigger channel, to MAXIMUM possible size + + VADataLengthW16[VMi26NbM1] = VDataLengthW16Max; + VADataLengthW8[VMi26NbM1] = VDataLengthW8Max; + VADataLengthW32[VMi26NbM1] = VDataLengthW32Max; + + // msg (( MSG_OUT, "VADataLengthW16[%d]=%d", VMi26NbM1, VADataLengthW16[VMi26NbM1] )); + + + // msg (( MSG_OUT, "VDataLengthW16Max = [6] =%d", VDataLengthW16Max )); + } + + + for ( ViMi26=0; ViMi26 < VMi26NbM1; ViMi26++ ) { + VPtFrame->Header.AMapsDataLength[ViMi26] = VADataLengthW8[ViMi26]; + } + + // Extra trigger channel => Copy only link D00 + + VPtFrame->Header.AMapsDataLength[VMi26NbM1] = (VADataLengthField[VMi26NbM1] & 0x0000FFFF); + + /* + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + */ + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * Mi26Nb /* 8 */; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VAPtCpyDestW32[ViMi26] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + (ViMi26 * VDataLengthW32Max) ); + } + + /* + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + */ + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + *VAPtCpyDestW32[ViMi26] = *VPtCpySrcW32; + ++VAPtCpyDestW32[ViMi26]; + ++VPtCpySrcW32; + } + + /* + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + + VPtEChanSrcW32 += Mi26Nb; // Bypass Mi26 x 8 data + + // VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + + VPtEChanSrcW32 += VMi26NbP1; + + // VPtEChanSrcW32 += 9; + + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32); + + // ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsTrailer[ViMi26] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + ViMi26 + (VMi26NbP1 * VADataLengthW32[ViMi26])]; + ++ViSrcW32; + } + + + // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + /* + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + */ + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + // // 9 = 9 x 1 Trailer + + } + + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + (2 * VMi26NbP1)]; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + + ViSrcW32 += (2 * VMi26NbP1); // 9 times 2 zero fields = 18 + + // ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // 14/06/13 : Force to test only NbMax Mi26 - 1, because the last channel is not a Mi26 but the extra trigger info + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, VMi26NbM1 /* Mi26Nb */ ); + + // 17/06/13 Print extra trig + + EFRIO__MI26_FPrintFrameExtraTrig ( VAcqId /* AcqId */ , VFrameId, VPtFrame, Mi26Nb /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +#endif // ifndef NO_MI26 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 17/01/2012 + : - Implementation of "sw" handling of Mi26 / "hard coded" + : It is enable by EFRIO__FREE_MI26_NB directive and ONLY implemented in mode EUDET 2 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__USR_TContext* VPtUsrContext = &EFRIO__USR_VGContext; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + +#ifndef NO_MI26 + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + } + + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + + #ifdef EFRIO__FREE_MI26_NB + + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 ( Mi26Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + + #else + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 5 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode5Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 12 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode12Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + #endif + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + + #ifdef EFRIO__FREE_MI26_NB + + // 14/06/13 : Uses ReadoutMode command line parameter to select between normal readout & readout with etra trigger info (Debug BT June 2013) + + if ( VPtUsrContext->ParReadoutMode == 0) { + // msg (( MSG_OUT, "Normal readout" )); + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 ( Mi26Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + } + + else { + // msg (( MSG_OUT, "Readout WITH extra trigger info" )); + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26ExtaTrigInfo ( Mi26Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + } + + + #else + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 5 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode5Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + #endif + + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); + +#endif // NO_MI26 + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagLoadFile ( char* FileName ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + msg (( MSG_OUT, "### EFRIO__FJtagLoadFile (FileName=%s)", FileName )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagLoadFile (FileName); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagLoadFile (FileName); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 13/03/2013 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagLoadDefFile () { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + char VFileName[GLB_FILE_PATH_SZ]; + + sprintf ( VFileName, "%s", "c:\\ccmos_sctrl\\Mimosa26_jtag\\config_files\\Default.mcf" ); + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagLoadDefFile (FileName=%s)", VFileName )); + + VRet = EFRIO__MI26_FJtagLoadFile (VFileName); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 08/11/2013 + : - Add dev 0 selection to fix "JTAG GUI panel bug" when using only one MAPS + : following an advise from KKJ, but it solves nothing ... let in place, in case of ... + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagLoadFile ( char* FileName ) { + + HRESULT VRetCode; + WideString VStatus; + WideString VFileName; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagLoadFile (FileName=%s)", FileName )); + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + + if ( VJtag.IsBound () ) { + + VFileName = FileName; + + OleCheck( VRetCode = VJtag.MasterConfLoadFile( VFileName , &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Load JTAG file = %s failed !", FileName) ); + } + + // 08/11/2013 + // Add dev 0 selection to fix "JTAG GUI panel bug" when using only one MAPS + // following an advise from KKJ, but it solves nothing ... let in place, in case of ... + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( 0, &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Set JTAG DevNum 0 failed !" ) ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagReset ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + msg (( MSG_OUT, "### EFRIO__FJtagReset ()" )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagReset (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagReset (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagReset ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagReset ()" )); + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfReset (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Reset chip failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagLoadChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + msg (( MSG_OUT, "### EFRIO__FJtagLoadChip () - ParMapsName=%d", VPtRun->ParMapsName )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagLoadChip (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagLoadChip (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: -n = error number on JTAG readback +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 28/09/2011 + : - Update code because MasterConfReadBack (...) has changed => return one more param = Reaad back errors nb + : If <> 0 return -(errors number) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FJtagLoadChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + long VReadBackErrorsNb; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagLoadChip ( ))" )); + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfUpdateAll (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + // 28/09/2011 + // Update code because MasterConfReadBack (...) has changed => return one more param = Reaad back errors nb + // If <> 0 return -(errors number) + + OleCheck( VRetCode = VJtag.MasterConfReadBack ( &VReadBackErrorsNb, &VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Read back chip parameters failed !") ); + } + + if ( VReadBackErrorsNb > 0 ) { + err_retfail ( -VReadBackErrorsNb, (ERR_OUT,"JTAG -> Read back chip => Write <> Read => %d errors !", VReadBackErrorsNb ) ); + } + + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 24/04/2013 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagResetAndLoadChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + msg (( MSG_OUT, "### EFRIO__FJtagResetAndLoadChip ()" )); + + + // ----------------------------------------------------------------------- + // Print JTAG file name in messages log file x:\log\msg_eudet_dll.txt + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "Reset & Reload JTAG => JTAG configuration file = %s", VPtRun->ParJtagFileName )); + + + // Reset Maps + + VRet = EFRIO__FJtagReset (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + err_error (( ERR_OUT, "EFRIO__FJtagReset () has failed !" )); + return (VRet); + } + + // Send parameters to Maps registers + // If read back registers <> values sent => an error is generated => VRet < 0 + + VRet = EFRIO__FJtagLoadChip (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + err_error (( ERR_OUT, "EFRIO__FJtagLoadChip () has failed !" )); + return (VRet); + } + + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagStartChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + msg (( MSG_OUT, "### EFRIO__FJtagStartChip ()" )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagStartChip (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagStartChip (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagStartChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + msg (( MSG_OUT, "### EFRIO__MI26_FJtagStartChip ()" )); + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfStart (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FHwStartChip ( SInt32 SpareS32Par ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + msg (( MSG_OUT, "### EFRIO__FHwStartChip (SpareS32Par=%d)", SpareS32Par )); + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + msg (( MSG_OUT, "EFRIO__FHwStartChip => Mi26 HW Start" )); + VRet = EFRIO__MI26_FHwStartChip ( SpareS32Par ); + break; } + + case ASIC__ULT1 : { + msg (( MSG_OUT, "EFRIO__FHwStartChip => ULT1 HW Start" )); + VRet = EFRIO__ULT1_FHwStartChip ( SpareS32Par ); + break; } + + default : { + msg (( MSG_OUT, "EFRIO__FHwStartChip => HW Start request - But unknown chip !" )); + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2010 +Doc date : 10/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FHwStartChip ( SInt32 SpareS32Par ) { + + err_warning (( ERR_OUT, "EFRIO__MI26_FHwStartChip (Par=%d)", SpareS32Par )); + + msg (( MSG_OUT, "### EFRIO__MI26_FHwStartChip - a - (Par=%d)", SpareS32Par )); + + // Start = D6, Speak = D7* + + #ifdef EFRIO__INCLUDE_PARA_PORT + + msg (( MSG_OUT, "### EFRIO__MI26_FHwStartChip - b - (Par=%d)", SpareS32Par )); + + PPO_FOutD6 ( 0 /* Id */, 0 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + + // Sleep ( 100 ); // 08/06/2011 => Debug for test with Flex RIO trig emulator + + PPO_FOutD6 ( 0 /* Id */, 0 ); + + #else + err_warning (( ERR_OUT, "HW start not done -> // port not enabled !" )); + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 19/05/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FTestOnDataGetJtagRef () { + + SInt32 VRet; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + // Sel Mi26 + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( ViMaps, &VStrComStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Select Maps Id = %d failed !", ViMaps) ); + } + + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 0 /* RegId */, &VHighTrailerFromJtag, &VRegValFromMi26, &VStrComStatus) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 1 /* RegId */, &VLowTrailerFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 2 /* RegId */, &VHighHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 3 /* RegId */, &VLowHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + + VPtTestCont->ParAMapsHeaderRef[ViMaps] = VLowHeaderFromJtag + (VHighHeaderFromJtag << 16); // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = VLowTrailerFromJtag + (VHighTrailerFromJtag << 16); // Mimosa 26 trailer field + + } + + } + + else { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + VPtTestCont->ParAMapsHeaderRef[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = 0; // Mimosa 26 trailer field + } + + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + + CoUninitialize(); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 29/04/2011 + : +Rev : 19/05/2011 + : - Handle both Mi26 and Ult1 + : + : 30/10/2013 + : Idea following bug fix of EFRIO__FTestOnDataResetErrCnt () on 30/10/2013 + : it may be not needed, but I prefer to implement it. + : => Update of "MapsNb fields" regardless of Test Start / Stop test + : - Update VPtTestCont->ParMapsNb with VPtRunCont->ParMi26Nb + : - Update VPtTestCont->ParMapsNbToTest with MapsNbToTest + : + : 27/01/2014 + : - Param Start replaced by StartAndTestType in order to select a type of test + : but with only one GUI control => "Start" button replaced by a list box + : -- Old field EFRIO__TTestOnDataCont.ParModeEnable set to 1 if StartAndTestType <> 0 + : -- New field EFRIO__TTestOnDataCont.ParTestType = StartAndTestType + : +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FTestOnDataStartStop ( SInt8 StartAndTestType, SInt8 MapsNbToTest, SInt8 PrintLvl ) { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + + + VPtTestCont->ParPrintLvl = PrintLvl; + + VPtTestCont->ParMapsNb = VPtRunCont->ParMi26Nb; // 30/10/13 + VPtTestCont->ParMapsNbToTest = MapsNbToTest; // 30/10/13 + VPtTestCont->ParTestType = StartAndTestType; // 27/01/14 + + // Stop and exit + + if ( StartAndTestType == 0 ) { + + // If already stopped => Do nothing & exit + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + // If running => Stop + message + + VPtTestCont->ParModeEnable = 0; + + // Print errors count + + EFRIO__FPrintTestOnDataCont ( "Errors count after Stop" ); + + err_retok (( ERR_OUT, "Stop command executed" )); + } + + + // Start procedure + + // If already running => Do nothing & exit + + if ( VPtTestCont->ParModeEnable == 1 ) { + return (0); + } + + // If not running => Start + Message + + memset ( VPtTestCont, 0, sizeof (EFRIO__TTestOnDataCont) ); + + VPtTestCont->ParMapsNb = VPtRunCont->ParMi26Nb; + VPtTestCont->ParMapsNbToTest = MapsNbToTest; + + + switch ( VPtRunCont->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FTestOnDataGetJtagRef (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FTestOnDataGetJtagRef (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRunCont->ParMapsName) ); + break; } + + } + + err_retfail ( VRet, (ERR_OUT,"Test aborted => Unable to get param from JTAG") ); + + // Enable test + + VPtTestCont->ParModeEnable = 1; + + // Print test context + + EFRIO__FPrintTestOnDataCont ( "Record state after Start" ); + + err_retok (( ERR_OUT, "Start command executed" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FTestOnDataResetErrCnt () + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 29/04/2011 +Rev : 29/05/2013 + : Since 29/05/13 it also reads JTAG reference values from JTAG application. + : The sequence is the following one + : 1 - Prints status (ref values + errors counts) in log file + : 2 - Reset errors counter + : 3 - Reads JTAG references + : 4 - Prints status (ref values + errors counts) in log file + : + : As switch "Enable Data test" is now forced to 1, therefore JTAG reference are read + : only on first run. The modification done in "Reset data errors counter " is the + : easiest way to update JTAG reference values at the beginning of each run. + : + : 30/10/2013 - Bug fix + : - Update VPtTestCont->ParMapsNb with VPtRunCont->ParMi26Nb + : - Otherwise change in MAPS nb from run ctrl is not updated, only done on first run + : + : +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FTestOnDataResetErrCnt () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + SInt8 ViMaps; + + + // Print test context => To get errors count before reset + + EFRIO__FPrintTestOnDataCont ( "Errors count before Reset" ); + + + VPtTestCont->ParMapsNb = VPtRunCont->ParMi26Nb; // 30/10/13 + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + VPtTestCont->ResAMapsErrCnt[ViMaps] = 0; + VPtTestCont->ResAMapsHeaderErrCnt[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ResAMapsFrameCntErrCnt[ViMaps] = 0; // Mimosa 26 frame counter field + VPtTestCont->ResAMapsDataLengthErrCnt[ViMaps] = 0; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + VPtTestCont->ResAMapsTrailerErrCnt[ViMaps] = 0; // Mimosa 26 trailer field + VPtTestCont->ResAMapsMatrixErrCnt[ViMaps] = 0; // Mimosa 26 matrix + + VPtTestCont->ResAMapsMatrixHitCnt[ViMaps] = 0; // Mimosa 26 hits cnt + } + + VPtTestCont->ResTotErrCnt = 0; + VPtTestCont->ResFrameNbWithErr = 0; + + // Rev : 29/05/13 + // Get JTAG reference values from JTAG application + + switch ( VPtRunCont->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FTestOnDataGetJtagRef (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FTestOnDataGetJtagRef (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRunCont->ParMapsName) ); + break; } + + } + + EFRIO__FPrintTestOnDataCont ( "Reset errors count done - Reference values after JTAG reading" ); + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FRestartDaqWaitOnDutDaq ( SInt32 TimeBeforeWaitMs, SInt8 WaitOnDutDaq, SInt32 TimeToWaitnDutDaqMs ) +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 29/04/2013 +Doc date : 29/04/2013 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FRestartDaqWaitOnDutDaq ( SInt32 TimeBeforeWaitMs, SInt8 WaitOnDutDaq, SInt32 TimeToWaitOnDutDaqMs ) { + + SInt32 ViWaitLoop; + SInt32 VWaitLoopNb; + SInt32 VLoopPeriodMs; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + + msg (( MSG_OUT, "Wait on DUT DAQ begin" )); + + VLoopPeriodMs = 30; + + // Set "Start/Restart" line to 0 + + PPO_FOutD4 ( 0 /* Id */, 0 /* State */ ); + + // Time before wait on DUT DAQ answer + + Application->ProcessMessages (); + Sleep ( TimeBeforeWaitMs ); + + + // Wait on DUT DAQ acknowledge + + if ( WaitOnDutDaq ) { + + VWaitLoopNb = TimeToWaitOnDutDaqMs / VLoopPeriodMs; + + // Wait loop on DUT DAQ ack + + for ( ViWaitLoop=0; ViWaitLoop < VWaitLoopNb; ViWaitLoop++) { + + // msg (( MSG_OUT, "Wait on DUT DAQ : Loop %d ", ViWaitLoop )); + + Application->ProcessMessages (); + Sleep ( VLoopPeriodMs ); + + if ( PPO_FInBusy ( 0 /* Id */ ) == 0 ) { + PPO_FOutD4 ( 0 /* Id */, 1 /* State */ ); // Reset "Start/Restart" line + msg (( MSG_OUT, "Wait on DUT DAQ end => ACQ RECEIVED :-)" )); + return (1); + } + + } + + // No ack from DUT DAQ + + PPO_FOutD4 ( 0 /* Id */, 1 /* State */ ); // Reset "Start/Restart" line + msg (( MSG_OUT, "Wait on DUT DAQ end => NO ACQ RECEIVED !" )); + return (0); + + } + + else { + + // No test on DUT ack => Return 1 after " TimeBeforeWaitMs " + + PPO_FOutD4 ( 0 /* Id */, 1 /* State */ ); // Reset "Start/Restart" line + msg (( MSG_OUT, "Wait on DUT DAQ end => NO WAIT ON DUT DAQ" )); + return (1); + } + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef NO_MI26 + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + + return (VTotAcqSz); + } + +#endif // NO_MI26 + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio.def b/include/pxi_daq_lib_v.2.1/eudet_frio.def new file mode 100755 index 0000000..a31b2a9 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio.def @@ -0,0 +1,279 @@ + + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.def +Goal : Macros definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_DEF +#define EUDET_FRIO_DEF + + +/* ======================= */ +/* Conditional compilation */ +/* ======================= */ + +// Enable EFRIO__FRAME_TAGS_ENABLE to add tags at beginning of EFRIO__TFrame record and sub-records +// +// Each sub-record has it own tag, see list of constants at end of file +// +// EFRIO__TFrame -> EFRIO__FRAME_TAG +// EFRIO__TFrameHeader -> EFRIO__FRAME_TAG_HEADER +// EFRIO__TFrameData -> EFRIO__FRAME_TAG_DATA +// EFRIO__TTriggerRec -> EFRIO__FRAME_TAG_TRIG + +#define EFRIO__FRAME_TAGS_ENABLE + + + + +// Enable / Disable demultiplexing of Mimosa 26 data part +// +// It has NO effect if running with a single Mimosa 26 +// +// In case of multiple Mimosa 26 acquisition, Flex RIO provides multiplexed data +// +// W32[0] Mi26 No 0 , W32[0] Mi26 No 1 ... W32[0] Mi26 No 5 +// W32[1] Mi26 No 0 , W32[1] Mi26 No 1 ... W32[1] Mi26 No 5 +// W32[2] Mi26 No 0 , W32[2] Mi26 No 1 ... W32[2] Mi26 No 5 +// W32[3] Mi26 No 0 , W32[3] Mi26 No 1 ... W32[3] Mi26 No 5 +// +// Data are demultiplexed if this directive is enabled +// This processing will cost CPU time -> it may be done on EUDET SW side if needed +// that's why this processing can be disabled + + +// #define NO_MI26 + +#define EFRIO__DEMUX_MI26_DATA_PART +#define EFRIO__DEMUX_ULT1_DATA_PART + + + + +/* ================= */ +/* Macro */ +/* ================= */ + + +// Test if board Id is valid, if not return (-1) and lof error message + +#define EFRIO__CHK_BOARD_ID(BoardId) { if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) err_retfail ( -1, (ERR_OUT,"Abort : Bad board Id=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 ) ); } + + +/* ================= */ +/* Constants */ +/* ================= */ + + +// Maximum board number handle by the lib ( define arrays size ) + +#define EFRIO__MAX_BOARDS_NB 2 + +// Maximum ASIC nb handle by the lib ( define arrays size ) + +// #define EFRIO__MAX_ASIC_NB 6 before 21/02/2011 + +#define EFRIO__MAX_ASIC_NB 16 // Set to 16 on 21/02/2011 + +#define EFRIO__MAX_ASIC_NB_FOR_DMA 12 // 25/05/2011 + // 8 Used to calculate DmaHostSz because Labview can't allocate memory for EFRIO__MAX_ASIC_NB = 16 + + +// Maximum number of frames per acquisition ( define arrays size ) +// - One frame = one readout of MAPS +// - One acquisition = N consecutives frames acquired in one call of board readout function + +#define EFRIO__MAX_FRAME_NB_PER_ACQ 1800 + + +// ************************************************************************************************************* +// Data transfer modes +// ************************************************************************************************************* +// Few information about how the Flex RIO board acquired Mimosa 26 +// +// - Flex RIO board can acquire the data of up to 6 Mimosa 26 and deserialize them +// Each Mimosa 26 is seen as an "acquisition channel", because fw is organized / Mimosa 26 +// +// - Now the fw doesn't care about trigger to select which frame to acquire, all frames are stored and the selection +// is done on-line by DAQ sw. Because it will be more flexible to adjust & modify trigger handling by sw rather than +// by fw and for 6 Mimosa 26 it seems possible to do it on execution time point of view. +// Later, this processing will be moved in fw, for AIDA but for EUDET it should work fine by sw. +// +// - The fw counts triggers and store it's own trigger information "Mimosa 26 trigger" ( the Mimosa 26 line read when trigger occurs ) +// This trigger information is written in the zero fields of Mimosa 26 ( by overwritting them ) +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 +// +// - An extra acquisition channel can be enabled to store trigger from TLU ( it has the same size as a Mimosa 26 channel = 2304 W8 ) +// It will store two W32 informations for each trigger +// - The trigger TLU -> See record EFRIO__TTluTrigger +// - The trigger from Flex RIO ( Mimosa 26 line + frame ) -> See record EFRIO__TFlexRioTimeStamp1 +// The extra channel can store up to 288 triggers ( 288 * W32 * 2 = 2304 ) +// +// We have decided to implement 4 data transfert mode, the difference is on trigger handling and only the last one will +// be useful for EUDET => EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// +// * EFRIO__TRF_MODE_IPHC +// +// Keep compatibility with IPHC DAQ -> limited to 3 triggers + data demultiplex which cost CPU time +// +// * EFRIO__TRF_MODE_EUDET__NO_TRG_CHAN, +// +// Send all frames, store 3 first "Mimosa 26 trigger", don't store TLU trigger +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_ALL_FRAMES, +// +// Send all frames, store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// Send only frame with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG +// store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// + + +typedef enum EFRIO__TRF_MODE { + EFRIO__TRF_MODE_IPHC, + EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, + EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, + EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + +} EFRIO__TTrfMode; + + +// We use the two "zero fields" of each 32 bits at the end of Mimosa 26 data stream to store first three triggers +// It's not trigger from TLU but the trigger we used in our first BT with flex RIO = Mimosa 26 line index when trigger occurs +// +// This is the field Mi26Line of the record EFRIO__TFlexRioTimeStamp1 x 16 because unit is Mimosa 26 clock cycle +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 + + +#define EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA 3 // CAN'T be higher than 3 !!!!!!!!!! + + +// The current frame - with trigger - is not enough to build the physics event +// due to internal MAPS logic ( double memory, pipelines etc ... ) following frames must be also used +// => This is the number of frames to read after the one which contains trigger to build physics event + +#define EFRIO__FRAME_NB_TO_READ_AFTER_TRIG 3 // For Mimosa 26 it's 3 + +// Constants to define extra channel size -> Hard coded ( don't use sizeof ( xyz) ) in order to reduce execution time +// The extra channel is a MAPS acquisition channel ( it has he same size ) but used to store trigger information +// It can store up to 288 triggers / MAPS frame +// +// Now 28/10/2010 +// - Each trigger info stored in extra channel contain two fields, each one is a W32, in the following order +// -- EFRIO__TTluTrigger +// -- EFRIO__TFlexRioTimeStamp1 +// --> Total trigger info size is 2 x W32 = 8 bytes +// - The extral channel has the same size of one Mi26 frame = 2304 W8 +// --> Maximum number of trigger info which can be stored = 2304 / 8 = 288 +// --> It means one trigger each two lines of Mimosa 26 readout ... ;-) + +// ------------------------------------------------------------------------------------------------- +// WARNING - 20/05/2011 => Solve bug of 19/05 = memory crash at second run ( first one ok ) ) +// ------------------------------------------------------------------------------------------------- +// - Ultimate allows 928 triggers / frame - Mi26 was limited to 288 +// - The test on max allowed trig number was not done in data processing loop => to save exec time +// but after the loop when padding zero part of frame is processed to find triggers +// - A test was done in this part, but only a warning was generated and waring messages were disabled ... +// ------------------------------------------------------------------------------------------------- +// Now ( 20/05/2011 ) +// - The size of temporary record used to stored trigger info has been increased to fit with Ultimate +// -- EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 288 +// -- EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 576 +// +// - But, in order to KEEP COMPATIBILIY with Mi26, the number of trigger copied to frame record has +// been limited to EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 = 288 +// +// - This may be increased LATER because frame record has variable size ( also for triggers part ) +// BUT now I DON'T KNOW if there are limitations somewhere else in sources ( run readout lib ? ) +// therefore I prefer to keep Mimosa 26 " triggers number limitation " +// ------------------------------------------------------------------------------------------------- + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 928 // Maximum number of trigger info = pair of W32 fields TLU Trig + Felx RIO TS +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 1856 // Maximum number of W32 fields + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 288 + +// #define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 288 // Maximum number of trigger info = pair of W32 fields TLU Trig + Felx RIO TS +// #define EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 576 // Maximum number of W32 fields + + +#define EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ 8 // Size of the trigger info = pair of W32 fields TLU Trig + Flex RIO TS + +#define EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ 4 // Size of one W32 field + + +// Maximum number of messages / board -> define array in EFRIO__TBoardStatus + +#define EFRIO__ERROR_MSG_LIST_MAX_NB 100 + + +// Maximum number of triggers in DAQ emulation configurable by GUI +// We can emulate more triggers than EFRIO__MAX_GUI_TRIG_NB but their value is hard coded in emulation function to 0 +// +// Only the first three triggers and the last one ( if EFRIO__MAX_GUI_TRIG_NB = 4 ) are configurable from GUI + +// #define EFRIO__MAX_GUI_TRIG_NB 4 // WARNING => Redined (with same value) in C++ Builder emulation application ! + +#define EFRIO__MAX_EMUL_GUI_TRIG_NB 4 // WARNING => Redefined (with same value) in C++ Builder emulaion application ! + + +// Tags values to be added at beginning of each EFRIO__TFrame sub-record + +#define EFRIO__FRAME_TAG 0x55550000 +#define EFRIO__FRAME_TAG_HEADER 0x00000001 +#define EFRIO__FRAME_TAG_DATA 0x00000002 +#define EFRIO__FRAME_TAG_TRIG 0x00000003 + +// Maximum size of one acquisition store to disk => Used by FIL__TCStreamFile class +// 20/05/2011 => Calculated for Ultimate + +// #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) + + +#ifdef CC_UNIX + #define ULT1__ZS_FFRAME_RAW_MAX_W8 7400 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 + #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +#else + #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +#endif + + + +typedef enum EFRIO__TJTAG_CHIP { + EFRIO__JTAG_MI26, + EFRIO__JTAG_ULT1, + EFRIO__JTAG_FSBB0 + +} EFRIO__TJtagChip; + + + + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio.h b/include/pxi_daq_lib_v.2.1/eudet_frio.h new file mode 100755 index 0000000..35f9c13 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio.h @@ -0,0 +1,96 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.h +Goal : Functions prototypes of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_H + +#include "func_header.def" + + +// 06/11/2010 -> 21 + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FCpyAcq ( UInt8* PtDest, SInt32 MaxDestSz, SInt32 AcqSz );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FEnd ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FEmuleEnd ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent, char* JtagFileName );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent, char* JtagFileName );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FStartSavingOnFile ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSaveAcqOnFile ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FStopSavingOnFile ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FJtagLoadFile ( char* FileName );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FJtagReset ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FJtagLoadChip ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FJtagResetAndLoadChip ( );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FJtagStartChip ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FHwStartChip ( SInt32 SpareS32Par );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FJtagLoadFile ( char* FileName );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FJtagLoadDefFile ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FJtagReset ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FJtagLoadChip ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FJtagStartChip ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FHwStartChip ( SInt32 SpareS32Par );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FTestOnDataStartStop ( SInt8 StartAndTestType, SInt8 MapsNbToTest, SInt8 PrintLvl );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FTestOnDataResetErrCnt ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FRestartDaqWaitOnDutDaq ( SInt32 TimeBeforeWaitMs, SInt8 WaitOnDutDaq, SInt32 TimeToWaitOnDutDaqMs );) + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_H + #define EUDET_FRIO_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio.typ b/include/pxi_daq_lib_v.2.1/eudet_frio.typ new file mode 100755 index 0000000..ff52bd3 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio.typ @@ -0,0 +1,996 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.typ +Goal : Types definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_TYP +#define EUDET_FRIO_TYP + + + +/* ============================================== */ +/* Board parameters configuration record */ +/* ---------------------------------------------- */ +/* Can be use to build a boards database */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// Remark for EUDET concerning trigger handling +// +// Most of the following trigger options will be useless for EUDET +// The operating mode for EUDET is : +// - The board takes data all the time regardless of trigger state +// - The fw store all triggers from TLU ( up to 288 / Mimsoa 26 frame ) are stored +// - The sw extract frames with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames after trigger + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + + char AsicName[GLB_CMT_SZ]; // The ASIC read by the board + + SInt32 AsicNb; // The number of ASICs read by the board + + SInt32 ReadoutMode; // The readout mode -> Future use + + SInt8 EmuleChannels; // Copy data of first MAPS in all channels, useful for test & debugging + // because it allows to run with one ASIC only but get data of all + + float DataClkFrequency; // Frequency of clock -> Future use, only useful in case board provide clock + + UInt32 DmaHostSz; // DMA size reserved on host CPU, must be >= size of one acquisition + + SInt32 FrameNbPerAcq; // Consecutives frames number stored during one acquisition + + SInt8 EnableExtraChannel; // Enable one more channel ( default is one channel per ASIC ) + // which can be used to store extra information -> eg : TLU trigger + + SInt32 AcqNbPerTrig; // TO BE CHECKED ! Number of consecutive acquisitions taken upon trigger detection by board + + SInt8 TriggerMode; // Trigger operating mode + + UInt32 TriggerDetectTimeWindow; // Time window during which we count triggers and decide to start acquisition if >= TriggerDetectOccurNb + + UInt32 TriggerDetectOccurNb; // Minimum trigger number during TriggerDetectTimeWindow to decide to start acquisition + + UInt32 TimeStampRes; // Resolution of time stamp + + SInt8 EnableTimeStamping; // Enable time stamping mode + + SInt8 EnableTrigCnt; // Enable trigger counter + + SInt8 TagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ ( HW line indicates that DUT has saved event ) + + UInt32 ReadTluTrigCntEachNTrig; // Period of reading TLU trigger + + +} EFRIO__TBoardConf; + + +/* ============================================== */ +/* Board status record */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + SInt8 BoardPresent; // Board present => 1, otherwise 0 + SInt8 FwLoaded; // Firmware has been loaded in board + SInt8 ConfDone; // The board has been configured by sw + + SInt32 StatusCode; // Current board status code + + char StatusStr[GLB_CMT_SZ]; // Status message associated to StatusCode + + // List of errors and last error + + char* ErrorMsgList[EFRIO__ERROR_MSG_LIST_MAX_NB]; + char LastErrorMsg[GLB_CMT_SZ]; + + // Registers read from board + + UInt32 RegDmaHostSz; // DMA host size in bytes + SInt32 RegFrameNbPerAcq; // Number of frames / acq + SInt8 RegEnableExtraChannel; // Extral channel state = enabled or not + SInt32 RegAcqNbPerTrig; // Consecutive acquisition nb per trigger + + SInt8 RegTriggerMode; // Trigger mode + UInt32 RegTriggerDetectTimeWindow; // Trigger detection window + UInt32 RegTriggerDetectOccurNb; // Number of triggers required during window to start acquisition + + UInt32 RegTimeStampRes; // Resolution of time stamp -> Check with CS if implemented ! + SInt8 RegEnableTimeStamping; // Enable time stamping mode -> Check with CS if implemented ! + + SInt8 RegEnableTrigCnt; // Enable trigger counter -> Check with CS if implemented ! + + SInt8 RegTagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ -> Check with CS if implemented ! + UInt32 RegReadTluTrigCntEachNTrig; // Period of reading TLU trigger -> Check with CS if implemented ! + + UInt64 RegTimeStamp; // Time stamp value + UInt32 RegTrigCnt; // Flex RIO rigger value + UInt32 RegTluTrigCnt; // TLU trigger value + +} EFRIO__TBoardStatus; + + + + +/* ============================================== */ +/* TLU trigger record */ +/* ---------------------------------------------- */ +/* Contains TLU trigger -> field TrigCnt */ +/* plus additional information */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 TrigCnt : 16; // Trigger counter read from TLU + UInt32 FrameIdInAcq : 11; // Index of frame in current acquisition during which trigger occurs ( 0 - 2407 ) + UInt32 EventTakenByDut : 1; // For future use : Flag at 1 if DUT has taken the event + UInt32 Reserved : 3; + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TTluTrigger; + + +/* ============================================== */ +/* Flex RIO time stamp 1 record */ +/* ---------------------------------------------- */ +/* This is the Flex RIO trigger, called */ +/* "time stamp" to avoid confusion / TLU */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Mi26Line : 10; // Line of Mi26 read during which trigger occurs + UInt32 Mi26Frame : 21; // Frame of Mi26 ( = frame counter field ) read during which trigger occurs + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TFlexRioTimeStamp1; + + +/* ============================================== */ +/* Frame header */ +/* ---------------------------------------------- */ +/* Each frame starts with a header which contains */ +/* - DAQ system info */ +/* - Mimosa 26 relevant fields */ +/* ---------------------------------------------- */ +/* Date : 22/10/2010 */ +/* Rev : 23/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_HEADER +#endif + + // New fields AcqStatus & TrigStatus 23/02/2011 + // + SInt32 AcqStatus; // Status of acquistion board for this acquisition + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + // + SInt32 TrigStatus; // No meaning now = reserved for future use + + UInt16 AcqId; // Index of acquisition containing this frame + UInt16 FrameIdInAcq; // Index of frame IN the CURRENT acquisition + + UInt16 MapsName; // MAPS name as a 16 bits code + UInt16 MapsNb; // Total number of MAPS in data + + UInt32 AMapsHeader[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 AMapsFrameCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 AMapsDataLength[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 AMapsTrailer[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + SInt16 TriggerNb; // Total triggers number during this frame + + UInt16 AMapsTrigInfo[EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA]; // First 3 "Mi26 trigger info" -> Line of Mi26 read during which trigger occurs + // if more than 3 trigger => look in trigger info block where all trigger are stored + +} EFRIO__TFrameHeader; + + +/* ============================================== */ +/* Frame data */ +/* ---------------------------------------------- */ +/* Each frame has a data part with variable size */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_DATA +#endif + UInt32 TotSz; // Total size of data bloc + UInt32 OneMapsSz; // Size of data of one MAPS + + UInt32 ADataW32[0]; // Beginning of data space + +} EFRIO__TFrameData; + + +/* ============================================== */ +/* Frame triggers list */ +/* ---------------------------------------------- */ +/* Each frame has a triggers list, up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB fields */ +/* which means up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB */ +/* trigger info */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_TRIG +#endif + UInt32 TotSz; // Total size of trigger info bloc + UInt16 TrigNb; // Total trigger nb + UInt16 TrigType; // Type of trigger info stored + + UInt32 ATrig[0]; // Beginning off triggers list + +} EFRIO__TTriggerRec; + + +/* ============================================== */ +/* Frame record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Data handling fields ( size etc ) */ +/* - The frame header */ +/* - The frame data part ( variable length ) */ +/* - Followed by the triggers info part */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new field DaqVersion */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG +#endif + SInt32 DaqVersion; // Version of DAQ - New field 21/02/2011 + SInt32 TotSz; // Total size of this frame + SInt32 TrigRecOffset; // Offset ( in bytes ) from beginning of frame to trigger info part + EFRIO__TFrameHeader Header; // Frame header + EFRIO__TFrameData Data; // Beginning of data part + + // The field EFRIO__TTriggerInfo is not defined here because "Data" has variable length + // the field BegData of Data field is used a pointer to beginning of data part + // The trigger info will be added at the end of this part but position is calculated dynamically + +} EFRIO__TFrame; + + +/* ============================================== */ +/* List of frames currently stored by lib */ +/* ---------------------------------------------- */ +/* This record stores frames list corresponding */ +/* to one acquisition */ +/* */ +/* It can be : */ +/* - frames acquired by DAQ */ +/* - frames loaded from a run file */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : */ +/* : 24/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// More information about frames storage in memory +// +// A buffer IS NOT allocated for EACH frame, a single bloc of memory is allocated for all frames of one acquisition. +// This will avoid copy frame by frame before sending them to Ethernet lib or saving them to disk. A single access +// can be done with a pointer on beginning of buffer and data size. +// +// But to process frames it's handly to have an array of pointers, each array item pointing on next frame, +// this is the goal of this list which provides : +// - The total number of frames in list +// - An array of pointers, eg : AFramePtr[2] points on third frame of acquisition +// - An array with the total size ( in bytes ) of each frame +// +// This list is built on-line while DAQ is running, or off-line via EFRIO__FBuildFrameListFromAcq (...) from +// the data of one acquisition stored in a run file. + +typedef struct { + + // New fields AcqStatus & TrigStatus 24/02/2011 + // + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + +} EFRIO__TFrameList; + + +/* ============================================== */ +/* Run configuration record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Run parameters -> Par... */ +/* - Informations built from Par etc -> Inf... */ +/* - Acquisition results ( ev cnt etc ) -> Res... */ +/* - Pointers to frames buffers */ +/* ---------------------------------------------- */ +/* This record is filled by EFRIO__FConfRun (...) */ +/* call with run parameters from GUI or Ethernet */ +/* ---------------------------------------------- */ +/* This record can be saved to disk as run config */ +/* file, but it can't be ONLY loaded from file ! */ +/* A call to EFRIO__FConfRun (...) must be done */ +/* because it allocates mem and do other tasks */ +/* -> load record from file */ +/* -> call EFRIO__FConfRun with record fields as */ +/* parameters, it will overwrite itself and all */ +/* " other tasks " will also be done */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new fields */ +/* : ParDaqVersion, ParMapsName */ +/* : - Change type of ParMi26Nb to S16 */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_... directive at a time ! + #endif + +#endif + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + char InfIndexFileName[GLB_FILE_PATH_SZ]; // Run index file name built from ParRunNo, ParFileNamePrefix, ParDestDir - 10/07/2012 + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_... directive at a time ! + #endif + +#endif + + + + + + +/* ============================================== */ +/* Acquisition emulation record */ +/* ---------------------------------------------- */ +/* This record contains context of DAQ emulator */ +/* application, it means : */ +/* - Parameters -> Par... */ +/* - Information, calculated from Par -> Inf... */ +/* - Results -> Res... */ +/* ---------------------------------------------- */ +/* All emulation functions are implemented in the */ +/* lib, therefore application task is only GUI. */ +/* That's why emulation context is defined here */ +/* ---------------------------------------------- */ +/* All run param for emulation are taken from */ +/* run config record -> EFRIO__TRunCont */ +/* ---------------------------------------------- */ +/* Date : 30/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqCycleMs; // Delai between two acquisitions + + SInt32 ParEmuleDRamReadMs; // Delai added to PC DRAM access to emulate Flex RIO DRAM access time + + SInt32 ParEmuleFunctNo; // Select emulation function to call -> Future use = not implemented now + + SInt8 ParRandomDataSz; // Enables random generation of data size per Mimosa 26 + // By default data size is fixed in emulation function + // Used to check if variabl length records are properly handled + + SInt8 ParSetMaxDataSzOnOneMaps; // Set maximum possible data sze on first Mi26, overwrite value set by emulation + // function, but next Mi26 keep the data size value from emulation function + // Used to check if DAQ loose frames while Mi26 provides full frames + + + UInt32 ParAHeader[EFRIO__MAX_ASIC_NB]; // Emulated header of each Mi26 + + UInt32 ParATrailer[EFRIO__MAX_ASIC_NB]; // Emulated trailer of each Mi26 + + SInt32 ParTrigNbPerFrame; // Number of trigger per frame, set the part trigger nb (B31B16) of Mi26 Zero1 field + + // In data transfer modes EUDET 2 & 3 a more complex trigger emulation is done + // We don't emulate ParTrigNbPerFrame on each frame but on N consecutives frames + // each M frames + // + SInt32 ParTrigOnOneFrameOverN; // Start emulate ParTrigNbPerFrame on one frame over M = ParTrigOnOneFrameOverN + SInt32 ParTrigOnNConsecutiveFrames; // Emulates on N consecutive frames = ParTrigOnNConsecutiveFrames + + // TLU trigger & Flex RIO trigger emulation + // Up to 288 couples TLU & Flex RIO triggers can be emulated but only EFRIO__MAX_EMUL_GUI_TRIG_NB + // are configurabbles from GUI, now EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + // - First three are configurable from GUI + // - The last one is configurable from GUI + // - Others are configured in emulation function and set to 0 + // + SInt32 ParATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated TLU trigger + SInt32 ParATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated Flex RIO trigger, called "Time stamp 1" + + // DRAM info to emulate Flex RIO readout ( we need a PC RAM bloc of same size as the board one ) + // + SInt32 InfDRamSzMb; // DRAM size in MB + SInt32 InfDRamSz; // DRAM size in bytes + UInt32* InfDRamPtr; // DRAM pointer + + SInt8 InfExtraChan; // Extra channel status ( enabled or not ) depends on data transfer mode ( -> run config ) + + char InfEmuleFuncCmt[GLB_CMT_SZ]; // A comment set by emulation function selected by ParEmuleFunctNo + // -> Future use = not implemented now + + // DAQ emulation results + // + SInt32 ResAcqCnt; // Acquisition counter + SInt32 ResEvCnt; // Events counter + // + SInt32 ResAcqFunctRetCode; // Error code returned by acquisition function + +} EFRIO__TAcqEmul; + + +/* ============================================== */ +/* Frames check record */ +/* ---------------------------------------------- */ +/* This is context of frames check functions */ +/* - EFRIO__MI26_FChkAcqIphcMode (...) */ +/* - EFRIO__MI26_FChkAcqEudetMode (...) */ +/* */ +/* They check frames integrity, can be used in */ +/* normal DAQ mode or emulation */ +/* ---------------------------------------------- */ +/* Date : 31/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqNo; // Acquisition index + + SInt32 ParFrNo; // Frame index + + SInt8 ParChkMode; // Check mode -> Allows to define a level of test + + SInt8 ParChkVerbose; // Verbose mode or not + + SInt8 ParFrPrintLevel; // Define the frame information printed in log file + // 0 -> No print + // 1 -> Print general info ( AcqId, FrameId, TrigNb ... ) + Mi26 header, frame cnt, trailer + // 2 -> Print also triggers list + + SInt8 InfMi26Nb; // Mi26 number runnig in the system + + // Values provided by DAQ to check + // They are compared to the " same fields " of EFRIO_TAcqEmul + // + UInt32 ResAHeader[EFRIO__MAX_ASIC_NB]; // Mi26 header + UInt32 ResATrailer[EFRIO__MAX_ASIC_NB]; // Mi26 trailer + UInt32 ResAFrameCnt[EFRIO__MAX_ASIC_NB]; // Mi26 frames counter + UInt32 ResADataLenght[EFRIO__MAX_ASIC_NB]; // Mi26 data part length ( in W8 not in W16 as in DataLength fields of Mi26 data stream ) + // + SInt32 ResTrigNb; // Trigger info ( couple TLU & Flex RIO trigger ) number UNDER GUI control => limited to EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + SInt32 ResATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // TLU triggers list + SInt32 ResATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Flex RIO trigegrs list + + SInt32 ResErrCnt; // Total errors counter => Information provide by DAQ <> value set in EFRIO_TAcqEmul + + +} EFRIO__TFrCheck; + +/* ============================================== */ +/* Board check record */ +/* ---------------------------------------------- */ +/* This is context of board check Vi */ +/* The board test is done by a Vi on Labview side */ +/* this record pass the parameters to the Vi */ +/* */ +/* Parameters are set via call to functions */ +/* EFRIO__FSetBoardChk... */ +/* */ +/* Parameters are read via call to functions */ +/* EFRIO__FGetBoardChk... */ +/* Theses functions are encapsulated in Vi */ +/* ---------------------------------------------- */ +/* */ +/* The test results are written in board status */ +/* record ABoardsStatus [BoardId] */ +/* */ +/* Test results are set or read functions */ +/* EFRIO__FSetBoardStatus... */ +/* EFRIO__FGetBoardStatus... */ +/* ---------------------------------------------- */ +/* Date : 22/12/2010 */ +/* Doc date : 22/12/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParBoardId; // Board to test + + SInt8 ParDoTheTest; // Set to 1 to request the test + // Reset once test has been started + + SInt32 ParTestId; // Identifier to select different tests + + SInt8 ResTestDone; // Set to 1 when test is finished + + SInt32 ResTestResult; // Test result + // < 0 => Test has failed + // = 0 => Test OK + +} EFRIO__TBoardCheck; + + +/* ============================================== */ +/* Spare W32 bloc of index file */ +/* ---------------------------------------------- */ +/* This record contains spare info for index file */ +/* ---------------------------------------------- */ +/* Date : 24/02/2011 */ +/* Doc date : 24/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + + SInt32 DiskSectorSz; // Size of disk sector + +} EFRIO__TFileSpareW32Info; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains monitoring via Eth conf */ +/* ---------------------------------------------- */ +/* Date : 15/02/2011 */ +/* Doc date : 15/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 InfFrameNbToSend; // Frame nb to send on Eth = " Frame nb per acq * % monitoring " + SInt32 InfSzToSend; // Size corresponding to InfFrameNbToSend + +} EFRIO__TMon; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains tests on data conf / res */ +/* ---------------------------------------------- */ +/* Date : 29/04/2011 */ +/* Doc date : 29/04/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + // Control + + SInt8 ParTestType; // + SInt8 ParModeEnable; // Enable test + SInt8 ParResetCnt; // Reset all error counters + SInt8 ParPrintLvl; // Errors print level + SInt8 ParMapsNb; // Nb of MAPS configured in JTAG + SInt8 ParMapsNbToTest; // Number of MAPS on which the test is performed + // MAPS no 0 to ParMapsNbToTest - 1 + + // Reference / expected values + + UInt32 ParAMapsHeaderRef[EFRIO__MAX_ASIC_NB]; // Mimosa 26/28 header field + UInt32 ParAMapsTrailerRef[EFRIO__MAX_ASIC_NB]; // Mimosa 26/28 trailer field + + ULT1__TRegDiscriW32 ParUlt1ALinePat0[EFRIO__MAX_ASIC_NB]; // Mimosa 28 line patten + ULT1__TRegDiscriW32 ParUlt1ALinePat1[EFRIO__MAX_ASIC_NB]; + + SInt16 ParAMatPatternLineNb [EFRIO__MAX_ASIC_NB]; // Mimosa 26/28 Max line number in emulated matrix + + + UInt32 InfMapsFrameCntRef; // Mimosa 26 frame counter field + + ULT1__TMatDiscriBit InfUlt1AMatBitFromJtag[EFRIO__MAX_ASIC_NB]; + ULT1__TMatDiscriW32 InfUlt1TmpMatW32; + + // Current values get from DAQ + + UInt32 ResAMapsHeaderVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 ResAMapsFrameCntVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 ResAMapsDataLengthVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 ResAMapsTrailerVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + ULT1__TZsFFrame ResUlt1AZsFFrame[EFRIO__MAX_ASIC_NB]; + + ULT1__TMatDiscriBit ResUlt1AMatBitFromDaq[EFRIO__MAX_ASIC_NB]; // Mimosa 28 matrix from DAQ + + + // Errors counters + + SInt32 ResAMapsErrCnt[EFRIO__MAX_ASIC_NB]; // Err counter / MAPS = sum errors on header, fc, trailer + + SInt32 ResAMapsHeaderErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + SInt32 ResAMapsFrameCntErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + SInt32 ResAMapsDataLengthErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + SInt32 ResAMapsTrailerErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + SInt32 ResAMapsMatrixErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 matrix + + + SInt32 ResTotErrCnt; // Total errors counter = sum of N MAPS + SInt32 ResFrameNbWithErr; // Number of frames with at least one error + SInt8 ResErrOnCurrentAcq; // Indicates errors on current acq - 25/04/2013 + // 0 => None + // 1 => Errors + + SInt32 ResAMapsMatrixHitCnt[EFRIO__MAX_ASIC_NB]; // 06/02/14 - Mimosa 28 hits cnt + + +} EFRIO__TTestOnDataCont; + + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : 07/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef struct { + +#ifndef EFRIO__V10 + + // Add on 11/05/2011 + // Lib version, eg : 1.2 + SInt8 VersionMajor; // Lib version major : version 1.2 => 1 + SInt8 VersionMinor; // Lib version minor : version 1.2 => 2 + + // Add on 11/05/2011 + char VersionCmt[GLB_CMT_SZ]; // Commetn about lib version = content of lib + +#endif + + SInt8 InfInitDone; // Lib iit done or not + + EFRIO__TBoardConf ABoardsConf[EFRIO__MAX_BOARDS_NB]; // Acquisition boards config + EFRIO__TBoardStatus ABoardsStatus[EFRIO__MAX_BOARDS_NB]; // Acquisition boards status + + EFRIO__TBoardCheck BoardChk; // Reserved for future implementation + // Parameters record to check + // - Boards + // - Mimosa 26 Clk & Sync signals + + EFRIO__TAcqEmul AcqEmul; // DAQ emulation context + EFRIO__TFrCheck FrCheck; // Frames check functions context + + EFRIO__TRunCont RunCont; // Run context = parameters, memory allocated, results + + EFRIO__TMon MonCont; // Monitoring context + + EFRIO__TTestOnDataCont TestOnDataCont; // Test on data context + + EFRIO__TFrameList AAcqFrameList[1]; // Frame list of acquistion - Can be extended to more than one acq if needed + + // List of frame Id to read ( Eudet3Mode => Trigger + 2 following frames ) / acquistion - Can be extended to more than one acq if needed + + SInt16 AAAcqFrameWithTrigList[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + // Used to solve FW trigger bug ( Ultimate => extra channel info shifted by two frames ) + + // For each frame Id stored in AAAcqFrameWithTrigList + // we store in the trigger nb in FwTrigBugAAAcqFrameWithTrigTrigNb + + SInt16 FwTrigBugAAAcqFrameWithTrigTrigNb[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + // Is set to 1 if this frame contains the trigger list of frame No - 2 + + SInt16 FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[1][EFRIO__MAX_FRAME_NB_PER_ACQ + 10]; + + + EFRIO__TTriggerRec* PtTmpTrigRec; // Temporary triggers record used for internal processing + +} EFRIO__TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio.var b/include/pxi_daq_lib_v.2.1/eudet_frio.var new file mode 100755 index 0000000..035ac58 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio.var @@ -0,0 +1,43 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.var +Goal : Variables definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_VAR +#define EUDET_FRIO_VAR + + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC EFRIO__TContext EFRIO__VGContext; + +EXTERN VAR_STATIC FIL__TCStreamFile EFRIO__VGRunDataFile ( "x:\\log\\err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); +EXTERN VAR_STATIC FIL__TCBinFile EFRIO__VGRunConfFile ( "x:\\log\\err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); + +#ifdef EFRIO__INCLUDE_JTAG + EXTERN VAR_STATIC SInt8 EFRIO__VGJtagChip; // 0 => Mi26, 1 => Ultimate + EXTERN VAR_STATIC TCOMIMI26MasterConf EFRIO_VGJtagMi26; + EXTERN VAR_STATIC TCOMIMI28COM EFRIO_VGJtagUlt1; + EXTERN VAR_STATIC TCOMIFSBBM0COM EFRIO_VGJtagFsbb0; + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio__100112.c b/include/pxi_daq_lib_v.2.1/eudet_frio__100112.c new file mode 100755 index 0000000..4a86379 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio__100112.c @@ -0,0 +1,9791 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr + +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_C +#define EUDET_FRIO_C + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: Acquisition size if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 15/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FCpyAcq ( UInt8* PtDest, SInt32 MaxDestSz, SInt32 AcqSz ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + UInt32* VPtDest; + SInt32 VTotSz; + + // Check destination buffer + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + // Calculate total size + // = AcqSz + 4 because first W32 is used to store size of acquistion + + VTotSz = AcqSz + 4; + + // Test buffer size + + if ( VTotSz > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Destination buffer is too small => VTotSz=%d > MaxDestSz=%d", VTotSz, MaxDestSz ) ); + } + + // ----------------------------------------------- + // Copy data + // ----------------------------------------------- + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Add size on first elt + + VPtDest = (UInt32*) PtDest; + + *VPtDest = VTotSz; + + ++VPtDest; + + // Copy + + memcpy ( VPtDest, VPtRun->PtFrame, AcqSz ); + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotSz); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : MapsName - Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 +Rev : 11/05/2011 + : - Handle version information -> majour, minor, comment + : + : 12/05/2011 + : - JTAG version Mi26 / Ult1 handling + : + : 19/05/2011 + : - Dma host size calculated for Ultimate because we don't know at this step which + : MAPS will be used and memory size for Ultimate is > the one for Mimosa 26 + : + : 25/05/2011 + : - Renamed in EFRIO__FBeginExt + : - Add parameter MapsName + : - Create a new EFRIO__FBegin (...) which call EFRIO__FBeginExt ( ASIC__MI26, ... ) + : This will keep compatibility with previous sw (EUDET), because EFRIO__FBegin call + : will configure Mimosa 26 as ASIC as it was done for first version of EUDET library. + : + : 28/09/2011 + : - Update code because EFRIO_VGJtagMi26.get_Info (...) has changed => returns one more param = SW version now + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBeginExt ( SInt8 MapsName, SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + SInt32 VRet; + SInt8 VEnableErrLog; + SInt8 VEnableMsgLog; + WideString VWsJtagStatus; + WideString VWsSwVersion; + +#ifdef EFRIO__INCLUDE_PARA_PORT + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + // Select JTAG Mi26 or Ultimate + + switch ( MapsName ) { + + case ASIC__MI26 : { + EFRIO__VGJtagMi26Ult1 = 0; // 0 => Mi26, 1 => Ultimate + break; } + + case ASIC__ULT1 : { + EFRIO__VGJtagMi26Ult1 = 1; // 0 => Mi26, 1 => Ultimate + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + + // Reset lib context record => Set all field to 0 + // BUT ! Set CmdRun to -1 + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + VPtCont->RunCont.CmdRun = -1; + + // Set version information ( only for version >= 2.0 ) + + #ifdef EFRIO__V20_AND_LATER + + #ifdef EFRIO__V20 + VPtCont->VersionMajor = 2; + VPtCont->VersionMinor = 0; + + sprintf ( VPtCont->VersionCmt, "Extension of V1.0 to Ultimate 1" ); + #endif + + #endif + + + // Conf errors logging + + VEnableErrLog = ( ErrorLogLvl != 0 ); + + VRet = ERR_FBegin ( VEnableErrLog, ErrorLogFile ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FBegin failed !" ) ); + + VRet = ERR_FSetFileLogLevel ( ErrorLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FSetFileLogLevel failed !" ) ); + + // Conf messages logging + + VEnableMsgLog = ( MsgLogLvl != 0 ); + + VRet = MSG_FBegin ( VEnableMsgLog, MsgLogFile ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FBegin failed !" ) ); + + VRet = MSG_FSetFileLogLevel ( MsgLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FSetFileLogLevel failed !" ) ); + + // Init // port + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FBegin ( VEnableErrLog, ErrorLogFile ); + PPO_FOpen ( 0x378 /* BaseAdr */, 0 /* Id */ ); + PPO_FEnableReadDataOutPortBeforeWrite ( 0 /* Id */, 1 /* Enable */ ); + #endif + + // Set default values to first board conf in order to get DmaHostSize initialized BEFORE fw loading + + VPtBoard->AsicNb = EFRIO__MAX_ASIC_NB; // Max possible number + VPtBoard->FrameNbPerAcq = EFRIO__MAX_FRAME_NB_PER_ACQ; // "Nominal" value + + // DMA host size is the memory size allocated for DMA on CPU side + // It must be equal AT LEAST to the size of one acquisition and higher value are not useful + // VPtBoard->AsicNb + 1 => + 1 for extra channel + + // 25/05/2011 => Calculate DMA host size in function of ASIC name + + switch ( MapsName ) { + + case ASIC__MI26 : { + VPtBoard->DmaHostSz = ((MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + + case ASIC__ULT1 : { + VPtBoard->DmaHostSz = ((ULT1__ZS_FFRAME_MODE_2X160MHZ_W8_SZ * 2 * (EFRIO__MAX_ASIC_NB_FOR_DMA + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + + + // Set default values of Header & Trailer for DQ emulation + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x8000800; + + VPtAcqEmul->ParATrailer[0] = 0xAAAAAAAA; + VPtAcqEmul->ParATrailer[1] = 0xBBBBBBBB; + VPtAcqEmul->ParATrailer[2] = 0xCCCCCCCC; + VPtAcqEmul->ParATrailer[3] = 0xDDDDDDDD; + VPtAcqEmul->ParATrailer[4] = 0xEEEEEEEE; + VPtAcqEmul->ParATrailer[5] = 0xFFFFFFFF; + + +#ifdef EFRIO__INCLUDE_JTAG + + +#ifdef OLD_COM_JTAG_CODE + + // Init JTAG + + if( ! EFRIO_VGJtagMi26.IsBound()) { + OleCheck(CoMI26MasterConf::Create(EFRIO_VGJtagMi26)); + } + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + // Init JTAG end + + +#else + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + + // JTAG Mi26 + + if ( EFRIO__VGJtagMi26Ult1 == 0 ) { + + VHrComErr = CoMI26MasterConf::Create( EFRIO_VGJtagMi26 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + // 28/09/2011 + // => Update code because EFRIO_VGJtagMi26.get_Info (...) has changed => returns one more param = SW version now + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsSwVersion, &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => Version %s - Status %s", TOOLS__FWideString2CStr (VWsSwVersion, NULL, 0), TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + } + + // JTAG Ult1 + + else { + + VHrComErr = CoMI28COM::Create( EFRIO_VGJtagUlt1 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI28COM::Create failed !" ) ); + } + + if ( EFRIO_VGJtagUlt1.IsBound () ) { + OleCheck ( EFRIO_VGJtagUlt1.Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + } + + + // Init JTAG end + +#endif + + + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + VPtCont->InfInitDone = 0; + + +#ifndef EFRIO__V20_AND_LATER + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "EUDET Flex RIO DLL compiled on %s at %s", __DATE__, __TIME__ )); + err_error (( ERR_OUT, "******************************************************************" )); + +#else + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "- EUDET Flex RIO DLL V%d.%d compiled on %s at %s", VPtCont->VersionMajor, VPtCont->VersionMinor, __DATE__, __TIME__ )); + err_error (( ERR_OUT, "------------------------------------------------------------------" )); + err_error (( ERR_OUT, "%s", VPtCont->VersionCmt )); + err_error (( ERR_OUT, "******************************************************************" )); + +#endif + + err_retok (( ERR_OUT, "end" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 +Rev : 11/05/2011 + : - Handle version information -> majour, minor, comment + : + : 12/05/2011 + : - JTAG version Mi26 / Ult1 handling + : + : 19/05/2011 + : - Dma host size calculated for Ultimate because we don't know at this step which + : MAPS will be used and memory size for Ultimate is > the one for Mimosa 26 + : + : 25/05/2011 + : - Body of function is " empty " => it has been moved in EFRIO__FBeginExt (...) + : - Call EFRIO__FBeginExt ( ASIC__MI26, ... ) + : - EFRIO__FBeginExt (...) handles MapsName parameter ( Mi26 / Ultimate / ... ) + : EFRIO__FBegin still configure Mimosa 26 as it was done in first version of lib. + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + + FIL__VGDbgPtEFRIOContext = &EFRIO__VGContext; /* Debug ! */ + + err_error (( ERR_OUT, "TRACE => Init done" )); + + return ( EFRIO__FBeginExt ( ASIC__MI26, ErrorLogLvl, ErrorLogFile, MsgLogLvl, MsgLogFile ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEnd () + : +Goal : Terminate lib + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 05/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEnd () { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FEnd (); + #endif + + // Close JTAG COM classe + // Avoid "assertion message" when LabView is stop and then restarted + + err_error (( ERR_OUT, "1" )); + +#ifdef EFRIO__INCLUDE_JTAG + + + // JTAG Mi26 + + if ( EFRIO__VGJtagMi26Ult1 == 0 ) { + EFRIO_VGJtagMi26.Unbind(); + } + + else { + EFRIO_VGJtagUlt1.Unbind(); + } + + +#endif + + // Free frames buffer if allocated + + err_error (( ERR_OUT, "2" )); + + if ( VPtCont->RunCont.PtZsFFrameRaw !=NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + // Reset context record + + err_error (( ERR_OUT, "3" )); + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : +Goal : Build the frame list for one acquisition + : +Inputs : AcqStatus - ACquisition status ( < 0 -> HW error, 0 -> OK, > 0 -> Frame nb lost ) + : TrigStatus - No meaning now, reserved for future use + : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : +Level : +Date : 06/11/2010 +Rev : 24/02/2011 + : - Add parameters AcqStatus, TrigStatus to field new fields of EFRIO__TFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->AcqStatus = AcqStatus; + PtList->TrigStatus = TrigStatus; + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) + : +Goal : Init DAQ emulation either in standalone DAQ emulation application ( without + : HW ) or in LabView DAQ application. Selection done by RunInLabview parameter. + : +Inputs : RunInLabview = 0 => Run in C++ Builder DAQ emulation application + : = 1 => Run in Labview DAQ + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : If emulation is running under Labview ( RunInLabview = 1 ), frames emulation + : function overwite memory already allocated for Flew RIO board. In case emulation + : is runing in a standalone application ( RunInLabview = 0 ), this function allocates + : memory in PC DRAM to emulate Flex RIO RAM. + : + : This function sets default values of DAQ emulation parameters. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// RunInLabview = 0 => Run in C++ Builder DAQ emulation application +// RunInLabview = 1 => Run in Labview DAQ + +SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + // Reset context records + + memset ( VPtAcqEmul, 0, sizeof (EFRIO__TAcqEmul) ); + + memset ( VPtFrChk , 0, sizeof (EFRIO__TFrCheck) ); + + // Set default value of DAQ emulation parameters => Mainly for Labview which will not control all of them + + VPtAcqEmul->ParAcqCycleMs = 200; + VPtAcqEmul->ParEmuleDRamReadMs = 0; + VPtAcqEmul->ParEmuleFunctNo = 0; + VPtAcqEmul->ParRandomDataSz = 0; + VPtAcqEmul->ParSetMaxDataSzOnOneMaps = 1; + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x80008006; + + VPtAcqEmul->ParATrailer[0] = 0xAAAA0001; + VPtAcqEmul->ParATrailer[1] = 0xAAAA0002; + VPtAcqEmul->ParATrailer[2] = 0xAAAA0003; + VPtAcqEmul->ParATrailer[3] = 0xAAAA0004; + VPtAcqEmul->ParATrailer[4] = 0xAAAA0005; + VPtAcqEmul->ParATrailer[5] = 0xAAAA0006; + + VPtAcqEmul->ParTrigNbPerFrame = 0; + VPtAcqEmul->ParTrigOnOneFrameOverN = 1; + VPtAcqEmul->ParTrigOnNConsecutiveFrames = 1; + + VPtAcqEmul->ParATrig[0] = 10; + VPtAcqEmul->ParATrig[1] = 20; + VPtAcqEmul->ParATrig[2] = 30; + VPtAcqEmul->ParATrig[3] = 40; + + VPtAcqEmul->ParATS[0] = 100; + VPtAcqEmul->ParATS[1] = 200; + VPtAcqEmul->ParATS[2] = 300; + VPtAcqEmul->ParATS[3] = 400; + + + // Set Mi26 nb + + VPtFrChk->InfMi26Nb = VPtRunCont->ParMi26Nb; + + // Extra channel or not ? + + if ( (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtAcqEmul->InfExtraChan = 1; + } + + else { + VPtAcqEmul->InfExtraChan = 0; + } + + if ( RunInLabview == 0 ) { + + // Calculate DRAM size + + VPtAcqEmul->InfDRamSz = (VPtRunCont->ParMi26Nb + VPtAcqEmul->InfExtraChan) * VPtRunCont->ParFrameNbPerAcq * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 4; + + VPtAcqEmul->InfDRamSzMb = VPtAcqEmul->InfDRamSz / (1024 * 1024); + + // Alloc RAM to emulate Flex RIO DRAM + + VPtAcqEmul->InfDRamPtr = (UInt32*) malloc ( VPtAcqEmul->InfDRamSz ); + + err_retnull ( VPtAcqEmul->InfDRamPtr, (ERR_OUT,"Allocation of %d bytes for Flex RIO DRAM emulation failed !", VPtAcqEmul->InfDRamSz) ); + + } // End if ( RunInLabview == 0 ) + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleEnd ( ) + : +Goal : Terminate DAQ emulation + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Free DRAM if allocated in PC to emulate Flex RIO DRAM. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEmuleEnd ( ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + if ( VPtAcqEmul->InfDRamPtr != NULL ) { + free ( VPtAcqEmul->InfDRamPtr ); + } + + err_retok (( ERR_OUT, "" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) + : +Goal : Emulate Flex RIO DRAM read + : +Inputs : Cmd - 0 => Do nothing + : - 1 => Fill memory with zero + : +Ouputs : A pointer to DRAM or NULL if not allocated + : +Globals : + : +Remark : A delay should also be added here later to emulate Flex RIO DRAM access time + : configured by field ParEmuleDRamReadMs of EFRIO__TAcqEmul. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + + + if ( Cmd == 1 ) { + memset ( VPtAcqEmul->InfDRamPtr, 0, VPtAcqEmul->InfDRamSz ); + } + + Sleep ( VPtAcqEmul->ParEmuleDRamReadMs ); + + return ( VPtAcqEmul->InfDRamPtr ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) + : +Goal : Used for DAQ emulation. + : Set the FrameId fields ( TLU & Flex RIO triggers ) of all triggers info in + : the record used to emulate triggers + : +Inputs : FrameId - The value of frame id to set in all triggers info + : TrigNb - The number of trigger info to set in record + : PtRec - Pointer to destination record + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : The field set are + : - for TLU trigger => F.FrameIdInAcq ( see record EFRIO__TTluTrigger in *.typ ) + : - for Flex RIO trigger => F.Mi26Frame ( see record EFRIO__TFlexRioTimeStamp1 in *.typ ) + : +Level : +Date : 03/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) { + + SInt32 ViTrig; + EFRIO__TTluTrigger* VPtTrig; + EFRIO__TFlexRioTimeStamp1* VPtTs; + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + if ( TrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"TrigNb=%d > Max=%d", TrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) ); + } + + for ( ViTrig=0; ViTrig < TrigNb; ViTrig++ ) { + + VPtTrig = (EFRIO__TTluTrigger*) &PtRec->ATrig[2 * ViTrig]; + VPtTs = (EFRIO__TFlexRioTimeStamp1*) &PtRec->ATrig[(2 * ViTrig)+1]; + + VPtTrig->F.FrameIdInAcq = FrameId; + VPtTs->F.Mi26Frame = FrameId; + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) + : +Goal : Function used to avoid data copy while transfering data from one Vi to + : another under Labview. Because sometimes, it seems that Labview use pointers + : but it's not the case, a copy of data is done, and execution time is lost ... + : +Inputs : CmdGetPtrCpyAlloc = 0 => return buffer pointer + : = 1 => store PtSrcW32 but NO copy of data + : = 2 => copy src to buffer + : = 3 => alloc buffer + : + : AllocW32Sz - Memory size to alloc in W32 ( if CmdGetPtrCpyAlloc = 3 ) + : PtSrcW32 - Pointer to source data to copy to buffer + : SrcW32Sz - Size of source data to copy to buffer + : +Ouputs : A pointer on the buffer or NULL if not allocated. + : +Globals : + : +Remark : It's mainly used to passe a pointer on board DRAM to DLL ( CmdGetPtrCpyAlloc = 1 ) + : +Level : +Date : 07/09/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) { + + static UInt32* VPtBuff = NULL; + static UInt32 VAllocW32Sz = 0; + UInt32 VAllocSz; + SInt32 Vi; + + // Get pointer request + + if ( CmdGetPtrCpyAlloc == 0 ) { + return (VPtBuff); + } + + // Store pointer request + + if ( CmdGetPtrCpyAlloc == 1 ) { + VPtBuff = PtSrcW32; + return (VPtBuff); + } + + // Copy request + + if ( CmdGetPtrCpyAlloc == 2 ) { + + if ( (VPtBuff == NULL) || (SrcW32Sz > VAllocW32Sz) ) { + err_error (( ERR_OUT, "VPtBuff = %x = NULL ? / SrcW32Sz=%d > VAllocW32Sz=%d", VPtBuff, SrcW32Sz, VAllocW32Sz )); + return (NULL); + } + + for ( Vi=0; Vi < SrcW32Sz; Vi++ ) { + VPtBuff[Vi] = PtSrcW32[Vi]; + } + + return (VPtBuff); + } + + + // Allocation request + + if ( CmdGetPtrCpyAlloc == 3 ) { + + // Free mem if already allocated + + if ( VPtBuff != NULL ) { + free ( VPtBuff ); + VPtBuff = NULL; + } + + // Alloc new mem + + VAllocW32Sz = AllocW32Sz; + VAllocSz = VAllocW32Sz * 4; + + VPtBuff = (UInt32*) malloc ( VAllocSz ); + + // If allocation failed => error message + ret NULL + + if ( VPtBuff == NULL ) { + err_error (( ERR_OUT, "Allocation of %d bytes failed !", VAllocSz )); + return (NULL); + } + + // If allocation OK => ret buffer pointer + + return (VPtBuff); + } + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 + : EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : Mi26Nb - Mimosa 26 number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 => Creation with all job done in function body + : +Rev : 12/05/2011 + : - Code moved to EFRIO__FConfRunExt (...) + : - Call EFRIO__FConfRunExt ( ASIC__MI26, ... ) + : + : +Doc date : 12/05/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) { + + SInt32 VRet; + + VRet = EFRIO__FConfRunExt ( ASIC__MI26, Mi26Nb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DataTransferMode, TrigMode, DestDir, FileNamePrefix, SaveToDisk, SendOnEth, SendOnEthPCent ); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, + : SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : MapsName - Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + : MapsNb - MAPS number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 -> Creation of EFRIO__FConfRun (...) + : 12/05/2011 -> Change name from EFRIO__FConfRun to EFRIO__FConfRunExt and add MapsName parameter + : See " Rev 12/05/2011 " + ; + : +Rev : 04/11/2010 + : - Save to disk + : + : 21/02/2011 + : - Set new fields ( ParDaqVersion, ParMapsName ) + : + : 12/05/2011 + : - A new parameter MapsName must be added, in order to keep compatibility with EUDET lib : + : -> This function has been renamed EFRIO__FConfRunExt ( it was EFRIO__FConfRun before ) + : -> The new parameter MapsName had been added + : -> The former EFRIO__FConfRun call now EFRIO__FConfRunExt with MapsName param = ASIC__MI26 + : + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRunExt ( SInt8 MapsName, SInt8 MapsNb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + SInt32 VMaxFrameSz; + SInt32 VRet; + + + // Check function parameters + + err_retnull ( DestDir , (ERR_OUT,"Abort : DestDir == NULL !") ); + err_retnull ( FileNamePrefix, (ERR_OUT,"Abort : FileNamePrefix == NULL !") ); + + // Debug print function parameters + + err_error (( ERR_OUT, "Call with : MapsNb=%d - RunNo=%d - TotEvNb=%d - EvNbPerFile=%d - FrameNbPerAcq=%d - DestDir=%s - FileNamePrefix=%s", MapsNb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DestDir, FileNamePrefix )); + + // Set hard coded parameters + + VPtCont->RunCont.ParMeasDataRate = 1; // Enable data rate measurement + VPtCont->RunCont.ParAcqNbToMeasDataRate = 10; // Uses 10 acquistions to measure data rate + + // Set default values to new fields + + VPtCont->RunCont.ParDaqVersion = 0; + + // Copy run parameters to run context record + + VPtCont->RunCont.ParMapsName = MapsName; + VPtCont->RunCont.ParMi26Nb = MapsNb; + VPtCont->RunCont.ParRunNo = RunNo; + VPtCont->RunCont.ParTotEvNb = TotEvNb; + VPtCont->RunCont.ParEvNbPerFile = EvNbPerFile; + VPtCont->RunCont.ParFrameNbPerAcq = FrameNbPerAcq; + VPtCont->RunCont.ParDataTransferMode = DataTransferMode; + VPtCont->RunCont.ParTrigMode = TrigMode; + + VPtCont->RunCont.ParSaveOnDisk = SaveToDisk; + VPtCont->RunCont.ParSendOnEth = SendOnEth; + VPtCont->RunCont.ParSendOnEthPCent = SendOnEthPCent; + + sprintf ( VPtCont->RunCont.ParDestDir , "%s", DestDir ); + sprintf ( VPtCont->RunCont.ParFileNamePrefix, "%s", FileNamePrefix ); + + sprintf ( VPtCont->RunCont.InfDataFileName, "%s\\%s%d.bin", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + sprintf ( VPtCont->RunCont.InfConfFileName, "%s\\%s%d.par", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + VPtCont->RunCont.InfSaveDataOnDiskRunning = 0; + + // Compare run conf paramters to the max parameters used to calculate DmaHostSz in FBegin + // If they have higher values => DmaHostSz send to board at fw loading is bad => Abort + + if ( (VPtCont->RunCont.ParMi26Nb > EFRIO__MAX_ASIC_NB) || (VPtCont->RunCont.ParFrameNbPerAcq > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_error (( ERR_OUT, "Bad Mi26 nb ? Run conf = %d - Max = %d", VPtCont->RunCont.ParMi26Nb, EFRIO__MAX_ASIC_NB )); + err_error (( ERR_OUT, "Bad frame nb per acq ? Run conf = %d - Max = %d", VPtCont->RunCont.ParFrameNbPerAcq, EFRIO__MAX_FRAME_NB_PER_ACQ )); + err_retfail ( -1, (ERR_OUT,"Abort : Bad value of AsicNb=%d or FrameNbPerAcq=%d", VPtCont->RunCont.ParMi26Nb, VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // Update monitor context fields + + VPtCont->MonCont.InfFrameNbToSend = (SInt32) ( (float) FrameNbPerAcq * (float) ( (float) SendOnEthPCent / (float) 100 )); + + VPtCont->MonCont.InfSzToSend = 0; // Because it's not known at this step + + err_error (( ERR_OUT, "TRACE => InfFrameNbToSend = %d", VPtCont->MonCont.InfFrameNbToSend )); + + // Overwrite default values of AsicNb & FrameNbPerAcq + + VPtBoard->AsicNb = VPtCont->RunCont.ParMi26Nb; + VPtBoard->FrameNbPerAcq = VPtCont->RunCont.ParFrameNbPerAcq; + + // DMA host size => Already initialized in FBegin function + // VPtBoard->DmaHostSz = (MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * VPtBoard->AsicNb * VPtBoard->FrameNbPerAcq) / (1024 * 1024); + + // Configure others board conf parameters + + VPtBoard->BoardId = 0; + + sprintf ( VPtBoard->AsicName, "%s", "Mimosa 26" ); + + VPtBoard->ReadoutMode = 0; // Reserved for future use + VPtBoard->DataClkFrequency = 80; // 80 MHz + + if ( (DataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (DataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtBoard->EnableExtraChannel = 1; // Yes + } + + else { + VPtBoard->EnableExtraChannel = 0; // No + } + + err_trace (( ERR_OUT, "EnableExtraChannel=%d", VPtBoard->EnableExtraChannel )); + + VPtBoard->TriggerMode = 0; // Trigger mode -> disabled + VPtBoard->TriggerDetectTimeWindow = 0; // Trigger mode -> Window during which we count triggers to detect beginning of spill + VPtBoard->TriggerDetectOccurNb = 0; // Trigger mode -> Number of trigger required during "TriggerDetectTimeWindow" to decide that spill has begun + VPtBoard->AcqNbPerTrig = 0; // Trigger mode -> Number of consecutive Acq stored after beginning of spill detection + + VPtBoard->EnableTimeStamping = 0; // On board time stamping -> disabled + VPtBoard->TimeStampRes = 0; // On board time stamp resolution in [ns] + + VPtBoard->EnableTrigCnt = 0; // On board trigger counter + + VPtBoard->TagEventsStoredByDUT = 0; // Tag events taken dy DUT -> disabled + VPtBoard->ReadTluTrigCntEachNTrig = 0; // Read event counter provided by TLU -> disabled + + + + // Allocate memory + + // IPHC data transfer mode + + if ( DataTransferMode == EFRIO__TRF_MODE_IPHC ) { + + // Free tmp trigger record if allocated + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + // Free EUDET mode buffer + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.PtFrame = NULL; + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Alloc IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + + VPtCont->RunCont.InfZsFFrameRawBuffSz = VPtCont->RunCont.ParMi26Nb * (VPtCont->RunCont.ParFrameNbPerAcq + 200) * sizeof (MI26__TZsFFrameRaw); + + VPtCont->RunCont.PtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + err_retnull ( VPtCont->RunCont.PtZsFFrameRaw, (ERR_OUT,"Allocation of IPHC buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // EUDET data transfer mode + + else { + + // Alloc tmp trigger record + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + VPtCont->PtTmpTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtCont->PtTmpTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Free IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + VPtCont->RunCont.InfZsFFrameRawBuffSz = 0; + + // Reset frame list + + memset ( VPtCont->AAcqFrameList, 0, sizeof (EFRIO__TFrameList) ); + + // Alloc + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Upgrade for Ultimate + + // VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VPtCont->RunCont.InfFrameBuffSz = VPtCont->RunCont.ParFrameNbPerAcq * VMaxFrameSz; + + VPtCont->RunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->RunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->RunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq) ); + + err_error (( ERR_OUT, "TRACE => Frames buffer sz = %d Bytes", VPtCont->RunCont.InfFrameBuffSz )); + err_error (( ERR_OUT, "TRACE => Frames buffer sz = %d MBytes", VPtCont->RunCont.InfFrameBuffSz / (1024 * 1024) )); + } + + + // Reset run context results fields + + VPtCont->RunCont.ResAcqCnt = 0; + VPtCont->RunCont.ResFrameCnt = 0; + VPtCont->RunCont.ResEventCnt = 0; + + // Set status conf done + + VPtCont->ABoardsStatus[0].ConfDone = 1; + + // Set flag init done + + VPtCont->InfInitDone = 1; + + // Init for Labview because some emulation parameters are not controlled by GUI + + #ifdef APP_DLL + EFRIO__FEmuleBegin ( 1 /* RunInLabview */ ); + #endif + + + err_retok (( ERR_OUT, "end" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 07/03/2011 + : - Get disk sector size from OS + : + : 20/05/2011 + : - Use run param to calculate TCStreamFile max buffer size + : + : 13/10/2011 + : - Add creation of a copy of run conf file in x:\log ( VInfConfFileNameCpy ). + : + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStartSavingOnFile () { + + SInt32 VRet; + char VDiskDrive[3]; + SInt32 VDiskSectorSz; + SInt8 VUseThread; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + EFRIO__TFrame* VPtFrame; + SInt32 VStreamFileMaxBlocSz; + char VInfConfFileNameCpy[GLB_FILE_PATH_SZ]; // Copy in x:\log of the run conf file + + + VRet = 0; + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + // Debug + + msg (( MSG_OUT, "EFRIO__FStartSavingOnFile () => Run No = %d", VPtRunCont->ParRunNo )); + + // Create & write conf file + + // msg (( MSG_OUT, "VPtRunCont->ResConfFileName=%s", VPtRunCont->ResConfFileName )); + + // Set pointer to 0 before saving and restor them afer + + VPtZsFFrameRaw = VPtRunCont->PtZsFFrameRaw; + VPtFrame = VPtRunCont->PtFrame; + + VPtRunCont->PtZsFFrameRaw = NULL; + VPtRunCont->PtFrame = NULL; + + VRet = VRet | EFRIO__VGRunConfFile.PubFConf ( VPtRunCont->InfConfFileName, FIL__TCBinFile_RWB_MODE_WRITE, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont), 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunConfFile.PubFCreate (); + VRet = VRet | EFRIO__VGRunConfFile.PubFSeqWrite ( VPtRunCont, sizeof (EFRIO__TRunCont) ); + VRet = VRet | EFRIO__VGRunConfFile.PubFClose (); + + VPtRunCont->PtZsFFrameRaw = VPtZsFFrameRaw; + VPtRunCont->PtFrame = VPtFrame; + + err_retfail ( VRet, (ERR_OUT,"Run config file = %s creation failed !", VPtRunCont->InfConfFileName) ); + + // Make a copy of run info file + + sprintf ( VInfConfFileNameCpy, "x:\\log\\%s%d.par", VPtRunCont->ParFileNamePrefix, VPtRunCont->ParRunNo ); // 13/10/2011 + + VRet = FIL_FCpyFile ( VPtRunCont->InfConfFileName, VInfConfFileNameCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT, "Copy of info = %s file i, %s failed !", VPtRunCont->InfConfFileName, VInfConfFileNameCpy )); + err_error (( ERR_OUT, "Copy of info = %s file i, %s failed !", VPtRunCont->InfConfFileName, VInfConfFileNameCpy )); + } + + // Create data file + + if ( VPtRunCont->ParSaveOnDisk == 1 ) { + VUseThread = 1; + } + + else { + VUseThread = 0; + } + + + // Get disk sector size + + strncpy ( VDiskDrive, VPtRunCont->InfDataFileName, 2 ); + + VDiskDrive[2] = 0; + + VDiskSectorSz = FIL_FGetDiskSectorSz ( VDiskDrive ); + + err_retfail ( VDiskSectorSz, (ERR_OUT,"Abort => Unable to get drive %s sector size !", VDiskDrive ) ); + + msg (( MSG_OUT, "Disk sector sz = %d Bytes", VDiskSectorSz )); + + // Set TCStreamFile disk sector size + + VRet = VRet | EFRIO__VGRunDataFile.PubFSetDiskSectorSz ( VDiskSectorSz ); + + // Conf TCStreamFile + + // VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + // VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + // 20/05/2011 + + VStreamFileMaxBlocSz = ( VPtRunCont->ParFrameNbPerAcq * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ); + + err_error (( ERR_OUT, "TRACE => Calc TCStreamFile max bloc sz - %d Fr/Acq - Bloc Sz = %d MB", VPtRunCont->ParFrameNbPerAcq, VStreamFileMaxBlocSz / (1024 * 1024) )); + + VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, VStreamFileMaxBlocSz /* Max */, VStreamFileMaxBlocSz /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + + err_retfail ( VRet, (ERR_OUT,"Run data file = %s creation failed !", VPtRunCont->InfDataFileName) ); + + VPtRunCont->InfSaveDataOnDiskRunning = 1; + + } + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 16/02/2011 + : - Test if ParTotEvNb reached, if yes => call EFRIO__FStopSavingOnFile () + : + : 24/02/2011 + : - Handle SpareW32Par as an array ASpareW32Par now + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSaveAcqOnFile () { + + SInt32 VRet; + SInt8 VUseThread; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TFileSpareW32Info VSpareW32Info; + + + VRet = 0; + + if ( VPtRunCont->InfSaveDataOnDiskRunning == 0 ) { + return (0); + } + + if ( VPtRunCont->ResEventCnt > VPtRunCont->ParTotEvNb ) { + EFRIO__FStopSavingOnFile (); + err_error (( ERR_OUT, "TRACE => End of run reached : %d events saved on disk", VPtRunCont->ResEventCnt )); + return (0); + } + + // Save acq on file if + // - Run conf "save on disk" parameter is set + // - There is something to save => ResAcqFunctRetCode = acquisition size <> 0 + + if ( (VPtRunCont->ParSaveOnDisk > 0) && (VPtRunCont->ResAcqFunctRetCode > 0) ) { + + VSpareW32Info.AcqStatus = VPtFrList->AcqStatus; + VSpareW32Info.TrigStatus = VPtFrList->TrigStatus; + VSpareW32Info.TotFrameNb = VPtFrList->TotFrameNb; + VSpareW32Info.DiskSectorSz = EFRIO__VGRunDataFile.PubFGetDiskSectorSz (); + + VRet = EFRIO__VGRunDataFile.PubFSeqWrite ( VPtRunCont->PtFrame, VPtRunCont->ResAcqFunctRetCode /* Acq sz */, VPtRunCont->ResEventCnt - 1 /* DbgCallPar */, 1 /* SpareW32InfoFormat */, (SInt32*) &VSpareW32Info, sizeof (VSpareW32Info) / 4 /* SpareW32InfoNb */ ); + + } + + err_retfail ( VRet, (ERR_OUT,"Saving Acq=%d of %d bytes on file %s failed", VPtRunCont->ResAcqCnt - 1, VPtRunCont->ResAcqFunctRetCode, VPtRunCont->InfDataFileName ) ); + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStopSavingOnFile () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + VRet = 0; + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_IPHC ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__TRF_MODE_IPHC not hanlded") ); + } + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + VPtRunCont->InfSaveDataOnDiskRunning = 0; + + VRet = VRet | EFRIO__VGRunDataFile.PubFFlush (); + VRet = VRet | EFRIO__VGRunDataFile.PubFClose (); + + err_retfail ( VRet, (ERR_OUT,"Error while closing data file = %s", VPtRunCont->InfDataFileName) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +#undef COMPIL_FTluTrigger2Str +#ifdef COMPIL_FTluTrigger2Str + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert TLU trigger info record to string for print or display + : +Inputs : Trig - Source trigger record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display + : +Inputs : Ts - Source time stamp record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger / timestamp as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in IPHC data transfer mode. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + SInt32 VNiFrame; + SInt32 VNiFramePMi26; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[0]; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VNiFrame = ViFrame * VPtRunCont->ParMi26Nb; + + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + VNiFramePMi26 = VNiFrame + ViMi26; + + if ( VPtFrame[VNiFramePMi26].Header != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Header, VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFrame[VNiFramePMi26].Trailer != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Trailer, VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFrame[VNiFramePMi26].FrameCnt; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFrame[VNiFramePMi26].FrameCnt != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].FrameCnt, VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in EUDET 1,2,3 data transfer modes. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +UInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrame* VPtFr; + SInt32 ViFrame; + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VPtFr = VPtFrList->AFramePtr[ViFrame]; + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + if ( VPtFr->Header.AMapsHeader[ViMi26] != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsHeader[ViMi26], VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFr->Header.AMapsTrailer[ViMi26] != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsTrailer[ViMi26], VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFr->Header.AMapsFrameCnt[ViMi26]; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFr->Header.AMapsFrameCnt[ViMi26] != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFr->Header.AMapsFrameCnt[ViMi26], VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 29/04/2011 ( DPXI version of 20/08/2009 moved here ) +Doc date : 20/08/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FChkFrameLight ( SInt16 FuncId, SInt32 CurFrame, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // Debug tool + + if ( VPtTestCont->ParPrintLvl == -1 ) { + msg (( MSG_OUT, "Nb Mi26 to test : %d", VMi26Nb )); + } + + + // Init frame cnt array on first frame values and errors flag + + if ( CurFrame == 0 ) { + + VErrors = 0; + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // Because CurFrame = 0 in this bloc => PtFrame[0] is first Mi26 + + for ( ViMi26=1; ViMi26 < VMi26Nb; ViMi26++ ) { + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "A - Frame cnt error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + } + + } + + else { + ++VPtTestCont->InfMapsFrameCntRef; + } + + // Check frame cnt & header & trailer + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter of CurFrame > 0 + + if ( CurFrame != 0 ) { + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "B - Frame cnt error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + } + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Header error [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Trailer error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + + return (VErrors); +} + + +#ifndef NO_MI26 + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 02/02/2010 +Rev : 07/05/2010 + : - Trigger calculation + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // msg (( MSG_OUT, "==> DPXI__MI26_FFRioAcqDeserData1Mi26 : Mi26NbToRead=%d - EltNb=%d - TotAnsSz=%d", VPtServ->PtParAcqReqFunc->AsicNbToRead, EltNb, PtAcq->InfTotAnsSz )); + + // Copy Acq inf pointers to local pointers + + // $$$ VPtAcqData = PtAcq->InfPtAcqData; + // $$$ VptZsFFrameRaw = PtAcq->InfPtZsFFrameRaw; + // $$$ msg (( MSG_OUT, "DPXI__MI26_FFRioAcqDeserData1Mi26 => AcqReqFuncSz=%d - MaxDataSz=%d - VTotAnsSz=%d", PtAcq->InfParAcqReqFuncSz, VPtServ->PtParAcqReqFunc->MaxDataSz, PtAcq->InfTotAnsSz )); + // $$$ memset ( VPtAcqData, 0, PtAcq->InfTotAnsSz ); + // $$$ err_trace (( ERR_OUT, "Start extract data for FrameNb=%d", VPtServ->PtParAcqReqFunc->FrameNb )); + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // $$$ VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VptZsFFrameRaw[ViFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[ViFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + VptZsFFrameRaw[ViFrame].DataLength = VDataLengthField; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32 = (UInt32*) VptZsFFrameRaw[ViFrame].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[ViFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + VptZsFFrameRaw[ViFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + VptZsFFrameRaw[ViFrame].Zero2 = VZero2; + ++ViSrcW32; + + // $$$ DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + VptZsFFrameRaw[ViFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[ViFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[ViFrame].SStatus.HitCnt = -1; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 09/03/2010 +Rev : 06/05/2010 + : - Add trigger extract + : Warning ! Copy Zero & Zero2 fields of frame chip No 0 to ALL others chips ! + : All fields Zero & Zero2 are equals to the fields of first chip + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + SInt32 V6iFrameP1; + SInt32 V6iFrameP2; + SInt32 V6iFrameP3; + SInt32 V6iFrameP4; + SInt32 V6iFrameP5; + UInt32 VADataLengthField[6]; + UInt16 VADataLengthW16[6]; + UInt16 VADataLengthW32[6]; + UInt16 VDataLengthW32Max; + register SInt32 ViSrcW32; + register SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get AcqId + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // err_warning (( ERR_OUT, "TRACE : Memset buffer")); + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + V6iFrameP1 = V6iFrame + 1; + V6iFrameP2 = V6iFrame + 2; + V6iFrameP3 = V6iFrame + 3; + V6iFrameP4 = V6iFrame + 4; + V6iFrameP5 = V6iFrame + 5; + + + VptZsFFrameRaw[V6iFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VptZsFFrameRaw[V6iFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + + VptZsFFrameRaw[V6iFrame].DataLength = VADataLengthField[0]; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VptZsFFrameRaw[V6iFrameP1].DataLength = VADataLengthField[1]; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + + VptZsFFrameRaw[V6iFrameP2].DataLength = VADataLengthField[2]; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VptZsFFrameRaw[V6iFrameP3].DataLength = VADataLengthField[3]; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VptZsFFrameRaw[V6iFrameP4].DataLength = VADataLengthField[4]; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VptZsFFrameRaw[V6iFrameP5].DataLength = VADataLengthField[5]; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + // Find max data length of the six Mi26 + + VDataLengthW32Max = MATH_FUInt16Max ( VADataLengthW32, 6 ); + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32Chip0 = (UInt32*) VptZsFFrameRaw[V6iFrame].ADataW16; + VPtDataW32Chip1 = (UInt32*) VptZsFFrameRaw[V6iFrameP1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VptZsFFrameRaw[V6iFrameP2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VptZsFFrameRaw[V6iFrameP3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VptZsFFrameRaw[V6iFrameP4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VptZsFFrameRaw[V6iFrameP5].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip1[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip2[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip3[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip4[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip5[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VptZsFFrameRaw[V6iFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + ++ViSrcW32; + + // DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + + VptZsFFrameRaw[V6iFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrame].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP1].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 1 + 18 + (6 * VADataLengthW32[1])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP1].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP1].SStatus.AsicNo = 1; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP1].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP2].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 2 + 18 + (6 * VADataLengthW32[2])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP2].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP2].SStatus.AsicNo = 2; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP2].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP3].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 3 + 18 + (6 * VADataLengthW32[3])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP3].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP3].SStatus.AsicNo = 3; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP3].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP4].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 4 + 18 + (6 * VADataLengthW32[4])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP4].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP4].SStatus.AsicNo = 4; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP4].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP5].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 5 + 18 + (6 * VADataLengthW32[5])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP5].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP5].SStatus.AsicNo = 5; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP5].SStatus.HitCnt = -1; + + + + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 6 /* Mi26Nb */ ); + // PtAcq->ResAsicErrorsRejCurAcq = 0; + + // if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 25/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 27/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointers + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // If length > max possible => Set it to 0 + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 29/10/2010 version handling 6 Mi26 ) +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V9iFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V9iFrame = 9 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 9 = 9 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; // 18 = 9 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + +// Mode 2 - 12 x Mi26 +// 23/11/2011 +// $$ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode12Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V13iFrame; + UInt32 VADataLengthField[12]; + UInt32 VADataLengthW8[12]; + UInt16 VADataLengthW16[12]; + UInt32 VADataLengthW32[12]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[12]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode12Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 13; // Divide by 13 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V13iFrame = 13 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[8] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[9] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[10] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[11] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + VADataLengthW16[8] = (VADataLengthField[8] & 0x0000FFFF) + ((VADataLengthField[8] & 0xFFFF0000) >> 16); + VADataLengthW16[9] = (VADataLengthField[9] & 0x0000FFFF) + ((VADataLengthField[9] & 0xFFFF0000) >> 16); + VADataLengthW16[10] = (VADataLengthField[10] & 0x0000FFFF) + ((VADataLengthField[10] & 0xFFFF0000) >> 16); + VADataLengthW16[11] = (VADataLengthField[11] & 0x0000FFFF) + ((VADataLengthField[11] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 12 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 12; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 12 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 12 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 12 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViMi26=0; ViMi26 < 12; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + VPtFrame->Header.AMapsDataLength[8] = VADataLengthW8[8]; + VPtFrame->Header.AMapsDataLength[9] = VADataLengthW8[9]; + VPtFrame->Header.AMapsDataLength[10] = VADataLengthW8[10]; + VPtFrame->Header.AMapsDataLength[11] = VADataLengthW8[11]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 12; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + VAPtCpyDestW32[8] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 8 * VDataLengthW32Max ) ); + VAPtCpyDestW32[9] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 9 * VDataLengthW32Max ) ); + VAPtCpyDestW32[10] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 10 * VDataLengthW32Max ) ); + VAPtCpyDestW32[11] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 11 * VDataLengthW32Max ) ); + + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[8] = *VPtCpySrcW32; + ++VAPtCpyDestW32[8]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[9] = *VPtCpySrcW32; + ++VAPtCpyDestW32[9]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[10] = *VPtCpySrcW32; + ++VAPtCpyDestW32[10]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[11] = *VPtCpySrcW32; + ++VAPtCpyDestW32[11]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 12; // Bypass Mi26 x 12 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 13; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (13 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * VADataLengthW32[0])]; // 39 = 13 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 1 + (13 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 2 + (13 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 3 + (13 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 4 + (13 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 5 + (13 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 6 + (13 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 7 + (13 * VADataLengthW32[7])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[8] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 8 + (13 * VADataLengthW32[8])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[9] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 9 + (13 * VADataLengthW32[9])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[10] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 10 + (13 * VADataLengthW32[10])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[11] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + 11 + (13 * VADataLengthW32[11])]; + ++ViSrcW32; + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * MI26__ZS_FFRAME_RAW_MAX_W32) + 13]; // 13 = 13 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V13iFrame) + 39 + (13 * MI26__ZS_FFRAME_RAW_MAX_W32) + 26]; // 26 = 13 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 26; // 13 times 2 zero fields = 26 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 12 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +// Mode 2 - N x Mi26 +// 17/11/2011 +// $$ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[16]; + UInt32 VADataLengthW8[16]; + UInt16 VADataLengthW16[16]; + UInt32 VADataLengthW32[16]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[16]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + + SInt8 VMi26NbP1; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 (Mi26Nb=%d, P=%x, EltNb=%d)", Mi26Nb, PtSrcW32, EltNb )); + + // Mi26 nb check + + if ( (Mi26Nb < 0) || (Mi26Nb > 16) ) { + err_retfail ( -1, (ERR_OUT,"Bad Mi26 Nb = %d => Out of range [0..16]", Mi26Nb) ); + } + + VMi26NbP1 = Mi26Nb + 1; + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / VMi26NbP1; // Divide by 7 because of extral channel + + // VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = VMi26NbP1 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsHeader[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsFrameCnt[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthField[ViMi26] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + /* + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VADataLengthW16[ViMi26] = (VADataLengthField[ViMi26] & 0x0000FFFF) + ((VADataLengthField[ViMi26] & 0xFFFF0000) >> 16); + } + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, Mi26Nb ); + + /* + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + */ + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < Mi26Nb /* 6 */; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, Mi26Nb /* 6 */ * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + + for ( ViMi26=0; ViMi26 < Mi26Nb /* 6 */; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsDataLength[ViMi26] = VADataLengthW8[ViMi26]; + } + + /* + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + */ + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * Mi26Nb; + + // VDataLengthW32ToCpy = VDataLengthW32Max * 6; + + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VAPtCpyDestW32[ViMi26] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + (ViMi26 * VDataLengthW32Max) ); + } + + + /* + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + */ + + + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + *VAPtCpyDestW32[ViMi26] = *VPtCpySrcW32; + ++VAPtCpyDestW32[ViMi26]; + ++VPtCpySrcW32; + } + + /* + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + */ + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += Mi26Nb; // Bypass Mi26 x 6 data + + // VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + + VPtEChanSrcW32 += VMi26NbP1; + + // VPtEChanSrcW32 += 7; + + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32); + + // ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VPtFrame->Header.AMapsTrailer[ViMi26] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + ViMi26 + (VMi26NbP1 * VADataLengthW32[ViMi26])]; + ++ViSrcW32; + } + + + + // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + /* + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + */ + + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + VMi26NbP1]; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + (3 * VMi26NbP1) + (VMi26NbP1 * MI26__ZS_FFRAME_RAW_MAX_W32) + (2 * VMi26NbP1)]; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += (2 * VMi26NbP1); // 7 times 2 zero fields = 14 + + // ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, Mi26Nb ); + + // EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 03/11/2010 version handling 6 Mi26 ) + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 9 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = 9 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + /* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + + */ + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + +#endif // NO_MI26 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + +#ifndef NO_MI26 + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + } + + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + + // VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 ( Mi26Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode8Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 12 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode12Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode8Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); + +#endif // NO_MI26 + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagLoadFile ( char* FileName ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagLoadFile (FileName); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagLoadFile (FileName); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagLoadFile ( char* FileName ) { + + HRESULT VRetCode; + WideString VStatus; + WideString VFileName; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + + if ( VJtag.IsBound () ) { + + VFileName = FileName; + + OleCheck( VRetCode = VJtag.MasterConfLoadFile( VFileName , &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Load JTAG file = %s failed !", FileName) ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagReset ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagReset (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagReset (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagReset ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfReset (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Reset chip failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagLoadChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagLoadChip (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagLoadChip (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: -n = error number on JTAG readback +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 28/09/2011 + : - Update code because MasterConfReadBack (...) has changed => return one more param = Reaad back errors nb + : If <> 0 return -(errors number) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FJtagLoadChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + long VReadBackErrorsNb; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfUpdateAll (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + // 28/09/2011 + // Update code because MasterConfReadBack (...) has changed => return one more param = Reaad back errors nb + // If <> 0 return -(errors number) + + OleCheck( VRetCode = VJtag.MasterConfReadBack ( &VReadBackErrorsNb, &VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Read back chip parameters failed !") ); + } + + if ( VReadBackErrorsNb > 0 ) { + err_retfail ( -VReadBackErrorsNb, (ERR_OUT,"JTAG -> Read back chip => Write <> Read => %d errors !", VReadBackErrorsNb ) ); + } + + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FJtagStartChip ( ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FJtagStartChip (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FJtagStartChip (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagStartChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfStart (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 11/05/2011 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FHwStartChip ( SInt32 SpareS32Par ) { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + + + switch ( VPtRun->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FHwStartChip ( SpareS32Par ); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FHwStartChip ( SpareS32Par ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRun->ParMapsName) ); + break; } + + } + + return (VRet); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2010 +Doc date : 10/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FHwStartChip ( SInt32 SpareS32Par ) { + + err_warning (( ERR_OUT, "EFRIO__MI26_FHwStartChip (Par=%d)", SpareS32Par )); + + // Start = D6, Speak = D7* + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD6 ( 0 /* Id */, 0 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + + Sleep ( 100 ); // 08/06/2011 => Debug for test with Flex RIO trig emulator + + PPO_FOutD6 ( 0 /* Id */, 0 ); + + #else + err_warning (( ERR_OUT, "HW start not done -> // port not enabled !" )); + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 19/05/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FTestOnDataGetJtagRef () { + + SInt32 VRet; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + // Sel Mi26 + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( ViMaps, &VStrComStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Select Maps Id = %d failed !", ViMaps) ); + } + + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 0 /* RegId */, &VHighTrailerFromJtag, &VRegValFromMi26, &VStrComStatus) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 1 /* RegId */, &VLowTrailerFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 2 /* RegId */, &VHighHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa26ConfGetHeaderTrailer ( 3 /* RegId */, &VLowHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + + VPtTestCont->ParAMapsHeaderRef[ViMaps] = VLowHeaderFromJtag + (VHighHeaderFromJtag << 16); // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = VLowTrailerFromJtag + (VHighTrailerFromJtag << 16); // Mimosa 26 trailer field + + } + + } + + else { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + VPtTestCont->ParAMapsHeaderRef[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = 0; // Mimosa 26 trailer field + } + + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + + CoUninitialize(); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 29/04/2011 + : +Rev : 19/05/2011 + : - Handle both Mi26 and Ult1 +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FTestOnDataStartStop ( SInt8 Start, SInt8 MapsNbToTest, SInt8 PrintLvl ) { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + + + VPtTestCont->ParPrintLvl = PrintLvl; + + + // Stop and exit + + if ( Start == 0 ) { + + // If already stopped => Do nothing & exit + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + // If running => Stop + message + + VPtTestCont->ParModeEnable = 0; + + // Print errors count + + EFRIO__FPrintTestOnDataCont ( "Errors count after Stop" ); + + err_retok (( ERR_OUT, "Stop command executed" )); + } + + + // Start procedure + + // If already running => Do nothing & exit + + if ( VPtTestCont->ParModeEnable == 1 ) { + return (0); + } + + // If not running => Start + Message + + memset ( VPtTestCont, 0, sizeof (EFRIO__TTestOnDataCont) ); + + VPtTestCont->ParMapsNb = VPtRunCont->ParMi26Nb; + VPtTestCont->ParMapsNbToTest = MapsNbToTest; + + + switch ( VPtRunCont->ParMapsName ) { + + case ASIC__MI26 : { + VRet = EFRIO__MI26_FTestOnDataGetJtagRef (); + break; } + + case ASIC__ULT1 : { + VRet = EFRIO__ULT1_FTestOnDataGetJtagRef (); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d", VPtRunCont->ParMapsName) ); + break; } + + } + + err_retfail ( VRet, (ERR_OUT,"Test aborted => Unable to get param from JTAG") ); + + // Enable test + + VPtTestCont->ParModeEnable = 1; + + // Print test context + + EFRIO__FPrintTestOnDataCont ( "Record state after Start" ); + + err_retok (( ERR_OUT, "Start command executed" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 29/04/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FTestOnDataResetErrCnt () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + SInt8 ViMaps; + + + // Print test context => To get errors count before reset + + EFRIO__FPrintTestOnDataCont ( "Errors count before Reset" ); + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + VPtTestCont->ResAMapsErrCnt[ViMaps] = 0; + VPtTestCont->ResAMapsHeaderErrCnt[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ResAMapsFrameCntErrCnt[ViMaps] = 0; // Mimosa 26 frame counter field + VPtTestCont->ResAMapsDataLengthErrCnt[ViMaps] = 0; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + VPtTestCont->ResAMapsTrailerErrCnt[ViMaps] = 0; // Mimosa 26 trailer field + + } + + VPtTestCont->ResTotErrCnt = 0; + VPtTestCont->ResFrameNbWithErr = 0; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef NO_MI26 + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + + return (VTotAcqSz); + } + +#endif // NO_MI26 + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio__270411.c b/include/pxi_daq_lib_v.2.1/eudet_frio__270411.c new file mode 100755 index 0000000..b7b1105 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio__270411.c @@ -0,0 +1,6068 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_C +#define EUDET_FRIO_C + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: Acquisition size if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 15/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FCpyAcq ( UInt8* PtDest, SInt32 MaxDestSz, SInt32 AcqSz ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + UInt32* VPtDest; + SInt32 VTotSz; + + // Check destination buffer + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + // Calculate total size + // = AcqSz + 4 because first W32 is used to store size of acquistion + + VTotSz = AcqSz + 4; + + // Test buffer size + + if ( VTotSz > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Destination buffer is too small => VTotSz=%d > MaxDestSz=%d", VTotSz, MaxDestSz ) ); + } + + // ----------------------------------------------- + // Copy data + // ----------------------------------------------- + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Add size on first elt + + VPtDest = (UInt32*) PtDest; + + *VPtDest = VTotSz; + + ++VPtDest; + + // Copy + + memcpy ( VPtDest, VPtRun->PtFrame, AcqSz ); + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotSz); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) + : +Goal : Init lib + : +Inputs : ErrorLogLvl - Error log level can be + : ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + : + : ErrorLogFile - Error log file + : MsgLogLvl - Messages log level => 127 to get all messages + : MsgLogFile - Messages log file + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Set default values to Acq emul header & trailer fields + : +Level : +Date : 05/08/2010 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + SInt32 VRet; + SInt8 VEnableErrLog; + SInt8 VEnableMsgLog; + WideString VWsJtagStatus; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + // Reset lib context record => Set all field to 0 + // BUT ! Set CmdRun to -1 + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + VPtCont->RunCont.CmdRun = -1; + + // Conf errors logging + + VEnableErrLog = ( ErrorLogLvl != 0 ); + + VRet = ERR_FBegin ( VEnableErrLog, ErrorLogFile ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FBegin failed !" ) ); + + VRet = ERR_FSetFileLogLevel ( ErrorLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FSetFileLogLevel failed !" ) ); + + // Conf messages logging + + VEnableMsgLog = ( MsgLogLvl != 0 ); + + VRet = MSG_FBegin ( VEnableMsgLog, MsgLogFile ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FBegin failed !" ) ); + + VRet = MSG_FSetFileLogLevel ( MsgLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FSetFileLogLevel failed !" ) ); + + // Init // port + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FBegin ( VEnableErrLog, ErrorLogFile ); + PPO_FOpen ( 0x378 /* BaseAdr */, 0 /* Id */ ); + PPO_FEnableReadDataOutPortBeforeWrite ( 0 /* Id */, 1 /* Enable */ ); + #endif + + // Reset lib context record => Set all field to 0 + // BUT ! Set CmdRun to -1 + + memset ( VPtCont, 0 , sizeof (EFRIO__TContext) ); + + VPtCont->RunCont.CmdRun = -1; + + // Set default values to first board conf in order to get DmaHostSize initialized BEFORE fw loading + + VPtBoard->AsicNb = EFRIO__MAX_ASIC_NB; // Max possible number + VPtBoard->FrameNbPerAcq = EFRIO__MAX_FRAME_NB_PER_ACQ; // "Nominal" value + + // DMA host size is the memory size allocated for DMA on CPU side + // It must be equal AT LEAST to the size of one acquisition and higher value are not useful + // VPtBoard->AsicNb + 1 => + 1 for extra channel + + VPtBoard->DmaHostSz = ((MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * (VPtBoard->AsicNb + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + + + // Set default values of Header & Trailer for DQ emulation + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x8000800; + + VPtAcqEmul->ParATrailer[0] = 0xAAAAAAAA; + VPtAcqEmul->ParATrailer[1] = 0xBBBBBBBB; + VPtAcqEmul->ParATrailer[2] = 0xCCCCCCCC; + VPtAcqEmul->ParATrailer[3] = 0xDDDDDDDD; + VPtAcqEmul->ParATrailer[4] = 0xEEEEEEEE; + VPtAcqEmul->ParATrailer[5] = 0xFFFFFFFF; + + +#ifdef EFRIO__INCLUDE_JTAG + + +#ifdef OLD_COM_JTAG_CODE + + // Init JTAG + + if( ! EFRIO_VGJtagMi26.IsBound()) { + OleCheck(CoMI26MasterConf::Create(EFRIO_VGJtagMi26)); + } + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + // Init JTAG end + + +#else + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( EFRIO_VGJtagMi26 ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( EFRIO_VGJtagMi26.IsBound () ) { + OleCheck ( EFRIO_VGJtagMi26.get_Info( &VWsJtagStatus )); + msg (( MSG_OUT, "JTAG => %s", TOOLS__FWideString2CStr (VWsJtagStatus, NULL, 0) )); + } + + else { + err_warning (( ERR_OUT, "JTAG control disabled => Because JTAG application not running !" )); + } + + // Init JTAG end + +#endif + + + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + VPtCont->InfInitDone = 0; + + err_error (( ERR_OUT, "******************************************************************" )); + err_error (( ERR_OUT, "EUDET Flex RIO DLL compiled on %s at %s", __DATE__, __TIME__ )); + err_error (( ERR_OUT, "******************************************************************" )); + + err_retok (( ERR_OUT, "end" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEnd () + : +Goal : Terminate lib + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 05/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEnd () { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FEnd (); + #endif + + // Close JTAG COM classe + // Avoid "assertion message" when LabView is stop and then restarted + +#ifdef EFRIO__INCLUDE_JTAG + EFRIO_VGJtagMi26.Unbind(); +#endif + + // Free frames buffer if allocated + + if ( VPtCont->RunCont.PtZsFFrameRaw !=NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + // Reset context record + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : +Goal : Build the frame list for one acquisition + : +Inputs : AcqStatus - ACquisition status ( < 0 -> HW error, 0 -> OK, > 0 -> Frame nb lost ) + : TrigStatus - No meaning now, reserved for future use + : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : +Level : +Date : 06/11/2010 +Rev : 24/02/2011 + : - Add parameters AcqStatus, TrigStatus to field new fields of EFRIO__TFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 AcqStatus, SInt32 TrigStatus, SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->AcqStatus = AcqStatus; + PtList->TrigStatus = TrigStatus; + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill followinf elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) + : +Goal : Init DAQ emulation either in standalone DAQ emulation application ( without + : HW ) or in LabView DAQ application. Selection done by RunInLabview parameter. + : +Inputs : RunInLabview = 0 => Run in C++ Builder DAQ emulation application + : = 1 => Run in Labview DAQ + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : If emulation is running under Labview ( RunInLabview = 1 ), frames emulation + : function overwite memory already allocated for Flew RIO board. In case emulation + : is runing in a standalone application ( RunInLabview = 0 ), this function allocates + : memory in PC DRAM to emulate Flex RIO RAM. + : + : This function sets default values of DAQ emulation parameters. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// RunInLabview = 0 => Run in C++ Builder DAQ emulation application +// RunInLabview = 1 => Run in Labview DAQ + +SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + // Reset context records + + memset ( VPtAcqEmul, 0, sizeof (EFRIO__TAcqEmul) ); + + memset ( VPtFrChk , 0, sizeof (EFRIO__TFrCheck) ); + + // Set default value of DAQ emulation parameters => Mainly for Labview which will not control all of them + + VPtAcqEmul->ParAcqCycleMs = 200; + VPtAcqEmul->ParEmuleDRamReadMs = 0; + VPtAcqEmul->ParEmuleFunctNo = 0; + VPtAcqEmul->ParRandomDataSz = 0; + VPtAcqEmul->ParSetMaxDataSzOnOneMaps = 1; + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x80008006; + + VPtAcqEmul->ParATrailer[0] = 0xAAAA0001; + VPtAcqEmul->ParATrailer[1] = 0xAAAA0002; + VPtAcqEmul->ParATrailer[2] = 0xAAAA0003; + VPtAcqEmul->ParATrailer[3] = 0xAAAA0004; + VPtAcqEmul->ParATrailer[4] = 0xAAAA0005; + VPtAcqEmul->ParATrailer[5] = 0xAAAA0006; + + VPtAcqEmul->ParTrigNbPerFrame = 0; + VPtAcqEmul->ParTrigOnOneFrameOverN = 1; + VPtAcqEmul->ParTrigOnNConsecutiveFrames = 1; + + VPtAcqEmul->ParATrig[0] = 10; + VPtAcqEmul->ParATrig[1] = 30; + VPtAcqEmul->ParATrig[2] = 30; + VPtAcqEmul->ParATrig[3] = 40; + + VPtAcqEmul->ParATS[0] = 100; + VPtAcqEmul->ParATS[1] = 200; + VPtAcqEmul->ParATS[2] = 300; + VPtAcqEmul->ParATS[3] = 400; + + + // Set Mi26 nb + + VPtFrChk->InfMi26Nb = VPtRunCont->ParMi26Nb; + + // Extra channel or not ? + + if ( (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtAcqEmul->InfExtraChan = 1; + } + + else { + VPtAcqEmul->InfExtraChan = 0; + } + + if ( RunInLabview == 0 ) { + + // Calculate DRAM size + + VPtAcqEmul->InfDRamSz = (VPtRunCont->ParMi26Nb + VPtAcqEmul->InfExtraChan) * VPtRunCont->ParFrameNbPerAcq * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 4; + + VPtAcqEmul->InfDRamSzMb = VPtAcqEmul->InfDRamSz / (1024 * 1024); + + // Alloc RAM to emulate Flex RIO DRAM + + VPtAcqEmul->InfDRamPtr = (UInt32*) malloc ( VPtAcqEmul->InfDRamSz ); + + err_retnull ( VPtAcqEmul->InfDRamPtr, (ERR_OUT,"Allocation of %d bytes for Flex RIO DRAM emulation failed !", VPtAcqEmul->InfDRamSz) ); + + } // End if ( RunInLabview == 0 ) + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FEmuleEnd ( ) + : +Goal : Terminate DAQ emulation + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : Free DRAM if allocated in PC to emulate Flex RIO DRAM. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEmuleEnd ( ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + if ( VPtAcqEmul->InfDRamPtr != NULL ) { + free ( VPtAcqEmul->InfDRamPtr ); + } + + err_retok (( ERR_OUT, "" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) + : +Goal : Emulate Flex RIO DRAM read + : +Inputs : Cmd - 0 => Do nothing + : - 1 => Fill memory with zero + : +Ouputs : A pointer to DRAM or NULL if not allocated + : +Globals : + : +Remark : A delay should also be added here later to emulate Flex RIO DRAM access time + : configured by field ParEmuleDRamReadMs of EFRIO__TAcqEmul. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + + + if ( Cmd == 1 ) { + memset ( VPtAcqEmul->InfDRamPtr, 0, VPtAcqEmul->InfDRamSz ); + } + + Sleep ( VPtAcqEmul->ParEmuleDRamReadMs ); + + return ( VPtAcqEmul->InfDRamPtr ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) + : +Goal : Used for DAQ emulation. + : Set the FrameId fields ( TLU & Flex RIO triggers ) of all triggers info in + : the record used to emulate triggers + : +Inputs : FrameId - The value of frame id to set in all triggers info + : TrigNb - The number of trigger info to set in record + : PtRec - Pointer to destination record + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : The field set are + : - for TLU trigger => F.FrameIdInAcq ( see record EFRIO__TTluTrigger in *.typ ) + : - for Flex RIO trigger => F.Mi26Frame ( see record EFRIO__TFlexRioTimeStamp1 in *.typ ) + : +Level : +Date : 03/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) { + + SInt32 ViTrig; + EFRIO__TTluTrigger* VPtTrig; + EFRIO__TFlexRioTimeStamp1* VPtTs; + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + if ( TrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"TrigNb=%d > Max=%d", TrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) ); + } + + for ( ViTrig=0; ViTrig < TrigNb; ViTrig++ ) { + + VPtTrig = (EFRIO__TTluTrigger*) &PtRec->ATrig[2 * ViTrig]; + VPtTs = (EFRIO__TFlexRioTimeStamp1*) &PtRec->ATrig[(2 * ViTrig)+1]; + + VPtTrig->F.FrameIdInAcq = FrameId; + VPtTs->F.Mi26Frame = FrameId; + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) + : +Goal : Function used to avoid data copy while transfering data from one Vi to + : another under Labview. Because sometimes, it seems that Labview use pointers + : but it's not the case, a copy of data is done, and execution time is lost ... + : +Inputs : CmdGetPtrCpyAlloc = 0 => return buffer pointer + : = 1 => store PtSrcW32 but NO copy of data + : = 2 => copy src to buffer + : = 3 => alloc buffer + : + : AllocW32Sz - Memory size to alloc in W32 ( if CmdGetPtrCpyAlloc = 3 ) + : PtSrcW32 - Pointer to source data to copy to buffer + : SrcW32Sz - Size of source data to copy to buffer + : +Ouputs : A pointer on the buffer or NULL if not allocated. + : +Globals : + : +Remark : It's mainly used to passe a pointer on board DRAM to DLL ( CmdGetPtrCpyAlloc = 1 ) + : +Level : +Date : 07/09/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) { + + static UInt32* VPtBuff = NULL; + static UInt32 VAllocW32Sz = 0; + UInt32 VAllocSz; + SInt32 Vi; + + // Get pointer request + + if ( CmdGetPtrCpyAlloc == 0 ) { + return (VPtBuff); + } + + // Store pointer request + + if ( CmdGetPtrCpyAlloc == 1 ) { + VPtBuff = PtSrcW32; + return (VPtBuff); + } + + // Copy request + + if ( CmdGetPtrCpyAlloc == 2 ) { + + if ( (VPtBuff == NULL) || (SrcW32Sz > VAllocW32Sz) ) { + err_error (( ERR_OUT, "VPtBuff = %x = NULL ? / SrcW32Sz=%d > VAllocW32Sz=%d", VPtBuff, SrcW32Sz, VAllocW32Sz )); + return (NULL); + } + + for ( Vi=0; Vi < SrcW32Sz; Vi++ ) { + VPtBuff[Vi] = PtSrcW32[Vi]; + } + + return (VPtBuff); + } + + + // Allocation request + + if ( CmdGetPtrCpyAlloc == 3 ) { + + // Free mem if already allocated + + if ( VPtBuff != NULL ) { + free ( VPtBuff ); + VPtBuff = NULL; + } + + // Alloc new mem + + VAllocW32Sz = AllocW32Sz; + VAllocSz = VAllocW32Sz * 4; + + VPtBuff = (UInt32*) malloc ( VAllocSz ); + + // If allocation failed => error message + ret NULL + + if ( VPtBuff == NULL ) { + err_error (( ERR_OUT, "Allocation of %d bytes failed !", VAllocSz )); + return (NULL); + } + + // If allocation OK => ret buffer pointer + + return (VPtBuff); + } + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 + : EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, + : char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) + : +Goal : Config run parameters, eg : get them from GUI or Ethernet + : +Inputs : Mi26Nb - Mimosa 26 number in the DAQ + : RunNo - Run no + : TotEvNb - Tot events number in run + : EvNbPerFile - Events number per file + : FrameNbPerAcq - Frames number per acquisition + : + : DataTransferMode - Data transfert mode + : + : 0 - EFRIO__TRF_MODE_IPHC + : => Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw + : + : 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN + : => Don't demultiplex data part, don't care about extra channel, send all frames + : + : 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES + : => Don't demultiplex data part, extract trigger info from extra channel, send all frames + : + : 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + : => Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + : + : DestDir - Destination directory for run file + : FileNamePrefix - Prefix of run file name ( eg : RUN_666 => "RUN" is the prefix ) + : SaveToDisk - Save or not data to disk + : SendOnEth - Send or not data to Ethernet + : SendOnEthPCent - % of events send on Ethernet ( if SendOnEth = 1 ) + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 06/08/2010 +Rev : 04/11/2010 + : - Save to disk + : 21/02/2011 + : - Set new fields ( ParDaqVersion, ParMapsName ) +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, SInt8 TrigMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + SInt32 VMaxFrameSz; + SInt32 VRet; + + // Check function parameters + + err_retnull ( DestDir , (ERR_OUT,"Abort : DestDir == NULL !") ); + err_retnull ( FileNamePrefix, (ERR_OUT,"Abort : FileNamePrefix == NULL !") ); + + // Debug print function parameters + + err_trace (( ERR_OUT, "Call with : Mi26Nb=%d - RunNo=%d - TotEvNb=%d - EvNbPerFile=%d - FrameNbPerAcq=%d - DestDir=%s - FileNamePrefix=%s", Mi26Nb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DestDir, FileNamePrefix )); + + // Set hard coded parameters + + VPtCont->RunCont.ParMeasDataRate = 1; // Enable data rate measurement + VPtCont->RunCont.ParAcqNbToMeasDataRate = 10; // Uses 10 acquistions to measure data rate + + // Set default values to new fields + + VPtCont->RunCont.ParDaqVersion = 0; + VPtCont->RunCont.ParMapsName = ASIC__MI26; + + // Copy run parameters to run context record + + VPtCont->RunCont.ParMi26Nb = Mi26Nb; + VPtCont->RunCont.ParRunNo = RunNo; + VPtCont->RunCont.ParTotEvNb = TotEvNb; + VPtCont->RunCont.ParEvNbPerFile = EvNbPerFile; + VPtCont->RunCont.ParFrameNbPerAcq = FrameNbPerAcq; + VPtCont->RunCont.ParDataTransferMode = DataTransferMode; + VPtCont->RunCont.ParTrigMode = TrigMode; + + VPtCont->RunCont.ParSaveOnDisk = SaveToDisk; + VPtCont->RunCont.ParSendOnEth = SendOnEth; + VPtCont->RunCont.ParSendOnEthPCent = SendOnEthPCent; + + sprintf ( VPtCont->RunCont.ParDestDir , "%s", DestDir ); + sprintf ( VPtCont->RunCont.ParFileNamePrefix, "%s", FileNamePrefix ); + + sprintf ( VPtCont->RunCont.InfDataFileName, "%s\\%s%d.bin", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + sprintf ( VPtCont->RunCont.InfConfFileName, "%s\\%s%d.par", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + + VPtCont->RunCont.InfSaveDataOnDiskRunning = 0; + + // Compare run conf paramters to the max parameters used to calculate DmaHostSz in FBegin + // If they have higher values => DmaHostSz send to board at fw loading is bad => Abort + + if ( (VPtCont->RunCont.ParMi26Nb > EFRIO__MAX_ASIC_NB) || (VPtCont->RunCont.ParFrameNbPerAcq > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_error (( ERR_OUT, "Bad Mi26 nb ? Run conf = %d - Max = %d", VPtCont->RunCont.ParMi26Nb, EFRIO__MAX_ASIC_NB )); + err_error (( ERR_OUT, "Bad frame nb per acq ? Run conf = %d - Max = %d", VPtCont->RunCont.ParFrameNbPerAcq, EFRIO__MAX_FRAME_NB_PER_ACQ )); + err_retfail ( -1, (ERR_OUT,"Abort : Bad value of AsicNb=%d or FrameNbPerAcq=%d", VPtCont->RunCont.ParMi26Nb, VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // Update monitor context fields + + VPtCont->MonCont.InfFrameNbToSend = (SInt32) ( (float) FrameNbPerAcq * (float) ( (float) SendOnEthPCent / (float) 100 )); + + VPtCont->MonCont.InfSzToSend = 0; // Because it's not known at this step + + err_error (( ERR_OUT, "TRACE => InfFrameNbToSend = %d", VPtCont->MonCont.InfFrameNbToSend )); + + // Overwrite default values of AsicNb & FrameNbPerAcq + + VPtBoard->AsicNb = VPtCont->RunCont.ParMi26Nb; + VPtBoard->FrameNbPerAcq = VPtCont->RunCont.ParFrameNbPerAcq; + + // DMA host size => Already initialized in FBegin function + // VPtBoard->DmaHostSz = (MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * VPtBoard->AsicNb * VPtBoard->FrameNbPerAcq) / (1024 * 1024); + + // Configure others board conf parameters + + VPtBoard->BoardId = 0; + + sprintf ( VPtBoard->AsicName, "%s", "Mimosa 26" ); + + VPtBoard->ReadoutMode = 0; // Reserved for future use + VPtBoard->DataClkFrequency = 80; // 80 MHz + + if ( (DataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (DataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtBoard->EnableExtraChannel = 1; // Yes + } + + else { + VPtBoard->EnableExtraChannel = 0; // No + } + + err_trace (( ERR_OUT, "EnableExtraChannel=%d", VPtBoard->EnableExtraChannel )); + + VPtBoard->TriggerMode = 0; // Trigger mode -> disabled + VPtBoard->TriggerDetectTimeWindow = 0; // Trigger mode -> Window during which we count triggers to detect beginning of spill + VPtBoard->TriggerDetectOccurNb = 0; // Trigger mode -> Number of trigger required during "TriggerDetectTimeWindow" to decide that spill has begun + VPtBoard->AcqNbPerTrig = 0; // Trigger mode -> Number of consecutive Acq stored after beginning of spill detection + + VPtBoard->EnableTimeStamping = 0; // On board time stamping -> disabled + VPtBoard->TimeStampRes = 0; // On board time stamp resolution in [ns] + + VPtBoard->EnableTrigCnt = 0; // On board trigger counter + + VPtBoard->TagEventsStoredByDUT = 0; // Tag events taken dy DUT -> disabled + VPtBoard->ReadTluTrigCntEachNTrig = 0; // Read event counter provided by TLU -> disabled + + // Allocate memory + + // IPHC data transfer mode + + if ( DataTransferMode == EFRIO__TRF_MODE_IPHC ) { + + // Free tmp trigger record if allocated + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + // Free EUDET mode buffer + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.PtFrame = NULL; + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Alloc IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + + VPtCont->RunCont.InfZsFFrameRawBuffSz = VPtCont->RunCont.ParMi26Nb * (VPtCont->RunCont.ParFrameNbPerAcq + 200) * sizeof (MI26__TZsFFrameRaw); + + VPtCont->RunCont.PtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + err_retnull ( VPtCont->RunCont.PtZsFFrameRaw, (ERR_OUT,"Allocation of IPHC buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // EUDET data transfer mode + + else { + + // Alloc tmp trigger record + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + VPtCont->PtTmpTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtCont->PtTmpTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Free IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + VPtCont->RunCont.InfZsFFrameRawBuffSz = 0; + + // Reset frame list + + memset ( VPtCont->AAcqFrameList, 0, sizeof (EFRIO__TFrameList) ); + + // Alloc + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.InfFrameBuffSz = 0; + + VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VPtCont->RunCont.InfFrameBuffSz = VPtCont->RunCont.ParFrameNbPerAcq * VMaxFrameSz; + + VPtCont->RunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->RunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->RunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq) ); + + } + + + // Reset run context results fields + + VPtCont->RunCont.ResAcqCnt = 0; + VPtCont->RunCont.ResFrameCnt = 0; + VPtCont->RunCont.ResEventCnt = 0; + + // Set status conf done + + VPtCont->ABoardsStatus[0].ConfDone = 1; + + // Set flag init done + + VPtCont->InfInitDone = 1; + + // Init for Labview because some emulation parameters are not controlled by GUI + + #ifdef APP_DLL + EFRIO__FEmuleBegin ( 1 /* RunInLabview */ ); + #endif + + + err_retok (( ERR_OUT, "end" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 07/03/2011 + : - Get disk sector size from OS + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStartSavingOnFile () { + + SInt32 VRet; + char VDiskDrive[3]; + SInt32 VDiskSectorSz; + SInt8 VUseThread; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + EFRIO__TFrame* VPtFrame; + + + VRet = 0; + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + // Create & write conf file + + // msg (( MSG_OUT, "VPtRunCont->ResConfFileName=%s", VPtRunCont->ResConfFileName )); + + // Set pointer to 0 before saving and restor them afer + + VPtZsFFrameRaw = VPtRunCont->PtZsFFrameRaw; + VPtFrame = VPtRunCont->PtFrame; + + VPtRunCont->PtZsFFrameRaw = NULL; + VPtRunCont->PtFrame = NULL; + + VRet = VRet | EFRIO__VGRunConfFile.PubFConf ( VPtRunCont->InfConfFileName, FIL__TCBinFile_RWB_MODE_WRITE, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont), 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunConfFile.PubFCreate (); + VRet = VRet | EFRIO__VGRunConfFile.PubFSeqWrite ( VPtRunCont, sizeof (EFRIO__TRunCont) ); + VRet = VRet | EFRIO__VGRunConfFile.PubFClose (); + + VPtRunCont->PtZsFFrameRaw = VPtZsFFrameRaw; + VPtRunCont->PtFrame = VPtFrame; + + err_retfail ( VRet, (ERR_OUT,"Run config file = %s creation failed !", VPtRunCont->InfConfFileName) ); + + // Create data file + + if ( VPtRunCont->ParSaveOnDisk == 1 ) { + VUseThread = 1; + } + + else { + VUseThread = 0; + } + + + // Get disk sector size + + strncpy ( VDiskDrive, VPtRunCont->InfDataFileName, 2 ); + + VDiskDrive[2] = 0; + + VDiskSectorSz = FIL_FGetDiskSectorSz ( VDiskDrive ); + + err_retfail ( VDiskSectorSz, (ERR_OUT,"Abort => Unable to get drive %s sector size !", VDiskDrive ) ); + + msg (( MSG_OUT, "Disk sector sz = %d Bytes", VDiskSectorSz )); + + // Set TCStreamFile disk sector size + + VRet = VRet | EFRIO__VGRunDataFile.PubFSetDiskSectorSz ( VDiskSectorSz ); + + // Conf TCStreamFile + + VRet = VRet | EFRIO__VGRunDataFile.PubFConf ( &EFRIO__VGRunDataFile, VUseThread /* UseThread */, VPtRunCont->InfDataFileName, FIL__TCBinFile_RWB_MODE_WRITE, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | EFRIO__VGRunDataFile.PubFCreate (); + + err_retfail ( VRet, (ERR_OUT,"Run data file = %s creation failed !", VPtRunCont->InfDataFileName) ); + + VPtRunCont->InfSaveDataOnDiskRunning = 1; + + } + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning + : 16/02/2011 + : - Test if ParTotEvNb reached, if yes => call EFRIO__FStopSavingOnFile () + : + : 24/02/2011 + : - Handle SpareW32Par as an array ASpareW32Par now + : +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSaveAcqOnFile () { + + SInt32 VRet; + SInt8 VUseThread; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TFileSpareW32Info VSpareW32Info; + + + VRet = 0; + + if ( VPtRunCont->InfSaveDataOnDiskRunning == 0 ) { + return (0); + } + + if ( VPtRunCont->ResEventCnt > VPtRunCont->ParTotEvNb ) { + EFRIO__FStopSavingOnFile (); + err_error (( ERR_OUT, "TRACE => End of run reached : %d events saved on disk", VPtRunCont->ResEventCnt )); + return (0); + } + + // Save acq on file if + // - Run conf "save on disk" parameter is set + // - There is something to save => ResAcqFunctRetCode = acquisition size <> 0 + + if ( (VPtRunCont->ParSaveOnDisk > 0) && (VPtRunCont->ResAcqFunctRetCode > 0) ) { + + VSpareW32Info.AcqStatus = VPtFrList->AcqStatus; + VSpareW32Info.TrigStatus = VPtFrList->TrigStatus; + VSpareW32Info.TotFrameNb = VPtFrList->TotFrameNb; + VSpareW32Info.DiskSectorSz = EFRIO__VGRunDataFile.PubFGetDiskSectorSz (); + + VRet = EFRIO__VGRunDataFile.PubFSeqWrite ( VPtRunCont->PtFrame, VPtRunCont->ResAcqFunctRetCode /* Acq sz */, VPtRunCont->ResEventCnt - 1 /* DbgCallPar */, 1 /* SpareW32InfoFormat */, (SInt32*) &VSpareW32Info, sizeof (VSpareW32Info) / 4 /* SpareW32InfoNb */ ); + + } + + err_retfail ( VRet, (ERR_OUT,"Saving Acq=%d of %d bytes on file %s failed", VPtRunCont->ResAcqCnt - 1, VPtRunCont->ResAcqFunctRetCode, VPtRunCont->InfDataFileName ) ); + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 08/11/2010 +Rev : 15/02/2011 + : - Handle InfSaveDataOnDiskRunning +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FStopSavingOnFile () { + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + VRet = 0; + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_IPHC ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__TRF_MODE_IPHC not hanlded") ); + } + + if ( VPtRunCont->ParSaveOnDisk > 0 ) { + + VPtRunCont->InfSaveDataOnDiskRunning = 0; + + VRet = VRet | EFRIO__VGRunDataFile.PubFFlush (); + VRet = VRet | EFRIO__VGRunDataFile.PubFClose (); + + err_retfail ( VRet, (ERR_OUT,"Error while closing data file = %s", VPtRunCont->InfDataFileName) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +#undef COMPIL_FTluTrigger2Str +#ifdef COMPIL_FTluTrigger2Str + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert TLU trigger info record to string for print or display + : +Inputs : Trig - Source trigger record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) + : +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display + : +Inputs : Ts - Source time stamp record ( it's only a W32 ) + : DestStr - Destination string + : MaxDestSz - Destination string size + : +Ouputs : The trigger / timestamp as a string in an human readable format + : +Globals : + : +Remark : If DestStr = NULL or is too small, a pointer to static local variable is + : returned. But please do a copy of the string, because if you use via the + : pointer, string content may / will change at next function call ! + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in IPHC data transfer mode. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + SInt32 VNiFrame; + SInt32 VNiFramePMi26; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[0]; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VNiFrame = ViFrame * VPtRunCont->ParMi26Nb; + + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + VNiFramePMi26 = VNiFrame + ViMi26; + + if ( VPtFrame[VNiFramePMi26].Header != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Header, VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFrame[VNiFramePMi26].Trailer != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Trailer, VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFrame[VNiFramePMi26].FrameCnt; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFrame[VNiFramePMi26].FrameCnt != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].FrameCnt, VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) + : +Goal : Check all frames of current acquisition in EUDET 1,2,3 data transfer modes. + : + : Test fields like Mimosa 26 header, frame counter, trailer. + : Compare to values set in AcqEmul record of lib context. + : +Inputs : PrevErrCnt - Global error counter + : Verbose - Print errors in log file -> value read & expected + : +Ouputs : The function returns PrevErrCnt + error count during this function call + : +Globals : + : +Remark : For Mi26 frames counter testing, it takes the first frame of acquisition as + : a starting point and check that counter increases frame by frame or one unit. + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +UInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrame* VPtFr; + SInt32 ViFrame; + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VPtFr = VPtFrList->AFramePtr[ViFrame]; + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + if ( VPtFr->Header.AMapsHeader[ViMi26] != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsHeader[ViMi26], VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFr->Header.AMapsTrailer[ViMi26] != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsTrailer[ViMi26], VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFr->Header.AMapsFrameCnt[ViMi26]; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFr->Header.AMapsFrameCnt[ViMi26] != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFr->Header.AMapsFrameCnt[ViMi26], VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 02/02/2010 +Rev : 07/05/2010 + : - Trigger calculation + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // msg (( MSG_OUT, "==> DPXI__MI26_FFRioAcqDeserData1Mi26 : Mi26NbToRead=%d - EltNb=%d - TotAnsSz=%d", VPtServ->PtParAcqReqFunc->AsicNbToRead, EltNb, PtAcq->InfTotAnsSz )); + + // Copy Acq inf pointers to local pointers + + // $$$ VPtAcqData = PtAcq->InfPtAcqData; + // $$$ VptZsFFrameRaw = PtAcq->InfPtZsFFrameRaw; + // $$$ msg (( MSG_OUT, "DPXI__MI26_FFRioAcqDeserData1Mi26 => AcqReqFuncSz=%d - MaxDataSz=%d - VTotAnsSz=%d", PtAcq->InfParAcqReqFuncSz, VPtServ->PtParAcqReqFunc->MaxDataSz, PtAcq->InfTotAnsSz )); + // $$$ memset ( VPtAcqData, 0, PtAcq->InfTotAnsSz ); + // $$$ err_trace (( ERR_OUT, "Start extract data for FrameNb=%d", VPtServ->PtParAcqReqFunc->FrameNb )); + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // $$$ VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VptZsFFrameRaw[ViFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[ViFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + VptZsFFrameRaw[ViFrame].DataLength = VDataLengthField; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32 = (UInt32*) VptZsFFrameRaw[ViFrame].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[ViFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + VptZsFFrameRaw[ViFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + VptZsFFrameRaw[ViFrame].Zero2 = VZero2; + ++ViSrcW32; + + // $$$ DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + VptZsFFrameRaw[ViFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[ViFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[ViFrame].SStatus.HitCnt = -1; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in IPHC mode + : + : Read data of one acquisition from Flex RIO, format them in IPHC mode + : by adding extra information and fill PC RAM buffer. + : + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 09/03/2010 +Rev : 06/05/2010 + : - Add trigger extract + : Warning ! Copy Zero & Zero2 fields of frame chip No 0 to ALL others chips ! + : All fields Zero & Zero2 are equals to the fields of first chip + : 19/05/2010 + : - Add trigger counter field handling in ASIC__TFrameStatus + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + SInt32 V6iFrameP1; + SInt32 V6iFrameP2; + SInt32 V6iFrameP3; + SInt32 V6iFrameP4; + SInt32 V6iFrameP5; + UInt32 VADataLengthField[6]; + UInt16 VADataLengthW16[6]; + UInt16 VADataLengthW32[6]; + UInt16 VDataLengthW32Max; + register SInt32 ViSrcW32; + register SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get AcqId + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // err_warning (( ERR_OUT, "TRACE : Memset buffer")); + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + V6iFrameP1 = V6iFrame + 1; + V6iFrameP2 = V6iFrame + 2; + V6iFrameP3 = V6iFrame + 3; + V6iFrameP4 = V6iFrame + 4; + V6iFrameP5 = V6iFrame + 5; + + + VptZsFFrameRaw[V6iFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VptZsFFrameRaw[V6iFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + + VptZsFFrameRaw[V6iFrame].DataLength = VADataLengthField[0]; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VptZsFFrameRaw[V6iFrameP1].DataLength = VADataLengthField[1]; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + + VptZsFFrameRaw[V6iFrameP2].DataLength = VADataLengthField[2]; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VptZsFFrameRaw[V6iFrameP3].DataLength = VADataLengthField[3]; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VptZsFFrameRaw[V6iFrameP4].DataLength = VADataLengthField[4]; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VptZsFFrameRaw[V6iFrameP5].DataLength = VADataLengthField[5]; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + // Find max data length of the six Mi26 + + VDataLengthW32Max = MATH_FUInt16Max ( VADataLengthW32, 6 ); + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32Chip0 = (UInt32*) VptZsFFrameRaw[V6iFrame].ADataW16; + VPtDataW32Chip1 = (UInt32*) VptZsFFrameRaw[V6iFrameP1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VptZsFFrameRaw[V6iFrameP2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VptZsFFrameRaw[V6iFrameP3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VptZsFFrameRaw[V6iFrameP4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VptZsFFrameRaw[V6iFrameP5].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip1[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip2[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip3[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip4[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip5[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VptZsFFrameRaw[V6iFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + ++ViSrcW32; + + // DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + + VptZsFFrameRaw[V6iFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrame].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP1].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 1 + 18 + (6 * VADataLengthW32[1])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP1].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP1].SStatus.AsicNo = 1; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP1].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP2].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 2 + 18 + (6 * VADataLengthW32[2])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP2].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP2].SStatus.AsicNo = 2; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP2].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP3].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 3 + 18 + (6 * VADataLengthW32[3])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP3].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP3].SStatus.AsicNo = 3; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP3].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP4].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 4 + 18 + (6 * VADataLengthW32[4])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP4].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP4].SStatus.AsicNo = 4; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP4].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP5].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 5 + 18 + (6 * VADataLengthW32[5])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP5].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP5].SStatus.AsicNo = 5; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP5].SStatus.HitCnt = -1; + + + + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 6 /* Mi26Nb */ ); + // PtAcq->ResAsicErrorsRejCurAcq = 0; + + // if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + err_retok (( ERR_OUT, "MsgOk" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 25/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 27/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointers + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // If length > max possible => Set it to 0 + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + } + + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagLoadFile ( char* FileName ) { + + HRESULT VRetCode; + WideString VStatus; + WideString VFileName; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + + if ( VJtag.IsBound () ) { + + VFileName = FileName; + + OleCheck( VRetCode = VJtag.MasterConfLoadFile( VFileName , &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Load JTAG file = %s failed !", FileName) ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagReset ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfReset (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Reset chip failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FJtagLoadChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfUpdateAll (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + OleCheck( VRetCode = VJtag.MasterConfReadBack (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Read back chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FJtagStartChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI26MasterConf VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI26MasterConf::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfStart (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2010 +Doc date : 10/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FHwStartChip ( SInt32 SpareS32Par ) { + + err_warning (( ERR_OUT, "EFRIO__MI26_FHwStartChip (Par=%d)", SpareS32Par )); + + // Start = D6, Speak = D7* + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD6 ( 0 /* Id */, 0 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 0 ); + + #else + err_warning (( ERR_OUT, "HW start not done -> // port not enabled !" )); + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + + return (VTotAcqSz); + } + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio__all_func_in_file_061110_13H43.c b/include/pxi_daq_lib_v.2.1/eudet_frio__all_func_in_file_061110_13H43.c new file mode 100755 index 0000000..c66ffc8 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio__all_func_in_file_061110_13H43.c @@ -0,0 +1,9274 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_C +#define EUDET_FRIO_C + + +// EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB +// EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB + +// EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ +// EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + SInt32 VRet; + SInt8 VEnableErrLog; + SInt8 VEnableMsgLog; + + + err_trace (( ERR_OUT, "DPXI_FBegin ( ErrorLogLvl=%d, ErrorLogFile=%s, MsgLogLvl=%d, MsgLogFile=%s )", ErrorLogLvl, ErrorLogFile, MsgLogLvl, MsgLogFile )); + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + // Conf errors logging + + VEnableErrLog = ( ErrorLogLvl != 0 ); + + VRet = ERR_FBegin ( VEnableErrLog, ErrorLogFile ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FBegin failed !" ) ); + + VRet = ERR_FSetFileLogLevel ( ErrorLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"ERR_FSetFileLogLevel failed !" ) ); + + // Conf messages logging + + VEnableMsgLog = ( MsgLogLvl != 0 ); + + VRet = MSG_FBegin ( VEnableMsgLog, MsgLogFile ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FBegin failed !" ) ); + + VRet = MSG_FSetFileLogLevel ( MsgLogLvl ); + + err_retfail ( VRet, (ERR_OUT,"MSG_FSetFileLogLevel failed !" ) ); + + // Init // port + + #ifdef DLL_INCLUDE_PARA_PORT + PPO_FBegin ( VEnableErrLog, ErrorLogFile ); + PPO_FOpen ( 0x378 /* BaseAdr */, 0 /* Id */ ); + PPO_FEnableReadDataOutPortBeforeWrite ( 0 /* Id */, 1 /* Enable */ ); + #endif + + // Reset lib context + + memset ( VPtCont, 0 , sizeof (EFRIO__TContext) ); + + // Set default values to first board conf in order to get DmaHostSize initialized BEFORE fw loading + + VPtBoard->AsicNb = EFRIO__MAX_ASIC_NB; // Max possible number + VPtBoard->FrameNbPerAcq = EFRIO__MAX_FRAME_NB_PER_ACQ; // "Nominal" value + + // DMA host size is the memory size allocated for DMA on CPU side + // It must be equal AT LEAST to the size of one acquisition and higher value are not useful + // VPtBoard->AsicNb + 1 => + 1 for extra channel + + VPtBoard->DmaHostSz = ((MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * (VPtBoard->AsicNb + 1) * VPtBoard->FrameNbPerAcq) / (1024 * 1024)) + 5; + + + // Set default values of Header & Trailer for DQ emulation + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x8000800; + + VPtAcqEmul->ParATrailer[0] = 0xAAAAAAAA; + VPtAcqEmul->ParATrailer[1] = 0xBBBBBBBB; + VPtAcqEmul->ParATrailer[2] = 0xCCCCCCCC; + VPtAcqEmul->ParATrailer[3] = 0xDDDDDDDD; + VPtAcqEmul->ParATrailer[4] = 0xEEEEEEEE; + VPtAcqEmul->ParATrailer[5] = 0xFFFFFFFF; + + + VPtCont->InfInitDone = 0; + + msg (( MSG_OUT, "EFRIO_FBegin Done :-)" )); + + err_error (( ERR_OUT, "********************************************************************" )); + err_error (( ERR_OUT, "Info => EUDET Flex RIO DLL compiled on %s at %s", __DATE__, __TIME__ )); + err_error (( ERR_OUT, "********************************************************************" )); + + err_error (( ERR_OUT, "TRACE ASIC__TFrameStatus=%d Bytes", sizeof (ASIC__TFrameStatus) )); + err_error (( ERR_OUT, "TRACE MI26__TZsFFrameRaw=%d Bytes", sizeof (MI26__TZsFFrameRaw) )); + + err_error (( ERR_OUT, "TRACE UInt64=%d", sizeof (UInt64) )); + + err_retok (( ERR_OUT, "end" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEnd () { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + #ifdef DLL_INCLUDE_PARA_PORT + PPO_FEnd (); + #endif + + // Free frames buffer if allocated + + if ( VPtCont->RunCont.PtZsFFrameRaw !=NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + // Reset context record + + memset ( &EFRIO__VGContext, 0, sizeof (EFRIO__TContext) ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : AcqId param is not used => Set it to -1 +: +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill followinf elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 31/10/2010 +Doc date : 31/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// RunInLabview = 0 => Run in C++ Builder DAQ emulation application +// RunInLabview = 1 => Run in Labview DAQ + +SInt32 EFRIO__FEmuleBegin ( SInt8 RunInLabview ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO_TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + // Reset context records + + memset ( VPtAcqEmul, 0, sizeof (EFRIO_TAcqEmul) ); + + memset ( VPtFrChk , 0, sizeof (EFRIO_TFrCheck) ); + + // Set default value of DAQ emulation parameters => Mainly for Labview which will not control all of them + + VPtAcqEmul->ParAcqCycleMs = 200; + VPtAcqEmul->ParEmuleDRamReadMs = 0; + VPtAcqEmul->ParEmuleFunctNo = 0; + VPtAcqEmul->ParRandomDataSz = 0; + VPtAcqEmul->ParSetMaxDataSzOnOneMaps = 0; + + VPtAcqEmul->ParAHeader[0] = 0x80008001; + VPtAcqEmul->ParAHeader[1] = 0x80008002; + VPtAcqEmul->ParAHeader[2] = 0x80008003; + VPtAcqEmul->ParAHeader[3] = 0x80008004; + VPtAcqEmul->ParAHeader[4] = 0x80008005; + VPtAcqEmul->ParAHeader[5] = 0x80008006; + + VPtAcqEmul->ParATrailer[0] = 0xAAAA0001; + VPtAcqEmul->ParATrailer[1] = 0xAAAA0002; + VPtAcqEmul->ParATrailer[2] = 0xAAAA0003; + VPtAcqEmul->ParATrailer[3] = 0xAAAA0004; + VPtAcqEmul->ParATrailer[4] = 0xAAAA0005; + VPtAcqEmul->ParATrailer[5] = 0xAAAA0006; + + VPtAcqEmul->ParTrigNbPerFrame = 0; + VPtAcqEmul->ParTrigOnOneFrameOverN = 1; + VPtAcqEmul->ParTrigOnNConsecutiveFrames = 1; + + VPtAcqEmul->ParATrig[0] = 0; + VPtAcqEmul->ParATrig[1] = 0; + VPtAcqEmul->ParATrig[2] = 0; + VPtAcqEmul->ParATrig[3] = 0; + + VPtAcqEmul->ParATS[0] = 0; + VPtAcqEmul->ParATS[1] = 0; + VPtAcqEmul->ParATS[2] = 0; + VPtAcqEmul->ParATS[3] = 0; + + + + // Set Mi26 nb + + VPtFrChk->InfMi26Nb = VPtRunCont->ParMi26Nb; + + // Extra channel or not ? + + if ( (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtAcqEmul->InfExtraChan = 1; + } + + else { + VPtAcqEmul->InfExtraChan = 0; + } + + if ( RunInLabview == 0 ) { + + // Calculate DRAM size + + VPtAcqEmul->InfDRamSz = (VPtRunCont->ParMi26Nb + VPtAcqEmul->InfExtraChan) * VPtRunCont->ParFrameNbPerAcq * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 4; + + VPtAcqEmul->InfDRamSzMb = VPtAcqEmul->InfDRamSz / (1024 * 1024); + + // Alloc RAM to emulate Flex RIO DRAM + + VPtAcqEmul->InfDRamPtr = (UInt32*) malloc ( VPtAcqEmul->InfDRamSz ); + + err_retnull ( VPtAcqEmul->InfDRamPtr, (ERR_OUT,"Allocation of %d bytes for Flex RIO DRAM emulation failed !", VPtAcqEmul->InfDRamSz) ); + + } // End if ( RunInLabview == 0 ) + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 31/10/2010 +Doc date : 31/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FEmuleEnd ( ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO_TFrCheck* VPtFrChk = &EFRIO__VGContext.FrCheck; + + + if ( VPtAcqEmul->InfDRamPtr != NULL ) { + free ( VPtAcqEmul->InfDRamPtr ); + } + + err_retok (( ERR_OUT, "" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 31/10/2010 +Doc date : 31/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32* EFRIO__FEmuleReadDRam ( SInt8 Cmd ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + + + if ( Cmd == 1 ) { + memset ( VPtAcqEmul->InfDRamPtr, 0, VPtAcqEmul->InfDRamSz ); + } + + + return ( VPtAcqEmul->InfDRamPtr ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : EmuleMode parameter is used to define number of trigger to emulate +: - EmuleMode >= 0 -> No trigger +: - EmuleMode < 0 -> Nb trigger = absolute value of EmuleMode +: +Level : This is a user level function. +Date : 03/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSetFrameIdInTriggerRec ( SInt32 FrameId, SInt32 TrigNb, EFRIO__TTriggerRec* PtRec ) { + + SInt32 ViTrig; + EFRIO__TTluTrigger* VPtTrig; + EFRIO__TFlexRioTimeStamp1* VPtTs; + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + if ( TrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"TrigNb=%d > Max=%d", TrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) ); + } + + for ( ViTrig=0; ViTrig < TrigNb; ViTrig++ ) { + + VPtTrig = (EFRIO__TTluTrigger*) &PtRec->ATrig[2 * ViTrig]; + VPtTs = (EFRIO__TFlexRioTimeStamp1*) &PtRec->ATrig[(2 * ViTrig)+1]; + + VPtTrig->F.FrameIdInAcq = FrameId; + VPtTs->F.Mi26Frame = FrameId; + } + + return (0); +} + + +// 07/09/2010 + +// CmdGetPtrCpyAlloc = 0 => return buffer pointer +// CmdGetPtrCpyAlloc = 1 => store PtSrcW32 but NO copy of data +// CmdGetPtrCpyAlloc = 2 => copy src to buffer +// CmdGetPtrCpyAlloc = 3 => alloc mem + +UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz ) { + + static UInt32* VPtBuff = NULL; + static UInt32 VAllocW32Sz = 0; + UInt32 VAllocSz; + SInt32 Vi; + + // Get pointer request + + if ( CmdGetPtrCpyAlloc == 0 ) { + return (VPtBuff); + } + + // Store pointer request + + if ( CmdGetPtrCpyAlloc == 1 ) { + VPtBuff = PtSrcW32; + return (VPtBuff); + } + + + // Copy request + + if ( CmdGetPtrCpyAlloc == 2 ) { + + if ( (VPtBuff == NULL) || (SrcW32Sz > VAllocW32Sz) ) { + err_error (( ERR_OUT, "VPtBuff = %x = NULL ? / SrcW32Sz=%d > VAllocW32Sz=%d", VPtBuff, SrcW32Sz, VAllocW32Sz )); + return (NULL); + } + + for ( Vi=0; Vi < SrcW32Sz; Vi++ ) { + VPtBuff[Vi] = PtSrcW32[Vi]; + } + + return (VPtBuff); + } + + + // Allocation request + + if ( CmdGetPtrCpyAlloc == 3 ) { + + // Free mem if already allocated + + if ( VPtBuff != NULL ) { + free ( VPtBuff ); + VPtBuff = NULL; + } + + // Alloc new mem + + VAllocW32Sz = AllocW32Sz; + VAllocSz = VAllocW32Sz * 4; + + VPtBuff = (UInt32*) malloc ( VAllocSz ); + + // If allocation failed => error message + ret NULL + + if ( VPtBuff == NULL ) { + err_error (( ERR_OUT, "Allocation of %d bytes failed !", VAllocSz )); + return (NULL); + } + + // If allocation OK => ret buffer pointer + + return (VPtBuff); + } + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 20/10/2010 +Doc date : 20/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Cmd = 0 => do nothing +// Cmd = 1 => alloc mem +// Cmd = 2 => free mem + +// Cmd = 3 => Copy with memcpy +// Cmd = 4 => Copy with W8 loop Vi ++ +// Cmd = 5 => Copy with W8 loop Vi -- +// Cmd = 6 => Copy with W32 loop Vi ++ +// Cmd = 7 => Copy with W32 loop Vi -- +// Cmd = 8 => Copy with memmove + +SInt32 EFRIO__FDbgMeasRamCpyTime ( SInt8 Cmd, SInt32 SzMb ) { + + static UInt8* VBuffSrc = NULL; + static UInt8* VBuffDest = NULL; + auto SInt32 _VSzW32; + auto SInt32 _Vi; + register SInt32 r_VSzW32; + register SInt32 r_Vi; + SInt32 VSzW8; + SInt32 VSzW32; + SInt32 VSzW64; + SInt32 Vi; + UInt8* VCpyBuffSrc; + UInt8* VCpyBuffDest; + UInt64* VCpyBuffSrcW64; + UInt64* VCpyBuffDestW64; + + + if ( (Cmd < 0) || (Cmd > 7) ) { + err_retfail ( Cmd, (ERR_OUT,"Bad Cmd=%d Our of range 0..7", Cmd) ); + } + + VSzW8 = SzMb * 1024 * 1024; + VSzW32 = VSzW8 / 4; + _VSzW32 = VSzW8 / 4; + r_VSzW32 = VSzW8 / 4; + VSzW64 = VSzW8 / 8; + + // err_error (( ERR_OUT, "TRACE => VSzW8=%d - VSzW32=%d", VSzW8, VSzW32 )); + + while (1) { + + // Allocation mem + + if ( Cmd == 1 ) { + + err_error (( ERR_OUT, "TRACE => Cmd=1 Alloc mem" )); + + // Source + + if ( VBuffSrc != NULL ) { + free ( VBuffSrc ); + } + + VBuffSrc = (UInt8*) malloc ( VSzW8 ); + + err_retnull ( VBuffSrc, (ERR_OUT,"Allocation of src buffer %d bytes failed !", VSzW8 ) ); + + // Dest + + if ( VBuffDest != NULL ) { + free ( VBuffDest ); + } + + VBuffDest = (UInt8*) malloc ( VSzW8 ); + + err_retnull ( VBuffDest, (ERR_OUT,"Allocation of dest buffer %d bytes failed !", VSzW8 ) ); + + break; + } + + // Free mem + + if ( Cmd == 2 ) { + + err_error (( ERR_OUT, "TRACE => Cmd=2 => Free mem" )); + + if ( VBuffSrc != NULL ) { + free ( VBuffSrc ); + VBuffSrc = NULL; + } + + if ( VBuffDest != NULL ) { + free ( VBuffDest ); + VBuffDest = NULL; + } + + break; + } + + // Copy with memcpy + + if ( Cmd == 3 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + memcpy ( VBuffDest, VBuffSrc, VSzW8 ); + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W8 loop Vi ++ + + if ( Cmd == 4 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( Vi=0; Vi < VSzW8; Vi++ ) { + VBuffDest[Vi] = VBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W8 loop Vi -- + + if ( Cmd == 5 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( Vi=VSzW8; Vi >= 0; Vi-- ) { + VBuffDest[Vi] = VBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W32 loop Vi ++ + + if ( Cmd == 6 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( Vi=0; Vi < VSzW32; Vi++ ) { + VBuffDest[Vi] = VBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W32 loop Vi -- + + if ( Cmd == 7 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( Vi=VSzW32; Vi >= 0; Vi-- ) { + VBuffDest[Vi] = VBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with memmove + + if ( Cmd == 8 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + memmove ( VBuffDest, VBuffSrc, VSzW8 ); + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + + // Copy with W32 loop Vi ++ with auto var + + if ( Cmd == 9 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( _Vi=0; _Vi < _VSzW32; _Vi++ ) { + VBuffDest[_Vi] = VBuffSrc[_Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W32 loop Vi ++ with local ptr + + if ( Cmd == 10 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + VCpyBuffSrc = VBuffSrc; + VCpyBuffDest = VBuffDest; + + for ( Vi=0; Vi < VSzW32; Vi++ ) { + VCpyBuffDest[Vi] = VCpyBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W32 loop Vi ++ with register var + + if ( Cmd == 11 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( r_Vi=0; r_Vi < r_VSzW32; r_Vi++ ) { + VBuffDest[r_Vi] = VBuffSrc[r_Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + + // Copy with W64 loop Vi ++ with local ptr + + if ( Cmd == 12 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + VCpyBuffSrcW64 = (UInt64*) VBuffSrc; + VCpyBuffDestW64 = (UInt64*) VBuffDest; + + for ( Vi=0; Vi < VSzW64; Vi++ ) { + VCpyBuffDestW64[Vi] = VCpyBuffSrcW64[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + + // End while (1) + } + + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/10/2010 +Doc date : 22/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +// Cmd = 0 -> Reset frame counter & flags ( don't care about trigger param ) +// Cmd = 1 -> Insert text line separator "=============" ( do nothing else ) +// Cmd = 2 -> Emule frame + +SInt32 EFRIO__FDbgCheckTrigAlgo ( SInt8 Cmd, SInt8 TriggerNb, SInt8 AddFrameBefore, SInt8 AddFrameAfter ) { + + static SInt32 VFrameCnt = 0; + static SInt8 VAddFrameNp1 = 0; + static SInt8 VAddFrameNm1Done = 0; + SInt32 VRetCurFrameId; + + while (1) { + + if ( Cmd == 0 ) { + VFrameCnt = 0; + VAddFrameNp1 = 0; + VAddFrameNm1Done = 0; + VRetCurFrameId = -1; + msg (( MSG_OUT, "Cmd = 0 -> Reset frame cnt done" )); + break; + } + + + if ( Cmd == 1 ) { + VRetCurFrameId = -1; + msg (( MSG_OUT, "*******************************************************" )); + break; + } + + + if ( Cmd == 2 ) { + + VRetCurFrameId = VFrameCnt; + + msg (( MSG_OUT, "-------------------------------------------------------" )); + msg (( MSG_OUT, "Emule frame %d - %d triggers - Add F before = %d - Add F after = %d", VFrameCnt, TriggerNb, AddFrameBefore, AddFrameAfter )); + msg (( MSG_OUT, "-------------------------------------------------------" )); + + + if ( TriggerNb > 0 ) { + + if ( AddFrameAfter == 1 ) { + VAddFrameNp1 = 1; + } + + + // Must add Fn-1 + + if ( (VAddFrameNm1Done == 0) && (AddFrameBefore == 1) ) { + msg (( MSG_OUT, "Add Fn-1 = %d", VFrameCnt-1 )); + } + + msg (( MSG_OUT, "Add Fn = %d", VFrameCnt )); + VAddFrameNm1Done = 1; + + } // End if ( TriggerNb > 0 ) + + + // TriggerNb == 0 + + else { + + // Must add Fn+1 + + if ( VAddFrameNp1 == 1 ) { + VAddFrameNp1 = 0; + + msg (( MSG_OUT, "Add Fn = %d", VFrameCnt )); + VAddFrameNm1Done = 1; + } + + // Don't add Fn+1 + + else { + VAddFrameNm1Done = 0; + } + + } // End TriggerNb == 0 + + + break; // End frame emulation + } + + + + msg (( MSG_OUT, "Unknown command = %d", Cmd )); + break; + } + + ++VFrameCnt; + + return (VRetCurFrameId); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 06/08/2010 +Rev : 04/11/2010 + : - Save to disk +Doc date : 06/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = &EFRIO__VGContext.ABoardsConf[0]; + SInt32 VMaxFrameSz; + SInt32 VRet; + + // Check function parameters + + err_retnull ( DestDir , (ERR_OUT,"Abort : DestDir == NULL !") ); + err_retnull ( FileNamePrefix, (ERR_OUT,"Abort : FileNamePrefix == NULL !") ); + + // Debug print function parameters + + err_trace (( ERR_OUT, "Call with : Mi26Nb=%d - RunNo=%d - TotEvNb=%d - EvNbPerFile=%d - FrameNbPerAcq=%d - DestDir=%s - FileNamePrefix=%s", Mi26Nb, RunNo, TotEvNb, EvNbPerFile, FrameNbPerAcq, DestDir, FileNamePrefix )); + + // Copy context parameters + + VPtCont->RunCont.ParDataTransferMode = DataTransferMode; + + // Copy run parameters to run context record + + VPtCont->RunCont.ParMi26Nb = Mi26Nb; + VPtCont->RunCont.ParRunNo = RunNo; + VPtCont->RunCont.ParTotEvNb = TotEvNb; + VPtCont->RunCont.ParEvNbPerFile = EvNbPerFile; + VPtCont->RunCont.ParFrameNbPerAcq = FrameNbPerAcq; + VPtCont->RunCont.ParDataTransferMode = DataTransferMode; + + VPtCont->RunCont.ParSaveOnDisk = SaveToDisk; + VPtCont->RunCont.ParSendOnEth = SendOnEth; + VPtCont->RunCont.ParSendOnEthPCent = SendOnEthPCent; + + sprintf ( VPtCont->RunCont.ParDestDir , "%s", DestDir ); + sprintf ( VPtCont->RunCont.ParFileNamePrefix, "%s", FileNamePrefix ); + + sprintf ( VPtCont->RunCont.ResDataFileName, "%s\\%s%d.bin", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + sprintf ( VPtCont->RunCont.ResConfFileName, "%s\\%s%d.par", VPtCont->RunCont.ParDestDir, VPtCont->RunCont.ParFileNamePrefix, VPtCont->RunCont.ParRunNo); + + + + // Compare run conf paramters to the max parameters used to calculate DmaHostSz in FBegin + // If they have higher values => DmaHostSz send to board at fw loading is bad => Abort + + if ( (VPtCont->RunCont.ParMi26Nb > EFRIO__MAX_ASIC_NB) || (VPtCont->RunCont.ParFrameNbPerAcq > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_error (( ERR_OUT, "Bad Mi26 nb ? Run conf = %d - Max = %d", VPtCont->RunCont.ParMi26Nb, EFRIO__MAX_ASIC_NB )); + err_error (( ERR_OUT, "Bad frame nb per acq ? Run conf = %d - Max = %d", VPtCont->RunCont.ParFrameNbPerAcq, EFRIO__MAX_FRAME_NB_PER_ACQ )); + err_retfail ( -1, (ERR_OUT,"Abort : Bad value of AsicNb=%d or FrameNbPerAcq=%d", VPtCont->RunCont.ParMi26Nb, VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // Overwrite default values of AsicNb & FrameNbPerAcq + + VPtBoard->AsicNb = VPtCont->RunCont.ParMi26Nb; + VPtBoard->FrameNbPerAcq = VPtCont->RunCont.ParFrameNbPerAcq; + + // DMA host size => Already initialized in FBegin function + // VPtBoard->DmaHostSz = (MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ * 2 * VPtBoard->AsicNb * VPtBoard->FrameNbPerAcq) / (1024 * 1024); + + // Configure others board conf parameters + + VPtBoard->BoardId = 0; + + sprintf ( VPtBoard->AsicName, "%s", "Mimosa 26" ); + + VPtBoard->ReadoutMode = 0; // Reserved for future use + VPtBoard->DataClkFrequency = 80; // 80 MHz + + if ( (DataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) || (DataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + VPtBoard->EnableExtraChannel = 1; // Yes + } + + else { + VPtBoard->EnableExtraChannel = 0; // No + } + + err_error (( ERR_OUT, "TRACE => EnableExtraChannel=%d", VPtBoard->EnableExtraChannel )); + + VPtBoard->TriggerMode = 0; // Trigger mode -> disabled + VPtBoard->TriggerDetectTimeWindow = 0; // Trigger mode -> Window during which we count triggers to detect beginning of spill + VPtBoard->TriggerDetectOccurNb = 0; // Trigger mode -> Number of trigger required during "TriggerDetectTimeWindow" to decide that spill has begun + VPtBoard->AcqNbPerTrig = 0; // Trigger mode -> Number of consecutive Acq stored after beginning of spill detection + + VPtBoard->EnableTimeStamping = 0; // On board time stamping -> disabled + VPtBoard->TimeStampRes = 0; // On board time stamp resolution in [ns] + + VPtBoard->EnableTrigCnt = 0; // On board trigger counter + + VPtBoard->TagEventsStoredByDUT = 0; // Tag events taken dy DUT -> disabled + VPtBoard->ReadTluTrigCntEachNTrig = 0; // Read event counter provided by TLU -> disabled + + + // Allocate memory + + // IPHC data transfer mode + + if ( DataTransferMode == EFRIO__TRF_MODE_IPHC ) { + + // Free tmp trigger record if allocated + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + // Free EUDET mode buffer + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.PtFrame = NULL; + VPtCont->RunCont.InfFrameBuffSz = 0; + + // Alloc IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + + VPtCont->RunCont.InfZsFFrameRawBuffSz = VPtCont->RunCont.ParMi26Nb * (VPtCont->RunCont.ParFrameNbPerAcq + 200) * sizeof (MI26__TZsFFrameRaw); + + VPtCont->RunCont.PtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + err_retnull ( VPtCont->RunCont.PtZsFFrameRaw, (ERR_OUT,"Allocation of IPHC buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq ) ); + } + + // EUDET data transfer mode + + else { + + // Alloc tmp trigger record + + if ( VPtCont->PtTmpTrigRec != NULL ) { + free ( VPtCont->PtTmpTrigRec ); + } + + VPtCont->PtTmpTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtCont->PtTmpTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Free IPHC mode buffer + + if ( VPtCont->RunCont.PtZsFFrameRaw != NULL ) { + free ( VPtCont->RunCont.PtZsFFrameRaw ); + } + + VPtCont->RunCont.PtZsFFrameRaw = NULL; + VPtCont->RunCont.InfZsFFrameRawBuffSz = 0; + + err_error (( ERR_OUT, "TRACE => EUDET - Reset frame list " )); + + // Reset frame list + + memset ( VPtCont->AAcqFrameList, 0, sizeof (EFRIO__TFrameList) ); + + // Alloc + + err_error (( ERR_OUT, "TRACE => EUDET - Alloc - Free revious buffer " )); + + if ( VPtCont->RunCont.PtFrame != NULL ) { + free ( VPtCont->RunCont.PtFrame ); + } + + VPtCont->RunCont.InfFrameBuffSz = 0; + + VMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->RunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + VPtCont->RunCont.InfFrameBuffSz = VPtCont->RunCont.ParFrameNbPerAcq * VMaxFrameSz; + + err_error (( ERR_OUT, "TRACE => EUDET VMaxFrameSz = %d Bytes", VMaxFrameSz )); + err_error (( ERR_OUT, "TRACE => EUDET InfFrameBuffSz = %d Bytes", VPtCont->RunCont.InfFrameBuffSz )); + + err_error (( ERR_OUT, "TRACE => EUDET - Alloc - Alloc new buffer" )); + + VPtCont->RunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->RunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->RunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->RunCont.ParFrameNbPerAcq) ); + + err_error (( ERR_OUT, "TRACE => EUDET - end" )); + + } + + // Reset run context results fields + + VPtCont->RunCont.ResAcqCnt = 0; + VPtCont->RunCont.ResFrameCnt = 0; + VPtCont->RunCont.ResEventCnt = 0; + + // Set status conf done + + VPtCont->ABoardsStatus[0].ConfDone = 1; + + // Set flag init done + + VPtCont->InfInitDone = 1; + + // Init for Labview because some emulation parameters are not controlled by GUI + + #ifdef APP_DLL + EFRIO__FEmuleBegin ( 1 /* RunInLabview */ ); + #endif + + + err_retok (( ERR_OUT, "end" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Run context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParMi26Nb = %.4d", PtRec->ParMi26Nb )); + msg (( MSG_OUT, "ParFrameNbPerAcq = %.4d", PtRec->ParFrameNbPerAcq )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParRunNo = %.4d", PtRec->ParRunNo )); + msg (( MSG_OUT, "ParTotEvNb = %.4d", PtRec->ParTotEvNb )); + msg (( MSG_OUT, "ParEvNbPerFile = %.4d", PtRec->ParEvNbPerFile )); + msg (( MSG_OUT, "ParDataTransferMode = %.4d", PtRec->ParDataTransferMode )); + msg (( MSG_OUT, "ParSaveOnDisk = %.4d", PtRec->ParSaveOnDisk )); + msg (( MSG_OUT, "ParSendOnEth = %.4d", PtRec->ParSendOnEth )); + msg (( MSG_OUT, "ParSendOnEthPCent = %.4d", PtRec->ParSendOnEthPCent )); + msg (( MSG_OUT, "ParDestDir = %s" , PtRec->ParDestDir )); + msg (( MSG_OUT, "ParFileNamePrefix = %s" , PtRec->ParFileNamePrefix )); + msg (( MSG_OUT, "InfMi26FrameSzFromFlexRio = %.4d", PtRec->InfMi26FrameSzFromFlexRio )); + msg (( MSG_OUT, "InfZsFFrameRawBuffSz = %.4d", PtRec->InfZsFFrameRawBuffSz )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResDataFileName = %s" , PtRec->ResDataFileName )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResFrameCnt = %.4d", PtRec->ResFrameCnt )); + msg (( MSG_OUT, "ResEventCnt = %.4d", PtRec->ResEventCnt )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "PtZsFFrameRaw = %.8x", PtRec->PtZsFFrameRaw )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunCont () { + + return ( EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board conf record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "AsicName = %s", PtRec->AsicName )); + msg (( MSG_OUT, "AsicNb = %.4d", PtRec->AsicNb )); + msg (( MSG_OUT, "ReadoutMode = %.4d", PtRec->ReadoutMode )); + msg (( MSG_OUT, "DataClkFrequency = %2.f", PtRec->DataClkFrequency )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "DmaHostSz = %.4d", PtRec->DmaHostSz )); + msg (( MSG_OUT, "FrameNbPerAcq = %.4d", PtRec->FrameNbPerAcq )); + msg (( MSG_OUT, "EnableExtraChannel = %.4d", PtRec->EnableExtraChannel )); + msg (( MSG_OUT, "AcqNbPerTrig = %.4d", PtRec->AcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TriggerMode = %.4d", PtRec->TriggerMode )); + msg (( MSG_OUT, "TriggerDetectTimeWindow = %.4d", PtRec->TriggerDetectTimeWindow )); + msg (( MSG_OUT, "TriggerDetectOccurNb = %.4d", PtRec->TriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TimeStampRes = %.4d", PtRec->TimeStampRes )); + msg (( MSG_OUT, "EnableTimeStamping = %.4d", PtRec->EnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EnableTrigCnt = %.4d", PtRec->EnableTrigCnt )); + msg (( MSG_OUT, "TagEventsStoredByDUT = %.4d", PtRec->TagEventsStoredByDUT )); + msg (( MSG_OUT, "ReadTluTrigCntEachNTrig = %.4d", PtRec->ReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board status record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "BoardPresent = %.4d", PtRec->BoardPresent )); + msg (( MSG_OUT, "FwLoaded = %.4d", PtRec->FwLoaded )); + msg (( MSG_OUT, "ConfDone = %.4d", PtRec->ConfDone )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "StatusCode = %.4d", PtRec->StatusCode )); + msg (( MSG_OUT, "StatusStr = %.4d", PtRec->StatusStr )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ErrorMsgList = %s", PtRec->ErrorMsgList )); + msg (( MSG_OUT, "LastErrorMsg = %s", PtRec->LastErrorMsg )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegDmaHostSz = %.4d", PtRec->RegDmaHostSz )); + msg (( MSG_OUT, "RegFrameNbPerAcq = %.4d", PtRec->RegFrameNbPerAcq )); + msg (( MSG_OUT, "RegEnableExtraChannel = %.4d", PtRec->RegEnableExtraChannel )); + msg (( MSG_OUT, "RegAcqNbPerTrig = %.4d", PtRec->RegAcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTriggerMode = %.4d", PtRec->RegTriggerMode )); + msg (( MSG_OUT, "RegTriggerDetectTimeWindow = %.4d", PtRec->RegTriggerDetectTimeWindow )); + msg (( MSG_OUT, "RegTriggerDetectOccurNb = %.4d", PtRec->RegTriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStampRes = %.4d", PtRec->RegTimeStampRes )); + msg (( MSG_OUT, "RegEnableTimeStamping = %.4d", PtRec->RegEnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegEnableTrigCnt = %.4d", PtRec->RegEnableTrigCnt )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTagEventsStoredByDUT = %.4d", PtRec->RegTagEventsStoredByDUT )); + msg (( MSG_OUT, "RegReadTluTrigCntEachNTrig = %.4d", PtRec->RegReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStamp = %.4d", PtRec->RegTimeStamp )); + msg (( MSG_OUT, "RegTrigCnt = %.4d", PtRec->RegTrigCnt )); + msg (( MSG_OUT, "RegTluTrigCnt = %.4d", PtRec->RegTluTrigCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 31/10/2010 +Doc date : 31/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO_TAcqEmul* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Acquistion emulation record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqCycleMs = %.4d", PtRec->ParAcqCycleMs )); + msg (( MSG_OUT, "ParEmuleDRamReadMs = %.4d", PtRec->ParEmuleDRamReadMs )); + msg (( MSG_OUT, "ParEmuleFunctNo = %.4d", PtRec->ParEmuleFunctNo )); + msg (( MSG_OUT, "InfEmuleFuncCmt = %s" , PtRec->InfEmuleFuncCmt )); + msg (( MSG_OUT, "ParRandomDataSz = %d" , PtRec->ParRandomDataSz )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParAHeader[0] , PtRec->ParAHeader[1] , PtRec->ParAHeader[2] , PtRec->ParAHeader[3] , PtRec->ParAHeader[4] , PtRec->ParAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParATrailer[0], PtRec->ParATrailer[1], PtRec->ParATrailer[2], PtRec->ParATrailer[3], PtRec->ParATrailer[4], PtRec->ParATrailer[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParTrigNbPerFrame = %.4d", PtRec->ParTrigNbPerFrame )); + msg (( MSG_OUT, "ParTrigOnOneFrameOverN = %.4d", PtRec->ParTrigOnOneFrameOverN )); + msg (( MSG_OUT, "ParTrigOnNConsecutiveFrames = %.4d", PtRec->ParTrigOnNConsecutiveFrames )); + msg (( MSG_OUT, "Trig [0]=%.4d [1]=%.4d [2]=%.4d [Last]=%.4d", PtRec->ParATrig[0], PtRec->ParATrig[1], PtRec->ParATrig[2], PtRec->ParATrig[3] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfDRamSzMb = %.4d", PtRec->InfDRamSzMb )); + msg (( MSG_OUT, "InfDRamSz = %.4d", PtRec->InfDRamSz )); + msg (( MSG_OUT, "InfDRamPtr = %.8x", PtRec->InfDRamPtr )); + msg (( MSG_OUT, "InfExtraChan = %.4d", PtRec->InfExtraChan )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqFunctRetCode = %.4d", PtRec->ResAcqFunctRetCode )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResEvCnt = %.4d", PtRec->ResEvCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmul () { + + return ( EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 31/10/2010 +Doc date : 31/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheckRec ( EFRIO_TFrCheck* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Frames check record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqNo = %.4d", PtRec->ParAcqNo )); + msg (( MSG_OUT, "ParFrNo = %.4d", PtRec->ParFrNo )); + msg (( MSG_OUT, "ParChkMode = %.4d", PtRec->ParChkMode )); + msg (( MSG_OUT, "ParFrPrintLevel = %.4d", PtRec->ParFrPrintLevel )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfMi26Nb = %.4d", PtRec->InfMi26Nb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResAHeader[0] , PtRec->ResAHeader[1] , PtRec->ResAHeader[2] , PtRec->ResAHeader[3] , PtRec->ResAHeader[4] , PtRec->ResAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResATrailer[0] , PtRec->ResATrailer[1] , PtRec->ResATrailer[2] , PtRec->ResATrailer[3] , PtRec->ResATrailer[4] , PtRec->ResATrailer[5] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResAFrameCnt[0] , PtRec->ResAFrameCnt[1] , PtRec->ResAFrameCnt[2] , PtRec->ResAFrameCnt[3] , PtRec->ResAFrameCnt[4] , PtRec->ResAFrameCnt[5] )); + msg (( MSG_OUT, "DL [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResADataLenght[0], PtRec->ResADataLenght[1], PtRec->ResADataLenght[2], PtRec->ResADataLenght[3], PtRec->ResADataLenght[4], PtRec->ResADataLenght[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResTrigNb = %.4d", PtRec->ResTrigNb )); + msg (( MSG_OUT, "TRG [0]=%.8d [1]=%.8d [3]=%.8d [Last]=%.8d", PtRec->ResATrig[0], PtRec->ResATrig[1], PtRec->ResATrig[2], PtRec->ResATrig[3] )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheck () { + + return ( EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( SInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( SInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTriggerRec* VPtTrig; + SInt16 ViTrig; + char VStrTrig[30]; + char VStrTs [30]; + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Trigger record follows the data record which has a VARIABLE size + + VPtTrig = (EFRIO__TTriggerRec*) ( (UInt8*) PtRec + PtRec->TrigRecOffset ); + + // ------------------------------------- + // Print TFrame fields + // ------------------------------------- + + msg (( MSG_OUT, "==============================================" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "Tag = %.8X [H]", PtRec->Tag )); +#endif + msg (( MSG_OUT, "TotSz = %.4d [D]", PtRec->TotSz )); + msg (( MSG_OUT, "TrigRecOffset = %.4d [D]", PtRec->TrigRecOffset )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "H.Tag = %.8X [H]", VPtHead->Tag )); +#endif + msg (( MSG_OUT, "H.AcqId = %.4d [D]", VPtHead->AcqId )); + msg (( MSG_OUT, "H.FrameIdInAcq = %.4d [D]", VPtHead->FrameIdInAcq )); + msg (( MSG_OUT, "H.MapsName = %.4d [D]", VPtHead->MapsName )); + msg (( MSG_OUT, "H.MapsNb = %.4d [D]", VPtHead->MapsNb )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.Header [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X" , VPtHead->AMapsHeader[0] , VPtHead->AMapsHeader[1] , VPtHead->AMapsHeader[2] , VPtHead->AMapsHeader[3] , VPtHead->AMapsHeader[4] , VPtHead->AMapsHeader[5] )); + msg (( MSG_OUT, "H.FrCnt [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d", VPtHead->AMapsFrameCnt[0] , VPtHead->AMapsFrameCnt[1] , VPtHead->AMapsFrameCnt[2] , VPtHead->AMapsFrameCnt[3] , VPtHead->AMapsFrameCnt[4] , VPtHead->AMapsFrameCnt[5] )); + msg (( MSG_OUT, "H.DataSz [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d", VPtHead->AMapsDataLength[0], VPtHead->AMapsDataLength[1], VPtHead->AMapsDataLength[2], VPtHead->AMapsDataLength[3], VPtHead->AMapsDataLength[4], VPtHead->AMapsDataLength[5] )); + msg (( MSG_OUT, "H.Trailer [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X" , VPtHead->AMapsTrailer[0] , VPtHead->AMapsTrailer[1] , VPtHead->AMapsTrailer[2] , VPtHead->AMapsTrailer[3] , VPtHead->AMapsTrailer[4] , VPtHead->AMapsTrailer[5] )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.TriggerNb = %.4d [D]", VPtHead->TriggerNb )); + msg (( MSG_OUT, "H.TrigInfo [0]=%.8X [1]=%.8X [2]=%.8X ", VPtHead->AMapsTrigInfo[0], VPtHead->AMapsTrigInfo[1], VPtHead->AMapsTrigInfo[2] )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "D.Tag = %.8X [H]", VPtData->Tag )); +#endif + msg (( MSG_OUT, "D.TotSz = %.4d [D]", VPtData->TotSz )); + msg (( MSG_OUT, "D.OneMapsSz = %.4d [D]", VPtData->OneMapsSz )); + + if ( PrintLevel < 2 ) { + msg (( MSG_OUT, "==============================================" )); + return (0); + } + + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "T.Tag = %X [H]", VPtTrig->Tag )); +#endif + msg (( MSG_OUT, "T.TotSz = %.4d [D]", VPtTrig->TotSz )); + msg (( MSG_OUT, "T.TrigNb = %.4d [D]", VPtTrig->TrigNb )); + msg (( MSG_OUT, "T.TrigType = %d [D]", VPtTrig->TrigType )); + + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) + : It can be used to insert this function call on an integer datapath under LabView +: +Level : +Date : 09/08/2010 +Rev : 25/10/2010 + : - Implementation -> Empty function before +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", Msg )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", Msg )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", Msg )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", Msg )); + + return (DummyS32In); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 09/08/2010 +Rev : 25/10/2010 + : - Rename EFRIO__FGetZsFFrameRawFields in EFRIO__FGetFrameRawFields + : - Handle both IPHC "ZsFFrameRaw" and EUDET "Frame" +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +UInt32* EFRIO__FGetFrameFields ( SInt32 AcqId, SInt8 Mi26Id, SInt32 FrameIdInAcq, UInt32* PtDest, SInt8 DestW32Sz ) { + + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + SInt8 ViField; + SInt8 VFieldNb = 15; + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViTrigInf; + + static UInt32 VAFields[15]; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + for ( ViField=0; ViField < VFieldNb; ViField++ ) { + VAFields[ViField] = 0; + } + + + // Set default values used in case of error + + VAFields [0] = 0x11111111; // Header + VAFields [1] = 100; // FrameCnt + VAFields [2] = 200; // DataLength + VAFields [3] = 0x11111111; // Trailer + VAFields [4] = 0x01; // Zero + VAFields [5] = 0x02; // Zero2 + VAFields [6] = 0; // Trigger number + VAFields [7] = 0; // Trigger 1 + VAFields [8] = 0; // Trigger 2 + VAFields [9] = 0; // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + + + while (1) { + + // IPHC mode + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_IPHC ) { + + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + + // err_error (( ERR_OUT, "TRACE => EFRIO__TRF_MODE_IPHC - ViFrame = %d", ViFrame )); + + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + + VAFields[0] = VPtFrame->Header; + VAFields[1] = VPtFrame->FrameCnt; + VAFields[2] = VPtFrame->DataLength; + VAFields[3] = VPtFrame->Trailer; + VAFields[4] = VPtFrame->Zero; + VAFields[5] = VPtFrame->Zero2; + VAFields [6] = (VPtFrame->Zero & 0xFFFF0000) >> 16; // Trigger number + VAFields [7] = (VPtFrame->Zero & 0x0000FFFF); // Trigger 1 + VAFields [8] = (VPtFrame->Zero2 & 0xFFFF0000) >> 16; // Trigger 2 + VAFields [9] = (VPtFrame->Zero2 & 0x0000FFFF); // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + + break; + } + + // EUDET 1 mode + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + break; + } + + // err_error (( ERR_OUT, "TRACE => EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN - FrameIdInAcq = %d", FrameIdInAcq )); + + VPtTrigRec = (EFRIO__TTriggerRec*) ( ((UInt8*) VPtFrList->AFramePtr[FrameIdInAcq]) + VPtFrList->AFramePtr[FrameIdInAcq]->TrigRecOffset ); + + VAFields[0] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsHeader[Mi26Id]; + VAFields[1] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsFrameCnt[Mi26Id]; + VAFields[2] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsDataLength[Mi26Id]; + VAFields[3] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrailer[Mi26Id]; + VAFields[4] = 0; // Zero + VAFields[5] = 0; // Zero2 + + VAFields[6] = VPtTrigRec->TrigNb; + + if ( VPtTrigRec->TrigNb > 0 ) { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields [8] = VPtTrigRec->ATrig[1]; // Trigger 2 + VAFields [9] = VPtTrigRec->ATrig[2]; // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + } + + else { + VAFields [7] = 0; // Trigger 1 + VAFields [8] = 0; // Trigger 2 + VAFields [9] = 0; // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + } + + + break; + } + + // EUDET 2 & 3 mode + + if ( (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) ||(VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + + // err_error (( ERR_OUT, "TRACE => EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES - FrameIdInAcq = %d", FrameIdInAcq )); + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + break; + } + + VPtTrigRec = (EFRIO__TTriggerRec*) ( ((UInt8*) VPtFrList->AFramePtr[FrameIdInAcq]) + VPtFrList->AFramePtr[FrameIdInAcq]->TrigRecOffset ); + + VAFields[0] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsHeader[Mi26Id]; + VAFields[1] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsFrameCnt[Mi26Id]; + VAFields[2] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsDataLength[Mi26Id]; + VAFields[3] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrailer[Mi26Id]; + VAFields[4] = 0; // Zero + VAFields[5] = 0; // Zero2 + + VAFields[6] = VPtTrigRec->TrigNb; + + if ( VPtTrigRec->TrigNb > 0 ) { + + switch ( VPtTrigRec->TrigNb ) { + + case 1 : { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields[11] = VPtTrigRec->ATrig[1]; // Time stamp 1 + break; } + + case 2: { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields [8] = VPtTrigRec->ATrig[2]; // Trigger 2 + VAFields[11] = VPtTrigRec->ATrig[1]; // Time stamp 1 + VAFields[12] = VPtTrigRec->ATrig[3]; // Time stamp 2 + break; } + + case 3 : { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields [8] = VPtTrigRec->ATrig[2]; // Trigger 2 + VAFields [9] = VPtTrigRec->ATrig[4]; // Trigger 3 + VAFields[11] = VPtTrigRec->ATrig[1]; // Time stamp 1 + VAFields[12] = VPtTrigRec->ATrig[3]; // Time stamp 2 + VAFields[13] = VPtTrigRec->ATrig[5]; // Time stamp 3 + break; } + + default : { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields [8] = VPtTrigRec->ATrig[2]; // Trigger 2 + VAFields [9] = VPtTrigRec->ATrig[4]; // Trigger 3 + VAFields[11] = VPtTrigRec->ATrig[1]; // Time stamp 1 + VAFields[12] = VPtTrigRec->ATrig[3]; // Time stamp 2 + VAFields[13] = VPtTrigRec->ATrig[5]; // Time stamp 3 + break; } + + } // End switch + + if ( VPtTrigRec->TrigNb > 3 ) { + VAFields[10] = VPtTrigRec->ATrig[(2 * (VPtTrigRec->TrigNb - 1))]; // Last trigger + VAFields[14] = VPtTrigRec->ATrig[(2 * (VPtTrigRec->TrigNb - 1)) + 1]; // Last time stamp + } + + else { + VAFields[10] = 0; // Last trigger + VAFields[14] = 0; // Last time stamp + } + + } // End if ( VPtTrigRec->TrigNb > 0 ) + + else { + VAFields [7] = 0; // Trigger 1 + VAFields [8] = 0; // Trigger 2 + VAFields [9] = 0; // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + } + + break; + } + + // If case not handled -> Return default values + + VAFields [0] = 0x11111111; // Header + VAFields [1] = 100; // FrameCnt + VAFields [2] = 200; // DataLength + VAFields [3] = 0x11111111; // Trailer + VAFields [4] = 0x01; // Zero + VAFields [5] = 0x02; // Zero2 + VAFields [6] = 0; // Trigger number + VAFields [7] = -1; // Trigger 1 + VAFields [8] = -1; // Trigger 2 + VAFields [9] = -1; // Trigger 3 + VAFields[10] = -1; // Last trigger + VAFields[11] = -1; // Time stamp 1 + VAFields[12] = -1; // Time stamp 2 + VAFields[13] = -1; // Time stamp 3 + VAFields[14] = -1; // Last stamp + break; + + } // End while (1) + + + if ( (PtDest != NULL) && (DestW32Sz >= VFieldNb) ) { + + for ( ViField=0; ViField < VFieldNb; ViField++ ) { + PtDest[ViField] = VAFields[ViField]; + } + + return (PtDest); + } + + err_warning (( ERR_OUT, "Use local array because : PtDest=%x == NULL or DestW32Sz=%d < 10", PtDest, DestW32Sz )); + + return (VAFields); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 06/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +EFRIO__TFrame* EFRIO__FGetFramePt ( SInt32 AcqId, SInt32 FrameIdInAcq ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"No frame=%d in list => Pointer NULL", FrameIdInAcq) ); + } + + return ( VPtFrList->AFramePtr[FrameIdInAcq] ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 31/10/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FChkAcqIphcMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + SInt32 VNiFrame; + SInt32 VNiFramePMi26; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[0]; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VNiFrame = ViFrame * VPtRunCont->ParMi26Nb; + + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + VNiFramePMi26 = VNiFrame + ViMi26; + + if ( VPtFrame[VNiFramePMi26].Header != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Header, VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFrame[VNiFramePMi26].Trailer != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].Trailer, VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFrame[VNiFramePMi26].FrameCnt; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFrame[VNiFramePMi26].FrameCnt != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFrame[VNiFramePMi26].FrameCnt, VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 31/10/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +UInt32 EFRIO__MI26_FChkAcqEudetMode ( SInt32 PrevErrCnt, SInt8 Verbose ) { + + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + EFRIO__TFrame* VPtFr; + SInt32 ViFrame; + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViMi26; + SInt32 VErrCnt; + UInt32 VAFrCnt[EFRIO__MAX_ASIC_NB]; + + + VErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtRunCont->ParFrameNbPerAcq; ViFrame++ ) { + + VPtFr = VPtFrList->AFramePtr[ViFrame]; + + for ( ViMi26=0; ViMi26 < VPtRunCont->ParMi26Nb; ViMi26++ ) { + + if ( VPtFr->Header.AMapsHeader[ViMi26] != VPtAcqEmul->ParAHeader[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Header error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsHeader[ViMi26], VPtAcqEmul->ParAHeader[ViMi26] )); + ++VErrCnt; + } + + if ( VPtFr->Header.AMapsTrailer[ViMi26] != VPtAcqEmul->ParATrailer[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Trailer error Frame=%d - Mi26=%d : Read %.8x <> JTAG %.8x", ViFrame, ViMi26, VPtFr->Header.AMapsTrailer[ViMi26], VPtAcqEmul->ParATrailer[ViMi26] )); + ++VErrCnt; + } + + + // Store frame counter of first frame of acq + + if ( ViFrame == 0 ) { + VAFrCnt[ViMi26] = VPtFr->Header.AMapsFrameCnt[ViMi26]; + } + + else { + ++VAFrCnt[ViMi26]; + + if ( VPtFr->Header.AMapsFrameCnt[ViMi26] != VAFrCnt[ViMi26] ) { + if ( Verbose ) err_error (( ERR_OUT, "Frame cnt error Frame=%d - Mi26=%d : Read %.8d <> %.8d", ViFrame, ViMi26, VPtFr->Header.AMapsFrameCnt[ViMi26], VAFrCnt[ViMi26] )); + ++VErrCnt; + } + + } + + } + + } + + + return ( PrevErrCnt + VErrCnt ); +} + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 09/03/2010 +Rev : 10/03/2010 +: - Add parameter PtFirstFrameNo +: +Doc date : 09/03/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VAEmulDataSzW16[6]; + + + + err_error (( ERR_OUT, "TRACE =>DPXI__MI26_FFRioEmulDeserData6Mi26 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + err_trace (( ERR_OUT, "1" )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + err_trace (( ERR_OUT, "2" )); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + err_trace (( ERR_OUT, "3" )); + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + err_trace (( ERR_OUT, "4" )); + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + err_trace (( ERR_OUT, "5" )); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_trace (( ERR_OUT, "6" )); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = 0x00030010; + VPtZsFFrameRaw[0].Zero2 = 0x00200040; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + err_trace (( ERR_OUT, "7" )); + + err_trace (( ERR_OUT, "Begin emul data loop" )); + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw[0].FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 29/10/2010 +Rev : + +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[6]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + // err_error (( ERR_OUT, "TRACE =>EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + err_trace (( ERR_OUT, "1" )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + err_trace (( ERR_OUT, "2" )); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + err_trace (( ERR_OUT, "3" )); + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + err_trace (( ERR_OUT, "4" )); + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + err_trace (( ERR_OUT, "5" )); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_trace (( ERR_OUT, "6" )); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + err_trace (( ERR_OUT, "7" )); + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw[0].FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 03/11/2010 +Rev : + +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[6]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + // err_error (( ERR_OUT, "TRACE =>DPXI__MI26_FFRioEmulDeserData6Mi26 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + err_trace (( ERR_OUT, "1" )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + err_trace (( ERR_OUT, "2" )); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + err_trace (( ERR_OUT, "3" )); + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + err_trace (( ERR_OUT, "4" )); + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + err_trace (( ERR_OUT, "5" )); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_trace (( ERR_OUT, "6" )); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = 0; // High W16 = trigger nb => Set in frames loop because it depends on frame Id + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameNo; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + err_trace (( ERR_OUT, "7" )); + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + EFRIO__FSetFrameIdInTriggerRec ( ViFrame, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB, VPtTrigRec ); + + // Emulate trigger on one frame over ParTrigOnOneFrameOverN and on ParTrigOnNConsecutiveFrames consecutive frames + + if ( (ViFrame % VPtAcqEmul->ParTrigOnOneFrameOverN) <= (VPtAcqEmul->ParTrigOnNConsecutiveFrames - 1) ) { + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + } + + // othewise => no trigger + + else { + VPtZsFFrameRaw[0].Zero = 0; + } + + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw[0].FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 29/10/2010 +Rev : + +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioPrintDataMi26WithEChan ( UInt32* PtSrcW32, SInt32 TotFrameNb, SInt32 FrameNo, SInt32 NbDataW32 ) { + + SInt32 Vi; + SInt32 ViFirstW32; + SInt32 ViFrame; + UInt32 VADlField[6]; + UInt32 VADlW16[6]; + UInt32 VADlW32[6]; + UInt32* Va; + SInt32 VAiTrailer[6]; + SInt32 ViZ1; + SInt32 ViZ2; + + if ( FrameNo >= TotFrameNb ) { + err_retfail ( -1, (ERR_OUT,"FrameNo=%d > Tot frame nb=%d", FrameNo, TotFrameNb ) ); + } + + ViFirstW32 = FrameNo * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 7; + + + Va = &PtSrcW32[ViFirstW32]; + + VADlField[0] = Va[14]; + VADlField[1] = Va[15]; + VADlField[2] = Va[16]; + VADlField[3] = Va[17]; + VADlField[4] = Va[18]; + VADlField[5] = Va[19]; + + for ( Vi=0; Vi < 6; Vi++ ) { + VADlW16[Vi] = ( (VADlField[Vi] & 0xFFFF0000) >> 16 ) + (VADlField[Vi] & 0x0000FFFF); + VADlW32[Vi] = VADlW16[Vi] / 2; + VAiTrailer[Vi] = 21 + ( VADlW32[Vi] * 7 ) + Vi; + } + + ViZ1 = 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7; // 21 = (H + FC + DL) x 7 chips + ViZ2 = 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14; + + + + msg (( MSG_OUT, "===============================================================================================================================" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ 0], Va[ 1], Va[ 2], Va[ 3], Va[ 4], Va[ 5], Va[ 6] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d (H) - E=%.8d (D)", Va[ 7], Va[ 8], Va[ 9], Va[10], Va[11], Va[12], Va[13] )); + msg (( MSG_OUT, "DL [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[14], Va[15], Va[16], Va[17], Va[18], Va[19], Va[20] )); + + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H)", Va[VAiTrailer[0]], Va[VAiTrailer[1]], Va[VAiTrailer[2]], Va[VAiTrailer[3]], Va[VAiTrailer[4]], Va[VAiTrailer[5]] )); + + + msg (( MSG_OUT, "Z1 [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ViZ1], Va[ViZ1+1], Va[ViZ1+2], Va[ViZ1+3], Va[ViZ1+4], Va[ViZ1+5], Va[ViZ1+6] )); + msg (( MSG_OUT, "Z2 [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ViZ2], Va[ViZ2+1], Va[ViZ2+2], Va[ViZ2+3], Va[ViZ2+4], Va[ViZ2+5], Va[ViZ2+6] )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : Trigger handling NOT done by this function => To be implemented in fw ! +: A crosscheck with sw can be done, but therefore we need on bit of RAM to +: store trigger => acq of 15 Mi26 instead of 16. +: +Level : This is a user level function. +Date : 02/02/2010 +Rev : 10/03/2010 +: - Add parameter PtFirstFrameNo + : 26/10/2010 + : - Moved from daq_pxi lib +Doc date : 02/02/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VEmulDataSzW16; + + + // err_trace (( ERR_OUT, "DPXI__MI26_FFRioEmulDeserData1Mi26 (P=%x, EltNb=%d, FrameNb=%d)", PtDestW32, EltNb, FrameNb )); + + err_trace (( ERR_OUT, "DPXI__MI26_FFRioEmulDeserData1Mi26 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + err_trace (( ERR_OUT, "1" )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + err_trace (( ERR_OUT, "2" )); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + err_trace (( ERR_OUT, "3" )); + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + err_trace (( ERR_OUT, "4" )); + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + err_trace (( ERR_OUT, "5" )); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + err_trace (( ERR_OUT, "6" )); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + + VPtZsFFrameRaw->Zero = 0x00030010; + VPtZsFFrameRaw->Zero2 = 0x00200040; + + +// VPtZsFFrameRaw->Zero = 0x00030020; +// VPtZsFFrameRaw->Zero2 = 0x00400080; + + err_trace (( ERR_OUT, "7" )); + + err_trace (( ERR_OUT, "Begin emul data loop" )); + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + } + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw->FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : EmuleMode parameter is used to define number of trigger to emulate + : - EmuleMode >= 0 -> No trigger + : - EmuleMode < 0 -> Nb trigger = absolute value of EmuleMode + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 ViTrigToEmulate; + SInt32 VEmulDataSzW16; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ / 2 ); // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) / 2 ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw->Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + VPtZsFFrameRaw->Zero2 = 0; + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + ViDestW32 = 0; + + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw->FrameCnt; + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + // Free trigger record + + free ( VPtTrigRec ); + + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : EmuleMode parameter is used to define number of trigger to emulate +: - EmuleMode >= 0 -> No trigger +: - EmuleMode < 0 -> Nb trigger = absolute value of EmuleMode +: +Level : This is a user level function. +Date : 03/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO_TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 ViTrigToEmulate; + SInt32 VEmulDataSzW16; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + err_error (( ERR_OUT, "TRACE => Begin" )); + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameNo, (ERR_OUT,"PtFirstFrameNo = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ / 2 ); // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) / 2 ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameNo; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw->Zero = 0; // High W16 = trigger nb => Set in frames loop because it depends on frame Id + VPtZsFFrameRaw->Zero2 = 0; + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + ViDestW32 = 0; + + +// msg (( MSG_OUT, "********************************************" )); + + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + EFRIO__FSetFrameIdInTriggerRec ( ViFrame, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB, VPtTrigRec ); + + // Emulate trigger on one frame over ParTrigOnOneFrameOverN and on ParTrigOnNConsecutiveFrames consecutive frames + + if ( (ViFrame % VPtAcqEmul->ParTrigOnOneFrameOverN) <= (VPtAcqEmul->ParTrigOnNConsecutiveFrames - 1) ) { + VPtZsFFrameRaw->Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + +// msg (( MSG_OUT, "Emul => Trig on frame %.4d", ViFrame )); + } + + // otherwise => no trigger + + else { + VPtZsFFrameRaw->Zero = 0; + } + + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameNo = VPtZsFFrameRaw->FrameCnt; + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + // Free trigger record + + free ( VPtTrigRec ); + + err_error (( ERR_OUT, "TRACE => End" )); + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : Trigger handling NOT done by this function => To be implemented in fw ! +: A crosscheck with sw can be done, but therefore we need on bit of RAM to +: store trigger => acq of 15 Mi26 instead of 16. +: +Level : This is a user level function. +Date : 02/02/2010 +Rev : 07/05/2010 +: - Trigger calculation +: 19/05/2010 +: - Add trigger counter field handling in ASIC__TFrameStatus + +Doc date : 02/02/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // msg (( MSG_OUT, "==> DPXI__MI26_FFRioAcqDeserData1Mi26 : Mi26NbToRead=%d - EltNb=%d - TotAnsSz=%d", VPtServ->PtParAcqReqFunc->AsicNbToRead, EltNb, PtAcq->InfTotAnsSz )); + + // Copy Acq inf pointers to local pointers + + // $$$ VPtAcqData = PtAcq->InfPtAcqData; + // $$$ VptZsFFrameRaw = PtAcq->InfPtZsFFrameRaw; + // $$$ msg (( MSG_OUT, "DPXI__MI26_FFRioAcqDeserData1Mi26 => AcqReqFuncSz=%d - MaxDataSz=%d - VTotAnsSz=%d", PtAcq->InfParAcqReqFuncSz, VPtServ->PtParAcqReqFunc->MaxDataSz, PtAcq->InfTotAnsSz )); + // $$$ memset ( VPtAcqData, 0, PtAcq->InfTotAnsSz ); + // $$$ err_trace (( ERR_OUT, "Start extract data for FrameNb=%d", VPtServ->PtParAcqReqFunc->FrameNb )); + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // Extract data + + // $$$ VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VptZsFFrameRaw[ViFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[ViFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + VptZsFFrameRaw[ViFrame].DataLength = VDataLengthField; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32 = (UInt32*) VptZsFFrameRaw[ViFrame].ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + VptZsFFrameRaw[ViFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + VptZsFFrameRaw[ViFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + VptZsFFrameRaw[ViFrame].Zero2 = VZero2; + ++ViSrcW32; + + // $$$ DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + VptZsFFrameRaw[ViFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[ViFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[ViFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[ViFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[ViFrame].SStatus.HitCnt = -1; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VRunFrameCnt; + + } // End for ViFrame + + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : Trigger handling NOT done by this function => To be implemented in fw ! +: A crosscheck with sw can be done, but therefore we need on bit of RAM to +: store trigger => acq of 15 Mi26 instead of 16. +: +Level : This is a user level function. +Date : 09/03/2010 +Rev : 06/05/2010 +: - Add trigger extract +: Warning ! Copy Zero & Zero2 fields of frame chip No 0 to ALL others chips ! +: All fields Zero & Zero2 are equals to the fields of first chip +: 19/05/2010 +: - Add trigger counter field handling in ASIC__TFrameStatus +Doc date : 09/03/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + SInt32 V6iFrameP1; + SInt32 V6iFrameP2; + SInt32 V6iFrameP3; + SInt32 V6iFrameP4; + SInt32 V6iFrameP5; + UInt32 VADataLengthField[6]; + UInt16 VADataLengthW16[6]; + UInt16 VADataLengthW32[6]; + UInt16 VDataLengthW32Max; + register SInt32 ViSrcW32; + register SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get AcqId + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + // err_warning (( ERR_OUT, "TRACE : Memset buffer")); + + // memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // err_warning (( ERR_OUT, "TRACE : Extract data")); + + // Extract data + + // VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 1", ViFrame )); + + + V6iFrame = 6 * ViFrame; + V6iFrameP1 = V6iFrame + 1; + V6iFrameP2 = V6iFrame + 2; + V6iFrameP3 = V6iFrame + 3; + V6iFrameP4 = V6iFrame + 4; + V6iFrameP5 = V6iFrame + 5; + + + VptZsFFrameRaw[V6iFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VptZsFFrameRaw[V6iFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + + VptZsFFrameRaw[V6iFrame].DataLength = VADataLengthField[0]; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VptZsFFrameRaw[V6iFrameP1].DataLength = VADataLengthField[1]; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + + VptZsFFrameRaw[V6iFrameP2].DataLength = VADataLengthField[2]; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VptZsFFrameRaw[V6iFrameP3].DataLength = VADataLengthField[3]; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VptZsFFrameRaw[V6iFrameP4].DataLength = VADataLengthField[4]; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VptZsFFrameRaw[V6iFrameP5].DataLength = VADataLengthField[5]; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + // Find max data length of the six Mi26 + + VDataLengthW32Max = MATH_FUInt16Max ( VADataLengthW32, 6 ); + + + // err_error (( ERR_OUT, "TRACE => Length W32 [0]=%d - [1]=%d - [2]=%d - [3]=%d - [4]=%d - [5]=%d", VADataLengthW32[0], VADataLengthW32[1], VADataLengthW32[2], VADataLengthW32[3], VADataLengthW32[4], VADataLengthW32[5] )); + // err_error (( ERR_OUT, "TRACE => MI26__ZS_FFRAME_RAW_MAX_W32 = %d", MI26__ZS_FFRAME_RAW_MAX_W32 )); + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32Chip0 = (UInt32*) VptZsFFrameRaw[V6iFrame].ADataW16; + VPtDataW32Chip1 = (UInt32*) VptZsFFrameRaw[V6iFrameP1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VptZsFFrameRaw[V6iFrameP2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VptZsFFrameRaw[V6iFrameP3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VptZsFFrameRaw[V6iFrameP4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VptZsFFrameRaw[V6iFrameP5].ADataW16; + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 2", ViFrame )); + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip1[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip2[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip3[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip4[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip5[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 3", ViFrame )); + + VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VptZsFFrameRaw[V6iFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + ++ViSrcW32; + + // DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 4", ViFrame )); + + VptZsFFrameRaw[V6iFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrame].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP1].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 1 + 18 + (6 * VADataLengthW32[1])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP1].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP1].SStatus.AsicNo = 1; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP1].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP2].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 2 + 18 + (6 * VADataLengthW32[2])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP2].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP2].SStatus.AsicNo = 2; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP2].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP3].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 3 + 18 + (6 * VADataLengthW32[3])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP3].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP3].SStatus.AsicNo = 3; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP3].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP4].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 4 + 18 + (6 * VADataLengthW32[4])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP4].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP4].SStatus.AsicNo = 4; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP4].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP5].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 5 + 18 + (6 * VADataLengthW32[5])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP5].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP5].SStatus.AsicNo = 5; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP5].SStatus.HitCnt = -1; + + + + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 6 /* Mi26Nb */ ); + // PtAcq->ResAsicErrorsRejCurAcq = 0; + + // if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // } + } + + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 5", ViFrame )); + + ++VRunFrameCnt; + + } // End for ViFrame + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + + + + +SInt32 OLD___EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + + SInt32 VAcqId; + UInt8* VPtAcqData; + MI26__TZsFFrameRaw* VptZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + SInt32 V6iFrameP1; + SInt32 V6iFrameP2; + SInt32 V6iFrameP3; + SInt32 V6iFrameP4; + SInt32 V6iFrameP5; + UInt32 VADataLengthField[6]; + // UInt32 VADataLengthW16[6]; + // UInt32 VADataLengthW32[6]; + UInt16 VADataLengthW16[6]; + UInt16 VADataLengthW32[6]; + UInt16 VDataLengthW32Max; + register SInt32 ViSrcW32; + register SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt32 VTrigLine; + SInt32 VTrigClk; + SInt32 VTrigNb; + SInt32 VNbW8ToCpy; + register SInt32 VNbS32ToCpy; + UInt32 VNbU32ToCpy; + UInt32* VPtCpySrc; + UInt32* VPtCpyDest; + + SInt32 ViSrcS32; + SInt32 ViDataS32; + SInt32 ViSrcU32; + SInt32 ViDataU32; + + + // SInt32 ViDataS32; + // UInt32 ViDataU32; + // SInt32 ViSrcS32; + // UInt32 ViSrcU32; + + UInt32 ViU32Dummy; + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Get AcqId + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + + // Init pointer to dest FFrameRaw buffer + + VptZsFFrameRaw = VPtCont->RunCont.PtZsFFrameRaw; + + // Check if buffer is allocated + + err_retnull ( VptZsFFrameRaw, (ERR_OUT,"Abort : FFrameRaw buffer not allocated !") ); + + // Reset destination FFrameRaw buffer => !!! Can be removed if it makes loosing too much execution time !!! + + err_warning (( ERR_OUT, "TRACE : Memset buffer")); + + memset ( VptZsFFrameRaw, 0, VPtCont->RunCont.InfZsFFrameRawBuffSz ); + + // err_warning (( ERR_OUT, "TRACE : Extract data")); + + // Extract data + + // VRunFrameCnt = PtAcq->InfRunFrameCnt; + + ViSrcW32 = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 1", ViFrame )); + + + V6iFrame = 6 * ViFrame; + V6iFrameP1 = V6iFrame + 1; + V6iFrameP2 = V6iFrame + 2; + V6iFrameP3 = V6iFrame + 3; + V6iFrameP4 = V6iFrame + 4; + V6iFrameP5 = V6iFrame + 5; + + + VptZsFFrameRaw[V6iFrame].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Header = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VptZsFFrameRaw[V6iFrame].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].FrameCnt = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + + + VptZsFFrameRaw[V6iFrame].DataLength = VADataLengthField[0]; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VptZsFFrameRaw[V6iFrameP1].DataLength = VADataLengthField[1]; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + + VptZsFFrameRaw[V6iFrameP2].DataLength = VADataLengthField[2]; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VptZsFFrameRaw[V6iFrameP3].DataLength = VADataLengthField[3]; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VptZsFFrameRaw[V6iFrameP4].DataLength = VADataLengthField[4]; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VptZsFFrameRaw[V6iFrameP5].DataLength = VADataLengthField[5]; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + // Find max data length of the six Mi26 + + VDataLengthW32Max = MATH_FUInt16Max ( VADataLengthW32, 6 ); + + + // err_error (( ERR_OUT, "TRACE => Length W32 [0]=%d - [1]=%d - [2]=%d - [3]=%d - [4]=%d - [5]=%d", VADataLengthW32[0], VADataLengthW32[1], VADataLengthW32[2], VADataLengthW32[3], VADataLengthW32[4], VADataLengthW32[5] )); + // err_error (( ERR_OUT, "TRACE => MI26__ZS_FFRAME_RAW_MAX_W32 = %d", MI26__ZS_FFRAME_RAW_MAX_W32 )); + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + VPtDataW32Chip0 = (UInt32*) VptZsFFrameRaw[V6iFrame].ADataW16; + VPtDataW32Chip1 = (UInt32*) VptZsFFrameRaw[V6iFrameP1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VptZsFFrameRaw[V6iFrameP2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VptZsFFrameRaw[V6iFrameP3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VptZsFFrameRaw[V6iFrameP4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VptZsFFrameRaw[V6iFrameP5].ADataW16; + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 2", ViFrame )); + + + switch ( DataConvertMode ) { + + // IPHC mode + + case EFRIO__TRF_MODE_IPHC : { + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip1[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip2[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip3[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip4[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtDataW32Chip5[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + break; } + + // Simple copy by array with W32 loop -> Vi signed + + case 2 : { + + VNbS32ToCpy = MI26__ZS_FFRAME_RAW_MAX_W32 * 6; + + for ( ViDataW32=0; ViDataW32 < VNbS32ToCpy; ViDataW32++, ++ViSrcW32 ) { + VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + } + + break; } + + + // Simple copy by array with W32 loop -> Vi signed + + case 20 : { + + VNbS32ToCpy = MI26__ZS_FFRAME_RAW_MAX_W32 * 6; + ViSrcS32 = ViSrcW32; + + for ( ViDataS32=0; ViDataS32 < VNbS32ToCpy; ViDataS32++, ++ViSrcS32 ) { + VPtDataW32Chip0[ViDataS32] = PtSrcW32[ViSrcS32]; + } + + ViSrcW32 = ViSrcS32; + + // for ( ViDataW32=0; ViDataW32 < VNbS32ToCpy; ViDataW32++, ++ViSrcW32 ) { + // VPtDataW32Chip0[ViDataW32] = PtSrcW32[ViSrcW32]; + // } + + + break; } + + // Simple copy by array with W32 loop -> Vi unsigned + + case 21 : { + + VNbU32ToCpy = MI26__ZS_FFRAME_RAW_MAX_W32 * 6; + ViSrcU32 = ViSrcW32; + + for ( ViDataU32=0; ViDataU32 < VNbU32ToCpy; ViDataU32++, ++ViSrcU32 ) { + VPtDataW32Chip0[ViDataU32] = PtSrcW32[ViSrcU32]; + } + + ViSrcW32 = ViSrcU32; + + break; } + + // Simple copy by array with W32 loop -> Vi unsigned + increment dummy U32 + + case 22 : { + + VNbU32ToCpy = MI26__ZS_FFRAME_RAW_MAX_W32 * 6; + ViSrcU32 = ViSrcW32; + + for ( ViDataU32=0; ViDataU32 < VNbU32ToCpy; ViDataU32++, ++ViSrcU32, ++ViU32Dummy ) { + VPtDataW32Chip0[ViDataU32] = PtSrcW32[ViSrcU32]; + } + + ViSrcW32 = ViSrcU32; + + break; } + + // Simple copy by ptr with W32 loop + + case 3 : { + + VNbS32ToCpy = MI26__ZS_FFRAME_RAW_MAX_W32 * 6; + VPtCpySrc = VPtDataW32Chip0; + VPtCpyDest = &PtSrcW32[ViSrcW32]; + ViSrcW32 = ViSrcW32 + VNbS32ToCpy; // Not useful here, but for processing after this bloc + + + for ( ViDataW32=0; ViDataW32 < VNbS32ToCpy; ViDataW32++, ++VPtCpySrc, ++VPtCpyDest ) { + *VPtCpyDest = *VPtCpySrc; + } + + break; } + + + + // Simple copy with memcpy + + case 4 : { + + VNbW8ToCpy = MI26__ZS_FFRAME_RAW_MAX_W32 * 6 * 4; + + memcpy ( (UInt8*) VPtDataW32Chip0, (UInt8*) &PtSrcW32[ViSrcW32], VNbW8ToCpy ); + + break; } + + + } + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 3", ViFrame )); + + VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VptZsFFrameRaw[V6iFrame].Zero = VZero; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + ++ViSrcW32; + + // DPXI__MI26_FFRioExtractFirstTrigger ( TrigStatus, ViFrame, VLastFrameWithTrigAllowed, VZero, VZero2, &VTrigLine, &VTrigClk, &VTrigNb ); + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 4", ViFrame )); + + VptZsFFrameRaw[V6iFrame].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrame].SStatus.AsicNo = 0; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrame].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrame].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrame].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP1].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 1 + 18 + (6 * VADataLengthW32[1])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP1].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP1].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP1].SStatus.AsicNo = 1; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP1].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP1].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP1].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP2].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 2 + 18 + (6 * VADataLengthW32[2])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP2].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP2].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP2].SStatus.AsicNo = 2; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP2].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP2].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP2].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP3].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 3 + 18 + (6 * VADataLengthW32[3])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP3].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP3].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP3].SStatus.AsicNo = 3; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP3].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP3].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP3].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP4].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 4 + 18 + (6 * VADataLengthW32[4])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP4].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP4].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP4].SStatus.AsicNo = 4; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP4].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP4].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP4].SStatus.HitCnt = -1; + + + VptZsFFrameRaw[V6iFrameP5].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 5 + 18 + (6 * VADataLengthW32[5])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero = VZero; + ++ViSrcW32; + VptZsFFrameRaw[V6iFrameP5].Zero2 = VZero2; + ++ViSrcW32; + + VptZsFFrameRaw[V6iFrameP5].SStatus.AcqNo = VAcqId; + VptZsFFrameRaw[V6iFrameP5].SStatus.AsicNo = 5; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInAcq = ViFrame; + VptZsFFrameRaw[V6iFrameP5].SStatus.FrameNoInRun = VRunFrameCnt; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = VTrigLine; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = VTrigClk; + VptZsFFrameRaw[V6iFrameP5].SStatus.ATrigRes[ASIC__MI26_TRIG_TOT_NB] = VTrigNb; + VptZsFFrameRaw[V6iFrameP5].SStatus.HitCnt = -1; + + + + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 6 /* Mi26Nb */ ); + // PtAcq->ResAsicErrorsRejCurAcq = 0; + + // if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // } + } + + + // err_warning (( ERR_OUT, "TRACE : Extract frame = %d - 5", ViFrame )); + + ++VRunFrameCnt; + + } // End for ViFrame + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + err_retok (( ERR_OUT, "MsgOk" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 25/10/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + +// err_error (( ERR_OUT, "TRACE => VEmptyTrigRecSz = %d", VEmptyTrigRecSz )); +// err_error (( ERR_OUT, "TRACE => VEmptyFrameRecSz = %d", VEmptyFrameRecSz )); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // err_error (( ERR_OUT, "TRACE : Set pointer frame %d - pointer = %d [D]", VPtFrList->TotFrameNb, VPtFrList->AFramePtr[VPtFrList->TotFrameNb] )); + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + // err_error (( ERR_OUT, "TRACE -> Before loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + // err_error (( ERR_OUT, "TRACE -> After loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + +// err_error (( ERR_OUT, "TRACE => VAMi26Trig[0]=%d - VAMi26Trig[1]=%d - VAMi26Trig[2]=%d", VAMi26Trig[0], VAMi26Trig[1], VAMi26Trig[2] )); +// err_error (( ERR_OUT, "TRACE => ATrig[0] =%d - ATrig[1] =%d - ATrig[2] =%d", VPtTrigRec->ATrig[0], VPtTrigRec->ATrig[1], VPtTrigRec->ATrig[2] )); + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 27/10/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // err_error (( ERR_OUT, "TRACE => VEmptyTrigRecSz = %d", VEmptyTrigRecSz )); + // err_error (( ERR_OUT, "TRACE => VEmptyFrameRecSz = %d", VEmptyFrameRecSz )); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // err_error (( ERR_OUT, "TRACE : Set pointer frame %d - pointer = %d [D]", VPtFrList->TotFrameNb, VPtFrList->AFramePtr[VPtFrList->TotFrameNb] )); + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + memset ( VADataLengthW8 , 0, 12 ); + memset ( VADataLengthW16, 0, 12 ); + memset ( VADataLengthW32, 0, 12 ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + // err_error (( ERR_OUT, "TRACE -> Before loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + + // A remplacer par memcpy !!!!!!!!! + + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + // err_error (( ERR_OUT, "TRACE => VAMi26Trig[0]=%d - VAMi26Trig[1]=%d - VAMi26Trig[2]=%d", VAMi26Trig[0], VAMi26Trig[1], VAMi26Trig[2] )); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 28/10/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // err_error (( ERR_OUT, "TRACE => VEmptyTrigRecSz = %d", VEmptyTrigRecSz )); + // err_error (( ERR_OUT, "TRACE => VEmptyFrameRecSz = %d", VEmptyFrameRecSz )); + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // err_error (( ERR_OUT, "TRACE : Set pointer frame %d - pointer = %d [D]", VPtFrList->TotFrameNb, VPtFrList->AFramePtr[VPtFrList->TotFrameNb] )); + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + // err_error (( ERR_OUT, "TRACE -> Before loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + // err_error (( ERR_OUT, "TRACE -> After loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 29/10/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // err_error (( ERR_OUT, "TRACE => VEmptyTrigRecSz = %d", VEmptyTrigRecSz )); + // err_error (( ERR_OUT, "TRACE => VEmptyFrameRecSz = %d", VEmptyFrameRecSz )); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // err_error (( ERR_OUT, "TRACE : Set pointer frame %d - pointer = %d [D]", VPtFrList->TotFrameNb, VPtFrList->AFramePtr[VPtFrList->TotFrameNb] )); + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + memset ( VADataLengthW8 , 0, 12 ); + memset ( VADataLengthW16, 0, 12 ); + memset ( VADataLengthW32, 0, 12 ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + // err_error (( ERR_OUT, "TRACE -> Before loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + + // A remplacer par memcpy !!!!!!!!! + + + // memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + + + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + + + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 03/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // err_error (( ERR_OUT, "TRACE => VEmptyTrigRecSz = %d", VEmptyTrigRecSz )); + // err_error (( ERR_OUT, "TRACE => VEmptyFrameRecSz = %d", VEmptyFrameRecSz )); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // err_error (( ERR_OUT, "TRACE : Set pointer frame %d - pointer = %d [D]", VPtFrList->TotFrameNb, VPtFrList->AFramePtr[VPtFrList->TotFrameNb] )); + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + memset ( VADataLengthW8 , 0, 12 ); + memset ( VADataLengthW16, 0, 12 ); + memset ( VADataLengthW32, 0, 12 ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + // err_error (( ERR_OUT, "TRACE -> Before loop - VFrameId=%d - VDataLengthW32=%d", VFrameId, VDataLengthW32 )); + + + // A remplacer par memcpy !!!!!!!!! + + + // memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + + + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + + + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + ++VPtCont->RunCont.ResAcqCnt; + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + return (VTotAcqSz); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Set board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation +Doc date : 11/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + SInt32 VEmuleFirstFrameNo; + + SInt32 VDbgOffset; + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + +/* + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[11] )); + +*/ + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataIphcMode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + } + + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet1Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + return (VRet); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Set board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSetBoardConf ( SInt32 BoardId, EFRIO__TBoardConf* PtSrc ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( PtSrc, (ERR_OUT,"Abort : PtSrc == NULL") ); + + EFRIO__VGContext.ABoardsConf[BoardId] = *PtSrc; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Set board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/08/2010 +Doc date : 10/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfBoardId ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].BoardId = BoardId; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfAsicName ( SInt32 BoardId, char* AsicName ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + snprintf ( EFRIO__VGContext.ABoardsConf[BoardId].AsicName, GLB_CMT_SZ - 1, "%s", AsicName ); + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfAsicNb ( SInt32 BoardId, SInt32 AsicNb ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].AsicNb = AsicNb; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfReadoutMode ( SInt32 BoardId, SInt32 ReadoutMode ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].ReadoutMode = ReadoutMode; + + err_retok (( ERR_OUT, "" )); +} + +// 11/08/2010 + +SInt32 EFRIO__FSetBoardConfEmuleChannels ( SInt32 BoardId, SInt8 EmuleChannels ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].EmuleChannels = EmuleChannels; + + err_retok (( ERR_OUT, "" )); +} + + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfDataClkFrequency ( SInt32 BoardId, float DataClkFrequency ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].DataClkFrequency = DataClkFrequency; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfDmaHostSz ( SInt32 BoardId, UInt32 DmaHostSz ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].DmaHostSz = DmaHostSz; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfFrameNbPerAcq ( SInt32 BoardId, SInt32 FrameNbPerAcq ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].FrameNbPerAcq = FrameNbPerAcq; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfEnableExtraChannel ( SInt32 BoardId, SInt8 EnableExtraChannel ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].EnableExtraChannel = EnableExtraChannel; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfAcqNbPerTrig ( SInt32 BoardId, SInt32 AcqNbPerTrig ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].AcqNbPerTrig = AcqNbPerTrig; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTriggerMode ( SInt32 BoardId, SInt8 TriggerMode ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TriggerMode = TriggerMode; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTriggerDetectTimeWindow ( SInt32 BoardId, UInt32 TriggerDetectTimeWindow ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TriggerDetectTimeWindow = TriggerDetectTimeWindow; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTriggerDetectOccurNb ( SInt32 BoardId, UInt32 TriggerDetectOccurNb ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TriggerDetectOccurNb = TriggerDetectOccurNb; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTimeStampRes ( SInt32 BoardId, UInt32 TimeStampRes ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TimeStampRes = TimeStampRes; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfEnableTimeStamping ( SInt32 BoardId, SInt8 EnableTimeStamping ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].EnableTimeStamping = EnableTimeStamping; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfEnableTrigCnt ( SInt32 BoardId, SInt8 EnableTrigCnt ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].EnableTrigCnt = EnableTrigCnt; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTagEventsStoredByDUT ( SInt32 BoardId, SInt8 TagEventsStoredByDUT ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TagEventsStoredByDUT = TagEventsStoredByDUT; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfReadTluTrigCntEachNTrig ( SInt32 BoardId, UInt32 ReadTluTrigCntEachNTrig ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].ReadTluTrigCntEachNTrig = ReadTluTrigCntEachNTrig; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Get board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FGetBoardConf ( SInt32 BoardId, EFRIO__TBoardConf* PtDest ) { + + err_trace (( ERR_OUT, "begin" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( PtDest, (ERR_OUT,"Abort : PtDest == NULL") ); + + *PtDest = EFRIO__VGContext.ABoardsConf[BoardId]; + + err_retok (( ERR_OUT, "end" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Get board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/08/2010 +Doc date : 10/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfBoardId ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].BoardId); +} + +// 10/08/2010 + +char* EFRIO__FGetBoardConfAsicName ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) { + return (NULL); + } + + return (EFRIO__VGContext.ABoardsConf[BoardId].AsicName); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfAsicNb ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].AsicNb); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfReadoutMode ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].ReadoutMode); +} + +// 11/08/2010 + +SInt8 EFRIO__FGetBoardConfEmuleChannels ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].EmuleChannels); +} + + +// 10/08/2010 + +float EFRIO__FGetBoardConfDataClkFrequency ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].DataClkFrequency); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfDmaHostSz ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].DmaHostSz); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfFrameNbPerAcq ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].FrameNbPerAcq); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfEnableExtraChannel ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].EnableExtraChannel); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfAcqNbPerTrig ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].AcqNbPerTrig); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfTriggerMode ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TriggerMode); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfTriggerDetectTimeWindow ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TriggerDetectTimeWindow); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfTriggerDetectOccurNb ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TriggerDetectOccurNb); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfTimeStampRes ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TimeStampRes); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfEnableTimeStamping ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].EnableTimeStamping); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfEnableTrigCnt ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].EnableTrigCnt); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfTagEventsStoredByDUT ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TagEventsStoredByDUT); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfReadTluTrigCntEachNTrig ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].ReadTluTrigCntEachNTrig); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Set board status fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/08/2010 +Doc date : 10/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusBoardId ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].BoardId = BoardId; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusBoardPresent ( SInt32 BoardId, SInt8 BoardPresent ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].BoardPresent = BoardPresent; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusFwLoaded ( SInt32 BoardId, SInt8 FwLoaded ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].FwLoaded = FwLoaded; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusConfDone ( SInt32 BoardId, SInt8 ConfDone ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].ConfDone = ConfDone; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusStatusCode ( SInt32 BoardId, SInt32 StatusCode ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].StatusCode = StatusCode; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusStatusStr ( SInt32 BoardId, char* StatusStr ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( StatusStr, (ERR_OUT,"Abort : StatusStr == NULL") ); + + snprintf ( EFRIO__VGContext.ABoardsStatus[BoardId].StatusStr, GLB_CMT_SZ - 1, "%s", StatusStr ); + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusErrorMsgList ( SInt32 BoardId, char* ErrorMsg, SInt32 Index ) { + + SInt32 VMsgLen; + EFRIO__TBoardStatus* VPtStatus; + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( ErrorMsg, (ERR_OUT,"Abort : ErrorMsg == NULL") ); + + VPtStatus = &EFRIO__VGContext.ABoardsStatus[BoardId]; + + // Check index limits + + if ( (Index < 0) || (Index >= EFRIO__ERROR_MSG_LIST_MAX_NB ) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Index=%d out of range [0..%d]", Index, EFRIO__ERROR_MSG_LIST_MAX_NB-1 ) ); + } + + // Get message length + + VMsgLen = strlen ( ErrorMsg ); + + // Free item if already allocated + + if ( VPtStatus->ErrorMsgList[Index] != NULL ) { + free ( VPtStatus->ErrorMsgList[Index] ); + } + + // Allocate memory for message + + VPtStatus->ErrorMsgList[Index] = (char*) malloc ( VMsgLen + 1 ); + + err_retnull ( VPtStatus->ErrorMsgList[Index], (ERR_OUT,"Abort : Allocation of message [%d] failed !", Index) ); + + // Copy message + + snprintf ( VPtStatus->ErrorMsgList[Index], VMsgLen, "%s", ErrorMsg ); + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusLastErrorMsg ( SInt32 BoardId, char* LastErrorMsg ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( LastErrorMsg, (ERR_OUT,"Abort : LastErrorMsg == NULL") ); + + snprintf ( EFRIO__VGContext.ABoardsStatus[BoardId].LastErrorMsg, GLB_CMT_SZ - 1, "%s", LastErrorMsg ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Get board status fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/08/2010 +Doc date : 10/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardStatusBoardId ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].BoardId); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardStatusBoardPresent ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].BoardPresent); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardStatusFwLoaded ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].FwLoaded); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardStatusConfDone ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].ConfDone); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardStatusStatusCode ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].StatusCode); +} + +// 10/08/2010 + +char* EFRIO__FGetBoardStatusStatusStr ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) { + err_error (( ERR_OUT, "Abort : BoardId=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 )); + return (NULL); + } + + return (EFRIO__VGContext.ABoardsStatus[BoardId].StatusStr); +} + + +// 10/08/2010 + +char* EFRIO__FGetBoardStatusErrorMsgList ( SInt32 BoardId, SInt32 Index ) { + + SInt32 VMsgLen; + EFRIO__TBoardStatus* VPtStatus; + + if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) { + err_error (( ERR_OUT, "Abort : BoardId=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 )); + return (NULL); + } + + VPtStatus = &EFRIO__VGContext.ABoardsStatus[BoardId]; + + // Check index limits + + if ( (Index < 0) || (Index >= EFRIO__ERROR_MSG_LIST_MAX_NB ) ) { + err_error (( ERR_OUT, "Abort : Index=%d out of range [0..%d]", Index, EFRIO__ERROR_MSG_LIST_MAX_NB-1 )); + return (NULL); + } + + return ( VPtStatus->ErrorMsgList[Index] ); +} + +// 10/08/2010 + +char* EFRIO__FGetBoardStatusLastErrorMsg ( SInt32 BoardId ) { + + if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) { + err_error (( ERR_OUT, "Abort : BoardId=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 )); + return (NULL); + } + + return (EFRIO__VGContext.ABoardsStatus[BoardId].LastErrorMsg); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! +: +Level : This is a user level function. +Date : 03/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // err_error (( ERR_OUT, "TRACE => VEmptyTrigRecSz = %d", VEmptyTrigRecSz )); + // err_error (( ERR_OUT, "TRACE => VEmptyFrameRecSz = %d", VEmptyFrameRecSz )); + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // err_error (( ERR_OUT, "TRACE : Set pointer frame %d - pointer = %d [D]", VPtFrList->TotFrameNb, VPtFrList->AFramePtr[VPtFrList->TotFrameNb] )); + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + // err_error (( ERR_OUT, "TRACE -> Before loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + // err_error (( ERR_OUT, "TRACE -> After loop - ViFrame=%d - VDataLengthW32=%d", ViFrame, VDataLengthW32 )); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + if ( 0 /* VPtServ->PtParAcqReqFunc->AsicChkFunc >= 0 */ ) { + + // No neeed to reset ResAsicErrorsRejCurAcq ( it's done on DPXI__MI26_FAsicChkFunc0Emul6Mi26 with ViFrame = 0 ) + // => ResAsicErrorsRejCurAcq = 1 if errors in current Acq + + // $$$ PtAcq->ResAsicErrorsRejCurAcq = DPXI__MI26_FAsicChkFuncMi26 ( VPtServ->PtParAcqReqFunc->AsicChkFunc, ViFrame, VptZsFFrameRaw, 1 /* Mi26Nb */ ); + // $$$ PtAcq->ResAsicErrorsRejCurAcq = 0; + + // $$$ if ( PtAcq->ResAsicErrorsRejCurAcq != 0 ) { + // $$$ msg (( MSG_OUT, "ViFrame=%d - VAsicErrorsRejCurAcq=%d", ViFrame, PtAcq->ResAsicErrorsRejCurAcq )); + // $$$ } + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + ++VPtCont->RunCont.ResAcqCnt; + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + + return (VTotAcqSz); + } + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio__all_func_in_file_061110_13H43.h b/include/pxi_daq_lib_v.2.1/eudet_frio__all_func_in_file_061110_13H43.h new file mode 100755 index 0000000..56f31c2 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio__all_func_in_file_061110_13H43.h @@ -0,0 +1,133 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.h +Goal : Functions prototypes of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + +FHEAD ( SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode1Mi26 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, SInt8 DataConvertMode );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FBegin ( SInt8 ErrorLogLvl, char* ErrorLogFile, SInt8 MsgLogLvl, char* MsgLogFile );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FEnd ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32* EFRIO__FTrfData ( SInt8 CmdGetPtrCpyAlloc, UInt32 AllocW32Sz, UInt32* PtSrcW32, UInt32 SrcW32Sz );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FDbgMeasRamCpyTime ( SInt8 Cmd, SInt32 SzMb );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FDbgCheckTrigAlgo ( SInt8 Cmd, SInt8 TriggerNb, SInt8 AddFrameBefore, SInt8 AddFrameAfter );) + +// Param add on 30/10/10 +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, char* FileNamePrefix );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FConfRun ( SInt8 Mi26Nb, SInt32 RunNo, SInt32 TotEvNb, SInt32 EvNbPerFile, SInt32 FrameNbPerAcq, SInt8 DataTransferMode, char* DestDir, char* FileNamePrefix, SInt8 SaveToDisk, SInt8 SendOnEth, SInt8 SendOnEthPCent );) + + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintRunCont ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) ;) + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32* EFRIO__FGetZsFFrameRawFields ( SInt32 AcqId, SInt8 Mi26Id, SInt32 FrameIdInAcq, UInt32* PtDest, SInt8 DestW32Sz );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32* EFRIO__FGetFrameFields ( SInt32 AcqId, SInt8 Mi26Id, SInt32 FrameIdInAcq, UInt32* PtDest, SInt8 DestW32Sz );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConf ( SInt32 BoardId, EFRIO__TBoardConf* PtSrc );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConf ( SInt32 BoardId, EFRIO__TBoardConf* PtDest );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt8 AcqStatus, SInt16 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode );) + +// Board conf fields access functions + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfBoardId ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfAsicName ( SInt32 BoardId, char* AsicName );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfAsicNb ( SInt32 BoardId, SInt32 AsicNb );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfReadoutMode ( SInt32 BoardId, SInt32 ReadoutMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfEmuleChannels ( SInt32 BoardId, SInt8 EmuleChannels );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfDataClkFrequency ( SInt32 BoardId, float DataClkFrequency );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfDmaHostSz ( SInt32 BoardId, UInt32 DmaHostSz );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfFrameNbPerAcq ( SInt32 BoardId, SInt32 FrameNbPerAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfEnableExtraChannel ( SInt32 BoardId, SInt8 EnableExtraChannel );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfAcqNbPerTrig ( SInt32 BoardId, SInt32 AcqNbPerTrig );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTriggerMode ( SInt32 BoardId, SInt8 TriggerMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTriggerDetectTimeWindow ( SInt32 BoardId, UInt32 TriggerDetectTimeWindow );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTriggerDetectOccurNb ( SInt32 BoardId, UInt32 TriggerDetectOccurNb );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTimeStampRes ( SInt32 BoardId, UInt32 TimeStampRes );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfEnableTimeStamping ( SInt32 BoardId, SInt8 EnableTimeStamping );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfEnableTrigCnt ( SInt32 BoardId, SInt8 EnableTrigCnt );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTagEventsStoredByDUT ( SInt32 BoardId, SInt8 TagEventsStoredByDUT );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfReadTluTrigCntEachNTrig ( SInt32 BoardId, UInt32 ReadTluTrigCntEachNTrig );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfBoardId ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FGetBoardConfAsicName ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfAsicNb ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfReadoutMode ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfEmuleChannels ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, float EFRIO__FGetBoardConfDataClkFrequency ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfDmaHostSz ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfFrameNbPerAcq ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfEnableExtraChannel ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfAcqNbPerTrig ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfTriggerMode ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfTriggerDetectTimeWindow ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfTriggerDetectOccurNb ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfTimeStampRes ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfEnableTimeStamping ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfEnableTrigCnt ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfTagEventsStoredByDUT ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfReadTluTrigCntEachNTrig ( SInt32 BoardId );) + +// Board status fields access functions + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusBoardId ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusBoardPresent ( SInt32 BoardId, SInt8 BoardPresent );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusFwLoaded ( SInt32 BoardId, SInt8 FwLoaded );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusConfDone ( SInt32 BoardId, SInt8 ConfDone );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusStatusCode ( SInt32 BoardId, SInt32 StatusCode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusStatusStr ( SInt32 BoardId, char* StatusStr );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusErrorMsgList ( SInt32 BoardId, char* ErrorMsg, SInt32 Index );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusLastErrorMsg ( SInt32 BoardId, char* LastErrorMsg );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardStatusBoardId ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardStatusBoardPresent ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardStatusFwLoaded ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardStatusConfDone ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardStatusStatusCode ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FGetBoardStatusStatusStr ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FGetBoardStatusErrorMsgList ( SInt32 BoardId, SInt32 Index );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FGetBoardStatusLastErrorMsg ( SInt32 BoardId );) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_H + #define EUDET_FRIO_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_array_one.typ b/include/pxi_daq_lib_v.2.1/eudet_frio_array_one.typ new file mode 100755 index 0000000..f59e36c --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_array_one.typ @@ -0,0 +1,792 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.typ +Goal : Types definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_TYP +#define EUDET_FRIO_TYP + + + +/* ============================================== */ +/* Board parameters configuration record */ +/* ---------------------------------------------- */ +/* Can be use to build a boards database */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// Remark for EUDET concerning trigger handling +// +// Most of the following trigger options will be useless for EUDET +// The operating mode for EUDET is : +// - The board takes data all the time regardless of trigger state +// - The fw store all triggers from TLU ( up to 288 / Mimsoa 26 frame ) are stored +// - The sw extract frames with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames after trigger + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + + char AsicName[GLB_CMT_SZ]; // The ASIC read by the board + + SInt32 AsicNb; // The number of ASICs read by the board + + SInt32 ReadoutMode; // The readout mode -> Future use + + SInt8 EmuleChannels; // Copy data of first MAPS in all channels, useful for test & debugging + // because it allows to run with one ASIC only but get data of all + + float DataClkFrequency; // Frequency of clock -> Future use, only useful in case board provide clock + + UInt32 DmaHostSz; // DMA size reserved on host CPU, must be >= size of one acquisition + + SInt32 FrameNbPerAcq; // Consecutives frames number stored during one acquisition + + SInt8 EnableExtraChannel; // Enable one more channel ( default is one channel per ASIC ) + // which can be used to store extra information -> eg : TLU trigger + + SInt32 AcqNbPerTrig; // TO BE CHECKED ! Number of consecutive acquisitions taken upon trigger detection by board + + SInt8 TriggerMode; // Trigger operating mode + + UInt32 TriggerDetectTimeWindow; // Time window during which we count triggers and decide to start acquisition if >= TriggerDetectOccurNb + + UInt32 TriggerDetectOccurNb; // Minimum trigger number during TriggerDetectTimeWindow to decide to start acquisition + + UInt32 TimeStampRes; // Resolution of time stamp + + SInt8 EnableTimeStamping; // Enable time stamping mode + + SInt8 EnableTrigCnt; // Enable trigger counter + + SInt8 TagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ ( HW line indicates that DUT has saved event ) + + UInt32 ReadTluTrigCntEachNTrig; // Period of reading TLU trigger + + +} EFRIO__TBoardConf; + + +/* ============================================== */ +/* Board status record */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + SInt8 BoardPresent; // Board present => 1, otherwise 0 + SInt8 FwLoaded; // Firmware has been loaded in board + SInt8 ConfDone; // The board has been configured by sw + + SInt32 StatusCode; // Current board status code + + char StatusStr[GLB_CMT_SZ]; // Status message associated to StatusCode + + // List of errors and last error + + char* ErrorMsgList[EFRIO__ERROR_MSG_LIST_MAX_NB]; + char LastErrorMsg[GLB_CMT_SZ]; + + // Registers read from board + + UInt32 RegDmaHostSz; // DMA host size in bytes + SInt32 RegFrameNbPerAcq; // Number of frames / acq + SInt8 RegEnableExtraChannel; // Extral channel state = enabled or not + SInt32 RegAcqNbPerTrig; // Consecutive acquisition nb per trigger + + SInt8 RegTriggerMode; // Trigger mode + UInt32 RegTriggerDetectTimeWindow; // Trigger detection window + UInt32 RegTriggerDetectOccurNb; // Number of triggers required during window to start acquisition + + UInt32 RegTimeStampRes; // Resolution of time stamp -> Check with CS if implemented ! + SInt8 RegEnableTimeStamping; // Enable time stamping mode -> Check with CS if implemented ! + + SInt8 RegEnableTrigCnt; // Enable trigger counter -> Check with CS if implemented ! + + SInt8 RegTagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ -> Check with CS if implemented ! + UInt32 RegReadTluTrigCntEachNTrig; // Period of reading TLU trigger -> Check with CS if implemented ! + + UInt64 RegTimeStamp; // Time stamp value + UInt32 RegTrigCnt; // Flex RIO rigger value + UInt32 RegTluTrigCnt; // TLU trigger value + +} EFRIO__TBoardStatus; + + + + +/* ============================================== */ +/* TLU trigger record */ +/* ---------------------------------------------- */ +/* Contains TLU trigger -> field TrigCnt */ +/* plus additional information */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 TrigCnt : 16; // Trigger counter read from TLU + UInt32 FrameIdInAcq : 11; // Index of frame in current acquisition during which trigger occurs ( 0 - 2407 ) + UInt32 EventTakenByDut : 1; // For future use : Flag at 1 if DUT has taken the event + UInt32 Reserved : 3; + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TTluTrigger; + + +/* ============================================== */ +/* Flex RIO time stamp 1 record */ +/* ---------------------------------------------- */ +/* This is the Flex RIO trigger, called */ +/* "time stamp" to avoid confusion / TLU */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Mi26Line : 10; // Line of Mi26 read during which trigger occurs + UInt32 Mi26Frame : 21; // Frame of Mi26 ( = frame counter field ) read during which trigger occurs + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TFlexRioTimeStamp1; + + +/* ============================================== */ +/* Frame header */ +/* ---------------------------------------------- */ +/* Each frame starts with a header which contains */ +/* - DAQ system info */ +/* - Mimosa 26 relevant fields */ +/* ---------------------------------------------- */ +/* Date : 22/10/2010 */ +/* Rev : 23/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_HEADER +#endif + + // New fields AcqStatus & TrigStatus 23/02/2011 + // + SInt32 AcqStatus; // Status of acquistion board for this acquisition + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + // + SInt32 TrigStatus; // No meaning now = reserved for future use + + UInt16 AcqId; // Index of acquisition containing this frame + UInt16 FrameIdInAcq; // Index of frame IN the CURRENT acquisition + + UInt16 MapsName; // MAPS name as a 16 bits code + UInt16 MapsNb; // Total number of MAPS in data + + UInt32 AMapsHeader[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 AMapsFrameCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 AMapsDataLength[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 AMapsTrailer[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + SInt16 TriggerNb; // Total triggers number during this frame + + UInt16 AMapsTrigInfo[EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA]; // First 3 "Mi26 trigger info" -> Line of Mi26 read during which trigger occurs + // if more than 3 trigger => look in trigger info block where all trigger are stored + +} EFRIO__TFrameHeader; + + +/* ============================================== */ +/* Frame data */ +/* ---------------------------------------------- */ +/* Each frame has a data part with variable size */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_DATA +#endif + UInt32 TotSz; // Total size of data bloc + UInt32 OneMapsSz; // Size of data of one MAPS + + UInt32 ADataW32[1]; // Beginning of data space + +} EFRIO__TFrameData; + + +/* ============================================== */ +/* Frame triggers list */ +/* ---------------------------------------------- */ +/* Each frame has a triggers list, up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB fields */ +/* which means up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB */ +/* trigger info */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_TRIG +#endif + UInt32 TotSz; // Total size of trigger info bloc + UInt16 TrigNb; // Total trigger nb + UInt16 TrigType; // Type of trigger info stored + + UInt32 ATrig[1]; // Beginning off triggers list + +} EFRIO__TTriggerRec; + + +/* ============================================== */ +/* Frame record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Data handling fields ( size etc ) */ +/* - The frame header */ +/* - The frame data part ( variable length ) */ +/* - Followed by the triggers info part */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new field DaqVersion */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG +#endif + SInt32 DaqVersion; // Version of DAQ - New field 21/02/2011 + SInt32 TotSz; // Total size of this frame + SInt32 TrigRecOffset; // Offset ( in bytes ) from beginning of frame to trigger info part + EFRIO__TFrameHeader Header; // Frame header + EFRIO__TFrameData Data; // Beginning of data part + + // The field EFRIO__TTriggerInfo is not defined here because "Data" has variable length + // the field BegData of Data field is used a pointer to beginning of data part + // The trigger info will be added at the end of this part but position is calculated dynamically + +} EFRIO__TFrame; + + +/* ============================================== */ +/* List of frames currently stored by lib */ +/* ---------------------------------------------- */ +/* This record stores frames list corresponding */ +/* to one acquisition */ +/* */ +/* It can be : */ +/* - frames acquired by DAQ */ +/* - frames loaded from a run file */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : */ +/* : 24/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// More information about frames storage in memory +// +// A buffer IS NOT allocated for EACH frame, a single bloc of memory is allocated for all frames of one acquisition. +// This will avoid copy frame by frame before sending them to Ethernet lib or saving them to disk. A single access +// can be done with a pointer on beginning of buffer and data size. +// +// But to process frames it's handly to have an array of pointers, each array item pointing on next frame, +// this is the goal of this list which provides : +// - The total number of frames in list +// - An array of pointers, eg : AFramePtr[2] points on third frame of acquisition +// - An array with the total size ( in bytes ) of each frame +// +// This list is built on-line while DAQ is running, or off-line via EFRIO__FBuildFrameListFromAcq (...) from +// the data of one acquisition stored in a run file. + +typedef struct { + + // New fields AcqStatus & TrigStatus 24/02/2011 + // + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + +} EFRIO__TFrameList; + + +/* ============================================== */ +/* Run configuration record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Run parameters -> Par... */ +/* - Informations built from Par etc -> Inf... */ +/* - Acquisition results ( ev cnt etc ) -> Res... */ +/* - Pointers to frames buffers */ +/* ---------------------------------------------- */ +/* This record is filled by EFRIO__FConfRun (...) */ +/* call with run parameters from GUI or Ethernet */ +/* ---------------------------------------------- */ +/* This record can be saved to disk as run config */ +/* file, but it can't be ONLY loaded from file ! */ +/* A call to EFRIO__FConfRun (...) must be done */ +/* because it allocates mem and do other tasks */ +/* -> load record from file */ +/* -> call EFRIO__FConfRun with record fields as */ +/* parameters, it will overwrite itself and all */ +/* " other tasks " will also be done */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new fields */ +/* : ParDaqVersion, ParMapsName */ +/* : - Change type of ParMi26Nb to S16 */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + +/* ============================================== */ +/* Acquisition emulation record */ +/* ---------------------------------------------- */ +/* This record contains context of DAQ emulator */ +/* application, it means : */ +/* - Parameters -> Par... */ +/* - Information, calculated from Par -> Inf... */ +/* - Results -> Res... */ +/* ---------------------------------------------- */ +/* All emulation functions are implemented in the */ +/* lib, therefore application task is only GUI. */ +/* That's why emulation context is defined here */ +/* ---------------------------------------------- */ +/* All run param for emulation are taken from */ +/* run config record -> EFRIO__TRunCont */ +/* ---------------------------------------------- */ +/* Date : 30/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqCycleMs; // Delai between two acquisitions + + SInt32 ParEmuleDRamReadMs; // Delai added to PC DRAM access to emulate Flex RIO DRAM access time + + SInt32 ParEmuleFunctNo; // Select emulation function to call -> Future use = not implemented now + + SInt8 ParRandomDataSz; // Enables random generation of data size per Mimosa 26 + // By default data size is fixed in emulation function + // Used to check if variabl length records are properly handled + + SInt8 ParSetMaxDataSzOnOneMaps; // Set maximum possible data sze on first Mi26, overwrite value set by emulation + // function, but next Mi26 keep the data size value from emulation function + // Used to check if DAQ loose frames while Mi26 provides full frames + + + UInt32 ParAHeader[EFRIO__MAX_ASIC_NB]; // Emulated header of each Mi26 + + UInt32 ParATrailer[EFRIO__MAX_ASIC_NB]; // Emulated trailer of each Mi26 + + SInt32 ParTrigNbPerFrame; // Number of trigger per frame, set the part trigger nb (B31B16) of Mi26 Zero1 field + + // In data transfer modes EUDET 2 & 3 a more complex trigger emulation is done + // We don't emulate ParTrigNbPerFrame on each frame but on N consecutives frames + // each M frames + // + SInt32 ParTrigOnOneFrameOverN; // Start emulate ParTrigNbPerFrame on one frame over M = ParTrigOnOneFrameOverN + SInt32 ParTrigOnNConsecutiveFrames; // Emulates on N consecutive frames = ParTrigOnNConsecutiveFrames + + // TLU trigger & Flex RIO trigger emulation + // Up to 288 couples TLU & Flex RIO triggers can be emulated but only EFRIO__MAX_EMUL_GUI_TRIG_NB + // are configurabbles from GUI, now EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + // - First three are configurable from GUI + // - The last one is configurable from GUI + // - Others are configured in emulation function and set to 0 + // + SInt32 ParATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated TLU trigger + SInt32 ParATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated Flex RIO trigger, called "Time stamp 1" + + // DRAM info to emulate Flex RIO readout ( we need a PC RAM bloc of same size as the board one ) + // + SInt32 InfDRamSzMb; // DRAM size in MB + SInt32 InfDRamSz; // DRAM size in bytes + UInt32* InfDRamPtr; // DRAM pointer + + SInt8 InfExtraChan; // Extra channel status ( enabled or not ) depends on data transfer mode ( -> run config ) + + char InfEmuleFuncCmt[GLB_CMT_SZ]; // A comment set by emulation function selected by ParEmuleFunctNo + // -> Future use = not implemented now + + // DAQ emulation results + // + SInt32 ResAcqCnt; // Acquisition counter + SInt32 ResEvCnt; // Events counter + // + SInt32 ResAcqFunctRetCode; // Error code returned by acquisition function + +} EFRIO__TAcqEmul; + + +/* ============================================== */ +/* Frames check record */ +/* ---------------------------------------------- */ +/* This is context of frames check functions */ +/* - EFRIO__MI26_FChkAcqIphcMode (...) */ +/* - EFRIO__MI26_FChkAcqEudetMode (...) */ +/* */ +/* They check frames integrity, can be used in */ +/* normal DAQ mode or emulation */ +/* ---------------------------------------------- */ +/* Date : 31/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqNo; // Acquisition index + + SInt32 ParFrNo; // Frame index + + SInt8 ParChkMode; // Check mode -> Allows to define a level of test + + SInt8 ParChkVerbose; // Verbose mode or not + + SInt8 ParFrPrintLevel; // Define the frame information printed in log file + // 0 -> No print + // 1 -> Print general info ( AcqId, FrameId, TrigNb ... ) + Mi26 header, frame cnt, trailer + // 2 -> Print also triggers list + + SInt8 InfMi26Nb; // Mi26 number runnig in the system + + // Values provided by DAQ to check + // They are compared to the " same fields " of EFRIO_TAcqEmul + // + UInt32 ResAHeader[EFRIO__MAX_ASIC_NB]; // Mi26 header + UInt32 ResATrailer[EFRIO__MAX_ASIC_NB]; // Mi26 trailer + UInt32 ResAFrameCnt[EFRIO__MAX_ASIC_NB]; // Mi26 frames counter + UInt32 ResADataLenght[EFRIO__MAX_ASIC_NB]; // Mi26 data part length ( in W8 not in W16 as in DataLength fields of Mi26 data stream ) + // + SInt32 ResTrigNb; // Trigger info ( couple TLU & Flex RIO trigger ) number UNDER GUI control => limited to EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + SInt32 ResATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // TLU triggers list + SInt32 ResATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Flex RIO trigegrs list + + SInt32 ResErrCnt; // Total errors counter => Information provide by DAQ <> value set in EFRIO_TAcqEmul + + +} EFRIO__TFrCheck; + +/* ============================================== */ +/* Board check record */ +/* ---------------------------------------------- */ +/* This is context of board check Vi */ +/* The board test is done by a Vi on Labview side */ +/* this record pass the parameters to the Vi */ +/* */ +/* Parameters are set via call to functions */ +/* EFRIO__FSetBoardChk... */ +/* */ +/* Parameters are read via call to functions */ +/* EFRIO__FGetBoardChk... */ +/* Theses functions are encapsulated in Vi */ +/* ---------------------------------------------- */ +/* */ +/* The test results are written in board status */ +/* record ABoardsStatus [BoardId] */ +/* */ +/* Test results are set or read functions */ +/* EFRIO__FSetBoardStatus... */ +/* EFRIO__FGetBoardStatus... */ +/* ---------------------------------------------- */ +/* Date : 22/12/2010 */ +/* Doc date : 22/12/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParBoardId; // Board to test + + SInt8 ParDoTheTest; // Set to 1 to request the test + // Reset once test has been started + + SInt32 ParTestId; // Identifier to select different tests + + SInt8 ResTestDone; // Set to 1 when test is finished + + SInt32 ResTestResult; // Test result + // < 0 => Test has failed + // = 0 => Test OK + +} EFRIO__TBoardCheck; + + +/* ============================================== */ +/* Spare W32 bloc of index file */ +/* ---------------------------------------------- */ +/* This record contains spare info for index file */ +/* ---------------------------------------------- */ +/* Date : 24/02/2011 */ +/* Doc date : 24/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + + SInt32 DiskSectorSz; // Size of disk sector + +} EFRIO__TFileSpareW32Info; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains monitoring via Eth conf */ +/* ---------------------------------------------- */ +/* Date : 15/02/2011 */ +/* Doc date : 15/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 InfFrameNbToSend; // Frame nb to send on Eth = " Frame nb per acq * % monitoring " + SInt32 InfSzToSend; // Size corresponding to InfFrameNbToSend + +} EFRIO__TMon; + + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : 07/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef struct { + + SInt8 InfInitDone; // Lib iit done or not + + EFRIO__TBoardConf ABoardsConf[EFRIO__MAX_BOARDS_NB]; // Acquisition boards config + EFRIO__TBoardStatus ABoardsStatus[EFRIO__MAX_BOARDS_NB]; // Acquisition boards status + + EFRIO__TBoardCheck BoardChk; // Reserved for future implementation + // Parameters record to check + // - Boards + // - Mimosa 26 Clk & Sync signals + + EFRIO__TAcqEmul AcqEmul; // DAQ emulation context + EFRIO__TFrCheck FrCheck; // Frames check functions context + + EFRIO__TRunCont RunCont; // Run context = parameters, memory allocated, results + + EFRIO__TMon MonCont; // Monitoring context + + EFRIO__TFrameList AAcqFrameList[1]; // Frame list of acquistion - Can be extended to more than one acq if needed + + // List of frame Id to read ( Eudet3Mode => Trigger + 2 following frames ) / acquistion - Can be extended to more than one acq if needed + + SInt16 AAAcqFrameWithTrigList[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + + EFRIO__TTriggerRec* PtTmpTrigRec; // Temporary triggers record used for internal processing + +} EFRIO__TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_array_zero.typ b/include/pxi_daq_lib_v.2.1/eudet_frio_array_zero.typ new file mode 100755 index 0000000..fa09c63 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_array_zero.typ @@ -0,0 +1,792 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.typ +Goal : Types definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_TYP +#define EUDET_FRIO_TYP + + + +/* ============================================== */ +/* Board parameters configuration record */ +/* ---------------------------------------------- */ +/* Can be use to build a boards database */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// Remark for EUDET concerning trigger handling +// +// Most of the following trigger options will be useless for EUDET +// The operating mode for EUDET is : +// - The board takes data all the time regardless of trigger state +// - The fw store all triggers from TLU ( up to 288 / Mimsoa 26 frame ) are stored +// - The sw extract frames with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames after trigger + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + + char AsicName[GLB_CMT_SZ]; // The ASIC read by the board + + SInt32 AsicNb; // The number of ASICs read by the board + + SInt32 ReadoutMode; // The readout mode -> Future use + + SInt8 EmuleChannels; // Copy data of first MAPS in all channels, useful for test & debugging + // because it allows to run with one ASIC only but get data of all + + float DataClkFrequency; // Frequency of clock -> Future use, only useful in case board provide clock + + UInt32 DmaHostSz; // DMA size reserved on host CPU, must be >= size of one acquisition + + SInt32 FrameNbPerAcq; // Consecutives frames number stored during one acquisition + + SInt8 EnableExtraChannel; // Enable one more channel ( default is one channel per ASIC ) + // which can be used to store extra information -> eg : TLU trigger + + SInt32 AcqNbPerTrig; // TO BE CHECKED ! Number of consecutive acquisitions taken upon trigger detection by board + + SInt8 TriggerMode; // Trigger operating mode + + UInt32 TriggerDetectTimeWindow; // Time window during which we count triggers and decide to start acquisition if >= TriggerDetectOccurNb + + UInt32 TriggerDetectOccurNb; // Minimum trigger number during TriggerDetectTimeWindow to decide to start acquisition + + UInt32 TimeStampRes; // Resolution of time stamp + + SInt8 EnableTimeStamping; // Enable time stamping mode + + SInt8 EnableTrigCnt; // Enable trigger counter + + SInt8 TagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ ( HW line indicates that DUT has saved event ) + + UInt32 ReadTluTrigCntEachNTrig; // Period of reading TLU trigger + + +} EFRIO__TBoardConf; + + +/* ============================================== */ +/* Board status record */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + SInt8 BoardPresent; // Board present => 1, otherwise 0 + SInt8 FwLoaded; // Firmware has been loaded in board + SInt8 ConfDone; // The board has been configured by sw + + SInt32 StatusCode; // Current board status code + + char StatusStr[GLB_CMT_SZ]; // Status message associated to StatusCode + + // List of errors and last error + + char* ErrorMsgList[EFRIO__ERROR_MSG_LIST_MAX_NB]; + char LastErrorMsg[GLB_CMT_SZ]; + + // Registers read from board + + UInt32 RegDmaHostSz; // DMA host size in bytes + SInt32 RegFrameNbPerAcq; // Number of frames / acq + SInt8 RegEnableExtraChannel; // Extral channel state = enabled or not + SInt32 RegAcqNbPerTrig; // Consecutive acquisition nb per trigger + + SInt8 RegTriggerMode; // Trigger mode + UInt32 RegTriggerDetectTimeWindow; // Trigger detection window + UInt32 RegTriggerDetectOccurNb; // Number of triggers required during window to start acquisition + + UInt32 RegTimeStampRes; // Resolution of time stamp -> Check with CS if implemented ! + SInt8 RegEnableTimeStamping; // Enable time stamping mode -> Check with CS if implemented ! + + SInt8 RegEnableTrigCnt; // Enable trigger counter -> Check with CS if implemented ! + + SInt8 RegTagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ -> Check with CS if implemented ! + UInt32 RegReadTluTrigCntEachNTrig; // Period of reading TLU trigger -> Check with CS if implemented ! + + UInt64 RegTimeStamp; // Time stamp value + UInt32 RegTrigCnt; // Flex RIO rigger value + UInt32 RegTluTrigCnt; // TLU trigger value + +} EFRIO__TBoardStatus; + + + + +/* ============================================== */ +/* TLU trigger record */ +/* ---------------------------------------------- */ +/* Contains TLU trigger -> field TrigCnt */ +/* plus additional information */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 TrigCnt : 16; // Trigger counter read from TLU + UInt32 FrameIdInAcq : 11; // Index of frame in current acquisition during which trigger occurs ( 0 - 2407 ) + UInt32 EventTakenByDut : 1; // For future use : Flag at 1 if DUT has taken the event + UInt32 Reserved : 3; + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TTluTrigger; + + +/* ============================================== */ +/* Flex RIO time stamp 1 record */ +/* ---------------------------------------------- */ +/* This is the Flex RIO trigger, called */ +/* "time stamp" to avoid confusion / TLU */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Mi26Line : 10; // Line of Mi26 read during which trigger occurs + UInt32 Mi26Frame : 21; // Frame of Mi26 ( = frame counter field ) read during which trigger occurs + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TFlexRioTimeStamp1; + + +/* ============================================== */ +/* Frame header */ +/* ---------------------------------------------- */ +/* Each frame starts with a header which contains */ +/* - DAQ system info */ +/* - Mimosa 26 relevant fields */ +/* ---------------------------------------------- */ +/* Date : 22/10/2010 */ +/* Rev : 23/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_HEADER +#endif + + // New fields AcqStatus & TrigStatus 23/02/2011 + // + SInt32 AcqStatus; // Status of acquistion board for this acquisition + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + // + SInt32 TrigStatus; // No meaning now = reserved for future use + + UInt16 AcqId; // Index of acquisition containing this frame + UInt16 FrameIdInAcq; // Index of frame IN the CURRENT acquisition + + UInt16 MapsName; // MAPS name as a 16 bits code + UInt16 MapsNb; // Total number of MAPS in data + + UInt32 AMapsHeader[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 AMapsFrameCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 AMapsDataLength[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 AMapsTrailer[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + SInt16 TriggerNb; // Total triggers number during this frame + + UInt16 AMapsTrigInfo[EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA]; // First 3 "Mi26 trigger info" -> Line of Mi26 read during which trigger occurs + // if more than 3 trigger => look in trigger info block where all trigger are stored + +} EFRIO__TFrameHeader; + + +/* ============================================== */ +/* Frame data */ +/* ---------------------------------------------- */ +/* Each frame has a data part with variable size */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_DATA +#endif + UInt32 TotSz; // Total size of data bloc + UInt32 OneMapsSz; // Size of data of one MAPS + + UInt32 ADataW32[0]; // Beginning of data space + +} EFRIO__TFrameData; + + +/* ============================================== */ +/* Frame triggers list */ +/* ---------------------------------------------- */ +/* Each frame has a triggers list, up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB fields */ +/* which means up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB */ +/* trigger info */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_TRIG +#endif + UInt32 TotSz; // Total size of trigger info bloc + UInt16 TrigNb; // Total trigger nb + UInt16 TrigType; // Type of trigger info stored + + UInt32 ATrig[0]; // Beginning off triggers list + +} EFRIO__TTriggerRec; + + +/* ============================================== */ +/* Frame record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Data handling fields ( size etc ) */ +/* - The frame header */ +/* - The frame data part ( variable length ) */ +/* - Followed by the triggers info part */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new field DaqVersion */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG +#endif + SInt32 DaqVersion; // Version of DAQ - New field 21/02/2011 + SInt32 TotSz; // Total size of this frame + SInt32 TrigRecOffset; // Offset ( in bytes ) from beginning of frame to trigger info part + EFRIO__TFrameHeader Header; // Frame header + EFRIO__TFrameData Data; // Beginning of data part + + // The field EFRIO__TTriggerInfo is not defined here because "Data" has variable length + // the field BegData of Data field is used a pointer to beginning of data part + // The trigger info will be added at the end of this part but position is calculated dynamically + +} EFRIO__TFrame; + + +/* ============================================== */ +/* List of frames currently stored by lib */ +/* ---------------------------------------------- */ +/* This record stores frames list corresponding */ +/* to one acquisition */ +/* */ +/* It can be : */ +/* - frames acquired by DAQ */ +/* - frames loaded from a run file */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : */ +/* : 24/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// More information about frames storage in memory +// +// A buffer IS NOT allocated for EACH frame, a single bloc of memory is allocated for all frames of one acquisition. +// This will avoid copy frame by frame before sending them to Ethernet lib or saving them to disk. A single access +// can be done with a pointer on beginning of buffer and data size. +// +// But to process frames it's handly to have an array of pointers, each array item pointing on next frame, +// this is the goal of this list which provides : +// - The total number of frames in list +// - An array of pointers, eg : AFramePtr[2] points on third frame of acquisition +// - An array with the total size ( in bytes ) of each frame +// +// This list is built on-line while DAQ is running, or off-line via EFRIO__FBuildFrameListFromAcq (...) from +// the data of one acquisition stored in a run file. + +typedef struct { + + // New fields AcqStatus & TrigStatus 24/02/2011 + // + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + +} EFRIO__TFrameList; + + +/* ============================================== */ +/* Run configuration record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Run parameters -> Par... */ +/* - Informations built from Par etc -> Inf... */ +/* - Acquisition results ( ev cnt etc ) -> Res... */ +/* - Pointers to frames buffers */ +/* ---------------------------------------------- */ +/* This record is filled by EFRIO__FConfRun (...) */ +/* call with run parameters from GUI or Ethernet */ +/* ---------------------------------------------- */ +/* This record can be saved to disk as run config */ +/* file, but it can't be ONLY loaded from file ! */ +/* A call to EFRIO__FConfRun (...) must be done */ +/* because it allocates mem and do other tasks */ +/* -> load record from file */ +/* -> call EFRIO__FConfRun with record fields as */ +/* parameters, it will overwrite itself and all */ +/* " other tasks " will also be done */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new fields */ +/* : ParDaqVersion, ParMapsName */ +/* : - Change type of ParMi26Nb to S16 */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + +/* ============================================== */ +/* Acquisition emulation record */ +/* ---------------------------------------------- */ +/* This record contains context of DAQ emulator */ +/* application, it means : */ +/* - Parameters -> Par... */ +/* - Information, calculated from Par -> Inf... */ +/* - Results -> Res... */ +/* ---------------------------------------------- */ +/* All emulation functions are implemented in the */ +/* lib, therefore application task is only GUI. */ +/* That's why emulation context is defined here */ +/* ---------------------------------------------- */ +/* All run param for emulation are taken from */ +/* run config record -> EFRIO__TRunCont */ +/* ---------------------------------------------- */ +/* Date : 30/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqCycleMs; // Delai between two acquisitions + + SInt32 ParEmuleDRamReadMs; // Delai added to PC DRAM access to emulate Flex RIO DRAM access time + + SInt32 ParEmuleFunctNo; // Select emulation function to call -> Future use = not implemented now + + SInt8 ParRandomDataSz; // Enables random generation of data size per Mimosa 26 + // By default data size is fixed in emulation function + // Used to check if variabl length records are properly handled + + SInt8 ParSetMaxDataSzOnOneMaps; // Set maximum possible data sze on first Mi26, overwrite value set by emulation + // function, but next Mi26 keep the data size value from emulation function + // Used to check if DAQ loose frames while Mi26 provides full frames + + + UInt32 ParAHeader[EFRIO__MAX_ASIC_NB]; // Emulated header of each Mi26 + + UInt32 ParATrailer[EFRIO__MAX_ASIC_NB]; // Emulated trailer of each Mi26 + + SInt32 ParTrigNbPerFrame; // Number of trigger per frame, set the part trigger nb (B31B16) of Mi26 Zero1 field + + // In data transfer modes EUDET 2 & 3 a more complex trigger emulation is done + // We don't emulate ParTrigNbPerFrame on each frame but on N consecutives frames + // each M frames + // + SInt32 ParTrigOnOneFrameOverN; // Start emulate ParTrigNbPerFrame on one frame over M = ParTrigOnOneFrameOverN + SInt32 ParTrigOnNConsecutiveFrames; // Emulates on N consecutive frames = ParTrigOnNConsecutiveFrames + + // TLU trigger & Flex RIO trigger emulation + // Up to 288 couples TLU & Flex RIO triggers can be emulated but only EFRIO__MAX_EMUL_GUI_TRIG_NB + // are configurabbles from GUI, now EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + // - First three are configurable from GUI + // - The last one is configurable from GUI + // - Others are configured in emulation function and set to 0 + // + SInt32 ParATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated TLU trigger + SInt32 ParATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated Flex RIO trigger, called "Time stamp 1" + + // DRAM info to emulate Flex RIO readout ( we need a PC RAM bloc of same size as the board one ) + // + SInt32 InfDRamSzMb; // DRAM size in MB + SInt32 InfDRamSz; // DRAM size in bytes + UInt32* InfDRamPtr; // DRAM pointer + + SInt8 InfExtraChan; // Extra channel status ( enabled or not ) depends on data transfer mode ( -> run config ) + + char InfEmuleFuncCmt[GLB_CMT_SZ]; // A comment set by emulation function selected by ParEmuleFunctNo + // -> Future use = not implemented now + + // DAQ emulation results + // + SInt32 ResAcqCnt; // Acquisition counter + SInt32 ResEvCnt; // Events counter + // + SInt32 ResAcqFunctRetCode; // Error code returned by acquisition function + +} EFRIO__TAcqEmul; + + +/* ============================================== */ +/* Frames check record */ +/* ---------------------------------------------- */ +/* This is context of frames check functions */ +/* - EFRIO__MI26_FChkAcqIphcMode (...) */ +/* - EFRIO__MI26_FChkAcqEudetMode (...) */ +/* */ +/* They check frames integrity, can be used in */ +/* normal DAQ mode or emulation */ +/* ---------------------------------------------- */ +/* Date : 31/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqNo; // Acquisition index + + SInt32 ParFrNo; // Frame index + + SInt8 ParChkMode; // Check mode -> Allows to define a level of test + + SInt8 ParChkVerbose; // Verbose mode or not + + SInt8 ParFrPrintLevel; // Define the frame information printed in log file + // 0 -> No print + // 1 -> Print general info ( AcqId, FrameId, TrigNb ... ) + Mi26 header, frame cnt, trailer + // 2 -> Print also triggers list + + SInt8 InfMi26Nb; // Mi26 number runnig in the system + + // Values provided by DAQ to check + // They are compared to the " same fields " of EFRIO_TAcqEmul + // + UInt32 ResAHeader[EFRIO__MAX_ASIC_NB]; // Mi26 header + UInt32 ResATrailer[EFRIO__MAX_ASIC_NB]; // Mi26 trailer + UInt32 ResAFrameCnt[EFRIO__MAX_ASIC_NB]; // Mi26 frames counter + UInt32 ResADataLenght[EFRIO__MAX_ASIC_NB]; // Mi26 data part length ( in W8 not in W16 as in DataLength fields of Mi26 data stream ) + // + SInt32 ResTrigNb; // Trigger info ( couple TLU & Flex RIO trigger ) number UNDER GUI control => limited to EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + SInt32 ResATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // TLU triggers list + SInt32 ResATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Flex RIO trigegrs list + + SInt32 ResErrCnt; // Total errors counter => Information provide by DAQ <> value set in EFRIO_TAcqEmul + + +} EFRIO__TFrCheck; + +/* ============================================== */ +/* Board check record */ +/* ---------------------------------------------- */ +/* This is context of board check Vi */ +/* The board test is done by a Vi on Labview side */ +/* this record pass the parameters to the Vi */ +/* */ +/* Parameters are set via call to functions */ +/* EFRIO__FSetBoardChk... */ +/* */ +/* Parameters are read via call to functions */ +/* EFRIO__FGetBoardChk... */ +/* Theses functions are encapsulated in Vi */ +/* ---------------------------------------------- */ +/* */ +/* The test results are written in board status */ +/* record ABoardsStatus [BoardId] */ +/* */ +/* Test results are set or read functions */ +/* EFRIO__FSetBoardStatus... */ +/* EFRIO__FGetBoardStatus... */ +/* ---------------------------------------------- */ +/* Date : 22/12/2010 */ +/* Doc date : 22/12/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParBoardId; // Board to test + + SInt8 ParDoTheTest; // Set to 1 to request the test + // Reset once test has been started + + SInt32 ParTestId; // Identifier to select different tests + + SInt8 ResTestDone; // Set to 1 when test is finished + + SInt32 ResTestResult; // Test result + // < 0 => Test has failed + // = 0 => Test OK + +} EFRIO__TBoardCheck; + + +/* ============================================== */ +/* Spare W32 bloc of index file */ +/* ---------------------------------------------- */ +/* This record contains spare info for index file */ +/* ---------------------------------------------- */ +/* Date : 24/02/2011 */ +/* Doc date : 24/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + + SInt32 DiskSectorSz; // Size of disk sector + +} EFRIO__TFileSpareW32Info; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains monitoring via Eth conf */ +/* ---------------------------------------------- */ +/* Date : 15/02/2011 */ +/* Doc date : 15/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 InfFrameNbToSend; // Frame nb to send on Eth = " Frame nb per acq * % monitoring " + SInt32 InfSzToSend; // Size corresponding to InfFrameNbToSend + +} EFRIO__TMon; + + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : 07/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef struct { + + SInt8 InfInitDone; // Lib iit done or not + + EFRIO__TBoardConf ABoardsConf[EFRIO__MAX_BOARDS_NB]; // Acquisition boards config + EFRIO__TBoardStatus ABoardsStatus[EFRIO__MAX_BOARDS_NB]; // Acquisition boards status + + EFRIO__TBoardCheck BoardChk; // Reserved for future implementation + // Parameters record to check + // - Boards + // - Mimosa 26 Clk & Sync signals + + EFRIO__TAcqEmul AcqEmul; // DAQ emulation context + EFRIO__TFrCheck FrCheck; // Frames check functions context + + EFRIO__TRunCont RunCont; // Run context = parameters, memory allocated, results + + EFRIO__TMon MonCont; // Monitoring context + + EFRIO__TFrameList AAcqFrameList[1]; // Frame list of acquistion - Can be extended to more than one acq if needed + + // List of frame Id to read ( Eudet3Mode => Trigger + 2 following frames ) / acquistion - Can be extended to more than one acq if needed + + SInt16 AAAcqFrameWithTrigList[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + + EFRIO__TTriggerRec* PtTmpTrigRec; // Temporary triggers record used for internal processing + +} EFRIO__TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_dbg.c b/include/pxi_daq_lib_v.2.1/eudet_frio_dbg.c new file mode 100755 index 0000000..cd8101a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_dbg.c @@ -0,0 +1,449 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_DBG_C +#define EUDET_FRIO_DBG_C + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 20/10/2010 +Doc date : 20/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Cmd = 0 => do nothing +// Cmd = 1 => alloc mem +// Cmd = 2 => free mem + +// Cmd = 3 => Copy with memcpy +// Cmd = 4 => Copy with W8 loop Vi ++ +// Cmd = 5 => Copy with W8 loop Vi -- +// Cmd = 6 => Copy with W32 loop Vi ++ +// Cmd = 7 => Copy with W32 loop Vi -- +// Cmd = 8 => Copy with memmove +// ..... +// Cmd = 12 => Copy with W64 loop Vi ++ + +SInt32 EFRIO__FDbgMeasRamCpyTime ( SInt8 Cmd, SInt32 SzMb ) { + + static UInt8* VBuffSrc = NULL; + static UInt8* VBuffDest = NULL; + auto SInt32 _VSzW32; + auto SInt32 _Vi; + register SInt32 r_VSzW32; + register SInt32 r_VSzW64; + register SInt32 r_Vi; + SInt32 VSzW8; + SInt32 VSzW32; + SInt32 VSzW64; + SInt32 Vi; + UInt8* VCpyBuffSrc; + UInt8* VCpyBuffDest; + UInt64* VCpyBuffSrcW64; + UInt64* VCpyBuffDestW64; + + + if ( (Cmd < 0) || (Cmd > 7) ) { + err_retfail ( Cmd, (ERR_OUT,"Bad Cmd=%d Our of range 0..7", Cmd) ); + } + + VSzW8 = SzMb * 1024 * 1024; + VSzW32 = VSzW8 / 4; + _VSzW32 = VSzW8 / 4; + r_VSzW32 = VSzW8 / 4; + VSzW64 = VSzW8 / 8; + r_VSzW64 = VSzW8 / 8; + + + while (1) { + + // Allocation mem + + if ( Cmd == 1 ) { + + err_error (( ERR_OUT, "TRACE => Cmd=1 Alloc mem" )); + + // Source + + if ( VBuffSrc != NULL ) { + free ( VBuffSrc ); + } + + VBuffSrc = (UInt8*) malloc ( VSzW8 ); + + err_retnull ( VBuffSrc, (ERR_OUT,"Allocation of src buffer %d bytes failed !", VSzW8 ) ); + + // Dest + + if ( VBuffDest != NULL ) { + free ( VBuffDest ); + } + + VBuffDest = (UInt8*) malloc ( VSzW8 ); + + err_retnull ( VBuffDest, (ERR_OUT,"Allocation of dest buffer %d bytes failed !", VSzW8 ) ); + + break; + } + + // Free mem + + if ( Cmd == 2 ) { + + err_error (( ERR_OUT, "TRACE => Cmd=2 => Free mem" )); + + if ( VBuffSrc != NULL ) { + free ( VBuffSrc ); + VBuffSrc = NULL; + } + + if ( VBuffDest != NULL ) { + free ( VBuffDest ); + VBuffDest = NULL; + } + + break; + } + + // Copy with memcpy + + if ( Cmd == 3 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + memcpy ( VBuffDest, VBuffSrc, VSzW8 ); + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W8 loop Vi ++ + + if ( Cmd == 4 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( Vi=0; Vi < VSzW8; Vi++ ) { + VBuffDest[Vi] = VBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W8 loop Vi -- + + if ( Cmd == 5 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( Vi=VSzW8; Vi >= 0; Vi-- ) { + VBuffDest[Vi] = VBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W32 loop Vi ++ + + if ( Cmd == 6 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( Vi=0; Vi < VSzW32; Vi++ ) { + VBuffDest[Vi] = VBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W32 loop Vi -- + + if ( Cmd == 7 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( Vi=VSzW32; Vi >= 0; Vi-- ) { + VBuffDest[Vi] = VBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with memmove + + if ( Cmd == 8 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + memmove ( VBuffDest, VBuffSrc, VSzW8 ); + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + + // Copy with W32 loop Vi ++ with auto var + + if ( Cmd == 9 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( _Vi=0; _Vi < _VSzW32; _Vi++ ) { + VBuffDest[_Vi] = VBuffSrc[_Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W32 loop Vi ++ with local ptr + + if ( Cmd == 10 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + VCpyBuffSrc = VBuffSrc; + VCpyBuffDest = VBuffDest; + + for ( Vi=0; Vi < VSzW32; Vi++ ) { + VCpyBuffDest[Vi] = VCpyBuffSrc[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + // Copy with W32 loop Vi ++ with register var + + if ( Cmd == 11 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + for ( r_Vi=0; r_Vi < r_VSzW32; r_Vi++ ) { + VBuffDest[r_Vi] = VBuffSrc[r_Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + + // Copy with W64 loop Vi ++ with local ptr + + if ( Cmd == 12 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + VCpyBuffSrcW64 = (UInt64*) VBuffSrc; + VCpyBuffDestW64 = (UInt64*) VBuffDest; + + for ( Vi=0; Vi < VSzW64; Vi++ ) { + VCpyBuffDestW64[Vi] = VCpyBuffSrcW64[Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + + // Copy with W64 loop Vi ++ register var - with local ptr + + if ( Cmd == 13 ) { + + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); + + VCpyBuffSrcW64 = (UInt64*) VBuffSrc; + VCpyBuffDestW64 = (UInt64*) VBuffDest; + + for ( r_Vi=0; r_Vi < r_VSzW64; r_Vi++ ) { + VCpyBuffDestW64[r_Vi] = VCpyBuffSrcW64[r_Vi]; + } + + PPO_FOutD7 ( 0 /* Id */, 0 /* State */ ); + + break; + } + + + // End while (1) + } + + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/10/2010 +Doc date : 22/10/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +// Cmd = 0 -> Reset frame counter & flags ( don't care about trigger param ) +// Cmd = 1 -> Insert text line separator "=============" ( do nothing else ) +// Cmd = 2 -> Emule frame + +SInt32 EFRIO__FDbgCheckTrigAlgo ( SInt8 Cmd, SInt8 TriggerNb, SInt8 AddFrameBefore, SInt8 AddFrameAfter ) { + + static SInt32 VFrameCnt = 0; + static SInt8 VAddFrameNp1 = 0; + static SInt8 VAddFrameNm1Done = 0; + SInt32 VRetCurFrameId; + + while (1) { + + if ( Cmd == 0 ) { + VFrameCnt = 0; + VAddFrameNp1 = 0; + VAddFrameNm1Done = 0; + VRetCurFrameId = -1; + msg (( MSG_OUT, "Cmd = 0 -> Reset frame cnt done" )); + break; + } + + + if ( Cmd == 1 ) { + VRetCurFrameId = -1; + msg (( MSG_OUT, "*******************************************************" )); + break; + } + + + if ( Cmd == 2 ) { + + VRetCurFrameId = VFrameCnt; + + msg (( MSG_OUT, "-------------------------------------------------------" )); + msg (( MSG_OUT, "Emule frame %d - %d triggers - Add F before = %d - Add F after = %d", VFrameCnt, TriggerNb, AddFrameBefore, AddFrameAfter )); + msg (( MSG_OUT, "-------------------------------------------------------" )); + + + if ( TriggerNb > 0 ) { + + if ( AddFrameAfter == 1 ) { + VAddFrameNp1 = 1; + } + + + // Must add Fn-1 + + if ( (VAddFrameNm1Done == 0) && (AddFrameBefore == 1) ) { + msg (( MSG_OUT, "Add Fn-1 = %d", VFrameCnt-1 )); + } + + msg (( MSG_OUT, "Add Fn = %d", VFrameCnt )); + VAddFrameNm1Done = 1; + + } // End if ( TriggerNb > 0 ) + + + // TriggerNb == 0 + + else { + + // Must add Fn+1 + + if ( VAddFrameNp1 == 1 ) { + VAddFrameNp1 = 0; + + msg (( MSG_OUT, "Add Fn = %d", VFrameCnt )); + VAddFrameNm1Done = 1; + } + + // Don't add Fn+1 + + else { + VAddFrameNm1Done = 0; + } + + } // End TriggerNb == 0 + + + break; // End frame emulation + } + + + + msg (( MSG_OUT, "Unknown command = %d", Cmd )); + break; + } + + ++VFrameCnt; + + return (VRetCurFrameId); +} + + + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_dbg.h b/include/pxi_daq_lib_v.2.1/eudet_frio_dbg.h new file mode 100755 index 0000000..9b58420 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_dbg.h @@ -0,0 +1,42 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.h +Goal : Functions prototypes of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_DBG_H + +#include "func_header.def" + + + +// 06/11/2010 -> 2 + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FDbgMeasRamCpyTime ( SInt8 Cmd, SInt32 SzMb );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FDbgCheckTrigAlgo ( SInt8 Cmd, SInt8 TriggerNb, SInt8 AddFrameBefore, SInt8 AddFrameAfter );) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_DBG_H + #define EUDET_FRIO_DBG_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_emul.c b/include/pxi_daq_lib_v.2.1/eudet_frio_emul.c new file mode 100755 index 0000000..bcbac18 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_emul.c @@ -0,0 +1,4543 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_EMUL_C +#define EUDET_FRIO_EMUL_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( + : UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb ) + : +Goal : Emulate one acquisition for one Mi26 in data transfer mode IPHC or EUDET 1 + : + : In this case there is no extra channel for TLU triggers. + : + : Triggers are stored in Zero fields of Mi26 frame, they represent line of Mi26 + : read while trigger occurs in 80 MHz clock unit -> divide by 16 to get line. + : Maximum number of triggers is 3. + : + : The number of triggers is hard coded to 3, their values are + : Trig[0] = 16 => line 1 + : Trig[1] = 32 => line 2 + : Trig[2] = 64 => line 4 + : + : +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite + : EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) + : + : PtFirstFrameFC - Pointer to a variable which contains a global frame counter + : Used to set frame counter of each frame of current acq + : Incremented by the number of frames of current acq at end of function + : + : FrameNb - The number of frame to emulate + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : + : +Level : This is a user level function. +Date : 02/02/2010 +Rev : 10/03/2010 + : - Add parameter PtFirstFrameFC + : 26/10/2010 + : - Moved from daq_pxi lib +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + SInt32 VEmulDataSzW16; + + + + err_trace (( ERR_OUT, "DPXI__MI26_FFRioEmulDeserData1Mi26 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + + VPtZsFFrameRaw->Zero = 0x00030010; + VPtZsFFrameRaw->Zero2 = 0x00200040; + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + } + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw->FrameCnt; + + err_trace (( ERR_OUT, "End emul data loop" )); + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( + : UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb ) + : +Goal : Emulate one acquisition for six Mi26 in data transfer mode IPHC or EUDET 1 + : + : In this case there is no extra channel for TLU triggers. + : + : Triggers are stored in Zero fields of Mi26 frame, they represent line of Mi26 + : read while trigger occurs in 80 MHz clock unit -> divide by 16 to get line. + : Maximum number of triggers is 3. + : + : The number of triggers is hard coded to 3, their values are + : Trig[0] = 16 => line 1 + : Trig[1] = 32 => line 2 + : Trig[2] = 64 => line 4 + : + : +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite + : EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) + : + : PtFirstFrameFC - Pointer to a variable which contains a global frame counter + : Used to set frame counter of each frame of current acq + : Incremented by the number of frames of current acq at end of function + : + : FrameNb - The number of frame to emulate + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : + : +Level : This is a user level function. +Date : 09/03/2010 +Rev : 10/03/2010 + : - Add parameter PtFirstFrameFC + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + SInt32 VAEmulDataSzW16[6]; + + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = 0x00030010; + VPtZsFFrameRaw[0].Zero2 = 0x00200040; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 1 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 2 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 3 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 4 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 6] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 6) + 5 + 18 + (6* MI26__ZS_FFRAME_RAW_MAX_W32) + 12] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw[0].FrameCnt; + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( UInt32* PtDestW32, + : SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) + : +Goal : Emulate one acquisition for one Mi26 in data transfer mode EUDET 2 + : + : In this case there is an extra channel for TLU & Flex RIO trigger triggers. + : + : For each trigger two informations are stored in the following order + : - TLU trigger -> see record EFRIO__TTluTrigger + : - Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + : The EmuleMode parameter sets triggers nb. + : The first three triggers + the last one are configured from GUI. + : Their values are stored in fields ParATrig, ParATS of AcqEmul part + : ( type EFRIO__TAcqEmul ) of lib context record. + : The other triggers are hard coded to 0. + : + : In this case the three triggers stored in MI26 Zero fields are set to 0. + : But he high 16 bits ( B31B16 ) of field Zero1 is still used to store the + : number of triggers. + : + : +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite + : EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) + : + : PtFirstFrameFC - Pointer to a variable which contains a global frame counter + : Used to set frame counter of each frame of current acq + : Incremented by the number of frames of current acq at end of function + : + : FrameNb - The number of frame to emulate + : + : EmuleMode >= 0 -> No trigger emulation + : < 0 -> Emulates | EmuleMode | on each frame + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Level : This is a user level function. +Date : 28/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 ViTrigToEmulate; + SInt32 VEmulDataSzW16; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ / 2 ); // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) / 2 ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw->Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + VPtZsFFrameRaw->Zero2 = 0; + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + ViDestW32 = 0; + + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw->FrameCnt; + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + // Free trigger record + + free ( VPtTrigRec ); + + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( UInt32* PtDestW32, + : SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) + : +Goal : Emulate one acquisition for one Mi26 in data transfer mode EUDET 2 + : + : In this case there is an extra channel for TLU & Flex RIO trigger triggers. + : + : For each trigger two informations are stored in the following order + : - TLU trigger -> see record EFRIO__TTluTrigger + : - Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + : The EmuleMode parameter sets triggers nb. + : The first three triggers + the last one are configured from GUI. + : Their values are stored in fields ParATrig, ParATS of AcqEmul part + : ( type EFRIO__TAcqEmul ) of lib context record. + : The other triggers are hard coded to 0. + : + : In this case the three triggers stored in MI26 Zero fields are set to 0. + : But he high 16 bits ( B31B16 ) of field Zero1 is still used to store the + : number of triggers. + : + : +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite + : EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) + : + : PtFirstFrameFC - Pointer to a variable which contains a global frame counter + : Used to set frame counter of each frame of current acq + : Incremented by the number of frames of current acq at end of function + : + : FrameNb - The number of frame to emulate + : + : EmuleMode >= 0 -> No trigger emulation + : < 0 -> Emulates | EmuleMode | on each frame + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Level : This is a user level function. +Date : 29/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[6]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + MI26__TStatesLine VStateLine; + MI26__TState VState; + SInt16 ViMi26Line; + SInt16 ViDataW16; + + + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 (EltNb=%d, FrameNb=%d, ... )", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + // 21/02/2011 + // Emulate data + // Set hits on column No corresponding to Mi26 index from lines 0 to 569 + // - Column 0 for Mimosa 26 No 0 + // - etc ... + // - Column 5 for Mimosa 26 No 5 + + + ViDataW16 = 0; + + for ( ViMi26Line=0; ViMi26Line < 570; ViMi26Line++ ) { + + VStateLine.F.StateNb = 1; + VStateLine.F.LineAddr = ViMi26Line; + VStateLine.F.Ovf = 0; + + // Write StateLine info to all Mi 26 + + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VStateLine.W16; + + ++ViDataW16; + + VState.F.HitNb = 0; // 0 => 1 hit !!! + VState.F.NotUsed = 0; + + // Write State info to all Mi 26 BUT set ColAddr = Mi26 No + 1 + + VState.F.ColAddr = 0; + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 1; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 2; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 3; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 4; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 5; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VState.W16; + + ++ViDataW16; + + } + + + + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw[0].FrameCnt; + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( UInt32* PtDestW32, + : SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) + : +Goal : Emulate one acquisition for one Mi26 in data transfer mode EUDET 2 + : + : In this case there is an extra channel for TLU & Flex RIO trigger triggers. + : + : For each trigger two informations are stored in the following order + : - TLU trigger -> see record EFRIO__TTluTrigger + : - Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + : The EmuleMode parameter sets triggers nb. + : The first three triggers + the last one are configured from GUI. + : Their values are stored in fields ParATrig, ParATS of AcqEmul part + : ( type EFRIO__TAcqEmul ) of lib context record. + : The other triggers are hard coded to 0. + : + : In this case the three triggers stored in MI26 Zero fields are set to 0. + : But he high 16 bits ( B31B16 ) of field Zero1 is still used to store the + : number of triggers. + : + : +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite + : EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) + : + : PtFirstFrameFC - Pointer to a variable which contains a global frame counter + : Used to set frame counter of each frame of current acq + : Incremented by the number of frames of current acq at end of function + : + : FrameNb - The number of frame to emulate + : + : EmuleMode >= 0 -> No trigger emulation + : < 0 -> Emulates | EmuleMode | on each frame + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 version of 29/10/2010 ) +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + UInt32* VPtDataW32Chip6; + UInt32* VPtDataW32Chip7; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[8]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + MI26__TStatesLine VStateLine; + MI26__TState VState; + SInt16 ViMi26Line; + SInt16 ViDataW16; + + + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 (EltNb=%d, FrameNb=%d, ... )", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 8 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 8 * sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + VPtZsFFrameRaw[6].Header = VPtAcqEmul->ParAHeader[6]; + VPtZsFFrameRaw[6].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[6].DataLength = 0x00700070; + VPtZsFFrameRaw[6].Trailer = VPtAcqEmul->ParATrailer[6]; + VPtZsFFrameRaw[6].Zero = 0x00000000; + VPtZsFFrameRaw[6].Zero2 = 0x00000000; + + VPtZsFFrameRaw[7].Header = VPtAcqEmul->ParAHeader[7]; + VPtZsFFrameRaw[7].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[7].DataLength = 0x00800080; + VPtZsFFrameRaw[7].Trailer = VPtAcqEmul->ParATrailer[7]; + VPtZsFFrameRaw[7].Zero = 0x00000000; + VPtZsFFrameRaw[7].Zero2 = 0x00000000; + + // 21/02/2011 + // Emulate data + // Set hits on column No corresponding to Mi26 index from lines 0 to 569 + // - Column 0 for Mimosa 26 No 0 + // - etc ... + // - Column 7 for Mimosa 26 No 7 + + + ViDataW16 = 0; + + for ( ViMi26Line=0; ViMi26Line < 570; ViMi26Line++ ) { + + VStateLine.F.StateNb = 1; + VStateLine.F.LineAddr = ViMi26Line; + VStateLine.F.Ovf = 0; + + // Write StateLine info to all Mi 26 + + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[6].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[7].ADataW16[ViDataW16] = VStateLine.W16; + + ++ViDataW16; + + VState.F.HitNb = 0; // 0 => 1 hit !!! + VState.F.NotUsed = 0; + + // Write State info to all Mi 26 BUT set ColAddr = Mi26 No + 1 + + VState.F.ColAddr = 0; + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 1; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 2; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 3; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 4; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 5; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 6; + VPtZsFFrameRaw[6].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 7; + VPtZsFFrameRaw[7].ADataW16[ViDataW16] = VState.W16; + + ++ViDataW16; + + } + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[6].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[7].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[6].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[7].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + VAEmulDataSzW16[6] = random (571); + VAEmulDataSzW16[7] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + VADataLengthField[6] = VAEmulDataSzW16[6] + (VAEmulDataSzW16[6] << 16); + VADataLengthField[7] = VAEmulDataSzW16[7] + (VAEmulDataSzW16[7] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + VADataLengthField[6] = VPtZsFFrameRaw[6].DataLength; + VADataLengthField[7] = VPtZsFFrameRaw[7].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[6]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[7]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW32[6] = VADataLengthW16[6] / 2; + + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + VADataLengthW32[7] = VADataLengthW16[7] / 2; + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + VPtDataW32Chip6 = (UInt32*) VPtZsFFrameRaw[6].ADataW16; + VPtDataW32Chip7 = (UInt32*) VPtZsFFrameRaw[7].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip6[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip7[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 27 + (9 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 1 + 27 + (9 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 1 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 1 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 2 + 27 + (9 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 2 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 2 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 3 + 27 + (9 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 3 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 3 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 4 + 27 + (9 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 4 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 4 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 5 + 27 + (9 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 5 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 5 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 6 + 27 + (9 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[6].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 6 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[6].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 6 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[6].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 7 + 27 + (9 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[7].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 7 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[7].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 7 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[7].Zero2; + ++ViDestW32; + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 8 + 27 + (9 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 8 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 8 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 8 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + ++VPtZsFFrameRaw[6].FrameCnt; + ++VPtZsFFrameRaw[7].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw[0].FrameCnt; + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( UInt32* PtDestW32, + : SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) + : +Goal : Emulate one acquisition for one Mi26 in data transfer mode EUDET 3 + : + : In this case there is an extra channel for TLU & Flex RIO trigger triggers. + : + : For each trigger two informations are stored in the following order + : - TLU trigger -> see record EFRIO__TTluTrigger + : - Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + : The EmuleMode parameter sets triggers nb. + : The first three triggers + the last one are configured from GUI. + : Their values are stored in fields ParATrig, ParATS of AcqEmul part + : ( type EFRIO__TAcqEmul ) of lib context record. + : The other triggers are hard coded to 0. + : + :*************************************************************************** + : For this data transfer mode - EUDET 3 - The triggers are not emulated on + : each frame but on M consecutive frames each N frames. M & N are defined + : from GUI, they are stored in fields ParTrigOnNConsecutiveFrames = M and + : ParTrigOnOneFrameOverN = N of AcqEmul part ( type EFRIO__TAcqEmul ) of lib + : context record. + :*************************************************************************** + : + : In this case the three triggers stored in MI26 Zero fields are set to 0. + : But he high 16 bits ( B31B16 ) of field Zero1 is still used to store the + : number of triggers. + : + : +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite + : EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) + : + : PtFirstFrameFC - Pointer to a variable which contains a global frame counter + : Used to set frame counter of each frame of current acq + : Incremented by the number of frames of current acq at end of function + : + : FrameNb - The number of frame to emulate + : + : EmuleMode >= 0 -> No trigger emulation + : < 0 -> Emulates | EmuleMode | on each frame + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Level : This is a user level function. +Date : 03/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 ViTrigToEmulate; + SInt32 VEmulDataSzW16; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + MI26__TStatesLine VStateLine; + MI26__TState VState; + SInt16 ViMi26Line; + SInt16 ViDataW16; + + + err_trace (( ERR_OUT, "Begin" )); + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 (EltNb=%d, FrameNb=%d) !!!", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32 , (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ / 2 ); // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) / 2 ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Check ParTrigOnOneFrameOverN --> Will create div by 0 error if NULL + + if ( VPtAcqEmul->ParTrigOnOneFrameOverN <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => ParTrigOnOneFrameOverN=%d <= 0 !", VPtAcqEmul->ParTrigOnOneFrameOverN) ); + } + + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + VPtZsFFrameRaw->Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw->FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw->DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw->DataLength = 0x00200020; + } + + VPtZsFFrameRaw->Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw->Zero = 0; // High W16 = trigger nb => Set in frames loop because it depends on frame Id + VPtZsFFrameRaw->Zero2 = 0; + + // 22/12/2010 + // Emulate data + // Set hits on column 1 from lines 0 to 569 + + + ViDataW16 = 0; + + for ( ViMi26Line=0; ViMi26Line < 570; ViMi26Line++ ) { + + VStateLine.F.StateNb = 1; + VStateLine.F.LineAddr = ViMi26Line; + VStateLine.F.Ovf = 0; + + VPtZsFFrameRaw->ADataW16[ViDataW16] = VStateLine.W16; + ++ViDataW16; + + VState.F.HitNb = 0; // 0 => 1 hit !!! + VState.F.ColAddr = 0; + VState.F.NotUsed = 0; + + VPtZsFFrameRaw->ADataW16[ViDataW16] = VState.W16; + ++ViDataW16; + + } + + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + randomize (); + } + + ViDestW32 = 0; + + + // msg (( MSG_OUT, "********************************************" )); + + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + EFRIO__FSetFrameIdInTriggerRec ( ViFrame, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB, VPtTrigRec ); + + // Emulate trigger on one frame over ParTrigOnOneFrameOverN and on ParTrigOnNConsecutiveFrames consecutive frames + + if ( (ViFrame % VPtAcqEmul->ParTrigOnOneFrameOverN) <= (VPtAcqEmul->ParTrigOnNConsecutiveFrames - 1) ) { + VPtZsFFrameRaw->Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + + // msg (( MSG_OUT, "Emul => Trig on frame %.4d", ViFrame )); + } + + // otherwise => no trigger + + else { + VPtZsFFrameRaw->Zero = 0; + } + + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw->FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz == 1 ) { + VEmulDataSzW16 = random (571); + VDataLengthField = VEmulDataSzW16 + (VEmulDataSzW16 << 16); + } + + else { + VDataLengthField = VPtZsFFrameRaw->DataLength; + } + + + PtDestW32[ViDestW32] = VDataLengthField; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + VDataLengthW32 = VDataLengthW16 / 2; + + VPtDataW32 = (UInt32*) VPtZsFFrameRaw->ADataW16; + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))] = VPtZsFFrameRaw->Trailer; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))] = VPtZsFFrameRaw->Zero; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))] = VPtZsFFrameRaw->Zero2; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw->FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw->FrameCnt; + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + // Free trigger record + + free ( VPtTrigRec ); + + err_trace (( ERR_OUT, "End" )); + + err_retok (( ERR_OUT, "ViFrame=%d - ViDestW32=%d", ViFrame, ViDestW32 )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( UInt32* PtDestW32, + : SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) + : +Goal : Emulate one acquisition for one Mi26 in data transfer mode EUDET 3 + : + : In this case there is an extra channel for TLU & Flex RIO trigger triggers. + : + : For each trigger two informations are stored in the following order + : - TLU trigger -> see record EFRIO__TTluTrigger + : - Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + : The EmuleMode parameter sets triggers nb. + : The first three triggers + the last one are configured from GUI. + : Their values are stored in fields ParATrig, ParATS of AcqEmul part + : ( type EFRIO__TAcqEmul ) of lib context record. + : The other triggers are hard coded to 0. + : + :*************************************************************************** + : For this data transfer mode - EUDET 3 - The triggers are not emulated on + : each frame but on M consecutive frames each N frames. M & N are defined + : from GUI, they are stored in fields ParTrigOnNConsecutiveFrames = M and + : ParTrigOnOneFrameOverN = N of AcqEmul part ( type EFRIO__TAcqEmul ) of lib + : context record. + :*************************************************************************** + : + : In this case the three triggers stored in MI26 Zero fields are set to 0. + : But he high 16 bits ( B31B16 ) of field Zero1 is still used to store the + : number of triggers. + : + : +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite + : EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) + : + : PtFirstFrameFC - Pointer to a variable which contains a global frame counter + : Used to set frame counter of each frame of current acq + : Incremented by the number of frames of current acq at end of function + : + : FrameNb - The number of frame to emulate + : + : EmuleMode >= 0 -> No trigger emulation + : < 0 -> Emulates | EmuleMode | on each frame + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Level : This is a user level function. +Date : 03/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[6]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + MI26__TStatesLine VStateLine; + MI26__TState VState; + SInt16 ViMi26Line; + SInt16 ViDataW16; + + + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 (EltNb=%d, FrameNb=%d, ... )", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Check ParTrigOnOneFrameOverN --> Will create div by 0 error if NULL + + if ( VPtAcqEmul->ParTrigOnOneFrameOverN <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => ParTrigOnOneFrameOverN=%d <= 0 !", VPtAcqEmul->ParTrigOnOneFrameOverN) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 6 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = 0; // High W16 = trigger nb => Set in frames loop because it depends on frame Id + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + + // 30/12/2010 + // Emulate data + // Set hits on column No corresponding to Mi26 index from lines 0 to 569 + // - Column 0 for Mimosa 26 No 0 + // - etc ... + // - Column 5 for Mimosa 26 No 5 + + ViDataW16 = 0; + + for ( ViMi26Line=0; ViMi26Line < 570; ViMi26Line++ ) { + + VStateLine.F.StateNb = 1; + VStateLine.F.LineAddr = ViMi26Line; + VStateLine.F.Ovf = 0; + + // Write StateLine info to all Mi 26 + + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VStateLine.W16; + + ++ViDataW16; + + VState.F.HitNb = 0; // 0 => 1 hit !!! + VState.F.NotUsed = 0; + + // Write State info to all Mi 26 BUT set ColAddr = Mi26 No + 1 + + VState.F.ColAddr = 0; + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 1; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 2; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 3; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 4; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 5; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VState.W16; + + ++ViDataW16; + + } + + + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + EFRIO__FSetFrameIdInTriggerRec ( ViFrame, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB, VPtTrigRec ); + + // Emulate trigger on one frame over ParTrigOnOneFrameOverN and on ParTrigOnNConsecutiveFrames consecutive frames + + if ( (ViFrame % VPtAcqEmul->ParTrigOnOneFrameOverN) <= (VPtAcqEmul->ParTrigOnNConsecutiveFrames - 1) ) { + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + } + + // othewise => no trigger + + else { + VPtZsFFrameRaw[0].Zero = 0; + } + + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw[0].FrameCnt; + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( UInt32* PtDestW32, + : SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) + : +Goal : Emulate one acquisition for one Mi26 in data transfer mode EUDET 3 + : + : In this case there is an extra channel for TLU & Flex RIO trigger triggers. + : + : For each trigger two informations are stored in the following order + : - TLU trigger -> see record EFRIO__TTluTrigger + : - Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + : The EmuleMode parameter sets triggers nb. + : The first three triggers + the last one are configured from GUI. + : Their values are stored in fields ParATrig, ParATS of AcqEmul part + : ( type EFRIO__TAcqEmul ) of lib context record. + : The other triggers are hard coded to 0. + : + :*************************************************************************** + : For this data transfer mode - EUDET 3 - The triggers are not emulated on + : each frame but on M consecutive frames each N frames. M & N are defined + : from GUI, they are stored in fields ParTrigOnNConsecutiveFrames = M and + : ParTrigOnOneFrameOverN = N of AcqEmul part ( type EFRIO__TAcqEmul ) of lib + : context record. + :*************************************************************************** + : + : In this case the three triggers stored in MI26 Zero fields are set to 0. + : But he high 16 bits ( B31B16 ) of field Zero1 is still used to store the + : number of triggers. + : + : +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite + : EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) + : + : PtFirstFrameFC - Pointer to a variable which contains a global frame counter + : Used to set frame counter of each frame of current acq + : Incremented by the number of frames of current acq at end of function + : + : FrameNb - The number of frame to emulate + : + : EmuleMode >= 0 -> No trigger emulation + : < 0 -> Emulates | EmuleMode | on each frame + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 of 03/11/2010 version ) +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + MI26__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + UInt32* VPtDataW32Chip6; + UInt32* VPtDataW32Chip7; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[8]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + MI26__TStatesLine VStateLine; + MI26__TState VState; + SInt16 ViMi26Line; + SInt16 ViDataW16; + + + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 (EltNb=%d, FrameNb=%d, ... )", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Check ParTrigOnOneFrameOverN --> Will create div by 0 error if NULL + + if ( VPtAcqEmul->ParTrigOnOneFrameOverN <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => ParTrigOnOneFrameOverN=%d <= 0 !", VPtAcqEmul->ParTrigOnOneFrameOverN) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (MI26__TZsFFrameRaw*) malloc ( 8 * sizeof (MI26__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 8 * sizeof (MI26__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = 0; // High W16 = trigger nb => Set in frames loop because it depends on frame Id + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + VPtZsFFrameRaw[6].Header = VPtAcqEmul->ParAHeader[6]; + VPtZsFFrameRaw[6].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[6].DataLength = 0x00700070; + VPtZsFFrameRaw[6].Trailer = VPtAcqEmul->ParATrailer[6]; + VPtZsFFrameRaw[6].Zero = 0x00000000; + VPtZsFFrameRaw[6].Zero2 = 0x00000000; + + VPtZsFFrameRaw[7].Header = VPtAcqEmul->ParAHeader[7]; + VPtZsFFrameRaw[7].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[7].DataLength = 0x00800080; + VPtZsFFrameRaw[7].Trailer = VPtAcqEmul->ParATrailer[7]; + VPtZsFFrameRaw[7].Zero = 0x00000000; + VPtZsFFrameRaw[7].Zero2 = 0x00000000; + + // 30/12/2010 + // Emulate data + // Set hits on column No corresponding to Mi26 index from lines 0 to 569 + // - Column 0 for Mimosa 26 No 0 + // - etc ... + // - Column 7 for Mimosa 26 No 7 + + ViDataW16 = 0; + + for ( ViMi26Line=0; ViMi26Line < 570; ViMi26Line++ ) { + + VStateLine.F.StateNb = 1; + VStateLine.F.LineAddr = ViMi26Line; + VStateLine.F.Ovf = 0; + + // Write StateLine info to all Mi 26 + + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[6].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[7].ADataW16[ViDataW16] = VStateLine.W16; + + ++ViDataW16; + + VState.F.HitNb = 0; // 0 => 1 hit !!! + VState.F.NotUsed = 0; + + // Write State info to all Mi 26 BUT set ColAddr = Mi26 No + 1 + + VState.F.ColAddr = 0; + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 1; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 2; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 3; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 4; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 5; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 6; + VPtZsFFrameRaw[6].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 7; + VPtZsFFrameRaw[7].ADataW16[ViDataW16] = VState.W16; + + ++ViDataW16; + + } + + + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + EFRIO__FSetFrameIdInTriggerRec ( ViFrame, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB, VPtTrigRec ); + + // Emulate trigger on one frame over ParTrigOnOneFrameOverN and on ParTrigOnNConsecutiveFrames consecutive frames + + if ( (ViFrame % VPtAcqEmul->ParTrigOnOneFrameOverN) <= (VPtAcqEmul->ParTrigOnNConsecutiveFrames - 1) ) { + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + } + + // othewise => no trigger + + else { + VPtZsFFrameRaw[0].Zero = 0; + } + + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[6].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[7].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[6].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[7].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (571); + VAEmulDataSzW16[1] = random (571); + VAEmulDataSzW16[2] = random (571); + VAEmulDataSzW16[3] = random (571); + VAEmulDataSzW16[4] = random (571); + VAEmulDataSzW16[5] = random (571); + VAEmulDataSzW16[6] = random (571); + VAEmulDataSzW16[7] = random (571); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + VADataLengthField[6] = VAEmulDataSzW16[6] + (VAEmulDataSzW16[6] << 16); + VADataLengthField[7] = VAEmulDataSzW16[7] + (VAEmulDataSzW16[7] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + VADataLengthField[6] = VPtZsFFrameRaw[6].DataLength; + VADataLengthField[7] = VPtZsFFrameRaw[7].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[6]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[7]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW32[6] = VADataLengthW16[6] / 2; + + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + VADataLengthW32[7] = VADataLengthW16[7] / 2; + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + VPtDataW32Chip6 = (UInt32*) VPtZsFFrameRaw[6].ADataW16; + VPtDataW32Chip7 = (UInt32*) VPtZsFFrameRaw[7].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < MI26__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip6[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip7[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 27 + (9 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 1 + 27 + (9 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 1 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 1 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 2 + 27 + (9 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 2 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 2 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 3 + 27 + (9 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 3 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 3 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 4 + 27 + (9 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 4 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 4 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 5 + 27 + (9 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 5 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 5 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 6 + 27 + (9 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[6].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 6 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[6].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 6 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[6].Zero2; + ++ViDestW32; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 7 + 27 + (9 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[7].Trailer; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 7 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtZsFFrameRaw[7].Zero; + ++ViDestW32; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 7 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtZsFFrameRaw[7].Zero2; + ++ViDestW32; + + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 8 + 27 + (9 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 8 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 8 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 9) + 8 + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + ++VPtZsFFrameRaw[6].FrameCnt; + ++VPtZsFFrameRaw[7].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw[0].FrameCnt; + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + +// $$$$$$$$$$ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode2 ( UInt32* PtDestW32, +: SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) +: +Goal : Emulate one acquisition for one Mi26 in data transfer mode EUDET 2 +: +: In this case there is an extra channel for TLU & Flex RIO trigger triggers. +: +: For each trigger two informations are stored in the following order +: - TLU trigger -> see record EFRIO__TTluTrigger +: - Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 +: +: The EmuleMode parameter sets triggers nb. +: The first three triggers + the last one are configured from GUI. +: Their values are stored in fields ParATrig, ParATS of AcqEmul part +: ( type EFRIO__TAcqEmul ) of lib context record. +: The other triggers are hard coded to 0. +: +: In this case the three triggers stored in MI26 Zero fields are set to 0. +: But he high 16 bits ( B31B16 ) of field Zero1 is still used to store the +: number of triggers. +: +: +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite +: EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) +: +: PtFirstFrameFC - Pointer to a variable which contains a global frame counter +: Used to set frame counter of each frame of current acq +: Incremented by the number of frames of current acq at end of function +: +: FrameNb - The number of frame to emulate +: +: EmuleMode >= 0 -> No trigger emulation +: < 0 -> Emulates | EmuleMode | on each frame +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Level : This is a user level function. +Date : 20/05/2011 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + ULT1__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[6]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + ULT1__TStatesLine VStateLine; + ULT1__TState VState; + SInt16 ViMi26Line; + SInt16 ViDataW16; + + + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 (EltNb=%d, FrameNb=%d, ... )", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (ULT1__TZsFFrameRaw*) malloc ( 6 * sizeof (ULT1__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (ULT1__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + // 20/05/2011 + // Emulate data + // Set hits on column No corresponding to Ult1 index from lines 0 to 927 + // - Column 0 for Mimosa 26 No 0 + // - etc ... + // - Column 5 for Mimosa 26 No 5 + + + ViDataW16 = 0; + + for ( ViMi26Line=0; ViMi26Line < 928; ViMi26Line++ ) { + + VStateLine.F.StateNb = 1; + VStateLine.F.LineAddr = ViMi26Line; + VStateLine.F.Ovf = 0; + + // Write StateLine info to all Mi 26 + + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VStateLine.W16; + + ++ViDataW16; + + VState.F.HitNb = 0; // 0 => 1 hit !!! + VState.F.NotUsed = 0; + + // Write State info to all Mi 26 BUT set ColAddr = Mi26 No + 1 + + VState.F.ColAddr = 0; + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 1; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 2; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 3; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 4; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 5; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VState.W16; + + ++ViDataW16; + + } + + + + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (1851); + VAEmulDataSzW16[1] = random (1851); + VAEmulDataSzW16[2] = random (1851); + VAEmulDataSzW16[3] = random (1851); + VAEmulDataSzW16[4] = random (1851); + VAEmulDataSzW16[5] = random (1851); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < ULT1__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + // PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw[0].FrameCnt; + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + +// $$$$$$$ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode3 ( UInt32* PtDestW32, +: SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) +: +Goal : Emulate one acquisition for one Mi26 in data transfer mode EUDET 3 +: +: In this case there is an extra channel for TLU & Flex RIO trigger triggers. +: +: For each trigger two informations are stored in the following order +: - TLU trigger -> see record EFRIO__TTluTrigger +: - Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 +: +: The EmuleMode parameter sets triggers nb. +: The first three triggers + the last one are configured from GUI. +: Their values are stored in fields ParATrig, ParATS of AcqEmul part +: ( type EFRIO__TAcqEmul ) of lib context record. +: The other triggers are hard coded to 0. +: +:*************************************************************************** +: For this data transfer mode - EUDET 3 - The triggers are not emulated on +: each frame but on M consecutive frames each N frames. M & N are defined +: from GUI, they are stored in fields ParTrigOnNConsecutiveFrames = M and +: ParTrigOnOneFrameOverN = N of AcqEmul part ( type EFRIO__TAcqEmul ) of lib +: context record. +:*************************************************************************** +: +: In this case the three triggers stored in MI26 Zero fields are set to 0. +: But he high 16 bits ( B31B16 ) of field Zero1 is still used to store the +: number of triggers. +: +: +Inputs : PtDestW32 - Pointer to Flex RIO DRAM to overwrite +: EltNb - Flex RIO DRAM size in W32 unit ( 1 Elt = 1 W32 ) +: +: PtFirstFrameFC - Pointer to a variable which contains a global frame counter +: Used to set frame counter of each frame of current acq +: Incremented by the number of frames of current acq at end of function +: +: FrameNb - The number of frame to emulate +: +: EmuleMode >= 0 -> No trigger emulation +: < 0 -> Emulates | EmuleMode | on each frame +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Level : This is a user level function. +Date : 03/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, UInt32* PtFirstFrameFC, SInt32 FrameNb, SInt16 EmuleMode ) { + + EFRIO__TAcqEmul* VPtAcqEmul = &EFRIO__VGContext.AcqEmul; + ULT1__TZsFFrameRaw* VPtZsFFrameRaw; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + SInt32 ViDestW32; + SInt32 ViDataW32; + UInt32* VPtDataW32Chip0; + UInt32* VPtDataW32Chip1; + UInt32* VPtDataW32Chip2; + UInt32* VPtDataW32Chip3; + UInt32* VPtDataW32Chip4; + UInt32* VPtDataW32Chip5; + EFRIO__TTriggerRec* VPtTrigRec; + SInt32 ViEChanTrigField; + SInt32 VTrigNbToEmulate; + SInt32 VAEmulDataSzW16[6]; + SInt32 ViTrigToEmulate; + EFRIO__TTluTrigger* VPtEmulTrig; + EFRIO__TFlexRioTimeStamp1* VPtEmulTs; + + ULT1__TStatesLine VStateLine; + ULT1__TState VState; + SInt16 ViMi26Line; + SInt16 ViDataW16; + + + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode3 (EltNb=%d, FrameNb=%d, ... )", EltNb, FrameNb )); + + // Pointers parameters check + + err_retnull ( PtDestW32, (ERR_OUT,"PtDestW32 = NULL") ); + err_retnull ( PtFirstFrameFC, (ERR_OUT,"PtFirstFrameFC = NULL") ); + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + + if ( VFrameNbFromBoardDrv != FrameNb ) { + err_retfail ( -1, (ERR_OUT,"Dest buffer too small : %d frames buffer <> %d frames requested", VFrameNbFromBoardDrv, FrameNb ) ); + } + + // Check ParTrigOnOneFrameOverN --> Will create div by 0 error if NULL + + if ( VPtAcqEmul->ParTrigOnOneFrameOverN <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort => ParTrigOnOneFrameOverN=%d <= 0 !", VPtAcqEmul->ParTrigOnOneFrameOverN) ); + } + + // Calculate nb of trigger to emulate + + if ( EmuleMode >= 0 ) { + VTrigNbToEmulate = 0; + } + + else { + VTrigNbToEmulate = abs ( EmuleMode ); + } + + + // Alloc ZsFrameRaw + + VPtZsFFrameRaw = (ULT1__TZsFFrameRaw*) malloc ( 6 * sizeof (ULT1__TZsFFrameRaw) ); + + err_retnull ( VPtZsFFrameRaw, (ERR_OUT,"Alloc ZsFFrameRaw failed !") ); + + // Alloc trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) malloc ( sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + err_retnull ( VPtTrigRec, (ERR_OUT,"Allocate tmp trigger buff failed !" ) ); + + + // Reset ZsFrameRaw + + memset ( VPtZsFFrameRaw, 0, 6 * sizeof (ULT1__TZsFFrameRaw) ); + + // Init ZsFrameRaw + + // RQ : Emulate trigger only on first Mi26 because it is used for trigger extraction + // by readout function, information stored in Mi26 [2..5] are ignored + + VPtZsFFrameRaw[0].Header = VPtAcqEmul->ParAHeader[0]; + VPtZsFFrameRaw[0].FrameCnt = *PtFirstFrameFC; + + if ( VPtAcqEmul->ParSetMaxDataSzOnOneMaps == 1 ) { + VPtZsFFrameRaw[0].DataLength = 0x023A023A; // Max + } + + else { + VPtZsFFrameRaw[0].DataLength = 0x00100010; + } + + VPtZsFFrameRaw[0].Trailer = VPtAcqEmul->ParATrailer[0]; + VPtZsFFrameRaw[0].Zero = 0; // High W16 = trigger nb => Set in frames loop because it depends on frame Id + VPtZsFFrameRaw[0].Zero2 = 0; + + VPtZsFFrameRaw[1].Header = VPtAcqEmul->ParAHeader[1]; + VPtZsFFrameRaw[1].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[1].DataLength = 0x00200020; + VPtZsFFrameRaw[1].Trailer = VPtAcqEmul->ParATrailer[1]; + VPtZsFFrameRaw[1].Zero = 0x00000000; + VPtZsFFrameRaw[1].Zero2 = 0x00000000; + + VPtZsFFrameRaw[2].Header = VPtAcqEmul->ParAHeader[2]; + VPtZsFFrameRaw[2].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[2].DataLength = 0x00300030; + VPtZsFFrameRaw[2].Trailer = VPtAcqEmul->ParATrailer[2]; + VPtZsFFrameRaw[2].Zero = 0x00000000; + VPtZsFFrameRaw[2].Zero2 = 0x00000000; + + VPtZsFFrameRaw[3].Header = VPtAcqEmul->ParAHeader[3]; + VPtZsFFrameRaw[3].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[3].DataLength = 0x00400040; + VPtZsFFrameRaw[3].Trailer = VPtAcqEmul->ParATrailer[3]; + VPtZsFFrameRaw[3].Zero = 0x00000000; + VPtZsFFrameRaw[3].Zero2 = 0x00000000; + + VPtZsFFrameRaw[4].Header = VPtAcqEmul->ParAHeader[4]; + VPtZsFFrameRaw[4].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[4].DataLength = 0x00500050; + VPtZsFFrameRaw[4].Trailer = VPtAcqEmul->ParATrailer[4]; + VPtZsFFrameRaw[4].Zero = 0x00000000; + VPtZsFFrameRaw[4].Zero2 = 0x00000000; + + VPtZsFFrameRaw[5].Header = VPtAcqEmul->ParAHeader[5]; + VPtZsFFrameRaw[5].FrameCnt = *PtFirstFrameFC; + VPtZsFFrameRaw[5].DataLength = 0x00600060; + VPtZsFFrameRaw[5].Trailer = VPtAcqEmul->ParATrailer[5]; + VPtZsFFrameRaw[5].Zero = 0x00000000; + VPtZsFFrameRaw[5].Zero2 = 0x00000000; + + + // 30/12/2010 + // Emulate data + // Set hits on column No corresponding to Ultimate index from lines 0 to 927 + // - Column 0 for Mimosa 26 No 0 + // - etc ... + // - Column 5 for Mimosa 26 No 5 + + ViDataW16 = 0; + + for ( ViMi26Line=0; ViMi26Line < 928; ViMi26Line++ ) { + + VStateLine.F.StateNb = 1; + VStateLine.F.LineAddr = ViMi26Line; + VStateLine.F.Ovf = 0; + + // Write StateLine info to all Mi 26 + + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VStateLine.W16; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VStateLine.W16; + + ++ViDataW16; + + VState.F.HitNb = 0; // 0 => 1 hit !!! + VState.F.NotUsed = 0; + + // Write State info to all Mi 26 BUT set ColAddr = Mi26 No + 1 + + VState.F.ColAddr = 0; + VPtZsFFrameRaw[0].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 1; + VPtZsFFrameRaw[1].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 2; + VPtZsFFrameRaw[2].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 3; + VPtZsFFrameRaw[3].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 4; + VPtZsFFrameRaw[4].ADataW16[ViDataW16] = VState.W16; + VState.F.ColAddr = 5; + VPtZsFFrameRaw[5].ADataW16[ViDataW16] = VState.W16; + + ++ViDataW16; + + } + + // Reset trigger record + + memset ( VPtTrigRec, 0xFF, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Init trigger record + + // VPtTrigRec->Tag -> don't care in this case + // VPtTrigRec->TotSz -> don't care in this case + // VPtTrigRec->TrigNb -> don't care in this case + // VPtTrigRec->TrigType -> don't care in this case + + // Fill all used trigger fields with 0, because : + // - More than 4 triggers be emulated BUT only 4 will be filled with a significant value + // - The first trigger field at -1 will stop trigger extraction by DAQ + // Therefore, triggers not controlled by GUI must be set at something <> -1, for example 0 + + // Limit here nb of trigger to emulate to max nb allowed + + if ( VTrigNbToEmulate > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB ) { + err_warning (( ERR_OUT, "Request %d trigger > Max = %d => Limit to max", VTrigNbToEmulate, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + VTrigNbToEmulate = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB; + } + + for ( ViTrigToEmulate=0; ViTrigToEmulate < (2 * VTrigNbToEmulate); ViTrigToEmulate++) { + VPtTrigRec->ATrig[ViTrigToEmulate] = 0; + } + + // Fill first three trigger info => Trigger + Time stamp + + VPtEmulTrig = (EFRIO__TTluTrigger*) VPtTrigRec->ATrig; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) VPtTrigRec->ATrig; + + VPtEmulTrig[0].F.TrigCnt = VPtAcqEmul->ParATrig[0]; + VPtEmulTs [1].F.Mi26Line = VPtAcqEmul->ParATS[0]; + VPtEmulTrig[2].F.TrigCnt = VPtAcqEmul->ParATrig[1]; + VPtEmulTs [3].F.Mi26Line = VPtAcqEmul->ParATS[1]; + VPtEmulTrig[4].F.TrigCnt = VPtAcqEmul->ParATrig[2]; + VPtEmulTs [5].F.Mi26Line = VPtAcqEmul->ParATS[2]; + + // Set last trigger + + if ( VTrigNbToEmulate >= 1 ) { + VPtEmulTrig = (EFRIO__TTluTrigger*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)]; + VPtEmulTs = (EFRIO__TFlexRioTimeStamp1*) &VPtTrigRec->ATrig[2 * (VTrigNbToEmulate-1)+1]; + + VPtEmulTrig->F.TrigCnt = VPtAcqEmul->ParATrig[3]; + VPtEmulTs->F.Mi26Line = VPtAcqEmul->ParATS[3]; + } + + + // Emul data data + + if ( VPtAcqEmul->ParRandomDataSz ) { + randomize (); + } + + ViDestW32 = 0; + + for ( ViFrame=0; ViFrame < FrameNb; ViFrame++ ) { + + ViEChanTrigField = 0; + + EFRIO__FSetFrameIdInTriggerRec ( ViFrame, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB, VPtTrigRec ); + + // Emulate trigger on one frame over ParTrigOnOneFrameOverN and on ParTrigOnNConsecutiveFrames consecutive frames + + if ( (ViFrame % VPtAcqEmul->ParTrigOnOneFrameOverN) <= (VPtAcqEmul->ParTrigOnNConsecutiveFrames - 1) ) { + VPtZsFFrameRaw[0].Zero = (VTrigNbToEmulate << 16); // High W16 = trigger nb + } + + // othewise => no trigger + + else { + VPtZsFFrameRaw[0].Zero = 0; + } + + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].Header; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + PtDestW32[ViDestW32] = VPtZsFFrameRaw[0].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[1].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[2].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[3].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[4].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtZsFFrameRaw[5].FrameCnt; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + if ( VPtAcqEmul->ParRandomDataSz ) { + VAEmulDataSzW16[0] = random (1851); + VAEmulDataSzW16[1] = random (1851); + VAEmulDataSzW16[2] = random (1851); + VAEmulDataSzW16[3] = random (1851); + VAEmulDataSzW16[4] = random (1851); + VAEmulDataSzW16[5] = random (1851); + + VADataLengthField[0] = VAEmulDataSzW16[0] + (VAEmulDataSzW16[0] << 16); + VADataLengthField[1] = VAEmulDataSzW16[1] + (VAEmulDataSzW16[1] << 16); + VADataLengthField[2] = VAEmulDataSzW16[2] + (VAEmulDataSzW16[2] << 16); + VADataLengthField[3] = VAEmulDataSzW16[3] + (VAEmulDataSzW16[3] << 16); + VADataLengthField[4] = VAEmulDataSzW16[4] + (VAEmulDataSzW16[4] << 16); + VADataLengthField[5] = VAEmulDataSzW16[5] + (VAEmulDataSzW16[5] << 16); + } + + else { + VADataLengthField[0] = VPtZsFFrameRaw[0].DataLength; + VADataLengthField[1] = VPtZsFFrameRaw[1].DataLength; + VADataLengthField[2] = VPtZsFFrameRaw[2].DataLength; + VADataLengthField[3] = VPtZsFFrameRaw[3].DataLength; + VADataLengthField[4] = VPtZsFFrameRaw[4].DataLength; + VADataLengthField[5] = VPtZsFFrameRaw[5].DataLength; + } + + + PtDestW32[ViDestW32] = VADataLengthField[0]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[1]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[2]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[3]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[4]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VADataLengthField[5]; + ++ViDestW32; + + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW32[0] = VADataLengthW16[0] / 2; + + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW32[1] = VADataLengthW16[1] / 2; + + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW32[2] = VADataLengthW16[2] / 2; + + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW32[3] = VADataLengthW16[3] / 2; + + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW32[4] = VADataLengthW16[4] / 2; + + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW32[5] = VADataLengthW16[5] / 2; + + + + VPtDataW32Chip0 = (UInt32*) VPtZsFFrameRaw[0].ADataW16; + VPtDataW32Chip1 = (UInt32*) VPtZsFFrameRaw[1].ADataW16; + VPtDataW32Chip2 = (UInt32*) VPtZsFFrameRaw[2].ADataW16; + VPtDataW32Chip3 = (UInt32*) VPtZsFFrameRaw[3].ADataW16; + VPtDataW32Chip4 = (UInt32*) VPtZsFFrameRaw[4].ADataW16; + VPtDataW32Chip5 = (UInt32*) VPtZsFFrameRaw[5].ADataW16; + + + for ( ViDataW32=0; ViDataW32 < ULT1__ZS_FFRAME_RAW_MAX_W32; ViDataW32++ ) { + PtDestW32[ViDestW32] = VPtDataW32Chip0[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip1[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip2[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip3[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip4[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtDataW32Chip5[ViDataW32]; + ++ViDestW32; + PtDestW32[ViDestW32] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + } + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * VADataLengthW32[0]) ] = VPtZsFFrameRaw[0].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[0].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[0].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * VADataLengthW32[1]) ] = VPtZsFFrameRaw[1].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[1].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 1 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[1].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * VADataLengthW32[2]) ] = VPtZsFFrameRaw[2].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[2].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 2 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[2].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * VADataLengthW32[3]) ] = VPtZsFFrameRaw[3].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[3].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 3 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[3].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * VADataLengthW32[4]) ] = VPtZsFFrameRaw[4].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[4].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 4 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[4].Zero2; + ++ViDestW32; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * VADataLengthW32[5]) ] = VPtZsFFrameRaw[5].Trailer; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtZsFFrameRaw[5].Zero; + ++ViDestW32; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 5 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtZsFFrameRaw[5].Zero2; + ++ViDestW32; + + // PtDestW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * VADataLengthW32[5]) ] = VPtTrigRec->ATrig[ViEChanTrigField];; + + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) ] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + PtDestW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame * 7) + 6 + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14] = VPtTrigRec->ATrig[ViEChanTrigField]; + ++ViDestW32; + ++ViEChanTrigField; + + + // Update ZsFrameRaw fields + + ++VPtZsFFrameRaw[0].FrameCnt; + ++VPtZsFFrameRaw[1].FrameCnt; + ++VPtZsFFrameRaw[2].FrameCnt; + ++VPtZsFFrameRaw[3].FrameCnt; + ++VPtZsFFrameRaw[4].FrameCnt; + ++VPtZsFFrameRaw[5].FrameCnt; + + } // End for ViFrame + + + *PtFirstFrameFC += VPtZsFFrameRaw[0].FrameCnt; + + + // Free ZsFrameRaw + + free ( VPtZsFFrameRaw ); + + err_retok (( ERR_OUT, "MsgOk" )); + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 29/10/2010 +Rev : + +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__MI26_FFRioPrintDataMi26WithEChan ( UInt32* PtSrcW32, SInt32 TotFrameNb, SInt32 FrameNo, SInt32 NbDataW32 ) { + + SInt32 Vi; + SInt32 ViFirstW32; + SInt32 ViFrame; + UInt32 VADlField[6]; + UInt32 VADlW16[6]; + UInt32 VADlW32[6]; + UInt32* Va; + SInt32 VAiTrailer[6]; + SInt32 ViZ1; + SInt32 ViZ2; + + if ( FrameNo >= TotFrameNb ) { + err_retfail ( -1, (ERR_OUT,"FrameNo=%d > Tot frame nb=%d", FrameNo, TotFrameNb ) ); + } + + ViFirstW32 = FrameNo * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * 7; + + + Va = &PtSrcW32[ViFirstW32]; + + VADlField[0] = Va[14]; + VADlField[1] = Va[15]; + VADlField[2] = Va[16]; + VADlField[3] = Va[17]; + VADlField[4] = Va[18]; + VADlField[5] = Va[19]; + + for ( Vi=0; Vi < 6; Vi++ ) { + VADlW16[Vi] = ( (VADlField[Vi] & 0xFFFF0000) >> 16 ) + (VADlField[Vi] & 0x0000FFFF); + VADlW32[Vi] = VADlW16[Vi] / 2; + VAiTrailer[Vi] = 21 + ( VADlW32[Vi] * 7 ) + Vi; + } + + ViZ1 = 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7; // 21 = (H + FC + DL) x 7 chips + ViZ2 = 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14; + + + + msg (( MSG_OUT, "===============================================================================================================================" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ 0], Va[ 1], Va[ 2], Va[ 3], Va[ 4], Va[ 5], Va[ 6] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d (H) - E=%.8d (D)", Va[ 7], Va[ 8], Va[ 9], Va[10], Va[11], Va[12], Va[13] )); + msg (( MSG_OUT, "DL [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[14], Va[15], Va[16], Va[17], Va[18], Va[19], Va[20] )); + + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H)", Va[VAiTrailer[0]], Va[VAiTrailer[1]], Va[VAiTrailer[2]], Va[VAiTrailer[3]], Va[VAiTrailer[4]], Va[VAiTrailer[5]] )); + + + msg (( MSG_OUT, "Z1 [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ViZ1], Va[ViZ1+1], Va[ViZ1+2], Va[ViZ1+3], Va[ViZ1+4], Va[ViZ1+5], Va[ViZ1+6] )); + msg (( MSG_OUT, "Z2 [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x (H) - E=%.8d (D)", Va[ViZ2], Va[ViZ2+1], Va[ViZ2+2], Va[ViZ2+3], Va[ViZ2+4], Va[ViZ2+5], Va[ViZ2+6] )); + + return (0); +} + + + + + + + + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_emul.h b/include/pxi_daq_lib_v.2.1/eudet_frio_emul.h new file mode 100755 index 0000000..7ff570d --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_emul.h @@ -0,0 +1,48 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.h +Goal : Functions prototypes of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_EMUL_H + +#include "func_header.def" + + +// 06/11/2010 -> 7 + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioEmulDeserData6Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioPrintDataMi26WithEChan ( UInt32* PtSrcW32, SInt32 TotFrameNb, SInt32 FrameNo, SInt32 NbDataW32 );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( UInt32* PtDestW32, SInt32 EltNb, SInt32* PtFirstFrameNo, SInt32 FrameNb, SInt16 EmuleMode );) + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_EMUL_H + #define EUDET_FRIO_EMUL_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.c b/include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.c new file mode 100755 index 0000000..89fd1f4 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.c @@ -0,0 +1,2883 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_fsbb0.c +Goal : Fsbb0 functions of flex rio board library for EUDET +Prj date : 01/10/2014 +File date : 01/10/2014 +Doc date : +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_FSBB0_C +#define EUDET_FRIO_FSBB0_C + + +// #define EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + +/* +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 +*/ + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSBB0_FMatDiscriPrintHit ( char* CmtStrTitle, SInt8 CmtSInt8MapsId, FSBB0__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + msg (( MSG_OUT, "***************************************************************************" )); + msg (( MSG_OUT, "* FSBB M [%d] %s : Coordinates pixels with hit *", CmtSInt8MapsId, CmtStrTitle )); + msg (( MSG_OUT, "***************************************************************************" )); + + // Scan matrix => Print coordinates if hit + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtDest->AALineCol[ViLine][ViCol] == 1 ) { + msg (( MSG_OUT, "Hit => Line [%.4d] - Col [%.4d]", ViLine, ViCol )); + } + + } + + } + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : SInt8 SUZE02_FHammingDecoder8_4(UInt8 CodedIn) + +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 10/07/2013 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + + UInt8 EFRIO__FSBB0_FHammingDecoder8_4(UInt8 CodedIn) + { + UInt8 VResult; + + switch (CodedIn){ + case 0:{ + VResult = 0; + break; + } + case 0x87:{ + VResult = 1; + break; + } + case 0x99:{ + VResult = 2; + break; + } + case 0x1e:{ + VResult = 3; + break; + } + case 0xaa:{ + VResult = 4; + break; + } + case 0x2d:{ + VResult = 5; + break; + } + case 0x33:{ + VResult = 6; + break; + } + case 0xb4:{ + VResult = 7; + break; + } + case 0x4b:{ + VResult = 8; + break; + } + case 0xcc:{ + VResult = 9; + break; + } + case 0xd2:{ + VResult = 0xa; + break; + } + case 0x55:{ + VResult = 0xb; + break; + } + case 0xe1:{ + VResult = 0xc; + break; + } + case 0x66:{ + VResult = 0xd; + break; + } + case 0x78:{ + VResult = 0xe; + break; + } + case 0xff:{ + VResult = 0xf; + break; + } + + }/* end switch CodedIn */ + + return (VResult); + +} /* End FSBB0_FHammingDecoder8_4 */ + + + + + + + +/******************************************************************************* +Prototype :SInt32 EFRIO__FSBB0_FConvEfrioFrameToZsFFrame ( EFRIO__TFrame* Src, SInt8 MapsId, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 14/10/2014 +Doc date : 14/10/2014 +Rev : copy of APP__FConvEfrioFrameToZsFFrame from read_flex_rio_daq_file_v22_gc + : +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 EFRIO__FSBB0_FConvEfrioFrameToZsFFrame ( EFRIO__TFrame* Src, SInt8 MapsId, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) { + + SInt32 VRetW30Length; + SInt32 ViData; + UInt16 VDataW30Length; + UInt16 VLastW30; + SInt16 ViSrcW30; + SInt32 VOneMapsSzW8; + SInt32 VOneMapsSzW32; + UInt32* VPtDataU32; + + FSBB0__TStatesLine VStatesLine; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbG0; + SInt8 VStatesNbG1; + SInt16 VPrevLine; + SInt8 VG0Overflow; + SInt8 VG1Overflow; + + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Get useful data length + + VOneMapsSzW8 = Src->Data.OneMapsSz; + VOneMapsSzW32 = VOneMapsSzW8 / 4; + + VDataW30Length = Src->Header.AMapsDataLength[MapsId]; + VRetW30Length = Src->Header.AMapsDataLength[MapsId]; + + msg (( MSG_OUT, "Conv : VOneMapsSzW32=%d - TotSzW32=%d", VOneMapsSzW32, Src->Data.TotSz / 4 )); + + msg (( MSG_OUT, "Conv : VDataW30Length=%d", VDataW30Length )); + + + if ( (PrintLvl == 5) || (PrintLvl == 6) || (PrintLvl == 7)/*||(PrintLvl == 8)*/ ) { + msg (( MSG_OUT, "TOTAL frame length : %d W30", VDataW30Length )); + msg (( MSG_OUT, "" )); + } + + // Add a check of data length, if > FSBB0__ZS_FFRAME_RAW_MAX_W30, force 0 and continue processing ( no exit on error ) + + if ( VDataW30Length > FSBB0__ZS_FFRAME_RAW_MAX_W32 ) { + err_error (( ERR_OUT, "Bad data length get from FSBB0 = %d W30 => Force 0 W30", VDataW30Length )); + VDataW30Length = 0; + Src->Data.OneMapsSz = 0; + VRetW30Length = -1; + } + + // Copy information fields + + Dest->SStatus.AsicNo = MapsId; // Index of Asic <0..N-1> in case more than one is acquired + Dest->SStatus.AcqNo = Src->Header.AcqId; // Index of current acquisition + Dest->SStatus.FrameNoInAcq = Src->Header.FrameIdInAcq; // Index of frame in acquisition <0..AcqFrameNb-1> + Dest->SStatus.FrameNoInRun = -1; // Index of frame in run <0..TotEventNb-1> + + Dest->SStatus.HitCnt = 0; // Counter of hits in frame + // Used for monitoring, may be not set, therefore HitCnt = -1 + + Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = Src->Header.AMapsTrigInfo[0]; // Trigger in [Fsbb bits] + Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__LINE] = Src->Header.AMapsTrigInfo[0] / 32; // Trigger in [Fsbb line] + Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = Src->Header.AMapsTrigInfo[0] % 32; // Trigger offset in Fsbb line in [Fsbb line] + + // ------------- + + Dest->Header.F.H0 = Src->Header.AMapsHeader[MapsId] & 0x0000FFFF; + Dest->Header.F.H1 = (Src->Header.AMapsHeader[MapsId] & 0xFFFF0000) >> 16; + + Dest->FrameCnt = Src->Header.AMapsFrameCnt[MapsId]; + + Dest->DataLength = Src->Header.AMapsDataLength[MapsId]; + + Dest->Trailer.F.T0 = Src->Header.AMapsTrailer[MapsId] & 0x0000FFFF; + Dest->Trailer.F.T1 = (Src->Header.AMapsTrailer[MapsId] & 0xFFFF0000) >> 16; + + + Dest->TrigSignalClk = Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__LINE]; + Dest->TrigSignalLine = Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE]; + + // Process frame + + ViSrcW30 = 0; + ViStatesLine = 0; + VPrevLine = -1; + + if ( PrintLvl == 4 ) { + msg (( MSG_OUT, "Frame data length = %d [W30]", VDataW30Length )); + msg (( MSG_OUT, "" )); + } + + VPtDataU32 = &(Src->Data.ADataW32[MapsId * VOneMapsSzW32]); + + // msg (( MSG_OUT, "Msg" )); + + if ( VDataW30Length != 0 ) { + + while ( ViSrcW30 < VDataW30Length ) { // Odd W30 nb handling => Don't process last W30 + + // Copy StatesLine field + + VStatesLine.W32 = VPtDataU32[ViSrcW30]; + Dest->AStatesRec[ViStatesLine].StatesLine = VStatesLine; + VG0Overflow = 0; + VG1Overflow = 0; + + VStatesNbG0 = EFRIO__FSBB0_FHammingDecoder8_4(VStatesLine.F.HitNbG0); + VStatesNbG1 = EFRIO__FSBB0_FHammingDecoder8_4(VStatesLine.F.HitNbG1); + //msg (( MSG_OUT, " ViStatesLine :%d :VStatesLine.F.HitNbG0 : %X - VStatesNbG0 : %x - VStatesLine.F.HitNbG1 : %X - VStatesNbG1 : %x ", ViStatesLine, VStatesLine.F.HitNbG0,VStatesNbG0,VStatesLine.F.HitNbG1,VStatesNbG1 )); + + Dest->AStatesRec[ViStatesLine].NbWinG0 = VStatesNbG0; + Dest->AStatesRec[ViStatesLine].NbWinG1 = VStatesNbG1; + Dest->AStatesRec[ViStatesLine].NbWinTot = VStatesNbG0 + VStatesNbG1; + + if (VStatesNbG0 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ){ + VG0Overflow = VStatesNbG0; + VStatesNbG0 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + } + + if (VStatesNbG1 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ){ + VG1Overflow = VStatesNbG1; + VStatesNbG1 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + } + + if ( (PrintLvl == 5) || (PrintLvl == 7) ) { + msg (( MSG_OUT, " ViStatesLine :%d :VStatesLine.W32 : %X - NbWinG0 : %d - NbWinG1 : %d ", ViStatesLine, VStatesLine.W32,Dest->AStatesRec[ViStatesLine].NbWinG0,Dest->AStatesRec[ViStatesLine].NbWinG1 )); + + msg (( MSG_OUT, "Line %4d - %d HitNbG0 (Ovf:%d) - %d HitNbG1 (Ovf:%d)", VStatesLine.F.SLineAddr, VStatesNbG0, VG0Overflow,VStatesNbG1,VG1Overflow )); + + } + + ++ViSrcW30; + + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + + + // Copy states G1 + if (VStatesNbG1 > 0){ + for ( ViState=0; ViState < VStatesNbG1; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].W32 = VPtDataU32[ViSrcW30]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "-->G1: State %d : Delta : %d - Col %4d - %X pixels", ViState, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Delta , Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code )); + if ( (PrintLvl == 8)&&(((Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code)& 0xFFFFF) == 0)&&(ViSrcW30 < VDataW30Length) ) { + msg (( MSG_OUT, " G1 : Frame :%d ,Word : %d of %d, SLineAddr :%d : Window word : %X - Code = 0, %d state out of %d ", Dest->FrameCnt, ViSrcW30,VDataW30Length, VStatesLine.F.SLineAddr, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].W32,ViState ,VStatesNbG0 )); + } + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + } + } + // Copy states G0 + + if (VStatesNbG0 > 0){ + for ( ViState=0; ViState < VStatesNbG0; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].W32 = VPtDataU32[ViSrcW30]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "-->G0: State %d : Delta : %d - Col %4d - %X pixels", ViState, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Delta , Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code )); + if ( (PrintLvl == 8)&&(((Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code)& 0xFFFFF) == 0)&&(ViSrcW30 < VDataW30Length) ) { + msg (( MSG_OUT, " G0 : Frame :%d ,Word : %d out of %d, SLineAddr :%d : Window word : %X - Code = 0, %d state out of %d ", Dest->FrameCnt, ViSrcW30,VDataW30Length, VStatesLine.F.SLineAddr, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].W32,ViState ,VStatesNbG0 )); + } + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + } + } + + ++ViStatesLine; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + + // Add on 25/03/2011 during test with random frame size + with all data = 0 + + if ( ViStatesLine >= FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "Max number of states reached = %d => Abort => Corrupted data !", FSBB0__ZS_FFRAME_MAX_STATES_REC )); + break; + } + + } // End while + + } // End if ( VDataW30Length != 0 ) + + Dest->StatesRecNb = ViStatesLine; + +//#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + if ( (PrintLvl == 5)/* || (PrintLvl == 6)*/|| (PrintLvl == 7) /*|| (PrintLvl == 8)*/ ) { + msg (( MSG_OUT, "Conv : %d StatesLines", Dest->StatesRecNb )); + msg (( MSG_OUT, "" )); + } + + return (VRetW30Length); +} // end EFRIO__FSBB0_FConvEfrioFrameToZsFFrame + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 14/10/2014 +Doc date : 14/10/2014 +Rev : copy of APP__FConvZsFFrameToMatDiscriBit from read_flex_rio_daq_file_v22_gc + : +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 EFRIO__FSBB0_FConvZsFFrameToMatDiscriBit ( FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDest, SInt32* PtOvfCnt, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 ViFirstLine; + SInt16 ViTopLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesLine; + SInt16 ViState; + SInt16 VStatesNbG0; + SInt16 VStatesNbG1; + SInt32 VHitCnt; + SInt32 VOfvCnt; + SInt32 VMask; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (FSBB0__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + // StatesRec loop + + VHitCnt = 0; + VOfvCnt = 0; + + if ( PtSrc->StatesRecNb > FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + err_error (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + PtSrc->StatesRecNb = FSBB0__ZS_FFRAME_MAX_STATES_REC; + } + + if (PtSrc->StatesRecNb > 0){ + + for ( ViStatesLine=0; ViStatesLine < PtSrc->StatesRecNb; ViStatesLine++ ) { + + VStatesNbG0 = PtSrc->AStatesRec[ViStatesLine].NbWinG0; + VStatesNbG1 = PtSrc->AStatesRec[ViStatesLine].NbWinG1; + ViTopLine = ((PtSrc->AStatesRec[ViStatesLine].StatesLine.F.SLineAddr + 1) * 4) - 1 ; + + + // States in one StateRec loop + + + if ( VStatesNbG0 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNbG0, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP )); + VStatesNbG0 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + ++VOfvCnt; + } + if ( VStatesNbG1 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNbG1, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP )); + VStatesNbG1 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + ++VOfvCnt; + } + + + if ( ViTopLine >= FSBB0__MAT_DISCRI_LINES_NB) { + err_warning (( ERR_OUT, "ViTopLine=%d >= FSBB0__MAT_DISCRI_LINES_NB=%d => Force %d", ViTopLine, FSBB0__MAT_DISCRI_LINES_NB, FSBB0__MAT_DISCRI_LINES_NB - 1 )); + ViTopLine = FSBB0__MAT_DISCRI_LINES_NB - 1; + } + // Decode Hits for Group 1 + if ( VStatesNbG1 > 0 ){ + for ( ViState = 0; ViState < VStatesNbG1; ViState++ ) { + + VFirstCol = (PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.ColAddr) + 224; + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + // Hits in one State loop + ViFirstLine = ViTopLine - (PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Delta); + VMask = 0x80000; + for (ViLine = ViFirstLine; ViLine > (ViFirstLine - 4); ViLine-- ){ + if (ViLine < 0){ + break; + } + for ( ViCol = VFirstCol; ViCol > VFirstCol - 5; ViCol-- ) { + if (ViCol < 0){ + break; + } + if ( ((PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code) & VMask) != 0){ + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + // 01/08/2014 - MS : removed the printing of the decoding of the data words + /* + if (PrintLvl ==7){ + msg (( MSG_OUT, " G1 : ViStatesLine :%d :ViTopLine : %d : ViState:%d - Hit Line : %d - Col : %d , VMask :0x%X ", ViStatesLine, ViTopLine,ViState, ViLine,ViCol,VMask )); + }*/ + } + else{ + PtDest->AALineCol[ViLine][ViCol] = 0; + + } + VMask = VMask >> 1; + + } // End For ViCol + } // End For ViLine + + } // End States in one StateRec loop for G1 + } /* end decoding groups for G1 */ + + // Decode Hits for Group 0 + if ( VStatesNbG0 > 0 ){ + for ( ViState=0; ViState < VStatesNbG0; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.ColAddr ; + //VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + // WARNING => Will slow down execution + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + + // Hits in one State loop + ViFirstLine = ViTopLine - (PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Delta); + VMask = 0x80000; + for (ViLine = ViFirstLine; ViLine > ViFirstLine - 4; ViLine-- ){ + if (ViLine < 0){ + break; + } + for ( ViCol=VFirstCol; ViCol > VFirstCol - 5; ViCol-- ) { + if (ViCol < 0){ + break; + } + //msg (( MSG_OUT, " ViStatesLine :%d :ViLine : %d - ViCol : %d - PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code : %d ", ViStatesLine, ViLine,ViCol,PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code )); + if ( (PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code & VMask) != 0){ + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + // 01/08/2014 - MS : removed the printing of the decoding of the data words + /* + if (PrintLvl ==7){ + msg (( MSG_OUT, " G0 : ViStatesLine :%d :ViTopLine : %d : ViState:%d - Hit Line : %d - Col : %d , VMask :0x%x ", ViStatesLine, ViTopLine,ViState, ViLine,ViCol,VMask )); + }*/ + } + VMask = VMask >> 1; + + } // End For ViCol + } // End For ViLine + + } // End States in one StateRec loop for G0 + } /* end decoding groups for G0 */ + } // End StatesRec loop + } /* end if (PtSrc->StatesRecNb > 0)*/ + + + if ( PtOvfCnt != NULL ) { + *PtOvfCnt = VOfvCnt; + } + + // err_error (( ERR_OUT, "TRACE - VHitCnt=%d", VHitCnt )); // 13/02/2013 + + return (VHitCnt); +} // end EFRIO__FSBB0_FConvZsFFrameToMatDiscriBit + + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode ( SInt32 BoardId, void* PtFrmRaw, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + FSBB0__TZsFFrameRaw * VPtSrcFsbb0FRmRaw ; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + //SInt32 V6iFrame; + // 01/10/2014 - MS + SInt32 ViFrameX6[6]; + + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViFSBB0; + //UInt32* VPtCpySrcW32; + UInt32* VPtDataW32FSBBNo0; + UInt32* VPtDataW32FSBBNo1; + UInt32* VPtDataW32FSBBNo2; + UInt32* VPtDataW32FSBBNo3; + UInt32* VPtDataW32FSBBNo4; + UInt32* VPtDataW32FSBBNo5; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViFSBB0ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode (P=%x, EltNb=%d)", PtFrmRaw, EltNb )); + + // Pointers parameters check + + err_retnull ( PtFrmRaw, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ ) / 6; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + VPtSrcFsbb0FRmRaw = (FSBB0__TZsFFrameRaw*)PtFrmRaw; + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + ViFrameX6[0]= 6 * ViFrame; + ViFrameX6[1]= ViFrameX6[0] + 1; + ViFrameX6[2]= ViFrameX6[0] + 2; + ViFrameX6[3]= ViFrameX6[0] + 3; + ViFrameX6[4]= ViFrameX6[0] + 4; + ViFrameX6[5]= ViFrameX6[0] + 5; + + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__FSBB0; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].Header.W32; + VPtFrame->Header.AMapsHeader[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[1]].Header.W32; + VPtFrame->Header.AMapsHeader[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[2]].Header.W32; + VPtFrame->Header.AMapsHeader[3] = VPtSrcFsbb0FRmRaw[ViFrameX6[3]].Header.W32; + VPtFrame->Header.AMapsHeader[4] = VPtSrcFsbb0FRmRaw[ViFrameX6[4]].Header.W32; + VPtFrame->Header.AMapsHeader[5] = VPtSrcFsbb0FRmRaw[ViFrameX6[5]].Header.W32; + // VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // ++VEChanTrigFieldCnt; + // Datalength + VADataLengthW32[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].UsefulDataLengthW30; + VADataLengthW32[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[1]].UsefulDataLengthW30; + VADataLengthW32[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[2]].UsefulDataLengthW30; + VADataLengthW32[3] = VPtSrcFsbb0FRmRaw[ViFrameX6[3]].UsefulDataLengthW30; + VADataLengthW32[4] = VPtSrcFsbb0FRmRaw[ViFrameX6[4]].UsefulDataLengthW30; + VADataLengthW32[5] = VPtSrcFsbb0FRmRaw[ViFrameX6[5]].UsefulDataLengthW30; + + VDataLengthW32Max = MATH_FUInt32Max ( VADataLengthW32, 6 ); + // Framecounter + VPtFrame->Header.AMapsFrameCnt[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[1]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[2]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[3] = VPtSrcFsbb0FRmRaw[ViFrameX6[3]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[4] = VPtSrcFsbb0FRmRaw[ViFrameX6[4]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[5] = VPtSrcFsbb0FRmRaw[ViFrameX6[5]].DataLengthRemFrCnt.F.FrameCnt; + + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW32Max > FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW32Max )); + + for ( ViFSBB0ChkDataLength = 0; ViFSBB0ChkDataLength < 6; ViFSBB0ChkDataLength++ ) { + if ( VADataLengthW32[ViFSBB0ChkDataLength] > FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViFSBB0ChkDataLength, VADataLengthW16[ViFSBB0ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViFSBB0=0; ViFSBB0 < 6; ViFSBB0++ ) { + VADataLengthW8[ViFSBB0] = VADataLengthW32[ViFSBB0] * 4; + VADataLengthW16[ViFSBB0] = VADataLengthW32[ViFSBB0] * 2; + } + + VDataLengthW8Max = VDataLengthW32Max * 4; + VDataLengthW16Max = VDataLengthW32Max * 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtDataW32FSBBNo0 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[0] ].ADataW32; + VPtDataW32FSBBNo1 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[1] ].ADataW32; + VPtDataW32FSBBNo2 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[2] ].ADataW32; + VPtDataW32FSBBNo3 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[3] ].ADataW32; + VPtDataW32FSBBNo4 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[4] ].ADataW32; + VPtDataW32FSBBNo5 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[5] ].ADataW32; + + + + //VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = VPtDataW32FSBBNo0[ViDataCpy]; + ++VAPtCpyDestW32[0]; + //++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = VPtDataW32FSBBNo1[ViDataCpy];; + ++VAPtCpyDestW32[1]; + // ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = VPtDataW32FSBBNo2[ViDataCpy];; + ++VAPtCpyDestW32[2]; + //++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = VPtDataW32FSBBNo3[ViDataCpy];; + ++VAPtCpyDestW32[3]; + // ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = VPtDataW32FSBBNo4[ViDataCpy];; + ++VAPtCpyDestW32[4]; + // ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = VPtDataW32FSBBNo5[ViDataCpy];; + ++VAPtCpyDestW32[5]; + //++VPtCpySrcW32; + + + // VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + // ++VPtCpySrcW32; + // ++VEChanTrigFieldCnt; + } + + // VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + //do { + // VEChanTrigField = *VPtEChanSrcW32; + + // if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + // err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + // break; + //} + + // VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + // VPtEChanSrcW32 += 7; + // ++VEChanTrigFieldCnt; + //} while ( (VEChanTrigField & 0x80000000) == 0 ); + + + //ViSrcW32 += (6 * FSBB0__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[1]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[2]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[3] = VPtSrcFsbb0FRmRaw[ViFrameX6[3]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[4] = VPtSrcFsbb0FRmRaw[ViFrameX6[4]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[5] = VPtSrcFsbb0FRmRaw[ViFrameX6[5]].Trailer.W32; + + //++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + //VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_MAX_W32 * ViFrameX6[0]) + 18 + (6 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + //ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + // VTrigNb = (VZero & 0xFFFF0000) >> 16; + + //if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + // err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + // VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + //} + + //if ( VTrigNb != 0 ) { + // VATrigVal[0] = (VZero & 0x0000FFFF); + // VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + // VATrigVal[2] = (VZero2 & 0x0000FFFF); + + // VATrigLine[0] = VATrigVal[0] / 16; + // VATrigLine[1] = VATrigVal[1] / 16; + // VATrigLine[2] = VATrigVal[2] / 16; + + // VATrigClk[0] = VATrigVal[0] % 16; + // VATrigClk[1] = VATrigVal[1] % 16; + // VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + // VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + // VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + // VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + //} + + //else { + // VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + // } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].SStatus.ATrigRes[ASIC__ULT1_TRIG_TOT_NB]; + VPtFrame->Header.AMapsTrigInfo[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].SStatus.ATrigRes[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].SStatus.ATrigRes[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].SStatus.ATrigRes[2]; + + // Add trigger info in trigger record + + //VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + //VPtTmpTrigRec->TrigNb = VTrigNb; + //VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + //VPtTmpTrigRec->TrigType = 2; + + //memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + //VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + // VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + //EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} /*end EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Fsbb0 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 01/10/2014 +Rev : +Doc date : 01/10/2014 +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSBB0_FConvNi6562ToFlexRIOEudet3Mode ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViFSBB0; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__FSBB0_FConvNi6562ToFlexRIOEudet3Mode (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViFSBB0=0; ViFSBB0 < 6; ViFSBB0++ ) { + VADataLengthW8[ViFSBB0] = 0; + VADataLengthW16[ViFSBB0] = 0; + VADataLengthW32[ViFSBB0] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViFSBB0=0; ViFSBB0 < 6; ViFSBB0++ ) { + VADataLengthW8[ViFSBB0] = VADataLengthW16[ViFSBB0] * 2; + VADataLengthW32[ViFSBB0] = VADataLengthW16[ViFSBB0] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + + + + +// $$$$$$$$$$$$$$ + +// : 03/02/2014 +// : - Add new tests on data + + +SInt32 EFRIO__FSBB0_FFRioAcqDeserDataEudet2Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViFsbb0ChkDataLength; + SInt32 VErrorsOnData; // 25/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // err_error (( ERR_OUT, "VDataLengthW16Max = %d", VDataLengthW16Max )); + + if ( VDataLengthW16Max > FSBB0__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViFsbb0ChkDataLength = 0; ViFsbb0ChkDataLength < 6; ViFsbb0ChkDataLength++ ) { + if ( VADataLengthW16[ViFsbb0ChkDataLength] > FSBB0__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViFsbb0ChkDataLength, VADataLengthW16[ViFsbb0ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; // 3; !!! 08/06/2011 => Force 3 triggers !!! + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + ( /* !!! 08/06/2011 => Force 3 triggers !!! 3 */ VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // 03/02/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + //VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + //VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + // VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + // VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + // VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + // VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + //VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + //VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + //VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + // Update frames & events counters ONLY if there is no errors on data - 25/04/2013 + + if ( VErrorsOnData == 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 17/01/2012 + : - Implementation of "sw" handling of Mi26 / "hard coded" + : It is enable by EFRIO__FREE_MI26_NB directive and ONLY implemented in mode EUDET 2 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__FSBB0_FFRioAcqDeserDataFsbb0 ( SInt8 Fsbb0Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__USR_TContext* VPtUsrContext = &EFRIO__USR_VGContext; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + +#ifndef NO_MI26 + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + + switch ( Fsbb0Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This mode is not handled now", Fsbb0Nb ) ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This mode is not handled now", Fsbb0Nb ) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + } + + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Fsbb0Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This mode is not handled now", Fsbb0Nb ) ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This mode is not handled now", Fsbb0Nb ) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + + #ifdef EFRIO__FREE_MI26_NB + + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 ( Fsbb0Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + + #else + + switch ( Fsbb0Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 5 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 6 : { + // to modify : fsbb0_frame raw not yet defined and initiialized + VRet = EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 12 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + } + + #endif + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + + #ifdef EFRIO__FREE_MI26_NB + + // 14/06/13 : Uses ReadoutMode command line parameter to select between normal readout & readout with etra trigger info (Debug BT June 2013) + + if ( VPtUsrContext->ParReadoutMode == 0) { + // msg (( MSG_OUT, "Normal readout" )); + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 ( Fsbb0Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + } + + else { + // msg (( MSG_OUT, "Readout WITH extra trigger info" )); + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26ExtaTrigInfo ( Fsbb0Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + } + + + #else + + switch ( Fsbb0Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 5 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 6 : { + //VRet = EFRIO__FSBB0_FConvNi6562ToFlexRIOEudet3Mode ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + } + + #endif + + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + // 10/10/14 - MS : is it still usefull ?? + // Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); + +#endif // NO_MI26 + +} + + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.h b/include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.h new file mode 100755 index 0000000..27d00e0 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_fsbb0.h @@ -0,0 +1,45 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_fsbb0.h +Goal : Fsbb0 functions prototypes of flex rio board library for EUDET +Prj date : 01/10/2014 +File date : 01/10/2014 +Doc date : +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_FSBB0_H + +#include "func_header.def" + + +// 06/11/2010 -> 21 + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSBB0_FMatDiscriPrintHit ( char* CmtStrTitle, SInt8 CmtSInt8MapsId, FSBB0__TMatDiscriBit* PtDest );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt8 EFRIO__FSBB0_FHammingDecoder8_4(UInt8 CodedIn);) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSBB0_FConvEfrioFrameToZsFFrame ( EFRIO__TFrame* Src, SInt8 MapsId, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSBB0_FConvZsFFrameToMatDiscriBit ( FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDest, SInt32* PtOvfCnt, SInt8 PrintLvl );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode ( SInt32 BoardId, void* PtFrmRaw, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSBB0_FConvNi6562ToFlexRIOEudet3Mode ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSBB0_FFRioAcqDeserDataFsbb0 ( SInt8 Fsbb0Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode );) + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_FSBB0_H + #define EUDET_FRIO_FSBB0_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_get.c b/include/pxi_daq_lib_v.2.1/eudet_frio_get.c new file mode 100755 index 0000000..8fb106b --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_get.c @@ -0,0 +1,2182 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_GET_C +#define EUDET_FRIO_GET_C + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 09/08/2010 +Rev : 25/10/2010 + : - Rename EFRIO__FGetZsFFrameRawFields in EFRIO__FGetFrameRawFields + : - Handle both IPHC "ZsFFrameRaw" and EUDET "Frame" +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +UInt32* EFRIO__FGetFrameFields ( SInt32 AcqId, SInt8 Mi26Id, SInt32 FrameIdInAcq, UInt32* PtDest, SInt8 DestW32Sz ) { + + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + SInt8 ViField; + SInt8 VFieldNb = 15; + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViTrigInf; + + static UInt32 VAFields[15]; + + + if ( AcqId > 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + for ( ViField=0; ViField < VFieldNb; ViField++ ) { + VAFields[ViField] = 0; + } + + + // Set default values used in case of error + + VAFields [0] = 0x11111111; // Header + VAFields [1] = 100; // FrameCnt + VAFields [2] = 200; // DataLength + VAFields [3] = 0x11111111; // Trailer + VAFields [4] = 0x01; // Zero + VAFields [5] = 0x02; // Zero2 + VAFields [6] = 0; // Trigger number + VAFields [7] = 0; // Trigger 1 + VAFields [8] = 0; // Trigger 2 + VAFields [9] = 0; // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + + + while (1) { + + // IPHC mode + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_IPHC ) { + + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + + VAFields[0] = VPtFrame->Header; + VAFields[1] = VPtFrame->FrameCnt; + VAFields[2] = VPtFrame->DataLength; + VAFields[3] = VPtFrame->Trailer; + VAFields[4] = VPtFrame->Zero; + VAFields[5] = VPtFrame->Zero2; + VAFields [6] = (VPtFrame->Zero & 0xFFFF0000) >> 16; // Trigger number + VAFields [7] = (VPtFrame->Zero & 0x0000FFFF); // Trigger 1 + VAFields [8] = (VPtFrame->Zero2 & 0xFFFF0000) >> 16; // Trigger 2 + VAFields [9] = (VPtFrame->Zero2 & 0x0000FFFF); // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + + break; + } + + // EUDET 1 mode + + if ( VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + break; + } + + VPtTrigRec = (EFRIO__TTriggerRec*) ( ((UInt8*) VPtFrList->AFramePtr[FrameIdInAcq]) + VPtFrList->AFramePtr[FrameIdInAcq]->TrigRecOffset ); + + VAFields[0] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsHeader[Mi26Id]; + VAFields[1] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsFrameCnt[Mi26Id]; + VAFields[2] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsDataLength[Mi26Id]; + VAFields[3] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrailer[Mi26Id]; + VAFields[4] = 0; // Zero + VAFields[5] = 0; // Zero2 + + VAFields[6] = VPtTrigRec->TrigNb; + + if ( VPtTrigRec->TrigNb > 0 ) { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields [8] = VPtTrigRec->ATrig[1]; // Trigger 2 + VAFields [9] = VPtTrigRec->ATrig[2]; // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + } + + else { + VAFields [7] = 0; // Trigger 1 + VAFields [8] = 0; // Trigger 2 + VAFields [9] = 0; // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + } + + + break; + } + + // EUDET 2 & 3 mode + + if ( (VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES) ||(VPtRunCont->ParDataTransferMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG) ) { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + break; + } + + VPtTrigRec = (EFRIO__TTriggerRec*) ( ((UInt8*) VPtFrList->AFramePtr[FrameIdInAcq]) + VPtFrList->AFramePtr[FrameIdInAcq]->TrigRecOffset ); + + VAFields[0] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsHeader[Mi26Id]; + VAFields[1] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsFrameCnt[Mi26Id]; + VAFields[2] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsDataLength[Mi26Id]; + VAFields[3] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrailer[Mi26Id]; + VAFields[4] = 0; // Zero + VAFields[5] = 0; // Zero2 + + VAFields[6] = VPtTrigRec->TrigNb; + + if ( VPtTrigRec->TrigNb > 0 ) { + + switch ( VPtTrigRec->TrigNb ) { + + case 1 : { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields[11] = VPtTrigRec->ATrig[1]; // Time stamp 1 + break; } + + case 2: { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields [8] = VPtTrigRec->ATrig[2]; // Trigger 2 + VAFields[11] = VPtTrigRec->ATrig[1]; // Time stamp 1 + VAFields[12] = VPtTrigRec->ATrig[3]; // Time stamp 2 + break; } + + case 3 : { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields [8] = VPtTrigRec->ATrig[2]; // Trigger 2 + VAFields [9] = VPtTrigRec->ATrig[4]; // Trigger 3 + VAFields[11] = VPtTrigRec->ATrig[1]; // Time stamp 1 + VAFields[12] = VPtTrigRec->ATrig[3]; // Time stamp 2 + VAFields[13] = VPtTrigRec->ATrig[5]; // Time stamp 3 + break; } + + default : { + VAFields [7] = VPtTrigRec->ATrig[0]; // Trigger 1 + VAFields [8] = VPtTrigRec->ATrig[2]; // Trigger 2 + VAFields [9] = VPtTrigRec->ATrig[4]; // Trigger 3 + VAFields[11] = VPtTrigRec->ATrig[1]; // Time stamp 1 + VAFields[12] = VPtTrigRec->ATrig[3]; // Time stamp 2 + VAFields[13] = VPtTrigRec->ATrig[5]; // Time stamp 3 + break; } + + } // End switch + + if ( VPtTrigRec->TrigNb > 3 ) { + VAFields[10] = VPtTrigRec->ATrig[(2 * (VPtTrigRec->TrigNb - 1))]; // Last trigger + VAFields[14] = VPtTrigRec->ATrig[(2 * (VPtTrigRec->TrigNb - 1)) + 1]; // Last time stamp + } + + else { + VAFields[10] = 0; // Last trigger + VAFields[14] = 0; // Last time stamp + } + + } // End if ( VPtTrigRec->TrigNb > 0 ) + + else { + VAFields [7] = 0; // Trigger 1 + VAFields [8] = 0; // Trigger 2 + VAFields [9] = 0; // Trigger 3 + VAFields[10] = 0; // Last trigger + VAFields[11] = 0; // Time stamp 1 + VAFields[12] = 0; // Time stamp 2 + VAFields[13] = 0; // Time stamp 3 + VAFields[14] = 0; // Last stamp + } + + break; + } + + // If case not handled -> Return default values + + VAFields [0] = 0x11111111; // Header + VAFields [1] = 100; // FrameCnt + VAFields [2] = 200; // DataLength + VAFields [3] = 0x11111111; // Trailer + VAFields [4] = 0x01; // Zero + VAFields [5] = 0x02; // Zero2 + VAFields [6] = 0; // Trigger number + VAFields [7] = -1; // Trigger 1 + VAFields [8] = -1; // Trigger 2 + VAFields [9] = -1; // Trigger 3 + VAFields[10] = -1; // Last trigger + VAFields[11] = -1; // Time stamp 1 + VAFields[12] = -1; // Time stamp 2 + VAFields[13] = -1; // Time stamp 3 + VAFields[14] = -1; // Last stamp + break; + + } // End while (1) + + + if ( (PtDest != NULL) && (DestW32Sz >= VFieldNb) ) { + + for ( ViField=0; ViField < VFieldNb; ViField++ ) { + PtDest[ViField] = VAFields[ViField]; + } + + return (PtDest); + } + + err_warning (( ERR_OUT, "Use local array because : PtDest=%x == NULL or DestW32Sz=%d < 10", PtDest, DestW32Sz )); + + return (VAFields); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameHeader ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + UInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViTrigInf; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = VPtFrame->Header; // FrameCnt, DataLength, Trailer, Zero, Zero2 + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + // VPtTrigRec = (EFRIO__TTriggerRec*) ( ((UInt8*) VPtFrList->AFramePtr[FrameIdInAcq]) + VPtFrList->AFramePtr[FrameIdInAcq]->TrigRecOffset ); + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsHeader[Mi26Id]; + } + + else { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + +// VAFields[0] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsHeader[Mi26Id]; +// VAFields[1] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsFrameCnt[Mi26Id]; +// VAFields[2] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsDataLength[Mi26Id]; +// VAFields[3] = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrailer[Mi26Id]; + + return (VField); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameFrameCnt ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + UInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = VPtFrame->FrameCnt; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsFrameCnt[Mi26Id]; + } + + else { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + return (VField); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameDataLength ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + UInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = VPtFrame->DataLength; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsDataLength[Mi26Id]; + } + + else { + VField = 0xFFFFFFFF; + err_error (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + return (VField); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameTrailer ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + UInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = VPtFrame->Trailer; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrailer[Mi26Id]; + } + + else { + VField = 0xFFFFFFFF; + err_error (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + return (VField); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 09/06/2010 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FGetFrameTrigStatus ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + SInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + VField = -1; // Not available + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : + { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.TrigStatus; + } + + else { + VField = -1; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = -1; + break; } + + } // End switch + + return (VField); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : 07/06/2011 + : - Handle TrigNb < 0 => Workarround of fw trigger bug => function returns SInt32 now +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FGetFrameTrigCnt ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + SInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = (VPtFrame->Zero & 0xFFFF0000) >> 16; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : + { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.TriggerNb; + } + + else { + // VField = 0xFFFFFFFF; + VField = 666; // 07/06/2011 + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + // VField = 0xFFFFFFFF; + VField = 666; // 07/06/2011 + break; } + + } // End switch + + return (VField); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameMi26Trig0 ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + UInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = (VPtFrame->Zero & 0x0000FFFF); + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrigInfo[0]; + } + + else { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + + + return (VField); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameMi26Trig1 ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + UInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = (VPtFrame->Zero2 & 0xFFFF0000) >> 16; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrigInfo[1]; + } + + else { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + + return (VField); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameMi26Trig2 ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + UInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = (VPtFrame->Zero2 & 0x0000FFFF); + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsTrigInfo[2]; + } + + else { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + return (VField); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameTluTrig ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq, SInt16 TrigNo ) { + + + UInt32 VField; + SInt32 VFieldIndex; + SInt32 VTrigNb; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViTrigInf; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( TrigNo < 0 ) { + err_warning (( ERR_OUT, "TrigNo=%d < 0", TrigNo )); + return (-1); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : { + VField = 0xFFFFFFFF; + err_error (( ERR_OUT, "No TLU trigger field in EFRIO__TRF_MODE_IPHC & EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN" )); + break; } + + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VTrigNb = VPtFrList->AFramePtr[FrameIdInAcq]->Header.TriggerNb; + VFieldIndex = TrigNo * 2; + + if ( VFieldIndex >= (2 * VTrigNb) ) { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Trigger index=%d out of range - TrigNb=%d", VFieldIndex, VTrigNb )); + } + + else { + VPtTrigRec = (EFRIO__TTriggerRec*) ( ((UInt8*) VPtFrList->AFramePtr[FrameIdInAcq]) + VPtFrList->AFramePtr[FrameIdInAcq]->TrigRecOffset ); + VField = VPtTrigRec->ATrig[VFieldIndex]; + } + + } + + else { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + + return (VField); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 08/11/2010 +Rev : 07/06/2011 + : - Handle TrigNb < 0 => Workarround of fw trigger bug +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 EFRIO__FGetFrameFlexRioTrig ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq, SInt16 TrigNo ) { + + + UInt32 VField; + SInt32 VFieldIndex; + SInt32 VTrigNb; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + EFRIO__TTriggerRec* VPtTrigRec; + SInt8 ViTrigInf; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( TrigNo < 0 ) { + err_warning (( ERR_OUT, "TrigNo=%d < 0", TrigNo )); + return (-1); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : { + VField = 0xFFFFFFFF; + err_error (( ERR_OUT, "No Flex RIO trigger field in EFRIO__TRF_MODE_IPHC & EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN" )); + break; } + + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + + VTrigNb = VPtFrList->AFramePtr[FrameIdInAcq]->Header.TriggerNb; + + VTrigNb = abs ( VTrigNb ); // 07/06/2011 => TrigNb < 0 if fw bug shift two frames + + VFieldIndex = (TrigNo * 2) + 1; + + if ( /* !!! 08/06/2011 Force read !!! */ /* VFieldIndex >= (2 * VTrigNb) */ 0 ) { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Trigger index=%d out of range - TrigNb=%d", VFieldIndex, VTrigNb )); + } + + else { + VPtTrigRec = (EFRIO__TTriggerRec*) ( ((UInt8*) VPtFrList->AFramePtr[FrameIdInAcq]) + VPtFrList->AFramePtr[FrameIdInAcq]->TrigRecOffset ); + VField = VPtTrigRec->ATrig[VFieldIndex]; + } + + } + + else { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + + return (VField); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float EFRIO__FGetDataRateMBPerSec ( SInt8 PrintInMsgFile ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + if ( PrintInMsgFile == 1 ) { + msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + } + + return (VPtRunCont->ResDataRateMBytesPerSec); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW + : DEBUG tools, process ONLY first state in data stream, ignore Mi26Id param. + : +Level : +Date : 21/06/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FGetFrameFirstStateLineWordStatesNb ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + SInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + MI26__TStatesLine VStatesLines; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + VField = -1; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Data.ADataW32[0]; + VStatesLines.W16 = VField; + VField = VStatesLines.F.StateNb; // LineAddr + } + + else { + VField = -1; + err_error (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + return (VField); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW + : DEBUG tools, process ONLY first state in data stream, ignore Mi26Id param. + : +Level : +Date : 21/06/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FGetFrameFirstStateLineWordLineNo ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + SInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + MI26__TStatesLine VStatesLines; + SInt32 ViFrame; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + VField = -1; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Data.ADataW32[0]; + VStatesLines.W16 = VField; + VField = VStatesLines.F.LineAddr; + } + + else { + VField = -1; + err_error (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + return (VField); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW + : DEBUG tools + : -> process ONLY first state in data stream, ignore Mi26Id param. + : -> works only if 6 Ultimate are acquired ( can be emul mode ) + extra chan enabled +: +Level : +Date : 21/06/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FGetFrameFirstGroupStatesNb ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + SInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + MI26__TZsFFrameRaw* VPtFrame; + MI26__TStatesLine VStatesLines; + SInt32 ViFrame; + UInt16* VPtDataW16; + SInt8 VStatesNbInLine; + SInt8 ViState; + SInt8 VFirstGroupStatesNb; + MI26__TState VState; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + VField = -1; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + + VStatesLines.W16 = VPtFrList->AFramePtr[FrameIdInAcq]->Data.ADataW32[0]; + VPtDataW16 = (UInt16*) VPtFrList->AFramePtr[FrameIdInAcq]->Data.ADataW32; + ++VPtDataW16; // Point on first W16 following State/Line W16 + VStatesNbInLine = VStatesLines.F.StateNb; + VFirstGroupStatesNb = 0; + + for ( ViState = 0; ViState < VStatesNbInLine; ViState++ ) { + VState.W16 = VPtDataW16[(ViState * 7)]; + + if ( (VState.F.ColAddr >= 0) && (VState.F.ColAddr <= 63) ) { + ++VFirstGroupStatesNb; + } + + } + + VField = VFirstGroupStatesNb; + } + + else { + VField = -1; + err_error (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } // End switch + + return (VField); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 23/01/2014 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FGetFrameHitCnt ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq ) { + + + UInt32 VField; + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + MI26__TZsFFrameRaw* VPtFrame; + SInt32 ViFrame; + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (Mi26Id < 0) ||(Mi26Id >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad Mi26Id=%d out of range [0..%d]", Mi26Id, VPtRunCont->ParMi26Nb-1 ) ); + return (-1); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + + // return ( EFRIO__FGetFrameDataLength ( AcqId, Mi26Id, FrameIdInAcq ) ); + + // 04/02/14 + // WARNING => Tmp code to return hits count, No chekc of Mi26Id !!!! + + return ( VPtTestCont->ResAMapsMatrixHitCnt[Mi26Id] ); + +/* + + switch ( VPtRunCont->ParDataTransferMode ) { + + case EFRIO__TRF_MODE_IPHC : { + ViFrame = (FrameIdInAcq * VPtRunCont->ParMi26Nb) + Mi26Id; + VPtFrame = &EFRIO__VGContext.RunCont.PtZsFFrameRaw[ViFrame]; + VField = VPtFrame->FrameCnt; + break; } + + case EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN : + case EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES : + case EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG : { + + if ( VPtFrList->AFramePtr[FrameIdInAcq] != NULL ) { + VField = VPtFrList->AFramePtr[FrameIdInAcq]->Header.AMapsFrameCnt[Mi26Id]; + } + + else { + VField = 0xFFFFFFFF; + err_warning (( ERR_OUT, "Frame=%d NOT in list (pointer = NULL) !", FrameIdInAcq )); + } + + break; } + + default : { + err_error (( ERR_OUT, "Unknown ParDataTransferMode=%d", VPtRunCont->ParDataTransferMode )); + VField = 0xFFFFFFFF; + break; } + + } + +*/ + + return (VField); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Param AcqId not used NOW +: +Level : +Date : 06/11/2010 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +EFRIO__TFrame* EFRIO__FGetFramePt ( SInt32 AcqId, SInt32 FrameIdInAcq ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TFrameList* VPtFrList = &EFRIO__VGContext.AAcqFrameList[0]; + + + if ( AcqId >= 0 ) { + err_warning (( ERR_OUT, "AcqId=%d NOT hanlded NOW", AcqId )); + } + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"No frame=%d in list => Pointer NULL", FrameIdInAcq) ); + } + + return ( VPtFrList->AFramePtr[FrameIdInAcq] ); +} + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Get board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FGetBoardConf ( SInt32 BoardId, EFRIO__TBoardConf* PtDest ) { + + err_trace (( ERR_OUT, "begin" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( PtDest, (ERR_OUT,"Abort : PtDest == NULL") ); + + *PtDest = EFRIO__VGContext.ABoardsConf[BoardId]; + + err_retok (( ERR_OUT, "end" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Get board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/08/2010 +Doc date : 10/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfBoardId ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].BoardId); +} + +// 10/08/2010 + +char* EFRIO__FGetBoardConfAsicName ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) { + return (NULL); + } + + return (EFRIO__VGContext.ABoardsConf[BoardId].AsicName); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfAsicNb ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].AsicNb); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfReadoutMode ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].ReadoutMode); +} + +// 11/08/2010 + +SInt8 EFRIO__FGetBoardConfEmuleChannels ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].EmuleChannels); +} + + +// 10/08/2010 + +float EFRIO__FGetBoardConfDataClkFrequency ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].DataClkFrequency); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfDmaHostSz ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].DmaHostSz); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfFrameNbPerAcq ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].FrameNbPerAcq); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfEnableExtraChannel ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].EnableExtraChannel); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardConfAcqNbPerTrig ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].AcqNbPerTrig); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfTriggerMode ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TriggerMode); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfTriggerDetectTimeWindow ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TriggerDetectTimeWindow); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfTriggerDetectOccurNb ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TriggerDetectOccurNb); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfTimeStampRes ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TimeStampRes); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfEnableTimeStamping ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].EnableTimeStamping); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfEnableTrigCnt ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].EnableTrigCnt); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardConfTagEventsStoredByDUT ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].TagEventsStoredByDUT); +} + +// 10/08/2010 + +UInt32 EFRIO__FGetBoardConfReadTluTrigCntEachNTrig ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsConf[BoardId].ReadTluTrigCntEachNTrig); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Get board status fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/08/2010 +Doc date : 10/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardStatusBoardId ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].BoardId); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardStatusBoardPresent ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].BoardPresent); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardStatusFwLoaded ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].FwLoaded); +} + +// 10/08/2010 + +SInt8 EFRIO__FGetBoardStatusConfDone ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].ConfDone); +} + +// 10/08/2010 + +SInt32 EFRIO__FGetBoardStatusStatusCode ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + EFRIO__CHK_BOARD_ID (BoardId); + + return (EFRIO__VGContext.ABoardsStatus[BoardId].StatusCode); +} + +// 10/08/2010 + +char* EFRIO__FGetBoardStatusStatusStr ( SInt32 BoardId ) { + + err_trace (( ERR_OUT, "" )); + + if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) { + err_error (( ERR_OUT, "Abort : BoardId=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 )); + return (NULL); + } + + return (EFRIO__VGContext.ABoardsStatus[BoardId].StatusStr); +} + + +// 10/08/2010 + +char* EFRIO__FGetBoardStatusErrorMsgList ( SInt32 BoardId, SInt32 Index ) { + + SInt32 VMsgLen; + EFRIO__TBoardStatus* VPtStatus; + + if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) { + err_error (( ERR_OUT, "Abort : BoardId=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 )); + return (NULL); + } + + VPtStatus = &EFRIO__VGContext.ABoardsStatus[BoardId]; + + // Check index limits + + if ( (Index < 0) || (Index >= EFRIO__ERROR_MSG_LIST_MAX_NB ) ) { + err_error (( ERR_OUT, "Abort : Index=%d out of range [0..%d]", Index, EFRIO__ERROR_MSG_LIST_MAX_NB-1 )); + return (NULL); + } + + return ( VPtStatus->ErrorMsgList[Index] ); +} + +// 10/08/2010 + +char* EFRIO__FGetBoardStatusLastErrorMsg ( SInt32 BoardId ) { + + if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) { + err_error (( ERR_OUT, "Abort : BoardId=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 )); + return (NULL); + } + + return (EFRIO__VGContext.ABoardsStatus[BoardId].LastErrorMsg); +} + +// 21/12/2010 + +SInt32 EFRIO__FGetCmdRun () { + + if ( (EFRIO__VGContext.RunCont.CmdRun == 0) || (EFRIO__VGContext.RunCont.CmdRun == 1) ) { + // msg (( MSG_OUT, "### EFRIO__FGetCmdRun () = %d", EFRIO__VGContext.RunCont.CmdRun )); + } + + return ( EFRIO__VGContext.RunCont.CmdRun ); +} + +// 15/02/2011 + +SInt32 EFRIO__FGetMonInfFrameNbToSend () { + + return (EFRIO__VGContext.MonCont.InfFrameNbToSend); +} + +// 15/02/2011 + +SInt32 EFRIO__FGetMonInfSzToSend () { + + return (EFRIO__VGContext.MonCont.InfSzToSend); +} + +// 16/02/2011 + +SInt32 EFRIO__FGetRunContSendOnEth () { + + return (EFRIO__VGContext.RunCont.ParSendOnEth); +} + +// 11/03/2011 + +SInt32 EFRIO__FGetRunContFrameNbPerAcq () { + + return (EFRIO__VGContext.RunCont.ParFrameNbPerAcq); +} + +// 02/05/2011 + +SInt32 EFRIO__FGetTestOnDataHeaderErrCnt ( SInt8 MapsId ) { + + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + if ( (MapsId < 0) ||(MapsId >= VPtRunCont->ParMi26Nb) ) { + err_warning ((ERR_OUT,"Abort : Bad MapsId=%d out of range [0..%d]", MapsId, VPtRunCont->ParMi26Nb-1 ) ); + return (0); + } + + return (EFRIO__VGContext.TestOnDataCont.ResAMapsHeaderErrCnt[MapsId]); +} + +// 02/05/2011 + +SInt32 EFRIO__FGetTestOnDataTotErrCnt () { + + return (EFRIO__VGContext.TestOnDataCont.ResTotErrCnt); +} + +// 25/04/2013 + +SInt32 EFRIO__FGetTestOnDataErrOnCurrentAcq () { + + return (EFRIO__VGContext.TestOnDataCont.ResErrOnCurrentAcq); +} + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_get.h b/include/pxi_daq_lib_v.2.1/eudet_frio_get.h new file mode 100755 index 0000000..3cb356e --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_get.h @@ -0,0 +1,104 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.h +Goal : Functions prototypes of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_GET_H + +#include "func_header.def" + +// 06/11/2010 -> 29 + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32* EFRIO__FGetFrameFields ( SInt32 AcqId, SInt8 Mi26Id, SInt32 FrameIdInAcq, UInt32* PtDest, SInt8 DestW32Sz );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameHeader ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameFrameCnt ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameDataLength ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameTrailer ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetFrameTrigCnt ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetFrameTrigStatus ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameMi26Trig0 ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameMi26Trig1 ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameMi26Trig2 ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameTluTrig ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq, SInt16 TrigNo );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetFrameFlexRioTrig ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq, SInt16 TrigNo );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetFrameHitCnt ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, float EFRIO__FGetDataRateMBPerSec ( SInt8 PrintInMsgFile );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, EFRIO__TFrame* EFRIO__FGetFramePt ( SInt32 AcqId, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConf ( SInt32 BoardId, EFRIO__TBoardConf* PtDest );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfBoardId ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FGetBoardConfAsicName ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfAsicNb ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfReadoutMode ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfEmuleChannels ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, float EFRIO__FGetBoardConfDataClkFrequency ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfDmaHostSz ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfFrameNbPerAcq ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfEnableExtraChannel ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardConfAcqNbPerTrig ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfTriggerMode ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfTriggerDetectTimeWindow ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfTriggerDetectOccurNb ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfTimeStampRes ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfEnableTimeStamping ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfEnableTrigCnt ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardConfTagEventsStoredByDUT ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, UInt32 EFRIO__FGetBoardConfReadTluTrigCntEachNTrig ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardStatusBoardId ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardStatusBoardPresent ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardStatusFwLoaded ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt8 EFRIO__FGetBoardStatusConfDone ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetBoardStatusStatusCode ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FGetBoardStatusStatusStr ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FGetBoardStatusErrorMsgList ( SInt32 BoardId, SInt32 Index );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO__FGetBoardStatusLastErrorMsg ( SInt32 BoardId );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetCmdRun ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetMonInfFrameNbToSend ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetMonInfSzToSend ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetRunContSendOnEth ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetRunContFrameNbPerAcq ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetTestOnDataHeaderErrCnt ( SInt8 MapsId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetTestOnDataTotErrCnt ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetTestOnDataErrOnCurrentAcq ();) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetFrameFirstStateLineWordStatesNb ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetFrameFirstStateLineWordLineNo ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FGetFrameFirstGroupStatesNb ( SInt32 AcqId, SInt16 Mi26Id, SInt32 FrameIdInAcq );) + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_GET_H + #define EUDET_FRIO_GET_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_print.c b/include/pxi_daq_lib_v.2.1/eudet_frio_print.c new file mode 100755 index 0000000..3a125eb --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_print.c @@ -0,0 +1,1460 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_PRINT_C +#define EUDET_FRIO_PRINT_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert TLU trigger info record to string for print or display +: +Inputs : Trig - Source trigger record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display +: +Inputs : Ts - Source time stamp record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger / timestamp as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) + : +Goal : Print run context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Rev : 21/02/2011 + : - Print new fields ParDaqVersion, ParMapsName +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Run context record" )); + msg (( MSG_OUT, "============================================================" )); +// msg (( MSG_OUT, "ParDaqVersion = %.4d", PtRec->ParDaqVersion )); +// msg (( MSG_OUT, "ParMapsName = %.4d", PtRec->ParMapsName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParMi26Nb = %.4d", PtRec->ParMi26Nb )); + msg (( MSG_OUT, "ParFrameNbPerAcq = %.4d", PtRec->ParFrameNbPerAcq )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParRunNo = %.4d", PtRec->ParRunNo )); + msg (( MSG_OUT, "ParTotEvNb = %.4d", PtRec->ParTotEvNb )); + msg (( MSG_OUT, "ParEvNbPerFile = %.4d", PtRec->ParEvNbPerFile )); + msg (( MSG_OUT, "ParDataTransferMode = %.4d", PtRec->ParDataTransferMode )); + msg (( MSG_OUT, "ParTrigMode = %.4d", PtRec->ParTrigMode )); + msg (( MSG_OUT, "ParSaveOnDisk = %.4d", PtRec->ParSaveOnDisk )); + msg (( MSG_OUT, "ParSendOnEth = %.4d", PtRec->ParSendOnEth )); + msg (( MSG_OUT, "ParSendOnEthPCent = %.4d", PtRec->ParSendOnEthPCent )); + msg (( MSG_OUT, "ParDestDir = %s" , PtRec->ParDestDir )); + msg (( MSG_OUT, "ParFileNamePrefix = %s" , PtRec->ParFileNamePrefix )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParJtagFileName = %s ", PtRec->ParJtagFileName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); +// msg (( MSG_OUT, "InfMi26FrameSzFromFlexRio = %.4d", PtRec->InfMi26FrameSzFromFlexRio )); + msg (( MSG_OUT, "InfZsFFrameRawBuffSz = %.4d", PtRec->InfZsFFrameRawBuffSz )); + msg (( MSG_OUT, "InfFrameBuffSz = %.4d", PtRec->InfFrameBuffSz )); + msg (( MSG_OUT, "InfConfFileName = %s" , PtRec->InfConfFileName )); + msg (( MSG_OUT, "InfDataFileName = %s" , PtRec->InfDataFileName )); + msg (( MSG_OUT, "InfSaveDataOnDiskRunning = %.4d", PtRec->InfSaveDataOnDiskRunning )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "CmdRun = %.4d", PtRec->CmdRun )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResFrameCnt = %.4d", PtRec->ResFrameCnt )); + msg (( MSG_OUT, "ResEventCnt = %.4d", PtRec->ResEventCnt )); + msg (( MSG_OUT, "ResDataRateMBytesPerSec = %.3f", PtRec->ResDataRateMBytesPerSec )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "PtZsFFrameRaw = %.8x", PtRec->PtZsFFrameRaw )); + msg (( MSG_OUT, "PtFrame = %.8x", PtRec->PtFrame )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunCont () + : +Goal : Print lib run context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunCont () { + + return ( EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) + : +Goal : Print board conf record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board conf record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "AsicName = %s", PtRec->AsicName )); + msg (( MSG_OUT, "AsicNb = %.4d", PtRec->AsicNb )); + msg (( MSG_OUT, "ReadoutMode = %.4d", PtRec->ReadoutMode )); + msg (( MSG_OUT, "DataClkFrequency = %2.f", PtRec->DataClkFrequency )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "DmaHostSz = %.4d", PtRec->DmaHostSz )); + msg (( MSG_OUT, "FrameNbPerAcq = %.4d", PtRec->FrameNbPerAcq )); + msg (( MSG_OUT, "EnableExtraChannel = %.4d", PtRec->EnableExtraChannel )); + msg (( MSG_OUT, "AcqNbPerTrig = %.4d", PtRec->AcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TriggerMode = %.4d", PtRec->TriggerMode )); + msg (( MSG_OUT, "TriggerDetectTimeWindow = %.4d", PtRec->TriggerDetectTimeWindow )); + msg (( MSG_OUT, "TriggerDetectOccurNb = %.4d", PtRec->TriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TimeStampRes = %.4d", PtRec->TimeStampRes )); + msg (( MSG_OUT, "EnableTimeStamping = %.4d", PtRec->EnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EnableTrigCnt = %.4d", PtRec->EnableTrigCnt )); + msg (( MSG_OUT, "TagEventsStoredByDUT = %.4d", PtRec->TagEventsStoredByDUT )); + msg (( MSG_OUT, "ReadTluTrigCntEachNTrig = %.4d", PtRec->ReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) + : +Goal : Print lib board conf record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) + : +Goal : Print board status record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board status record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "BoardPresent = %.4d", PtRec->BoardPresent )); + msg (( MSG_OUT, "FwLoaded = %.4d", PtRec->FwLoaded )); + msg (( MSG_OUT, "ConfDone = %.4d", PtRec->ConfDone )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "StatusCode = %.4d", PtRec->StatusCode )); + msg (( MSG_OUT, "StatusStr = %.4d", PtRec->StatusStr )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ErrorMsgList = %s", PtRec->ErrorMsgList )); + msg (( MSG_OUT, "LastErrorMsg = %s", PtRec->LastErrorMsg )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegDmaHostSz = %.4d", PtRec->RegDmaHostSz )); + msg (( MSG_OUT, "RegFrameNbPerAcq = %.4d", PtRec->RegFrameNbPerAcq )); + msg (( MSG_OUT, "RegEnableExtraChannel = %.4d", PtRec->RegEnableExtraChannel )); + msg (( MSG_OUT, "RegAcqNbPerTrig = %.4d", PtRec->RegAcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTriggerMode = %.4d", PtRec->RegTriggerMode )); + msg (( MSG_OUT, "RegTriggerDetectTimeWindow = %.4d", PtRec->RegTriggerDetectTimeWindow )); + msg (( MSG_OUT, "RegTriggerDetectOccurNb = %.4d", PtRec->RegTriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStampRes = %.4d", PtRec->RegTimeStampRes )); + msg (( MSG_OUT, "RegEnableTimeStamping = %.4d", PtRec->RegEnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegEnableTrigCnt = %.4d", PtRec->RegEnableTrigCnt )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTagEventsStoredByDUT = %.4d", PtRec->RegTagEventsStoredByDUT )); + msg (( MSG_OUT, "RegReadTluTrigCntEachNTrig = %.4d", PtRec->RegReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStamp = %.4d", PtRec->RegTimeStamp )); + msg (( MSG_OUT, "RegTrigCnt = %.4d", PtRec->RegTrigCnt )); + msg (( MSG_OUT, "RegTluTrigCnt = %.4d", PtRec->RegTluTrigCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) + : +Goal : Print lib board status record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) + : +Goal : Print acquisition emulation context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Acquistion emulation record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqCycleMs = %.4d", PtRec->ParAcqCycleMs )); + msg (( MSG_OUT, "ParEmuleDRamReadMs = %.4d", PtRec->ParEmuleDRamReadMs )); + msg (( MSG_OUT, "ParEmuleFunctNo = %.4d", PtRec->ParEmuleFunctNo )); + msg (( MSG_OUT, "InfEmuleFuncCmt = %s" , PtRec->InfEmuleFuncCmt )); + msg (( MSG_OUT, "ParRandomDataSz = %d" , PtRec->ParRandomDataSz )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParAHeader[0] , PtRec->ParAHeader[1] , PtRec->ParAHeader[2] , PtRec->ParAHeader[3] , PtRec->ParAHeader[4] , PtRec->ParAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParATrailer[0], PtRec->ParATrailer[1], PtRec->ParATrailer[2], PtRec->ParATrailer[3], PtRec->ParATrailer[4], PtRec->ParATrailer[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParTrigNbPerFrame = %.4d", PtRec->ParTrigNbPerFrame )); + msg (( MSG_OUT, "ParTrigOnOneFrameOverN = %.4d", PtRec->ParTrigOnOneFrameOverN )); + msg (( MSG_OUT, "ParTrigOnNConsecutiveFrames = %.4d", PtRec->ParTrigOnNConsecutiveFrames )); + msg (( MSG_OUT, "Trig [0]=%.4d [1]=%.4d [2]=%.4d [Last]=%.4d", PtRec->ParATrig[0], PtRec->ParATrig[1], PtRec->ParATrig[2], PtRec->ParATrig[3] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfDRamSzMb = %.4d", PtRec->InfDRamSzMb )); + msg (( MSG_OUT, "InfDRamSz = %.4d", PtRec->InfDRamSz )); + msg (( MSG_OUT, "InfDRamPtr = %.8x", PtRec->InfDRamPtr )); + msg (( MSG_OUT, "InfExtraChan = %.4d", PtRec->InfExtraChan )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqFunctRetCode = %.4d", PtRec->ResAcqFunctRetCode )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResEvCnt = %.4d", PtRec->ResEvCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmul () + : +Goal : Print lib acquisition emulation context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.AcqEmul = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) + : +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmul () { + + return ( EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheckRec ( EFRIO_TFrCheck* PtRec ) + : +Goal : Print frame check context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheckRec ( EFRIO__TFrCheck* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Frames check record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqNo = %.4d", PtRec->ParAcqNo )); + msg (( MSG_OUT, "ParFrNo = %.4d", PtRec->ParFrNo )); + msg (( MSG_OUT, "ParChkMode = %.4d", PtRec->ParChkMode )); + msg (( MSG_OUT, "ParFrPrintLevel = %.4d", PtRec->ParFrPrintLevel )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfMi26Nb = %.4d", PtRec->InfMi26Nb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResAHeader[0] , PtRec->ResAHeader[1] , PtRec->ResAHeader[2] , PtRec->ResAHeader[3] , PtRec->ResAHeader[4] , PtRec->ResAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResATrailer[0] , PtRec->ResATrailer[1] , PtRec->ResATrailer[2] , PtRec->ResATrailer[3] , PtRec->ResATrailer[4] , PtRec->ResATrailer[5] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResAFrameCnt[0] , PtRec->ResAFrameCnt[1] , PtRec->ResAFrameCnt[2] , PtRec->ResAFrameCnt[3] , PtRec->ResAFrameCnt[4] , PtRec->ResAFrameCnt[5] )); + msg (( MSG_OUT, "DL [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResADataLenght[0], PtRec->ResADataLenght[1], PtRec->ResADataLenght[2], PtRec->ResADataLenght[3], PtRec->ResADataLenght[4], PtRec->ResADataLenght[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResTrigNb = %.4d", PtRec->ResTrigNb )); + msg (( MSG_OUT, "TRG [0]=%.8d [1]=%.8d [3]=%.8d [Last]=%.8d", PtRec->ResATrig[0], PtRec->ResATrig[1], PtRec->ResATrig[2], PtRec->ResATrig[3] )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheck () + : +Goal : Print lib frame check context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.FrCheck = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheck () { + + return ( EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - > 0 -> print state list for each line + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 22/12/2010 +Rev : 30/12/2010 + : - Add handling of N Mimosa 26 + : +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + MI26__TStatesLine VStatesLine; + MI26__TState VState; + SInt16 ViMi26; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + char VStrState[255]; + char VStrLine[255]; + + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + + msg (( MSG_OUT, "===================================================================================" )); + msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); + msg (( MSG_OUT, "===================================================================================" )); + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + ViStatesLine = 0; + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Copy StatesLine field + + VStatesLine.W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VStatesLine.F.StateNb; + + sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf ); + + if ( (PrintLevel != 0) ) { + msg (( MSG_OUT, "%s", VStrLine )); + } + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + VState.W16 = VPtSrcW16[ViSrcW16]; + + sprintf ( VStrState, "[Col %4d - %1d pixel(s)] ", VState.F.ColAddr, VState.F.HitNb + 1 ); + // strcat ( VStrLine , VStrState ); + + if ( (PrintLevel != 0) ) { + msg (( MSG_OUT, "%s", VStrState )); + } + + ++ViSrcW16; + } + + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + ++ViStatesLine; + + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + } // End for ( ViMi26 ) + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - 1 -> Print AcqId & FrId + : - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + : - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + : - 4 -> Print trigger list + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 06/11/2010 +Rev : 21/02/2011 + : - Print new field DaqVersion + : 23/06/2013 + : - Print header, frame cnt, data sz, header of MAPS No 6 (debug time-stamping) +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTriggerRec* VPtTrig; + SInt16 ViTrig; + char VStrTrig[30]; + char VStrTs [30]; + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Trigger record follows the data record which has a VARIABLE size + + VPtTrig = (EFRIO__TTriggerRec*) ( (UInt8*) PtRec + PtRec->TrigRecOffset ); + + // ------------------------------------- + // Print TFrame fields + // ------------------------------------- + + if ( PrintLevel == 1 ) { + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, "AcqId = %.4d - FrameIdInAcq = %.4d - TrigNb = %.4d [D]", VPtHead->AcqId, VPtHead->FrameIdInAcq, VPtTrig->TrigNb )); + msg (( MSG_OUT, "Trigger line [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] & 0x3FF, VPtHead->AMapsTrigInfo[1] & 0x3FF, VPtHead->AMapsTrigInfo[2] & 0x3FF)); + msg (( MSG_OUT, "Trigger TS [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] >> 10, VPtHead->AMapsTrigInfo[1] >> 10, VPtHead->AMapsTrigInfo[2] >> 10)); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + + return (0); + } + + + msg (( MSG_OUT, "==============================================" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "Tag = %.8X [H]", PtRec->Tag )); +#endif + msg (( MSG_OUT, "DaqVersion = %.4d [D]", PtRec->DaqVersion )); + msg (( MSG_OUT, "TotSz = %.4d [D]", PtRec->TotSz )); + msg (( MSG_OUT, "TrigRecOffset = %.4d [D]", PtRec->TrigRecOffset )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "H.Tag = %.8X [H]", VPtHead->Tag )); +#endif + msg (( MSG_OUT, "H.AcqStatus = %.4d [D]", VPtHead->AcqStatus )); + msg (( MSG_OUT, "H.TrigStatus = %.4d [D]", VPtHead->TrigStatus )); + msg (( MSG_OUT, "H.AcqId = %.4d [D]", VPtHead->AcqId )); + msg (( MSG_OUT, "H.FrameIdInAcq = %.4d [D]", VPtHead->FrameIdInAcq )); + msg (( MSG_OUT, "H.MapsName = %.4d [D]", VPtHead->MapsName )); + msg (( MSG_OUT, "H.MapsNb = %.4d [D]", VPtHead->MapsNb )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.Header [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsHeader[0] , VPtHead->AMapsHeader[1] , VPtHead->AMapsHeader[2] , VPtHead->AMapsHeader[3] , VPtHead->AMapsHeader[4] , VPtHead->AMapsHeader[5], VPtHead->AMapsHeader[6], VPtHead->AMapsHeader[7] )); + msg (( MSG_OUT, "H.FrCnt [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsFrameCnt[0] , VPtHead->AMapsFrameCnt[1] , VPtHead->AMapsFrameCnt[2] , VPtHead->AMapsFrameCnt[3] , VPtHead->AMapsFrameCnt[4] , VPtHead->AMapsFrameCnt[5], VPtHead->AMapsFrameCnt[6], VPtHead->AMapsFrameCnt[7] )); + msg (( MSG_OUT, "H.DataSz [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsDataLength[0], VPtHead->AMapsDataLength[1], VPtHead->AMapsDataLength[2], VPtHead->AMapsDataLength[3], VPtHead->AMapsDataLength[4], VPtHead->AMapsDataLength[5], VPtHead->AMapsDataLength[6], VPtHead->AMapsDataLength[7] )); + msg (( MSG_OUT, "H.Trailer [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsTrailer[0] , VPtHead->AMapsTrailer[1] , VPtHead->AMapsTrailer[2] , VPtHead->AMapsTrailer[3] , VPtHead->AMapsTrailer[4] , VPtHead->AMapsTrailer[5], VPtHead->AMapsTrailer[6], VPtHead->AMapsTrailer[7] )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.TriggerNb = %.4d [D]", VPtHead->TriggerNb )); + // msg (( MSG_OUT, "H.TrigInfo [0]=%.8X [1]=%.8X [2]=%.8X ", VPtHead->AMapsTrigInfo[0], VPtHead->AMapsTrigInfo[1], VPtHead->AMapsTrigInfo[2] )); + msg (( MSG_OUT, "H.TrigInfo line [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] & 0x3FF, VPtHead->AMapsTrigInfo[1] & 0x3FF, VPtHead->AMapsTrigInfo[2] & 0x3FF)); + msg (( MSG_OUT, "H.TrigInfo TS [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] >> 10, VPtHead->AMapsTrigInfo[1] >> 10, VPtHead->AMapsTrigInfo[2] >> 10)); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "D.Tag = %.8X [H]", VPtData->Tag )); +#endif + msg (( MSG_OUT, "D.TotSz = %.4d [D]", VPtData->TotSz )); + msg (( MSG_OUT, "D.OneMapsSz = %.4d [D]", VPtData->OneMapsSz )); + + if ( PrintLevel == 3 ) { + EFRIO__FPrintFrameData ( PtRec, PrintLevel ); + } + + if ( PrintLevel < 4 ) { + msg (( MSG_OUT, "===================================================================================" )); + return (0); + } + + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "T.Tag = %X [H]", VPtTrig->Tag )); +#endif + msg (( MSG_OUT, "T.TotSz = %.4d [D]", VPtTrig->TotSz )); + msg (( MSG_OUT, "T.TrigNb = %.4d [D]", VPtTrig->TrigNb )); + msg (( MSG_OUT, "T.TrigType = %d [D]", VPtTrig->TrigType )); + + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameDataFsbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - > 0 -> print state list for each line + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 22/12/2010 +Rev : 30/12/2010 + : - Add handling of N Mimosa 26 + : +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ +#ifdef EFRIO_FSBB0 +SInt32 EFRIO__FPrintFrameDataFsbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + SInt16 ViFsbb0; + EFRIO__TFrameHeader* VPtHead; + + FSBB0__TZsFFrame VZsFFrame; + FSBB0__TMatDiscriBit VMatBit; + SInt32 VOvfCnt; + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + VPtHead = &PtRec->Header; + + memset ( &VZsFFrame, 0, sizeof (VZsFFrame) ); + memset ( &VMatBit , 0, sizeof (VMatBit) ); + + for ( ViFsbb0=0; ViFsbb0 < VPtHead->MapsNb ; ViFsbb0++ ) { + + msg (( MSG_OUT, "===================================================================================" )); + msg (( MSG_OUT, " Fsbb0 No %2d ", ViFsbb0 )); + msg (( MSG_OUT, "===================================================================================" )); + + EFRIO__FSBB0_FConvEfrioFrameToZsFFrame ( PtRec /* Src */, ViFsbb0 /* MapsId */, &VZsFFrame, 0 /* PrintLvl */ ); + + EFRIO__FSBB0_FConvZsFFrameToMatDiscriBit ( &VZsFFrame /* PtSrc */, &VMatBit /* PtDest */ , &VOvfCnt /* PtOvfCnt */, 0 /* PrintLvl */ ); + + EFRIO__FSBB0_FMatDiscriPrintHit ( "" /* CmtStrTitle */, ViFsbb0 /* CmtSInt8MapsId */, &VMatBit ); + } // End for ( ViFsbb0 ) + return (0); + +} /* end EFRIO__FPrintFrameDataFsbb0 */ +#endif + + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameRecFSbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - 1 -> Print AcqId & FrId + : - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + : - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + : - 4 -> Print trigger list + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : copy of function SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) from GC + : +Level : +Date : 09/10/2014 +Rev : +Doc date : 09/10/2014 +Author : Matthieu SPecht +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ +#ifdef EFRIO_FSBB0 + +SInt32 EFRIO__FPrintFrameRecFsbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTriggerRec* VPtTrig; + SInt16 ViTrig; + char VStrTrig[30]; + char VStrTs [30]; + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Trigger record follows the data record which has a VARIABLE size + + VPtTrig = (EFRIO__TTriggerRec*) ( (UInt8*) PtRec + PtRec->TrigRecOffset ); + + // ------------------------------------- + // Print TFrame fields + // ------------------------------------- + + if ( PrintLevel == 1 ) { + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, "AcqId = %.4d - FrameIdInAcq = %.4d - TrigNb = %.4d [D]", VPtHead->AcqId, VPtHead->FrameIdInAcq, VPtTrig->TrigNb )); + msg (( MSG_OUT, "Trigger line [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] & 0x3FF, VPtHead->AMapsTrigInfo[1] & 0x3FF, VPtHead->AMapsTrigInfo[2] & 0x3FF)); + msg (( MSG_OUT, "Trigger TS [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] >> 10, VPtHead->AMapsTrigInfo[1] >> 10, VPtHead->AMapsTrigInfo[2] >> 10)); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + + return (0); + } + + + msg (( MSG_OUT, "==============================================" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "Tag = %.8X [H]", PtRec->Tag )); +#endif + msg (( MSG_OUT, "DaqVersion = %.4d [D]", PtRec->DaqVersion )); + msg (( MSG_OUT, "TotSz = %.4d [D]", PtRec->TotSz )); + msg (( MSG_OUT, "TrigRecOffset = %.4d [D]", PtRec->TrigRecOffset )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "H.Tag = %.8X [H]", VPtHead->Tag )); +#endif + msg (( MSG_OUT, "H.AcqStatus = %.4d [D]", VPtHead->AcqStatus )); + msg (( MSG_OUT, "H.TrigStatus = %.4d [D]", VPtHead->TrigStatus )); + msg (( MSG_OUT, "H.AcqId = %.4d [D]", VPtHead->AcqId )); + msg (( MSG_OUT, "H.FrameIdInAcq = %.4d [D]", VPtHead->FrameIdInAcq )); + msg (( MSG_OUT, "H.MapsName = %.4d [D]", VPtHead->MapsName )); + msg (( MSG_OUT, "H.MapsNb = %.4d [D]", VPtHead->MapsNb )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.Header [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsHeader[0] , VPtHead->AMapsHeader[1] , VPtHead->AMapsHeader[2] , VPtHead->AMapsHeader[3] , VPtHead->AMapsHeader[4] , VPtHead->AMapsHeader[5], VPtHead->AMapsHeader[6], VPtHead->AMapsHeader[7] )); + msg (( MSG_OUT, "H.FrCnt [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsFrameCnt[0] , VPtHead->AMapsFrameCnt[1] , VPtHead->AMapsFrameCnt[2] , VPtHead->AMapsFrameCnt[3] , VPtHead->AMapsFrameCnt[4] , VPtHead->AMapsFrameCnt[5], VPtHead->AMapsFrameCnt[6], VPtHead->AMapsFrameCnt[7] )); + msg (( MSG_OUT, "H.DataSz [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsDataLength[0], VPtHead->AMapsDataLength[1], VPtHead->AMapsDataLength[2], VPtHead->AMapsDataLength[3], VPtHead->AMapsDataLength[4], VPtHead->AMapsDataLength[5], VPtHead->AMapsDataLength[6], VPtHead->AMapsDataLength[7] )); + msg (( MSG_OUT, "H.Trailer [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsTrailer[0] , VPtHead->AMapsTrailer[1] , VPtHead->AMapsTrailer[2] , VPtHead->AMapsTrailer[3] , VPtHead->AMapsTrailer[4] , VPtHead->AMapsTrailer[5], VPtHead->AMapsTrailer[6], VPtHead->AMapsTrailer[7] )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.TriggerNb = %.4d [D]", VPtHead->TriggerNb )); + // msg (( MSG_OUT, "H.TrigInfo [0]=%.8X [1]=%.8X [2]=%.8X ", VPtHead->AMapsTrigInfo[0], VPtHead->AMapsTrigInfo[1], VPtHead->AMapsTrigInfo[2] )); + msg (( MSG_OUT, "H.TrigInfo line [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] & 0x3FF, VPtHead->AMapsTrigInfo[1] & 0x3FF, VPtHead->AMapsTrigInfo[2] & 0x3FF)); + msg (( MSG_OUT, "H.TrigInfo TS [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] >> 10, VPtHead->AMapsTrigInfo[1] >> 10, VPtHead->AMapsTrigInfo[2] >> 10)); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "D.Tag = %.8X [H]", VPtData->Tag )); +#endif + msg (( MSG_OUT, "D.TotSz = %.4d [D]", VPtData->TotSz )); + msg (( MSG_OUT, "D.OneMapsSz = %.4d [D]", VPtData->OneMapsSz )); + + if ( PrintLevel == 3 ) { + EFRIO__FPrintFrameDataFsbb0 ( PtRec, PrintLevel ); + } + + if ( PrintLevel < 4 ) { + msg (( MSG_OUT, "===================================================================================" )); + return (0); + } + + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "T.Tag = %X [H]", VPtTrig->Tag )); +#endif + msg (( MSG_OUT, "T.TotSz = %.4d [D]", VPtTrig->TotSz )); + msg (( MSG_OUT, "T.TrigNb = %.4d [D]", VPtTrig->TrigNb )); + msg (( MSG_OUT, "T.TrigType = %d [D]", VPtTrig->TrigType )); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "" )); + +} +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) + : +Goal : Print monitor context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Monitor context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "InfFrameNbToSend = %.4d", PtRec->InfFrameNbToSend )); + msg (( MSG_OUT, "InfSzToSend = %.4d", PtRec->InfSzToSend )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonCont () + : +Goal : Print lib monitor context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMoniCont () { + + return ( EFRIO__FPrintMonContRec (&EFRIO__VGContext.MonCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintTestOnDataContRec ( EFRIO__TTestOnDataCont* PtRec, char* Msg ) +: +Goal : Print monitor context record in log file +: +Inputs : PtRec - Pointer on the record +: +Ouputs : The function returns +: 0 if ok +: -1 if PtRec = NULL +: +Globals : +: +Remark : +: +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintTestOnDataContRec ( EFRIO__TTestOnDataCont* PtRec, char* Msg ) { + + SInt8 ViMaps; + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Test on data context record => Print only relevant fields !" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "Message : %s", Msg )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParModeEnable = %d", PtRec->ParModeEnable )); + msg (( MSG_OUT, "ParResetCnt = %d", PtRec->ParResetCnt )); + msg (( MSG_OUT, "ParPrintLvl = %d", PtRec->ParResetCnt )); + msg (( MSG_OUT, "ParMapsNb = %d", PtRec->ParMapsNb )); + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ParAMapsHeaderRef[%d] = %.8x", ViMaps, PtRec->ParAMapsHeaderRef[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ParAMapsTrailerRef[%d] = %8x", ViMaps, PtRec->ParAMapsTrailerRef[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsErrCnt[ViMaps] )); + } + + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsHeaderErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsHeaderErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsFrameCntErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsFrameCntErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsDataLengthErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsDataLengthErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsTrailerErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsTrailerErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsMatrixErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsMatrixErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + + msg (( MSG_OUT, "ResTotErrCnt = %.4d", PtRec->ResTotErrCnt )); + msg (( MSG_OUT, "ResFrameNbWithErr = %.4d", PtRec->ResFrameNbWithErr )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintTestOnDataCont ( char* Msg ) +: +Goal : Print lib monitor context record in log file +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible +: +Globals : +: +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) +: +Level : +Date : 29/04/2011 +Doc date : 29/04/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintTestOnDataCont ( char* Msg ) { + + return ( EFRIO__FPrintTestOnDataContRec (&EFRIO__VGContext.TestOnDataCont, Msg) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMsg ( + : SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, + : SInt8 PrintAsError, char* Msg ) + : +Goal : Print messages in msg or error log file from LabView -> A Vi encapsulets this function. + : +Inputs : DummyS32In - Dummy value used under Labview to easily " chain " function execution. + : + : To execute it after a Vi call, connect any output of this Vi to the + : DummyS32In pin and it will be automatically called after Vi end. + : To execute it before a Vi call, if this Vi has an integer parameter + : cut the wire and insert DummyS32In input and function output on it. + : + : Printing mode flags + : + : PrintAsMsg - If 1 -> Print in messages log file + : PrintAsTrace - If 1 -> Print in errors log file as a trace message + : PrintAsWarning - If 1 -> Print in errors log file as a warning message + : PrintAsError - If 1 -> Print in errors log file as an error message + : + : Msg - Message to print ( string ) + : +Ouputs : The function always returns the input parameter DummyS32In. + : +Globals : + : +Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) + : It can be used to insert this function call on an integer datapath under LabView + : + : If more than one printing mode flag is enabled therefore the same message will + : be printed in different ways. + : +Level : +Date : 09/08/2010 +Rev : 25/10/2010 + : - Implementation -> Empty function before +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", Msg )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", Msg )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", Msg )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", Msg )); + + return (DummyS32In); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMsg ( +: SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, +: SInt8 PrintAsError, char* Msg ) +: +Goal : Print messages in msg or error log file from LabView -> A Vi encapsulets this function. +: +Inputs : DummyS32In - Dummy value used under Labview to easily " chain " function execution. +: +: To execute it after a Vi call, connect any output of this Vi to the +: DummyS32In pin and it will be automatically called after Vi end. +: To execute it before a Vi call, if this Vi has an integer parameter +: cut the wire and insert DummyS32In input and function output on it. +: +: Printing mode flags +: +: PrintAsMsg - If 1 -> Print in messages log file +: PrintAsTrace - If 1 -> Print in errors log file as a trace message +: PrintAsWarning - If 1 -> Print in errors log file as a warning message +: PrintAsError - If 1 -> Print in errors log file as an error message +: +: Msg - Message to print ( string ) +: +Ouputs : The function always returns the input parameter DummyS32In. +: +Globals : +: +Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) +: It can be used to insert this function call on an integer datapath under LabView +: +: If more than one printing mode flag is enabled therefore the same message will +: be printed in different ways. +: +Level : +Date : 24/04/2013 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef CC_UNIX + +SInt32 EFRIO__FPrintMsgWithTimeStamp ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + TDateTime VDateTime; + char VStrMsgDateTime[GLB_CMT_SZ]; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + unsigned short VHour; + unsigned short VMin; + unsigned short VSec; + unsigned short VMSec; + + + VDateTime = VDateTime.CurrentDateTime(); + + VDateTime.DecodeDate ( &VYear, &VMonth, &VDay ); + VDateTime.DecodeTime ( &VHour, &VMin, &VSec, &VMSec ); + + + sprintf ( VStrMsgDateTime, "%.2d/%.2d/%.2d - %.2d:%.2d:%.2d|%.2d : %s", VDay, VMonth, VYear, VHour, VMin, VSec, VMSec, Msg ); + + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", VStrMsgDateTime )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", VStrMsgDateTime )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", VStrMsgDateTime )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", VStrMsgDateTime )); + + return (DummyS32In); +} + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_print.h b/include/pxi_daq_lib_v.2.1/eudet_frio_print.h new file mode 100755 index 0000000..c12fe47 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_print.h @@ -0,0 +1,59 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.h +Goal : Functions prototypes of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_PRINT_H + +#include "func_header.def" + + +// 06/11/2010 -> 11 + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintRunCont ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintAcqEmul ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintFrCheckRec ( EFRIO__TFrCheck* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintFrCheck ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintFrameRecFsbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintMonCont ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FPrintMsgWithTimeStamp ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg );) + + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_PRINT_H + #define EUDET_FRIO_PRINT_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_set.c b/include/pxi_daq_lib_v.2.1/eudet_frio_set.c new file mode 100755 index 0000000..e2635a9 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_set.c @@ -0,0 +1,449 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_SET_C +#define EUDET_FRIO_SET_C + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Set board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/08/2010 +Doc date : 09/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSetBoardConf ( SInt32 BoardId, EFRIO__TBoardConf* PtSrc ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( PtSrc, (ERR_OUT,"Abort : PtSrc == NULL") ); + + EFRIO__VGContext.ABoardsConf[BoardId] = *PtSrc; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Set board conf fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/08/2010 +Doc date : 10/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfBoardId ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].BoardId = BoardId; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfAsicName ( SInt32 BoardId, char* AsicName ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + snprintf ( EFRIO__VGContext.ABoardsConf[BoardId].AsicName, GLB_CMT_SZ - 1, "%s", AsicName ); + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfAsicNb ( SInt32 BoardId, SInt32 AsicNb ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].AsicNb = AsicNb; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfReadoutMode ( SInt32 BoardId, SInt32 ReadoutMode ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].ReadoutMode = ReadoutMode; + + err_retok (( ERR_OUT, "" )); +} + +// 11/08/2010 + +SInt32 EFRIO__FSetBoardConfEmuleChannels ( SInt32 BoardId, SInt8 EmuleChannels ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].EmuleChannels = EmuleChannels; + + err_retok (( ERR_OUT, "" )); +} + + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfDataClkFrequency ( SInt32 BoardId, float DataClkFrequency ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].DataClkFrequency = DataClkFrequency; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfDmaHostSz ( SInt32 BoardId, UInt32 DmaHostSz ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].DmaHostSz = DmaHostSz; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfFrameNbPerAcq ( SInt32 BoardId, SInt32 FrameNbPerAcq ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].FrameNbPerAcq = FrameNbPerAcq; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfEnableExtraChannel ( SInt32 BoardId, SInt8 EnableExtraChannel ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].EnableExtraChannel = EnableExtraChannel; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfAcqNbPerTrig ( SInt32 BoardId, SInt32 AcqNbPerTrig ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].AcqNbPerTrig = AcqNbPerTrig; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTriggerMode ( SInt32 BoardId, SInt8 TriggerMode ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TriggerMode = TriggerMode; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTriggerDetectTimeWindow ( SInt32 BoardId, UInt32 TriggerDetectTimeWindow ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TriggerDetectTimeWindow = TriggerDetectTimeWindow; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTriggerDetectOccurNb ( SInt32 BoardId, UInt32 TriggerDetectOccurNb ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TriggerDetectOccurNb = TriggerDetectOccurNb; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTimeStampRes ( SInt32 BoardId, UInt32 TimeStampRes ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TimeStampRes = TimeStampRes; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfEnableTimeStamping ( SInt32 BoardId, SInt8 EnableTimeStamping ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].EnableTimeStamping = EnableTimeStamping; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfEnableTrigCnt ( SInt32 BoardId, SInt8 EnableTrigCnt ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].EnableTrigCnt = EnableTrigCnt; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfTagEventsStoredByDUT ( SInt32 BoardId, SInt8 TagEventsStoredByDUT ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].TagEventsStoredByDUT = TagEventsStoredByDUT; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardConfReadTluTrigCntEachNTrig ( SInt32 BoardId, UInt32 ReadTluTrigCntEachNTrig ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsConf[BoardId].ReadTluTrigCntEachNTrig = ReadTluTrigCntEachNTrig; + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : Set board status fields +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/08/2010 +Doc date : 10/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusBoardId ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].BoardId = BoardId; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusBoardPresent ( SInt32 BoardId, SInt8 BoardPresent ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].BoardPresent = BoardPresent; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusFwLoaded ( SInt32 BoardId, SInt8 FwLoaded ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].FwLoaded = FwLoaded; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusConfDone ( SInt32 BoardId, SInt8 ConfDone ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].ConfDone = ConfDone; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusStatusCode ( SInt32 BoardId, SInt32 StatusCode ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + EFRIO__VGContext.ABoardsStatus[BoardId].StatusCode = StatusCode; + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusStatusStr ( SInt32 BoardId, char* StatusStr ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( StatusStr, (ERR_OUT,"Abort : StatusStr == NULL") ); + + snprintf ( EFRIO__VGContext.ABoardsStatus[BoardId].StatusStr, GLB_CMT_SZ - 1, "%s", StatusStr ); + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusErrorMsgList ( SInt32 BoardId, char* ErrorMsg, SInt32 Index ) { + + SInt32 VMsgLen; + EFRIO__TBoardStatus* VPtStatus; + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( ErrorMsg, (ERR_OUT,"Abort : ErrorMsg == NULL") ); + + VPtStatus = &EFRIO__VGContext.ABoardsStatus[BoardId]; + + // Check index limits + + if ( (Index < 0) || (Index >= EFRIO__ERROR_MSG_LIST_MAX_NB ) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Index=%d out of range [0..%d]", Index, EFRIO__ERROR_MSG_LIST_MAX_NB-1 ) ); + } + + // Get message length + + VMsgLen = strlen ( ErrorMsg ); + + // Free item if already allocated + + if ( VPtStatus->ErrorMsgList[Index] != NULL ) { + free ( VPtStatus->ErrorMsgList[Index] ); + } + + // Allocate memory for message + + VPtStatus->ErrorMsgList[Index] = (char*) malloc ( VMsgLen + 1 ); + + err_retnull ( VPtStatus->ErrorMsgList[Index], (ERR_OUT,"Abort : Allocation of message [%d] failed !", Index) ); + + // Copy message + + snprintf ( VPtStatus->ErrorMsgList[Index], VMsgLen, "%s", ErrorMsg ); + + err_retok (( ERR_OUT, "" )); +} + +// 10/08/2010 + +SInt32 EFRIO__FSetBoardStatusLastErrorMsg ( SInt32 BoardId, char* LastErrorMsg ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + err_retnull ( LastErrorMsg, (ERR_OUT,"Abort : LastErrorMsg == NULL") ); + + snprintf ( EFRIO__VGContext.ABoardsStatus[BoardId].LastErrorMsg, GLB_CMT_SZ - 1, "%s", LastErrorMsg ); + + err_retok (( ERR_OUT, "" )); +} + +// 21/12/2010 + +SInt32 EFRIO__FSetCmdRun ( SInt32 Cmd ) { + + if ( Cmd == 0 ) { + if ( EFRIO__VGContext.RunCont.CmdRun == 1 ) { + EFRIO__VGContext.RunCont.CmdRun = 0; + } + } + + else { + EFRIO__VGContext.RunCont.CmdRun = Cmd; + } + + return (0); +} + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_set.h b/include/pxi_daq_lib_v.2.1/eudet_frio_set.h new file mode 100755 index 0000000..a240f04 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_set.h @@ -0,0 +1,69 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.h +Goal : Functions prototypes of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_SET_H + +#include "func_header.def" + + +// 06/11/2010 -> 27 + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConf ( SInt32 BoardId, EFRIO__TBoardConf* PtSrc );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfBoardId ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfAsicName ( SInt32 BoardId, char* AsicName );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfAsicNb ( SInt32 BoardId, SInt32 AsicNb );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfReadoutMode ( SInt32 BoardId, SInt32 ReadoutMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfEmuleChannels ( SInt32 BoardId, SInt8 EmuleChannels );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfDataClkFrequency ( SInt32 BoardId, float DataClkFrequency );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfDmaHostSz ( SInt32 BoardId, UInt32 DmaHostSz );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfFrameNbPerAcq ( SInt32 BoardId, SInt32 FrameNbPerAcq );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfEnableExtraChannel ( SInt32 BoardId, SInt8 EnableExtraChannel );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfAcqNbPerTrig ( SInt32 BoardId, SInt32 AcqNbPerTrig );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTriggerMode ( SInt32 BoardId, SInt8 TriggerMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTriggerDetectTimeWindow ( SInt32 BoardId, UInt32 TriggerDetectTimeWindow );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTriggerDetectOccurNb ( SInt32 BoardId, UInt32 TriggerDetectOccurNb );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTimeStampRes ( SInt32 BoardId, UInt32 TimeStampRes );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfEnableTimeStamping ( SInt32 BoardId, SInt8 EnableTimeStamping );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfEnableTrigCnt ( SInt32 BoardId, SInt8 EnableTrigCnt );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfTagEventsStoredByDUT ( SInt32 BoardId, SInt8 TagEventsStoredByDUT );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardConfReadTluTrigCntEachNTrig ( SInt32 BoardId, UInt32 ReadTluTrigCntEachNTrig );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusBoardId ( SInt32 BoardId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusBoardPresent ( SInt32 BoardId, SInt8 BoardPresent );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusFwLoaded ( SInt32 BoardId, SInt8 FwLoaded );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusConfDone ( SInt32 BoardId, SInt8 ConfDone );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusStatusCode ( SInt32 BoardId, SInt32 StatusCode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusStatusStr ( SInt32 BoardId, char* StatusStr );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusErrorMsgList ( SInt32 BoardId, char* ErrorMsg, SInt32 Index );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetBoardStatusLastErrorMsg ( SInt32 BoardId, char* LastErrorMsg );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__FSetCmdRun ( SInt32 Cmd );) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_SET_H + #define EUDET_FRIO_SET_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_ult1.c b/include/pxi_daq_lib_v.2.1/eudet_frio_ult1.c new file mode 100755 index 0000000..74845ef --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_ult1.c @@ -0,0 +1,9046 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_ult1.c +Goal : Ultimate 1 functions of flex rio board library for EUDET +Prj date : 11/05/2011 +File date : 11/05/2011 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_ULT1_C +#define EUDET_FRIO_ULT1_C + + +// #define EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + +/* +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 +*/ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 19/05/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FTestOnDataGetJtagRef () { + + SInt32 VRet; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + HRESULT VRetCode; + WideString VStatus; + + #ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; + #endif + + char* VJtagFileName; + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + SInt32 ViRegLinePat; + + + SInt8 ViMaps; + + + #ifdef EFRIO__INCLUDE_JTAG + + // + + // ParJtagFileName + + // ParAMatPatternLineNb + + VJtagFileName = FIL_FExtractFileNameFromFilePath (VPtRunCont->ParJtagFileName); + + msg (( MSG_OUT, "JTAG file name = %s", VJtagFileName )); + + while (1) { + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpa.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpb.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpc.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpd.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpe.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + // Default + + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + + } + + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + // -------------------------------------- + // Sel Mi28 + // -------------------------------------- + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( ViMaps, &VStrComStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Select Maps Id = %d failed !", ViMaps) ); + } + + // -------------------------------------- + // Read Header & Trailer from JTAG conf + // -------------------------------------- + + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 0 /* RegId */, &VHighTrailerFromJtag, &VRegValFromMi26, &VStrComStatus) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 1 /* RegId */, &VLowTrailerFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 2 /* RegId */, &VHighHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 3 /* RegId */, &VLowHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + + VPtTestCont->ParAMapsHeaderRef[ViMaps] = VLowHeaderFromJtag + (VHighHeaderFromJtag << 16); // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = VLowTrailerFromJtag + (VHighTrailerFromJtag << 16); // Mimosa 26 trailer field + + // -------------------------------------- + // Build reference matrix from JTAG conf + // -------------------------------------- + + for ( ViRegLinePat=0; ViRegLinePat < ULT1__REG_DISCRI_W32_SZ; ViRegLinePat++ ) { + OleCheck( VJtag.Mimosa28ConfGetLinePat0 ( (long) ViRegLinePat, (unsigned long*) &VPtTestCont->ParUlt1ALinePat0[ViMaps].AW32[ViRegLinePat], (unsigned long*) &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VJtag.Mimosa28ConfGetLinePat1 ( (long) ViRegLinePat, (unsigned long*) &VPtTestCont->ParUlt1ALinePat1[ViMaps].AW32[ViRegLinePat], (unsigned long*) &VRegValFromMi26, &VStrComStatus ) ); + } + + ULT1__FBuildMatDiscriW32FromLinePatReg ( &VPtTestCont->ParUlt1ALinePat0[ViMaps], &VPtTestCont->ParUlt1ALinePat1[ViMaps], &VPtTestCont->InfUlt1TmpMatW32 ); + ULT1__FMatDiscriConvW32ToBit ( &VPtTestCont->InfUlt1TmpMatW32, &VPtTestCont->InfUlt1AMatBitFromJtag[ViMaps] ); + + ULT1__FMatDiscriPrintHit ( "Emulated matrix from JTAG" /* CmtStrTitle */, ViMaps /* CmtSInt8MapsId */, &VPtTestCont->InfUlt1AMatBitFromJtag[ViMaps] ); + + } // End for + + } + + else { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + VPtTestCont->ParAMapsHeaderRef[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = 0; // Mimosa 26 trailer field + } + + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + + CoUninitialize(); + + #else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + #endif + + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 19/05/2011 ( DPXI version of 20/08/2009 moved here ) +Rev : 15/05/2013 + : - Modification of frame counter test, the test Fr(n+1) = Fr(n) + 1 has been + : removed because in beam test (EUDET3 mode) the frames in one acquisition are + : not all consecutives, there it detects fake errors. Now the test is only done + : by a comparison of all Mimosa 28 frame couters frame by frame. + : + : 25/04/2013 + : - Update test context field ResErrOnCurrentAcq with errors count + : + : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameLight ( SInt16 FuncId, SInt32 CurFrame, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // err_error (( ERR_OUT, "TRACE : ParMapsNbToTest=%d - Mi26Nb=%d - VMi26Nb=%d", VPtTestCont->ParMapsNbToTest, Mi26Nb, VMi26Nb )); + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the one of Mimosa28 [0] + // This is done frame by frame = doesn't care about previous frame counter value - 15/05/2013 + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Frame cnt error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Header error %s - %s : [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Trailer error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 31/01/14 Bug fix : Error status stored in ResErrOnCurrentAcq flag was cleared if one of the following MAPS has no error + // The above line shows the code with bug + // VPtTestCont->ResErrOnCurrentAcq = VErrors; // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + return (VErrors); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 23/01/2014 ( DPXI version of 20/08/2009 moved here ) +: +Rev : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( SInt16 FuncId, EFRIO__TFrame* PtFrame, SInt16 CurFrame, SInt8 Mi26Nb, UInt32 FrameCntOfFirstFrameOfAcq ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // err_error (( ERR_OUT, "TRACE : ParMapsNbToTest=%d - Mi26Nb=%d - VMi26Nb=%d", VPtTestCont->ParMapsNbToTest, Mi26Nb, VMi26Nb )); + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + // VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + VPtTestCont->InfMapsFrameCntRef = FrameCntOfFirstFrameOfAcq + CurFrame; // 23/01/2014 + + // err_error (( ERR_OUT, "TRACE => FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + +// if ( VPtTestCont->ParPrintLvl == 2 ) { +// msg (( MSG_OUT, "FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); +// } + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the frame counter (Mi28[0]) of first frame of acq + frame no + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Frame cnt error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Header error %s - %s : [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Trailer error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + + // Print headers values + + if ( (VPtTestCont->ParPrintLvl == 3) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Header [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + + // Print fames counter values + + if ( (VPtTestCont->ParPrintLvl == 4) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + msg (( MSG_OUT, "Frame cnt [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + + // Print trailers values + + if ( (VPtTestCont->ParPrintLvl == 5) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Trailer [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 31/01/14 Bug fix : Error status stored in ResErrOnCurrentAcq flag was cleared if one of the following MAPS has no error + // The above line shows the code with bug + // VPtTestCont->ResErrOnCurrentAcq = VErrors; // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + return (VErrors); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 24/01/2014 ( DPXI version of 20/08/2009 moved here ) +: +Rev : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( SInt16 FuncId, EFRIO__TFrame* PtFrame, SInt16 CurFrame, SInt8 Mi26Nb, UInt32 FrameCntOfFirstFrameOfAcq ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + SInt32 VErrNbOnMatrix; + + ULT1__TZsFFrame* VUlt1APtZsFFRame[EFRIO__MAX_ASIC_NB]; + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + + // msg (( MSG_OUT, "SIZE : ULT1__TZsFFrame=%d - ResUlt1AZsFFrame=%d", sizeof(ULT1__TZsFFrame), sizeof(VPtTestCont->ResUlt1AZsFFrame) )); + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // err_error (( ERR_OUT, "TRACE : ParMapsNbToTest=%d - Mi26Nb=%d - VMi26Nb=%d", VPtTestCont->ParMapsNbToTest, Mi26Nb, VMi26Nb )); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VUlt1APtZsFFRame[ViMi26] = &VPtTestCont->ResUlt1AZsFFrame[ViMi26]; + } + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + // VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + VPtTestCont->InfMapsFrameCntRef = FrameCntOfFirstFrameOfAcq + CurFrame; // 23/01/2014 + + // err_error (( ERR_OUT, "TRACE => FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the frame counter (Mi28[0]) of first frame of acq + frame no + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Frame cnt error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Header error %s - %s : [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Trailer error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + + // Print headers values + + if ( (VPtTestCont->ParPrintLvl == 3) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Header [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + + // Print fames counter values + + if ( (VPtTestCont->ParPrintLvl == 4) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + msg (( MSG_OUT, "Frame cnt [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + + // Print trailers values + + if ( (VPtTestCont->ParPrintLvl == 5) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Trailer [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } // End for ViMi26 + + + // Matrix - $$$$ + + EFRIO__ULT1_FConvTFrameToZsFFrame ( PtFrame, VUlt1APtZsFFRame, 8 /* Mi28DestBuffersNb */, 0 /* PrintLevel */ ); + + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + ULT1__FConvZsFFrameToMatDiscriBit ( VUlt1APtZsFFRame[ViMi26], &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26], NULL /* PtOvfCnt */, 0 /* PrintLvl */ ); + + VErrNbOnMatrix = ULT1__FCompareMatDiscriBit ( VPtTestCont->ParAMatPatternLineNb[ViMi26] /* LineNbToCompare */, &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26] /* PtMat */, &VPtTestCont->InfUlt1AMatBitFromJtag[ViMi26] /* PtMatRef */, VPtTestCont->ParPrintLvl, ViMi26 /* PrintMimosaId */, PtFrame->Header.AcqId /* PrintAcqId */, PtFrame->Header.FrameIdInAcq /* PrintFrameId */ ); + + if ( VErrNbOnMatrix != 0 ) { + VPtTestCont->ResAMapsMatrixErrCnt[ViMi26] += VErrNbOnMatrix; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; // Count ONLY one error if error(s) on matrix in order to avoid cumul counters ovf + ++VPtTestCont->ResTotErrCnt; // Count ONLY one error if error(s) on matrix in order to avoid cumul counters ovf + VErrors = 1; + } + + if ( VPtTestCont->ParPrintLvl == 7) { + // 09/10/14 - MS : removed this function because it is not compatible with the ULT1 lib + //ULT1__FMatDiscriPrintHit ( "Matrix from DAQ ", ViMi26 /* CmtSInt8MapsId */, &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26] ); + } + + + } // End for ViMi26 + + + + +// if ( 1 /* CurFrame % 10 == 0 */ ) { +// EFRIO__ULT1_FConvTFrameToZsFFrame ( PtFrame, VUlt1APtZsFFRame, 8 /* Mi28DestBuffersNb */, 0 /* PrintLevel */ ); +// ULT1__FConvZsFFrameToMatDiscriBit ( VUlt1APtZsFFRame[0], &VPtTestCont->ResUlt1AMatBitFromDaq[0], NULL /* PtOvfCnt */, 0 /* PrintLvl */ ); +// ULT1__FMatDiscriPrintHit ( "Matrix from DAQ ", 0 /* CmtSInt8MapsId */, &VPtTestCont->ResUlt1AMatBitFromDaq[0] ); +// } + + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 31/01/14 Bug fix : Error status stored in ResErrOnCurrentAcq flag was cleared if one of the following MAPS has no error + // The above line shows the code with bug + // VPtTestCont->ResErrOnCurrentAcq = VErrors; // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + return (VErrors); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 30/01/2014 ( DPXI version of 20/08/2009 moved here ) + : +Rev : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( SInt16 FuncId, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + SInt32 VErrNbOnMatrix; + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + ULT1__TZsFFrame* VUlt1APtZsFFRame[EFRIO__MAX_ASIC_NB]; + + + + + // msg (( MSG_OUT, "SIZE : ULT1__TZsFFrame=%d - ResUlt1AZsFFrame=%d", sizeof(ULT1__TZsFFrame), sizeof(VPtTestCont->ResUlt1AZsFFrame) )); + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // err_error (( ERR_OUT, "TRACE : ParMapsNbToTest=%d - Mi26Nb=%d - VMi26Nb=%d", VPtTestCont->ParMapsNbToTest, Mi26Nb, VMi26Nb )); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VUlt1APtZsFFRame[ViMi26] = &VPtTestCont->ResUlt1AZsFFrame[ViMi26]; + } + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + // err_error (( ERR_OUT, "TRACE => FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the frame counter (Mi28[0]) of first frame of acq + frame no + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Frame cnt error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Header error %s - %s : [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Trailer error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + + // Print headers values + + if ( (VPtTestCont->ParPrintLvl == 3) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Header [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + + // Print fames counter values + + if ( (VPtTestCont->ParPrintLvl == 4) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Frame cnt [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + + // Print trailers values + + if ( (VPtTestCont->ParPrintLvl == 5) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Trailer [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } // End for ViMi26 + + + // Matrix - $$$$ + + EFRIO__ULT1_FConvTFrameToZsFFrame ( PtFrame, VUlt1APtZsFFRame, 8 /* Mi28DestBuffersNb */, 0 /* PrintLevel */ ); + + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + ULT1__FConvZsFFrameToMatDiscriBit ( VUlt1APtZsFFRame[ViMi26], &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26], NULL /* PtOvfCnt */, 0 /* PrintLvl */ ); + + VErrNbOnMatrix = ULT1__FCompareMatDiscriBit ( VPtTestCont->ParAMatPatternLineNb[ViMi26] /* LineNbToCompare */, &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26] /* PtMat */, &VPtTestCont->InfUlt1AMatBitFromJtag[ViMi26] /* PtMatRef */, VPtTestCont->ParPrintLvl, ViMi26 /* PrintMimosaId */, PtFrame->Header.AcqId /* PrintAcqId */, PtFrame->Header.FrameIdInAcq /* PrintFrameId */ ); + + if ( VErrNbOnMatrix != 0 ) { + VPtTestCont->ResAMapsMatrixErrCnt[ViMi26] += VErrNbOnMatrix; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; // Count ONLY one error if error(s) on matrix in order to avoid cumul counters ovf + ++VPtTestCont->ResTotErrCnt; // Count ONLY one error if error(s) on matrix in order to avoid cumul counters ovf + VErrors = 1; + } + + if ( VPtTestCont->ParPrintLvl == 7) { + // 09/10/14 - MS removed this function because it is not compatible with the function of the ULT1 lib + //ULT1__FMatDiscriPrintHit ( "Matrix from DAQ ", ViMi26 /* CmtSInt8MapsId */, &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26] ); + } + + + } // End for ViMi26 + + + + + // if ( 1 /* CurFrame % 10 == 0 */ ) { + // EFRIO__ULT1_FConvTFrameToZsFFrame ( PtFrame, VUlt1APtZsFFRame, 8 /* Mi28DestBuffersNb */, 0 /* PrintLevel */ ); + // ULT1__FConvZsFFrameToMatDiscriBit ( VUlt1APtZsFFRame[0], &VPtTestCont->ResUlt1AMatBitFromDaq[0], NULL /* PtOvfCnt */, 0 /* PrintLvl */ ); + // ULT1__FMatDiscriPrintHit ( "Matrix from DAQ ", 0 /* CmtSInt8MapsId */, &VPtTestCont->ResUlt1AMatBitFromDaq[0] ); + // } + + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 31/01/14 Bug fix : Error status stored in ResErrOnCurrentAcq flag was cleared if one of the following MAPS has no error + // The above line shows the code with bug + // VPtTestCont->ResErrOnCurrentAcq = VErrors; // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + return (VErrors); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 25/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 27/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointers + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // If length > max possible => Set it to 0 + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Ultimate 1 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 11/05/2011 + : - Convert function fromM26 readout to Ultimate 1 + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ) || (VDbgDataLenghtD1 > ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( ULT1__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * ULT1__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + ULT1__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + ULT1__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 19/05/2011 + : - Convert function fromM26 readout to Ultimate 1 + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1__fion_rewritten ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 26/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + +// $$$$$$$$$$$$$$ + +// : 03/02/2014 +// : - Add new tests on data + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 25/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // err_error (( ERR_OUT, "VDataLengthW16Max = %d", VDataLengthW16Max )); + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; // 3; !!! 08/06/2011 => Force 3 triggers !!! + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + ( /* !!! 08/06/2011 => Force 3 triggers !!! 3 */ VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // 03/02/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + // Update frames & events counters ONLY if there is no errors on data - 25/04/2013 + + if ( VErrorsOnData == 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 29/10/2010 version handling 6 Mi26 ) +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : + : 29/10/2013 + : - Upgrade the code for Ult1, previous code was a copy of Mi26 code + : + : 30/01/2014 + : - Add data test options, selection done from DAQ GUI "Enable data test" list + : -- 0 : No test + : -- 1 : Light (H, FC compare,T) => Test Header, Trailer, compare Frame Counter MAPS 0..7 but dont check increment + : -- 2 : Basic (H, FC increment,T) => Test Header, Trailer, check Frame Counter MAPS 0..7 increment during one Acq + : -- 3 : Data (Basic + Matrix) => Basic test + Compare matrix data to expected pattern calculated from JTAG + : + : 01/02/2014 + : - Handle return value from header, frame counter, trailer, matrix data test functions + : => Don't increment RunCont.ResAcqCnt, ResFrameCnt, ResEventCnt in case of error(s) + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V9iFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V9iFrame = 9 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi28 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (9 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; // 9 = 9 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 18]; // 18 = 9 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // xx/01/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 8 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + break; } + + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + + // $$$$ + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + // Update frames & events counters ONLY if there is no errors on data - 01/02/14 + + if ( VErrorsOnData == 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + if ( (VPtCont->RunCont.ResAcqCnt % 100) == 0 ) { + + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Run status %s - %s : %d Acq - %d Frames - %d Errors", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtCont->RunCont.ResAcqCnt, VPtCont->RunCont.ResFrameCnt, VPtCont->TestOnDataCont.ResTotErrCnt )); + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : + : XX/05/2011 + : - Upgrade Mi26 function for Ultimate 1 + : + : 07/06/2011 + : - Modify frames with trigger search loop to solve FW trigger bug ( delayed by 2 frames ) + : + : 03/02/2014 + : - Add new tests on data + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + + EFRIO__TFrame* VPtFrame; + EFRIO__TFrame* VPtFrameMinus2; // Pointer two frames before VPtFrame to solve FW trigger bug + + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + EFRIO__TTriggerRec* VPtTrigRecFrameMinus2; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + SInt16* VPtFwTrigBugFrameWithTrigTrigNb; + SInt16* VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2; + + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + // Limits of trigger info search in case of FW trigger bug + // => trigger info appears N (should be 2) frames after trigger occurs + + SInt32 VFwTrigBugFirstFrameTrigInfAllowed; + SInt32 VFwTrigBugLastFrameTrigInfAllowed; + SInt32 VFwTrigBugLastFrameIdStored; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // 09/06/2011 + + memset ( VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0], 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0][0]) ); + + memset ( VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0], 0, (EFRIO__MAX_FRAME_NB_PER_ACQ + 10) * sizeof (VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0][0]) ); + + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + VPtFwTrigBugFrameWithTrigTrigNb = VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0]; // 09/06/2011 + + VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2 = VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0]; // 09/06/2011 + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + + +// Frame with trigger search loop in case of FW bug on trigger +// => Trigger info appears two frames after trigger + +#define FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + +#ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // ------------------------------------------------------------------ + // Trigger bug + // - Info in zero fields at end of frame are at the right place + // => The info extracted from zero fields are ok without any shift + // => Trigger Nb & the first three triggers are OK + // - But the triggers list stored in extra channel will appear two + // frames later + // ------------------------------------------------------------------ + // The frame which contains trigger (in data) must be in current acq + // = we don't want to handle trigger from one acq to the next one + // We take 3 frames after the one which contains trigger + // = constant EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is ignored + // ------------------------------------------------------------------ + // => we exit function if EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is <> 3 + // => we reject trigger if info appears on frame > FrameNbPerAcq - 4 + + + if ( EFRIO__FRAME_NB_TO_READ_AFTER_TRIG != 3 ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__FRAME_NB_TO_READ_AFTER_TRIG=%d <> 3 => NOT handled in trig fw bug correction mode !", EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ); + } + + + VFwTrigBugFirstFrameTrigInfAllowed = 0; + VFwTrigBugLastFrameTrigInfAllowed = VPtBoard->FrameNbPerAcq - 4; + + VFwTrigBugLastFrameIdStored = -1; + + // Start search on first frame trigger info is allowed + + for ( VFrameId=VFwTrigBugFirstFrameTrigInfAllowed; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + +// -------------------- + + if ( (VTrigNb != 0) && (VFrameId <= VFwTrigBugLastFrameTrigInfAllowed) ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + + if ( VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] != 0 ) { + err_warning (( ERR_OUT, "Trigger error => Elt[%d] = frame %d already filled with %d", VFrameWithTrigCnt, VFrameId, VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] )); + } + + VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] = VTrigNb; // Store trigger cnt in frame which doesn't contain extra chan trig list + + VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[VFrameWithTrigCnt + 2] = 1; // Set flag "is trigger list" of frame No - 2 + + ++VFrameWithTrigCnt; + } + + else { + + if ( (VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + +// -------------------- + + } // End for ( ViFrame ) + + +// Frame with trigger search loop in case the is NO FW bug on trigger + +#else + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + +#endif + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + VPtFrameMinus2 = NULL; // 07/06/2011 + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // 07/06/2011 + + if ( VPtFrList->TotFrameNb > 1 ) { + VPtFrameMinus2 = VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 2]; + } + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + // Test coherence of trigger nb list / current frame trigger nb info + + if ( (VTrigNb > 0) && (VPtFwTrigBugFrameWithTrigTrigNb[ViFrameWithTrig] != VTrigNb) ) { + err_warning (( ERR_OUT, "Trigger nb list error => ViFrameWithTrig=%d - FrameId=%d - TrigNb=%d <> Trig nb from list=%d", ViFrameWithTrig, VPtFrameWithTrigList[ViFrameWithTrig], VTrigNb, VPtFwTrigBugFrameWithTrigTrigNb[ViFrameWithTrig] )); + } + + + #ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + VPtFrame->Header.TrigStatus = VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[ViFrameWithTrig]; + #else + VPtFrame->Header.TrigStatus = 0; + #endif + + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; // 3; 08/06/2011 !!! Force 3 triggers !!! + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + ( /* !!! 08/06/2011 Force 3 triggers !!! */ VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + #ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // If current frame contains triggers list of frame N-2 => Update frame N-2 + + if ( VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[ViFrameWithTrig] == 1 ) { + + // Do it only if pointer is valid + + if ( VPtFrameMinus2 != NULL ) { + + // Trigger record should have the same size as current frame because same trigger nb + // But check in case of ... + + VPtTrigRecFrameMinus2 = (EFRIO__TTriggerRec*) ( (UInt32) VPtFrameMinus2 + VPtFrameMinus2->TrigRecOffset ); + + if ( VPtTrigRecFrameMinus2->TotSz == VPtTmpTrigRec->TotSz ) { + memcpy ( VPtTrigRecFrameMinus2, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + } + + else { + err_warning (( ERR_OUT, "Abort update trig rec of Fr-2 because TrigRecSz=%d <> Current frame[%d] TrigRecSz=%d", VPtTrigRecFrameMinus2->TotSz, ViFrameWithTrig, VPtTmpTrigRec->TotSz )); + } + + } + + + } + + #endif + + + // 03/02/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrameWithTrig, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrameWithTrig, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrameWithTrig, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + } + + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1__with_fw_bug_on_ext_chan ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Warning ! : THIS VERSION HAS A BUG ON EXTRA CHANNEL HANLDING => ON TRIGGERS LIST + : BUT the first three triggers stored in "zero fiels" are OK !!!! + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 03/11/2010 version handling 6 Mi26 ) + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : + : XX/05/2011 + : - Upgrade Mi26 function for Ultimate 1 + : + : 07/06/2011 + : - Modify frames with trigger search loop to solve FW trigger bug ( delayed by 2 frames ) + : + : 29/10/2013 + : - Upgrade the code for Ult1, previous code was a copy of Mi26 code + : + : 30/01/2014 + : - Add data test options, selection done from DAQ GUI "Enable data test" list + : -- 0 : No test + : -- 1 : Light (H, FC compare,T) => Test Header, Trailer, compare Frame Counter MAPS 0..7 but dont check increment + : -- 2 : Basic (H, FC increment,T) => Test Header, Trailer, check Frame Counter MAPS 0..7 increment during one Acq + : -- 3 : Data (Basic + Matrix) => Basic test + Compare matrix data to expected pattern calculated from JTAG + : + : 03/02/2014 + : - Bug fix : Trigger line calculation from zero fields, Mi28 has 32 clk / lines, not 16 line Mi26 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1__with_fw_bug_on_ext_chan ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + + // Frame with trigger search loop in case of FW bug on trigger + // => Trigger info appears two frames after trigger + +#ifdef EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // ------------------------------------------------------------------ + // The frame which contains trigger (in data) must be in current acq + // = we don't want to handle trigger from one acq to the next one + // We take 3 frames after the one which contains trigger + // = constant EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is ignored + // ------------------------------------------------------------------ + // => we exit function if EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is <> 3 + // => we reject trigger if info appears on frame no < 2 + // => we reject trigger if info appears on frame > FrameNbPerAcq - 3 + 1 + + + err_retfail ( -1, (ERR_OUT,"Abort => Correction for FW trigger bug NOT IMPLEMENTED yet !") ); + + +// Frame with trigger search loop in case the is NO FW bug on trigger + +#else + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + +#endif + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 9 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = 9 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + /* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + + */ + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (9 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 18]; + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + // 03/02/14 Bug fix : Mi28 has 32 clk / line, not 16 like Mi26 + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // 30/01/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrameWithTrig, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrameWithTrig, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrameWithTrig, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + } + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + // + // EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + if ( (VPtCont->RunCont.ResAcqCnt % 100) == 0 ) { + + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Run status %s - %s : %d Acq - %d Frames - %d Errors", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtCont->RunCont.ResAcqCnt, VPtCont->RunCont.ResFrameCnt, VPtCont->TestOnDataCont.ResTotErrCnt )); + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 03/11/2010 version handling 6 Mi26 ) + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : + : XX/05/2011 + : - Upgrade Mi26 function for Ultimate 1 + : + : 07/06/2011 + : - Modify frames with trigger search loop to solve FW trigger bug ( delayed by 2 frames ) + : + : 29/10/2013 + : - Upgrade the code for Ult1, previous code was a copy of Mi26 code + : + : 30/01/2014 + : - Add data test options, selection done from DAQ GUI "Enable data test" list + : -- 0 : No test + : -- 1 : Light (H, FC compare,T) => Test Header, Trailer, compare Frame Counter MAPS 0..7 but dont check increment + : -- 2 : Basic (H, FC increment,T) => Test Header, Trailer, check Frame Counter MAPS 0..7 increment during one Acq + : -- 3 : Data (Basic + Matrix) => Basic test + Compare matrix data to expected pattern calculated from JTAG + : + : 03/02/2014 + : - Bug fix : Trigger line calculation from zero fields, Mi28 has 32 clk / lines, not 16 line Mi26 + : - Mi28 Flex RIO FW bug on extra channel handling correction by SW + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + + EFRIO__TFrame* VPtFrame; + EFRIO__TFrame* VPtFrameMinus2; // 03/02/14 : Pointer two frames before VPtFrame to solve FW trigger bug + + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + EFRIO__TTriggerRec* VPtTrigRecFrameMinus2; // 03/02/14 + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + SInt16* VPtFwTrigBugFrameWithTrigTrigNb; // 03/02/14 + SInt16* VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2; // 03/02/14 + + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + // 03/02/14 + // Limits of trigger info search in case of FW trigger bug + // => trigger info appears N (should be 2) frames after trigger occurs + + SInt32 VFwTrigBugFirstFrameTrigInfAllowed; + SInt32 VFwTrigBugLastFrameTrigInfAllowed; + SInt32 VFwTrigBugLastFrameIdStored; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // 03/02/14 (09/06/2011) + + memset ( VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0], 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0][0]) ); + + memset ( VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0], 0, (EFRIO__MAX_FRAME_NB_PER_ACQ + 10) * sizeof (VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + VPtFwTrigBugFrameWithTrigTrigNb = VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0]; // 03/02/14 (09/06/2011) + VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2 = VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0]; // 03/02/14 (09/06/2011) + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + // Frame with trigger search loop in case of FW bug on trigger + // => Trigger info appears two frames after trigger + + #define FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + #ifdef EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // ------------------------------------------------------------------ + // Trigger bug + // - Info in zero fields at end of frame are at the right place + // => The info extracted from zero fields are ok without any shift + // => Trigger Nb & the first three triggers are OK + // - But the triggers list stored in extra channel will appear two + // frames later + // ------------------------------------------------------------------ + // The frame which contains trigger (in data) must be in current acq + // = we don't want to handle trigger from one acq to the next one + // We take 3 frames after the one which contains trigger + // = constant EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is ignored + // ------------------------------------------------------------------ + // => we exit function if EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is <> 3 + // => we reject trigger if info appears on frame > FrameNbPerAcq - 4 + + + if ( EFRIO__FRAME_NB_TO_READ_AFTER_TRIG != 3 ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__FRAME_NB_TO_READ_AFTER_TRIG=%d <> 3 => NOT handled in trig fw bug correction mode !", EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ); + } + + + VFwTrigBugFirstFrameTrigInfAllowed = 0; + VFwTrigBugLastFrameTrigInfAllowed = VPtBoard->FrameNbPerAcq - 4; + + VFwTrigBugLastFrameIdStored = -1; + + // Start search on first frame trigger info is allowed + + for ( VFrameId=VFwTrigBugFirstFrameTrigInfAllowed; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // -------------------- + + if ( (VTrigNb != 0) && (VFrameId <= VFwTrigBugLastFrameTrigInfAllowed) ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + + if ( VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] != 0 ) { + err_warning (( ERR_OUT, "Trigger error => Elt[%d] = frame %d already filled with %d", VFrameWithTrigCnt, VFrameId, VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] )); + } + + VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] = VTrigNb; // Store trigger cnt in frame which doesn't contain extra chan trig list + + VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[VFrameWithTrigCnt + 2] = 1; // Set flag "is trigger list" of frame No - 2 + + ++VFrameWithTrigCnt; + } + + else { + + if ( (VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + + // -------------------- + + } // End for ( ViFrame ) + + + // Frame with trigger search loop in case the is NO FW bug on trigger + + #else + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #endif + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 9 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = 9 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + /* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + + */ + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (9 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 18]; + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + // 03/02/14 Bug fix : Mi28 has 32 clk / line, not 16 like Mi26 + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // 03/02/14 : Add trigger info in frame header + + // 03/02/14 : Test coherence of trigger nb list / current frame trigger nb info + + if ( (VTrigNb > 0) && (VPtFwTrigBugFrameWithTrigTrigNb[ViFrameWithTrig] != VTrigNb) ) { + err_warning (( ERR_OUT, "Trigger nb list error => ViFrameWithTrig=%d - FrameId=%d - TrigNb=%d <> Trig nb from list=%d", ViFrameWithTrig, VPtFrameWithTrigList[ViFrameWithTrig], VTrigNb, VPtFwTrigBugFrameWithTrigTrigNb[ViFrameWithTrig] )); + } + + // 03/02/14 : + + #ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + VPtFrame->Header.TrigStatus = VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[ViFrameWithTrig]; + #else + VPtFrame->Header.TrigStatus = 0; + #endif + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // 03/02/14 : + + #ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // If current frame contains triggers list of frame N-2 => Update frame N-2 + + if ( VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[ViFrameWithTrig] == 1 ) { + + // Do it only if pointer is valid + + if ( VPtFrameMinus2 != NULL ) { + + // Trigger record should have the same size as current frame because same trigger nb + // But check in case of ... + + VPtTrigRecFrameMinus2 = (EFRIO__TTriggerRec*) ( (UInt32) VPtFrameMinus2 + VPtFrameMinus2->TrigRecOffset ); + + if ( VPtTrigRecFrameMinus2->TotSz == VPtTmpTrigRec->TotSz ) { + memcpy ( VPtTrigRecFrameMinus2, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + } + + else { + err_warning (( ERR_OUT, "Abort update trig rec of Fr-2 because TrigRecSz=%d <> Current frame[%d] TrigRecSz=%d", VPtTrigRecFrameMinus2->TotSz, ViFrameWithTrig, VPtTmpTrigRec->TotSz )); + } + + } + + } + + #endif + + + // 30/01/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrameWithTrig, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrameWithTrig, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrameWithTrig, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 8 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrameWithTrig, VPtFrame, 8 /* Mi26Nb */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + break; } + + } + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + // + // EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + if ( (VPtCont->RunCont.ResAcqCnt % 1000) == 0 ) { + + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Run status %s - %s : %d Acq - %d Frames - %d Errors", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtCont->RunCont.ResAcqCnt, VPtCont->RunCont.ResFrameCnt, VPtCont->TestOnDataCont.ResTotErrCnt )); + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataUlt1 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 27/03/2013 + : - Add param DataTestTotErrCnt and return it as run status in RunCont.ParDaqVersion + : using bits B00B23, bits B24B31 are reserved for Daq version. + : + : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataUlt1 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode, UInt32 DataTestTotErrCnt ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + + + // 31/01/14 Bug fix : + // The bug fix is not here, it's done in data test functions on ResErrOnCurrentAcq handling + // but NOW we must reset data test "error(s) on current acq flag" at beginning of each acquisition + + VPtTestCont->ResErrOnCurrentAcq = 0; + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - IPHC / EUDET 1 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Emul - IPHC / EUDET 1 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of Ultimate = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 2 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 2 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of Ultimate = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 3 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 3 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC is not handled for Ultimate" ) ); + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + // err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi28 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + // err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi28 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi28 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + // WARNING ! Use ParDaqVersion to return Data test total errors counter + // Overwrite the ParDaqVersion field with the errors count converted in a NEGATIVE NUMBER + + VPtCont->RunCont.ParDaqVersion = DataTestTotErrCnt & 0x00FFFFFF; // B24B31 reserved for Daq version + + + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 08/11/2013 + : - Add dev 0 selection to fix "JTAG GUI panel bug" when using only one MAPS + : following an advise from KKJ, but it solves nothing ... let in place, in case of ... + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagLoadFile ( char* FileName ) { + + HRESULT VRetCode; + WideString VStatus; + WideString VFileName; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + + if ( VJtag.IsBound () ) { + + VFileName = FileName; + + OleCheck( VRetCode = VJtag.MasterConfLoadFile( VFileName , &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Load JTAG file = %s failed !", FileName) ); + } + + + // 08/11/2013 + // Add dev 0 selection to fix "JTAG GUI panel bug" when using only one MAPS + // following an advise from KKJ, but it solves nothing ... let in place, in case of ... + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( 0, &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Set JTAG DevNum 0 failed !" ) ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 13/03/2013 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagLoadDefFile () { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + char VFileName[GLB_FILE_PATH_SZ]; + + sprintf ( VFileName, "%s", "c:\\ccmos_sctrl\\Mimosa28_jtag\\config_files\\Default.mcf" ); + + msg (( MSG_OUT, "### EFRIO__ULT1_FJtagLoadDefFile (FileName=%s)", VFileName )); + + VRet = EFRIO__ULT1_FJtagLoadFile (VFileName); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagReset ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfReset (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Reset chip failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 20/03/2013 + : - Exit if r/w errors detected on MasterConfReadBack () call + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FJtagLoadChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + SInt32 VRbErr; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + + +#ifdef EFRIO__INCLUDE_JTAG + +// msg (( MSG_OUT, "EFRIO__ULT1_FJtagLoadChip ()")); + + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfUpdateAll (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + OleCheck( VRetCode = VJtag.MasterConfReadBack (&VRbErr, &VStatus) ); + +// msg (( MSG_OUT, "EFRIO__ULT1_FJtagLoadChip ( ) => Readback code=%d - errnb=%d", VRetCode, VRbErr )); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Read back chip parameters failed !") ); + } + + if ( VRbErr > 0 ) { + err_retfail ( -VRbErr, (ERR_OUT,"JTAG -> Read back chip => Write <> Read => %d errors !", VRbErr ) ); + } + + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagStartChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfStart (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2010 +Doc date : 10/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FHwStartChip ( SInt32 SpareS32Par ) { + + err_warning (( ERR_OUT, "EFRIO__MI26_FHwStartChip (Par=%d)", SpareS32Par )); + + // Start = D6, Speak = D7* + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD6 ( 0 /* Id */, 0 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 0 ); + + #else + err_warning (( ERR_OUT, "HW start not done -> // port not enabled !" )); + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + + return (VTotAcqSz); + } + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) +: +Goal : print one frame content in log file +: +Inputs : PtRec - Pointer on the record +: +: PrintLevel - 0 -> Print nothing +: - > 0 -> print state list for each line +: +Ouputs : The function returns +: 0 if ok +: -1 if PtRec = NULL +: +Globals : +: +Remark : +: +Level : +Date : 22/12/2010 +Rev : 30/12/2010 +: - Add handling of N Mimosa 26 +: +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FConvTFrameToZsFFrame ( EFRIO__TFrame* PtRec, ULT1__TZsFFrame* APtDest[EFRIO__MAX_ASIC_NB], SInt8 Mi28DestBuffersNb, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + +// ULT1__TStatesLine VStatesLine; +// ULT1__TState VState; + + + ULT1__TStatesLine* VPtStatesLine; + ULT1__TState* VPtState; // [ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + + + SInt16 ViMi26; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + char VStrState[255]; + char VStrLine[255]; + + SInt32 VTimeBegMs; + SInt32 VTimeEndMs; + SInt32 VTimeExecMs; + + + // VTimeBegMs = GetTickCount (); + + // ------------------------------------- + // Check parameters + // ------------------------------------- + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL !") ); + + // Init pointers on TFrame sub records + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Check destination buffers nb + + if ( Mi28DestBuffersNb < VPtHead->MapsNb ) { + err_retfail ( -1, (ERR_OUT,"Abort : Not enought destination Mi28 buffers : %d allocated / %d require", Mi28DestBuffersNb, VPtHead->MapsNb) ); + } + + // Check destination buffers allocation + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb; ViMi26++ ) { + + if ( APtDest[ViMi26] == NULL ) { + err_retfail ( -1, (ERR_OUT,"Abort : Buffer [%d] for Mi28 not allocated (Ptr = NULL) !", ViMi26) ); + } + + } + + // ------------------------------------- + // Processing + // ------------------------------------- + + // Reset destination buffer + // Copy header, trailer, etc ... + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb; ViMi26++ ) { + + memset ( APtDest[ViMi26], 0, sizeof (ULT1__TZsFFrameRaw) ); + + APtDest[ViMi26]->SStatus.AsicNo = ViMi26; + APtDest[ViMi26]->SStatus.AcqNo = PtRec->Header.AcqId; + APtDest[ViMi26]->SStatus.FrameNoInAcq = PtRec->Header.FrameIdInAcq; + APtDest[ViMi26]->SStatus.FrameNoInRun = 0; // => Not yet calculated ! + APtDest[ViMi26]->SStatus.HitCnt = 0; // => Not yet calculated ! + + APtDest[ViMi26]->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = PtRec->Header.AMapsTrigInfo[0]; + + // ASIC__MI26_TRIG_RES__SIG_LINE + // ASIC__MI26_TRIG_RES__SIG_CLK + // ASIC__MI26_TRIG_RES__LINE + + APtDest[ViMi26]->Header = PtRec->Header.AMapsHeader[ViMi26]; + APtDest[ViMi26]->FrameCnt = PtRec->Header.AMapsFrameCnt[ViMi26]; + APtDest[ViMi26]->DataLength = PtRec->Header.AMapsDataLength[ViMi26]; + APtDest[ViMi26]->TrigSignalLine = PtRec->Header.AMapsTrigInfo[0]; + APtDest[ViMi26]->TrigSignalClk = 0; // => Not yet calculated ! + APtDest[ViMi26]->TrigLine = 0; // => Not yet calculated ! + APtDest[ViMi26]->Trailer = PtRec->Header.AMapsTrailer[ViMi26]; + APtDest[ViMi26]->Zero = 0; + APtDest[ViMi26]->Zero2 = 0; + + } + + // Process data + + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + +// msg (( MSG_OUT, "===================================================================================" )); +// msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); +// msg (( MSG_OUT, "===================================================================================" )); + + + ViStatesLine = 0; // 28/01/14 + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + // ViStatesLine = 0; // 28/01/14 : Moved before loop, otherwise StatesRecNb was set with a random value after loop if VDataW16Length == 0 !!! + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + VPtStatesLine = &APtDest[ViMi26]->AStatesRec[ViStatesLine].StatesLine; + VPtState = &APtDest[ViMi26]->AStatesRec[ViStatesLine].AStates[0]; // [ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + + // Copy StatesLine field + + VPtStatesLine->W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VPtStatesLine->F.StateNb; + + // sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VPtStatesLine->F.LineAddr, VPtStatesLine->F.StateNb, VPtStatesLine->F.Ovf ); + // + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + VPtState[ViState].W16 = VPtSrcW16[ViSrcW16]; + + // sprintf ( VStrState, "[Col %4d - %1d pixel(s)] ", VPtState[ViState].F.ColAddr, VPtState[ViState].F.HitNb + 1 ); + // + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrState )); + // } + + ++ViSrcW16; + } + + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + ++ViStatesLine; + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + APtDest[ViMi26]->StatesRecNb = ViStatesLine; + + } // End for ( ViMi26 ) + + // VTimeEndMs = GetTickCount (); + // VTimeExecMs = VTimeEndMs - VTimeBegMs; + + // msg (( MSG_OUT, "$$$$$ Convert maxtrix exec time = %d [ms]", VTimeExecMs )); + +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : print one frame content in log file +: +Inputs : PtRec - Pointer on the record +: +: PrintLevel - 0 -> Print nothing +: - > 0 -> print state list for each line +: +Ouputs : The function returns +: 0 if ok +: -1 if PtRec = NULL +: +Globals : +: +Remark : +: +Level : +Date : +Rev : +: - Add handling of N Mimosa 26 +: +Doc date : 31/01/2014 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FCheckTFrame ( EFRIO__TFrame* PtRec, SInt8 EmulErr ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + + ULT1__TStatesLine VStatesLine; + SInt8 VStatesNbPerLine; + UInt16 VStatesLineAddr; + + SInt16 ViMi26; + SInt8 VErrors; + + static UInt32 VEmulErrW16Cnt = 1; + + + // ------------------------------------- + // Check parameters + // ------------------------------------- + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL !") ); + + // Init pointers on TFrame sub records + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + + // ------------------------------------- + // Processing + // ------------------------------------- + +/* + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb; ViMi26++ ) { + + memset ( APtDest[ViMi26], 0, sizeof (ULT1__TZsFFrameRaw) ); + + APtDest[ViMi26]->SStatus.AsicNo = ViMi26; + APtDest[ViMi26]->SStatus.AcqNo = PtRec->Header.AcqId; + APtDest[ViMi26]->SStatus.FrameNoInAcq = PtRec->Header.FrameIdInAcq; + APtDest[ViMi26]->SStatus.FrameNoInRun = 0; + APtDest[ViMi26]->SStatus.HitCnt = 0; + + APtDest[ViMi26]->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = PtRec->Header.AMapsTrigInfo[0]; + + APtDest[ViMi26]->Header = PtRec->Header.AMapsHeader[ViMi26]; + APtDest[ViMi26]->FrameCnt = PtRec->Header.AMapsFrameCnt[ViMi26]; + APtDest[ViMi26]->DataLength = PtRec->Header.AMapsDataLength[ViMi26]; + APtDest[ViMi26]->TrigSignalLine = PtRec->Header.AMapsTrigInfo[0]; + APtDest[ViMi26]->TrigSignalClk = 0; + APtDest[ViMi26]->TrigLine = 0; + APtDest[ViMi26]->Trailer = PtRec->Header.AMapsTrailer[ViMi26]; + APtDest[ViMi26]->Zero = 0; + APtDest[ViMi26]->Zero2 = 0; + + } + +*/ + + // Process data + + VErrors = 0; + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + + VPtTestCont->ResAMapsMatrixHitCnt[ViMi26] = 0; // 06/02/14 + + // msg (( MSG_OUT, "===================================================================================" )); + // msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); + // msg (( MSG_OUT, "===================================================================================" )); + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + // ViStatesLine = 0; // 28/01/14 : Moved before loop, otherwise StatesRecNb was set with a random value after loop if VDataW16Length == 0 !!! + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Emul errors + + if ( EmulErr ) { + + if ( (VEmulErrW16Cnt % 100000000) == 0 ) { + msg (( MSG_OUT, "$$$ Error emulated ! Acq %d - Frame %d - MAPS[%d]", VPtHead->AcqId, VPtHead->FrameIdInAcq, ViMi26 )); + VPtSrcW16[ViSrcW16] = 0xFFFF; + } + + ++VEmulErrW16Cnt; + + } + + + // Copy StatesLine field + + VStatesLine.W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VStatesLine.F.StateNb; + VStatesLineAddr = VStatesLine.F.LineAddr; + + + // msg (( MSG_OUT, "Frame %d : States/line nb = %d on MAPS[%d]", CurFrame, VStatesNbPerLine, ViMi26 )); + + if ( (VStatesNbPerLine == 0) || (VStatesNbPerLine > 9) || (VStatesLineAddr > 927) ) { + msg (( MSG_OUT, "StateLine error ! Acq %d - Frame %d - MAPS[%d] : Bad number of states/line = %d OR LineAddr = %d on MAPS[%d] - Jump to next MAPS", VPtHead->AcqId, VPtHead->FrameIdInAcq, ViMi26 , VStatesNbPerLine, VStatesLineAddr )); + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + break; // => In order to exit while loop and jump to next Mi26 + } + + // 06/02/14 + + VPtTestCont->ResAMapsMatrixHitCnt[ViMi26] += VStatesNbPerLine; + + // Bypass states readout => jump to next state/line word + + ViSrcW16 += (VStatesNbPerLine + 1); + + // sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VPtStatesLine->F.LineAddr, VPtStatesLine->F.StateNb, VPtStatesLine->F.Ovf ); + // + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + } // End for ( ViMi26 ) + + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + + } + + return (VErrors); +} + + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_ult1.h b/include/pxi_daq_lib_v.2.1/eudet_frio_ult1.h new file mode 100755 index 0000000..beffc14 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_ult1.h @@ -0,0 +1,60 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_ult1.h +Goal : Ultimate 1 functions prototypes of flex rio board library for EUDET +Prj date : 11/05/2011 +File date : 11/05/2011 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_ULT1_H + +#include "func_header.def" + + +// 06/11/2010 -> 21 + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD ( SInt32 REF_FHello ();) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FTestOnDataGetJtagRef ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataIphcMode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataIphcMode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FFRioAcqDeserDataUlt1 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode, UInt32 DataTestTotErrCnt );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FJtagLoadFile ( char* FileName );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FJtagLoadDefFile ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FJtagReset ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FJtagLoadChip ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FJtagStartChip ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FHwStartChip ( SInt32 SpareS32Par );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FConvTFrameToZsFFrame ( EFRIO__TFrame* PtRec, ULT1__TZsFFrame* APtDest[EFRIO__MAX_ASIC_NB], SInt8 Mi28DestBuffersNb, SInt8 PrintLevel );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO__ULT1_FCheckTFrame ( EFRIO__TFrame* PtRec, SInt8 EmulErr );) + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_ULT1_H + #define EUDET_FRIO_ULT1_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_ult1_300513.c b/include/pxi_daq_lib_v.2.1/eudet_frio_ult1_300513.c new file mode 100755 index 0000000..c8371ad --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_ult1_300513.c @@ -0,0 +1,6453 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_ult1.c +Goal : Ultimate 1 functions of flex rio board library for EUDET +Prj date : 11/05/2011 +File date : 11/05/2011 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_ULT1_C +#define EUDET_FRIO_ULT1_C + + +// #define EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + +/* +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 +*/ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 19/05/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FTestOnDataGetJtagRef () { + + SInt32 VRet; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + HRESULT VRetCode; + WideString VStatus; + + #ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; + #endif + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + + SInt8 ViMaps; + + + #ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + // Sel Mi26 + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( ViMaps, &VStrComStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Select Maps Id = %d failed !", ViMaps) ); + } + + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 0 /* RegId */, &VHighTrailerFromJtag, &VRegValFromMi26, &VStrComStatus) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 1 /* RegId */, &VLowTrailerFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 2 /* RegId */, &VHighHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 3 /* RegId */, &VLowHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + + VPtTestCont->ParAMapsHeaderRef[ViMaps] = VLowHeaderFromJtag + (VHighHeaderFromJtag << 16); // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = VLowTrailerFromJtag + (VHighTrailerFromJtag << 16); // Mimosa 26 trailer field + + } + + } + + else { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + VPtTestCont->ParAMapsHeaderRef[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = 0; // Mimosa 26 trailer field + } + + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + + CoUninitialize(); + + #else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + #endif + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 19/05/2011 ( DPXI version of 20/08/2009 moved here ) +Rev : 15/05/2013 + : - Modification of frame counter test, the test Fr(n+1) = Fr(n) + 1 has been + : removed because in beam test (EUDET3 mode) the frames in one acquisition are + : not all consecutives, there it detects fake errors. Now the test is only done + : by a comparison of all Mimosa 28 frame couters frame by frame. +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameLight ( SInt16 FuncId, SInt32 CurFrame, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the one of Mimosa28 [0] + // This is done frame by frame = doesn't care about previous frame counter value - 15/05/2013 + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "B - Frame cnt error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Header error [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + msg (( MSG_OUT, "Trailer error [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VErrors; + + return (VErrors); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 25/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 27/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointers + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // If length > max possible => Set it to 0 + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Ultimate 1 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 11/05/2011 + : - Convert function fromM26 readout to Ultimate 1 + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ) || (VDbgDataLenghtD1 > ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( ULT1__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * ULT1__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + ULT1__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + ULT1__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 19/05/2011 + : - Convert function fromM26 readout to Ultimate 1 + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1__fion_rewritten ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 26/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + +// $$$$$$$$$$$$$$ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 25/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // err_error (( ERR_OUT, "VDataLengthW16Max = %d", VDataLengthW16Max )); + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; // 3; !!! 08/06/2011 => Force 3 triggers !!! + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + ( /* !!! 08/06/2011 => Force 3 triggers !!! 3 */ VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + // Update frames & events counters ONLY if there is no errors on data - 25/04/2013 + + if ( VErrorsOnData == 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 29/10/2010 version handling 6 Mi26 ) +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V9iFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V9iFrame = 9 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > 2304 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 9 = 9 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; // 18 = 9 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : + : XX/05/2011 + : - Upgrade Mi26 function for Ultimate 1 + : + : 07/06/2011 + : - Modify frames with trigger search loop to solve FW trigger bug ( delayed by 2 frames ) + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + + EFRIO__TFrame* VPtFrame; + EFRIO__TFrame* VPtFrameMinus2; // Pointer two frames before VPtFrame to solve FW trigger bug + + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + EFRIO__TTriggerRec* VPtTrigRecFrameMinus2; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + SInt16* VPtFwTrigBugFrameWithTrigTrigNb; + SInt16* VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2; + + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + // Limits of trigger info search in case of FW trigger bug + // => trigger info appears N (should be 2) frames after trigger occurs + + SInt32 VFwTrigBugFirstFrameTrigInfAllowed; + SInt32 VFwTrigBugLastFrameTrigInfAllowed; + SInt32 VFwTrigBugLastFrameIdStored; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // 09/06/2011 + + memset ( VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0], 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0][0]) ); + + memset ( VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0], 0, (EFRIO__MAX_FRAME_NB_PER_ACQ + 10) * sizeof (VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0][0]) ); + + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + VPtFwTrigBugFrameWithTrigTrigNb = VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0]; // 09/06/2011 + + VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2 = VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0]; // 09/06/2011 + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + + +// Frame with trigger search loop in case of FW bug on trigger +// => Trigger info appears two frames after trigger + +#define FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + +#ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // ------------------------------------------------------------------ + // Trigger bug + // - Info in zero fields at end of frame are at the right place + // => The info extracted from zero fields are ok without any shift + // => Trigger Nb & the first three triggers are OK + // - But the triggers list stored in extra channel will appear two + // frames later + // ------------------------------------------------------------------ + // The frame which contains trigger (in data) must be in current acq + // = we don't want to handle trigger from one acq to the next one + // We take 3 frames after the one which contains trigger + // = constant EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is ignored + // ------------------------------------------------------------------ + // => we exit function if EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is <> 3 + // => we reject trigger if info appears on frame > FrameNbPerAcq - 4 + + + if ( EFRIO__FRAME_NB_TO_READ_AFTER_TRIG != 3 ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__FRAME_NB_TO_READ_AFTER_TRIG=%d <> 3 => NOT handled in trig fw bug correction mode !", EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ); + } + + + VFwTrigBugFirstFrameTrigInfAllowed = 0; + VFwTrigBugLastFrameTrigInfAllowed = VPtBoard->FrameNbPerAcq - 4; + + VFwTrigBugLastFrameIdStored = -1; + + // Start search on first frame trigger info is allowed + + for ( VFrameId=VFwTrigBugFirstFrameTrigInfAllowed; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + +// -------------------- + + if ( (VTrigNb != 0) && (VFrameId <= VFwTrigBugLastFrameTrigInfAllowed) ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + + if ( VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] != 0 ) { + err_warning (( ERR_OUT, "Trigger error => Elt[%d] = frame %d already filled with %d", VFrameWithTrigCnt, VFrameId, VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] )); + } + + VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] = VTrigNb; // Store trigger cnt in frame which doesn't contain extra chan trig list + + VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[VFrameWithTrigCnt + 2] = 1; // Set flag "is trigger list" of frame No - 2 + + ++VFrameWithTrigCnt; + } + + else { + + if ( (VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + +// -------------------- + + } // End for ( ViFrame ) + + +// Frame with trigger search loop in case the is NO FW bug on trigger + +#else + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + +#endif + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + VPtFrameMinus2 = NULL; // 07/06/2011 + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // 07/06/2011 + + if ( VPtFrList->TotFrameNb > 1 ) { + VPtFrameMinus2 = VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 2]; + } + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + // Test coherence of trigger nb list / current frame trigger nb info + + if ( (VTrigNb > 0) && (VPtFwTrigBugFrameWithTrigTrigNb[ViFrameWithTrig] != VTrigNb) ) { + err_warning (( ERR_OUT, "Trigger nb list error => ViFrameWithTrig=%d - FrameId=%d - TrigNb=%d <> Trig nb from list=%d", ViFrameWithTrig, VPtFrameWithTrigList[ViFrameWithTrig], VTrigNb, VPtFwTrigBugFrameWithTrigTrigNb[ViFrameWithTrig] )); + } + + + #ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + VPtFrame->Header.TrigStatus = VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[ViFrameWithTrig]; + #else + VPtFrame->Header.TrigStatus = 0; + #endif + + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; // 3; 08/06/2011 !!! Force 3 triggers !!! + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + ( /* !!! 08/06/2011 Force 3 triggers !!! */ VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + #ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // If current frame contains triggers list of frame N-2 => Update frame N-2 + + if ( VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[ViFrameWithTrig] == 1 ) { + + // Do it only if pointer is valid + + if ( VPtFrameMinus2 != NULL ) { + + // Trigger record should have the same size as current frame because same trigger nb + // But check in case of ... + + VPtTrigRecFrameMinus2 = (EFRIO__TTriggerRec*) ( (UInt32) VPtFrameMinus2 + VPtFrameMinus2->TrigRecOffset ); + + if ( VPtTrigRecFrameMinus2->TotSz == VPtTmpTrigRec->TotSz ) { + memcpy ( VPtTrigRecFrameMinus2, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + } + + else { + err_warning (( ERR_OUT, "Abort update trig rec of Fr-2 because TrigRecSz=%d <> Current frame[%d] TrigRecSz=%d", VPtTrigRecFrameMinus2->TotSz, ViFrameWithTrig, VPtTmpTrigRec->TotSz )); + } + + } + + + } + + #endif + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 03/11/2010 version handling 6 Mi26 ) + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : + : XX/05/2011 + : - Upgrade Mi26 function for Ultimate 1 + : + : 07/06/2011 + : - Modify frames with trigger search loop to solve FW trigger bug ( delayed by 2 frames ) + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + + // Frame with trigger search loop in case of FW bug on trigger + // => Trigger info appears two frames after trigger + +#ifdef EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // ------------------------------------------------------------------ + // The frame which contains trigger (in data) must be in current acq + // = we don't want to handle trigger from one acq to the next one + // We take 3 frames after the one which contains trigger + // = constant EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is ignored + // ------------------------------------------------------------------ + // => we exit function if EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is <> 3 + // => we reject trigger if info appears on frame no < 2 + // => we reject trigger if info appears on frame > FrameNbPerAcq - 3 + 1 + + + err_retfail ( -1, (ERR_OUT,"Abort => Correction for FW trigger bug NOT IMPLEMENTED yet !") ); + + +// Frame with trigger search loop in case the is NO FW bug on trigger + +#else + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + +#endif + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 9 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = 9 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + /* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + + */ + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (9 * MI26__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * MI26__ZS_FFRAME_RAW_MAX_W32) + 18]; + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataUlt1 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 27/03/2013 + : - Add param DataTestTotErrCnt and return it as run status in RunCont.ParDaqVersion + : using bits B00B23, bits B24B31 are reserved for Daq version. + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataUlt1 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode, UInt32 DataTestTotErrCnt ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - IPHC / EUDET 1 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Emul - IPHC / EUDET 1 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of Ultimate = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 2 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 2 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of Ultimate = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 3 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 3 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC is not handled for Ultimate" ) ); + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + // WARNING ! Use ParDaqVersion to return Data test total errors counter + // Overwrite the ParDaqVersion field with the errors count converted in a NEGATIVE NUMBER + + VPtCont->RunCont.ParDaqVersion = DataTestTotErrCnt & 0x00FFFFFF; // B24B31 reserved for Daq version + + + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagLoadFile ( char* FileName ) { + + HRESULT VRetCode; + WideString VStatus; + WideString VFileName; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + + if ( VJtag.IsBound () ) { + + VFileName = FileName; + + OleCheck( VRetCode = VJtag.MasterConfLoadFile( VFileName , &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Load JTAG file = %s failed !", FileName) ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 13/03/2013 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagLoadDefFile () { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + char VFileName[GLB_FILE_PATH_SZ]; + + sprintf ( VFileName, "%s", "c:\\ccmos_sctrl\\Mimosa28_jtag\\config_files\\Default.mcf" ); + + msg (( MSG_OUT, "### EFRIO__ULT1_FJtagLoadDefFile (FileName=%s)", VFileName )); + + VRet = EFRIO__ULT1_FJtagLoadFile (VFileName); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagReset ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfReset (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Reset chip failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 20/03/2013 + : - Exit if r/w errors detected on MasterConfReadBack () call + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FJtagLoadChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + SInt32 VRbErr; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + + +#ifdef EFRIO__INCLUDE_JTAG + +// msg (( MSG_OUT, "EFRIO__ULT1_FJtagLoadChip ()")); + + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfUpdateAll (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + OleCheck( VRetCode = VJtag.MasterConfReadBack (&VRbErr, &VStatus) ); + +// msg (( MSG_OUT, "EFRIO__ULT1_FJtagLoadChip ( ) => Readback code=%d - errnb=%d", VRetCode, VRbErr )); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Read back chip parameters failed !") ); + } + + if ( VRbErr > 0 ) { + err_retfail ( -VRbErr, (ERR_OUT,"JTAG -> Read back chip => Write <> Read => %d errors !", VRbErr ) ); + } + + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagStartChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfStart (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2010 +Doc date : 10/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FHwStartChip ( SInt32 SpareS32Par ) { + + err_warning (( ERR_OUT, "EFRIO__MI26_FHwStartChip (Par=%d)", SpareS32Par )); + + // Start = D6, Speak = D7* + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD6 ( 0 /* Id */, 0 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 0 ); + + #else + err_warning (( ERR_OUT, "HW start not done -> // port not enabled !" )); + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + + return (VTotAcqSz); + } + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_ult1__code_listing.c b/include/pxi_daq_lib_v.2.1/eudet_frio_ult1__code_listing.c new file mode 100755 index 0000000..55d3561 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_ult1__code_listing.c @@ -0,0 +1,7921 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_ult1.c +Goal : Ultimate 1 functions of flex rio board library for EUDET +Prj date : 11/05/2011 +File date : 11/05/2011 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_ULT1_C +#define EUDET_FRIO_ULT1_C + + +// #define EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + +/* +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 +*/ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__F +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 19/05/2011 +Rev : +: +Doc date : /2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FTestOnDataGetJtagRef () { + + SInt32 VRet; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + HRESULT VRetCode; + WideString VStatus; + + #ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; + #endif + + char* VJtagFileName; + + SInt32 VRegValFromMi26; + SInt32 VLowHeaderFromJtag; + SInt32 VHighHeaderFromJtag; + SInt32 VLowTrailerFromJtag; + SInt32 VHighTrailerFromJtag; + SInt32 ViRegLinePat; + + + SInt8 ViMaps; + + + #ifdef EFRIO__INCLUDE_JTAG + + // + + // ParJtagFileName + + // ParAMatPatternLineNb + + VJtagFileName = FIL_FExtractFileNameFromFilePath (VPtRunCont->ParJtagFileName); + + msg (( MSG_OUT, "JTAG file name = %s", VJtagFileName )); + + while (1) { + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpa.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpb.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpc.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpd.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + if ( strcmp (VJtagFileName, "MI28_2x160Mhz_suze_lpe.mcf") ) { + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + } + + // Default + + VPtTestCont->ParAMatPatternLineNb[0] = 928; + VPtTestCont->ParAMatPatternLineNb[1] = 928; + VPtTestCont->ParAMatPatternLineNb[2] = 928; + VPtTestCont->ParAMatPatternLineNb[3] = 928; + VPtTestCont->ParAMatPatternLineNb[4] = 928; + VPtTestCont->ParAMatPatternLineNb[5] = 928; + VPtTestCont->ParAMatPatternLineNb[6] = 928; + VPtTestCont->ParAMatPatternLineNb[7] = 928; + break; + + } + + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + + // -------------------------------------- + // Sel Mi28 + // -------------------------------------- + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( ViMaps, &VStrComStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Select Maps Id = %d failed !", ViMaps) ); + } + + // -------------------------------------- + // Read Header & Trailer from JTAG conf + // -------------------------------------- + + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 0 /* RegId */, &VHighTrailerFromJtag, &VRegValFromMi26, &VStrComStatus) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 1 /* RegId */, &VLowTrailerFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 2 /* RegId */, &VHighHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VRetCode = VJtag.Mimosa28ConfGetHeaderTrailer ( 3 /* RegId */, &VLowHeaderFromJtag , &VRegValFromMi26, &VStrComStatus ) ); + + VPtTestCont->ParAMapsHeaderRef[ViMaps] = VLowHeaderFromJtag + (VHighHeaderFromJtag << 16); // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = VLowTrailerFromJtag + (VHighTrailerFromJtag << 16); // Mimosa 26 trailer field + + // -------------------------------------- + // Build reference matrix from JTAG conf + // -------------------------------------- + + for ( ViRegLinePat=0; ViRegLinePat < ULT1__REG_DISCRI_W32_SZ; ViRegLinePat++ ) { + OleCheck( VJtag.Mimosa28ConfGetLinePat0 ( (long) ViRegLinePat, (unsigned long*) &VPtTestCont->ParUlt1ALinePat0[ViMaps].AW32[ViRegLinePat], (unsigned long*) &VRegValFromMi26, &VStrComStatus ) ); + OleCheck( VJtag.Mimosa28ConfGetLinePat1 ( (long) ViRegLinePat, (unsigned long*) &VPtTestCont->ParUlt1ALinePat1[ViMaps].AW32[ViRegLinePat], (unsigned long*) &VRegValFromMi26, &VStrComStatus ) ); + } + + ULT1__FBuildMatDiscriW32FromLinePatReg ( &VPtTestCont->ParUlt1ALinePat0[ViMaps], &VPtTestCont->ParUlt1ALinePat1[ViMaps], &VPtTestCont->InfUlt1TmpMatW32 ); + ULT1__FMatDiscriConvW32ToBit ( &VPtTestCont->InfUlt1TmpMatW32, &VPtTestCont->InfUlt1AMatBitFromJtag[ViMaps] ); + + ULT1__FMatDiscriPrintHit ( "Emulated matrix from JTAG" /* CmtStrTitle */, ViMaps /* CmtSInt8MapsId */, &VPtTestCont->InfUlt1AMatBitFromJtag[ViMaps] ); + + } // End for + + } + + else { + + for ( ViMaps=0; ViMaps < VPtTestCont->ParMapsNb; ViMaps++ ) { + VPtTestCont->ParAMapsHeaderRef[ViMaps] = 0; // Mimosa 26 header field + VPtTestCont->ParAMapsTrailerRef[ViMaps] = 0; // Mimosa 26 trailer field + } + + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + + CoUninitialize(); + + #else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + #endif + + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 19/05/2011 ( DPXI version of 20/08/2009 moved here ) +Rev : 15/05/2013 + : - Modification of frame counter test, the test Fr(n+1) = Fr(n) + 1 has been + : removed because in beam test (EUDET3 mode) the frames in one acquisition are + : not all consecutives, there it detects fake errors. Now the test is only done + : by a comparison of all Mimosa 28 frame couters frame by frame. + : + : 25/04/2013 + : - Update test context field ResErrOnCurrentAcq with errors count + : + : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameLight ( SInt16 FuncId, SInt32 CurFrame, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // err_error (( ERR_OUT, "TRACE : ParMapsNbToTest=%d - Mi26Nb=%d - VMi26Nb=%d", VPtTestCont->ParMapsNbToTest, Mi26Nb, VMi26Nb )); + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the one of Mimosa28 [0] + // This is done frame by frame = doesn't care about previous frame counter value - 15/05/2013 + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Frame cnt error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Header error %s - %s : [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Trailer error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 31/01/14 Bug fix : Error status stored in ResErrOnCurrentAcq flag was cleared if one of the following MAPS has no error + // The above line shows the code with bug + // VPtTestCont->ResErrOnCurrentAcq = VErrors; // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + return (VErrors); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 23/01/2014 ( DPXI version of 20/08/2009 moved here ) +: +Rev : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( SInt16 FuncId, EFRIO__TFrame* PtFrame, SInt16 CurFrame, SInt8 Mi26Nb, UInt32 FrameCntOfFirstFrameOfAcq ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // err_error (( ERR_OUT, "TRACE : ParMapsNbToTest=%d - Mi26Nb=%d - VMi26Nb=%d", VPtTestCont->ParMapsNbToTest, Mi26Nb, VMi26Nb )); + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + // VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + VPtTestCont->InfMapsFrameCntRef = FrameCntOfFirstFrameOfAcq + CurFrame; // 23/01/2014 + + // err_error (( ERR_OUT, "TRACE => FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + +// if ( VPtTestCont->ParPrintLvl == 2 ) { +// msg (( MSG_OUT, "FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); +// } + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the frame counter (Mi28[0]) of first frame of acq + frame no + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Frame cnt error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Header error %s - %s : [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Trailer error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + + // Print headers values + + if ( (VPtTestCont->ParPrintLvl == 3) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Header [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + + // Print fames counter values + + if ( (VPtTestCont->ParPrintLvl == 4) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + msg (( MSG_OUT, "Frame cnt [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + + // Print trailers values + + if ( (VPtTestCont->ParPrintLvl == 5) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Trailer [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 31/01/14 Bug fix : Error status stored in ResErrOnCurrentAcq flag was cleared if one of the following MAPS has no error + // The above line shows the code with bug + // VPtTestCont->ResErrOnCurrentAcq = VErrors; // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + return (VErrors); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 24/01/2014 ( DPXI version of 20/08/2009 moved here ) +: +Rev : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( SInt16 FuncId, EFRIO__TFrame* PtFrame, SInt16 CurFrame, SInt8 Mi26Nb, UInt32 FrameCntOfFirstFrameOfAcq ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + SInt32 VErrNbOnMatrix; + + ULT1__TZsFFrame* VUlt1APtZsFFRame[EFRIO__MAX_ASIC_NB]; + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + + // msg (( MSG_OUT, "SIZE : ULT1__TZsFFrame=%d - ResUlt1AZsFFrame=%d", sizeof(ULT1__TZsFFrame), sizeof(VPtTestCont->ResUlt1AZsFFrame) )); + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // err_error (( ERR_OUT, "TRACE : ParMapsNbToTest=%d - Mi26Nb=%d - VMi26Nb=%d", VPtTestCont->ParMapsNbToTest, Mi26Nb, VMi26Nb )); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VUlt1APtZsFFRame[ViMi26] = &VPtTestCont->ResUlt1AZsFFrame[ViMi26]; + } + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + // VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + VPtTestCont->InfMapsFrameCntRef = FrameCntOfFirstFrameOfAcq + CurFrame; // 23/01/2014 + + // err_error (( ERR_OUT, "TRACE => FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the frame counter (Mi28[0]) of first frame of acq + frame no + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Frame cnt error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Header error %s - %s : [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Trailer error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + + // Print headers values + + if ( (VPtTestCont->ParPrintLvl == 3) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Header [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + + // Print fames counter values + + if ( (VPtTestCont->ParPrintLvl == 4) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + msg (( MSG_OUT, "Frame cnt [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + + // Print trailers values + + if ( (VPtTestCont->ParPrintLvl == 5) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Trailer [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } // End for ViMi26 + + + // Matrix - $$$$ + + EFRIO__ULT1_FConvTFrameToZsFFrame ( PtFrame, VUlt1APtZsFFRame, 8 /* Mi28DestBuffersNb */, 0 /* PrintLevel */ ); + + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + ULT1__FConvZsFFrameToMatDiscriBit ( VUlt1APtZsFFRame[ViMi26], &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26], NULL /* PtOvfCnt */, 0 /* PrintLvl */ ); + + VErrNbOnMatrix = ULT1__FCompareMatDiscriBit ( VPtTestCont->ParAMatPatternLineNb[ViMi26] /* LineNbToCompare */, &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26] /* PtMat */, &VPtTestCont->InfUlt1AMatBitFromJtag[ViMi26] /* PtMatRef */, VPtTestCont->ParPrintLvl, ViMi26 /* PrintMimosaId */, PtFrame->Header.AcqId /* PrintAcqId */, PtFrame->Header.FrameIdInAcq /* PrintFrameId */ ); + + if ( VErrNbOnMatrix != 0 ) { + VPtTestCont->ResAMapsMatrixErrCnt[ViMi26] += VErrNbOnMatrix; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; // Count ONLY one error if error(s) on matrix in order to avoid cumul counters ovf + ++VPtTestCont->ResTotErrCnt; // Count ONLY one error if error(s) on matrix in order to avoid cumul counters ovf + VErrors = 1; + } + + if ( VPtTestCont->ParPrintLvl == 7) { + ULT1__FMatDiscriPrintHit ( "Matrix from DAQ ", ViMi26 /* CmtSInt8MapsId */, &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26] ); + } + + + } // End for ViMi26 + + + + +// if ( 1 /* CurFrame % 10 == 0 */ ) { +// EFRIO__ULT1_FConvTFrameToZsFFrame ( PtFrame, VUlt1APtZsFFRame, 8 /* Mi28DestBuffersNb */, 0 /* PrintLevel */ ); +// ULT1__FConvZsFFrameToMatDiscriBit ( VUlt1APtZsFFRame[0], &VPtTestCont->ResUlt1AMatBitFromDaq[0], NULL /* PtOvfCnt */, 0 /* PrintLvl */ ); +// ULT1__FMatDiscriPrintHit ( "Matrix from DAQ ", 0 /* CmtSInt8MapsId */, &VPtTestCont->ResUlt1AMatBitFromDaq[0] ); +// } + + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 31/01/14 Bug fix : Error status stored in ResErrOnCurrentAcq flag was cleared if one of the following MAPS has no error + // The above line shows the code with bug + // VPtTestCont->ResErrOnCurrentAcq = VErrors; // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + return (VErrors); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : This is a user level function. +Date : 30/01/2014 ( DPXI version of 20/08/2009 moved here ) + : +Rev : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( SInt16 FuncId, EFRIO__TFrame* PtFrame, SInt8 Mi26Nb ) { + + + SInt32 VRet; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt8 VMi26Nb; + SInt8 ViMi26; + static SInt8 VErrors; + EFRIO__TFrameHeader* VPtFrHd; + SInt32 VErrNbOnMatrix; + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + ULT1__TZsFFrame* VUlt1APtZsFFRame[EFRIO__MAX_ASIC_NB]; + + + + + // msg (( MSG_OUT, "SIZE : ULT1__TZsFFrame=%d - ResUlt1AZsFFrame=%d", sizeof(ULT1__TZsFFrame), sizeof(VPtTestCont->ResUlt1AZsFFrame) )); + + // ----------------------------------------------- + // Test disabled => Exit + // ----------------------------------------------- + + if ( VPtTestCont->ParModeEnable == 0 ) { + return (0); + } + + + // ----------------------------------------------- + // Perform test + // ----------------------------------------------- + + // Init ptr + + VPtFrHd = &PtFrame->Header; + + // Check MAPS nb to test + + if ( Mi26Nb > VPtTestCont->ParMapsNbToTest ) { + VMi26Nb = VPtTestCont->ParMapsNbToTest; + } + + else { + VMi26Nb = Mi26Nb; + } + + // err_error (( ERR_OUT, "TRACE : ParMapsNbToTest=%d - Mi26Nb=%d - VMi26Nb=%d", VPtTestCont->ParMapsNbToTest, Mi26Nb, VMi26Nb )); + + + for ( ViMi26=0; ViMi26 < Mi26Nb; ViMi26++ ) { + VUlt1APtZsFFRame[ViMi26] = &VPtTestCont->ResUlt1AZsFFrame[ViMi26]; + } + + // Reset errors flag + + VErrors = 0; + + // Check frame cnt & header & trailer + + // Store frame counter of first Mi28 to use it as a reference value + + VPtTestCont->InfMapsFrameCntRef = VPtFrHd->AMapsFrameCnt[0]; // 15/05/2013 + + // err_error (( ERR_OUT, "TRACE => FrameCntOfFirstFrameOfAcq=%d - CurFrame=%d - InfMapsFrameCntRef = %d", FrameCntOfFirstFrameOfAcq, CurFrame, VPtTestCont->InfMapsFrameCntRef )); + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + // Check frame counter => Compare all Mimosa 28 frame counters to the frame counter (Mi28[0]) of first frame of acq + frame no + + if ( VPtFrHd->AMapsFrameCnt[ViMi26] != VPtTestCont->InfMapsFrameCntRef ) { + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Frame cnt error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + } + + + // Check header and trailer + + if ( VPtFrHd->AMapsHeader[ViMi26] != VPtTestCont->ParAMapsHeaderRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsHeaderErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Header error %s - %s : [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + } + + if ( VPtFrHd->AMapsTrailer[ViMi26] != VPtTestCont->ParAMapsTrailerRef[ViMi26] ) { + + ++VPtTestCont->ResAMapsTrailerErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + // Print errors + + if ( VPtTestCont->ParPrintLvl == 1 ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Trailer error %s - %s : [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } + + + // Print headers values + + if ( (VPtTestCont->ParPrintLvl == 3) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Header [Acq %.4d - Frame in Acq %.4dx - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsHeader[ViMi26], VPtTestCont->ParAMapsHeaderRef[ViMi26] )); + } + + + // Print fames counter values + + if ( (VPtTestCont->ParPrintLvl == 4) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Frame cnt [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %.6d - Must be %.6d ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsFrameCnt[ViMi26], VPtTestCont->InfMapsFrameCntRef )); + } + + + // Print trailers values + + if ( (VPtTestCont->ParPrintLvl == 5) || (VPtTestCont->ParPrintLvl == 6) ) { + msg (( MSG_OUT, "Trailer [Acq %.4d - Frame in Acq %.4d - Mi26 No %d] : Get %8x - Must be %.8x ", VPtFrHd->AcqId, VPtFrHd->FrameIdInAcq, ViMi26, VPtFrHd->AMapsTrailer[ViMi26], VPtTestCont->ParAMapsTrailerRef[ViMi26] )); + } + + } // End for ViMi26 + + + // Matrix - $$$$ + + EFRIO__ULT1_FConvTFrameToZsFFrame ( PtFrame, VUlt1APtZsFFRame, 8 /* Mi28DestBuffersNb */, 0 /* PrintLevel */ ); + + + for ( ViMi26=0; ViMi26 < VMi26Nb; ViMi26++ ) { + + ULT1__FConvZsFFrameToMatDiscriBit ( VUlt1APtZsFFRame[ViMi26], &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26], NULL /* PtOvfCnt */, 0 /* PrintLvl */ ); + + VErrNbOnMatrix = ULT1__FCompareMatDiscriBit ( VPtTestCont->ParAMatPatternLineNb[ViMi26] /* LineNbToCompare */, &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26] /* PtMat */, &VPtTestCont->InfUlt1AMatBitFromJtag[ViMi26] /* PtMatRef */, VPtTestCont->ParPrintLvl, ViMi26 /* PrintMimosaId */, PtFrame->Header.AcqId /* PrintAcqId */, PtFrame->Header.FrameIdInAcq /* PrintFrameId */ ); + + if ( VErrNbOnMatrix != 0 ) { + VPtTestCont->ResAMapsMatrixErrCnt[ViMi26] += VErrNbOnMatrix; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; // Count ONLY one error if error(s) on matrix in order to avoid cumul counters ovf + ++VPtTestCont->ResTotErrCnt; // Count ONLY one error if error(s) on matrix in order to avoid cumul counters ovf + VErrors = 1; + } + + if ( VPtTestCont->ParPrintLvl == 7) { + ULT1__FMatDiscriPrintHit ( "Matrix from DAQ ", ViMi26 /* CmtSInt8MapsId */, &VPtTestCont->ResUlt1AMatBitFromDaq[ViMi26] ); + } + + + } // End for ViMi26 + + + + + // if ( 1 /* CurFrame % 10 == 0 */ ) { + // EFRIO__ULT1_FConvTFrameToZsFFrame ( PtFrame, VUlt1APtZsFFRame, 8 /* Mi28DestBuffersNb */, 0 /* PrintLevel */ ); + // ULT1__FConvZsFFrameToMatDiscriBit ( VUlt1APtZsFFRame[0], &VPtTestCont->ResUlt1AMatBitFromDaq[0], NULL /* PtOvfCnt */, 0 /* PrintLvl */ ); + // ULT1__FMatDiscriPrintHit ( "Matrix from DAQ ", 0 /* CmtSInt8MapsId */, &VPtTestCont->ResUlt1AMatBitFromDaq[0] ); + // } + + + + // Update counter of frames with error(s) + + if ( VErrors ) { + ++VPtTestCont->ResFrameNbWithErr; + } + + // FuncId = 1 => Emulate errors + // Code not UP TO DATE !!!!!!!!!!!!!!!!!!!!!!!! + + if ( FuncId == 1 ) { + + if ( (VPtFrHd->AcqId % 10) == 0 ) { + msg (( MSG_OUT, "Error emulation on Acq=%d", VPtFrHd->AcqId )); + VErrors = 1; + } + + } + + // 31/01/14 Bug fix : Error status stored in ResErrOnCurrentAcq flag was cleared if one of the following MAPS has no error + // The above line shows the code with bug + // VPtTestCont->ResErrOnCurrentAcq = VErrors; // 25/04/2013 + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + return (VErrors); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 25/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ); // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VDbgDataLenghtD0, VDbgDataLenghtD1 )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy all data fields = We don't care about DataLength field + // We can decide to optimize later, but NOW I want to get ALL board RAM + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = MI26__ZS_FFRAME_RAW_MAX_W8; + VPtFrame->Data.OneMapsSz = MI26__ZS_FFRAME_RAW_MAX_W8; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + } + + ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + VDataLengthW32)]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1)]; + ++ViSrcW32; + + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2)]; + ++ViSrcW32; + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 1 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 1 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is not enabled in EUDET mode 1, therefore TLU trigger is + : ignored. Only the first three triggers are stored by Flex RIO and coded in + : "Mi26 format" = line index of Mimosa 26 read when trigger occurs. + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 27/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V6iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 6; // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointers + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V6iFrame = 6 * ViFrame; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // If length > max possible => Set it to 0 + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + memcpy ( VPtFrame->Data.ADataW32, &PtSrcW32[ViSrcW32], VDataLengthW8ToCpy ); + + // err_error (( ERR_OUT, "TRACE => VDataLengthW8ToCpy=%d", VDataLengthW8ToCpy )); + + // for ( ViDataW32=0; ViDataW32 < VDataLengthW32ToCpy; ViDataW32++ ) { + // VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // } + + // ViSrcW32 = ViSrcW32 + ( (6 * MI26__ZS_FFRAME_RAW_MAX_W32) - VDataLengthW32ToCpy ); + + ViSrcW32 += (6 * MI26__ZS_FFRAME_RAW_MAX_W32); + + +// VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length +// ++ViSrcW32; + +// VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; +// VptZsFFrameRaw[V6iFrame].Zero = VZero; +// ++ViSrcW32; + +// VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; +// VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; +// ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 1 + (6 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 2 + (6 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 3 + (6 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 4 + (6 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + 5 + (6 * VADataLengthW32[5])]; + ++ViSrcW32; + + VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + + ViSrcW32 += 12; // 6 times 2 zero fields = 12 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTrigRec->TrigNb = VTrigNb; + VPtTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ); + VPtTrigRec->TrigType = 1; + VPtTrigRec->ATrig[0] = VAMi26Trig[0]; + VPtTrigRec->ATrig[1] = VAMi26Trig[1]; + VPtTrigRec->ATrig[2] = VAMi26Trig[2]; + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Ultimate 1 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 11/05/2011 + : - Convert function fromM26 readout to Ultimate 1 + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt32 VErrorsOnData; // 26/04/2013 + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ) || (VDbgDataLenghtD1 > ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - ViFrame=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", ViFrame, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( ULT1__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * ULT1__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + ULT1__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * ViFrame) + (2 * (3 + ULT1__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_error (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + } // End for ViFrame + + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 19/05/2011 + : - Convert function fromM26 readout to Ultimate 1 + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1__fion_rewritten ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 26/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + +// $$$$$$$$$$$$$$ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 25/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // err_error (( ERR_OUT, "VDataLengthW16Max = %d", VDataLengthW16Max )); + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 6; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; // 3; !!! 08/06/2011 => Force 3 triggers !!! + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + ( /* !!! 08/06/2011 => Force 3 triggers !!! 3 */ VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + // Update frames & events counters ONLY if there is no errors on data - 25/04/2013 + + if ( VErrorsOnData == 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 29/10/2010 version handling 6 Mi26 ) +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode + : + : 09/06/2011 + : - Fix bug in "end of frame" triggers info calculation => 32 clk / line not 16 like Mi26 + : + : 29/10/2013 + : - Upgrade the code for Ult1, previous code was a copy of Mi26 code + : + : 30/01/2014 + : - Add data test options, selection done from DAQ GUI "Enable data test" list + : -- 0 : No test + : -- 1 : Light (H, FC compare,T) => Test Header, Trailer, compare Frame Counter MAPS 0..7 but dont check increment + : -- 2 : Basic (H, FC increment,T) => Test Header, Trailer, check Frame Counter MAPS 0..7 increment during one Acq + : -- 3 : Data (Basic + Matrix) => Basic test + Compare matrix data to expected pattern calculated from JTAG + : + : 01/02/2014 + : - Handle return value from header, frame counter, trailer, matrix data test functions + : => Don't increment RunCont.ResAcqCnt, ResFrameCnt, ResEventCnt in case of error(s) + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V9iFrame; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V9iFrame = 9 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi28 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (9 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; // 9 = 9 x 1 Trailer + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9iFrame) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 18]; // 18 = 9 x ( 1 Trailer + 1 Zero ) + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // xx/01/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + + // $$$$ + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + // Update frames & events counters ONLY if there is no errors on data - 01/02/14 + + if ( VErrorsOnData == 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + if ( (VPtCont->RunCont.ResAcqCnt % 100) == 0 ) { + + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Run status %s - %s : %d Acq - %d Frames - %d Errors", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtCont->RunCont.ResAcqCnt, VPtCont->RunCont.ResFrameCnt, VPtCont->TestOnDataCont.ResTotErrCnt )); + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : + : XX/05/2011 + : - Upgrade Mi26 function for Ultimate 1 + : + : 07/06/2011 + : - Modify frames with trigger search loop to solve FW trigger bug ( delayed by 2 frames ) + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + + EFRIO__TFrame* VPtFrame; + EFRIO__TFrame* VPtFrameMinus2; // Pointer two frames before VPtFrame to solve FW trigger bug + + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + EFRIO__TTriggerRec* VPtTrigRecFrameMinus2; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + SInt16* VPtFwTrigBugFrameWithTrigTrigNb; + SInt16* VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2; + + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + // Limits of trigger info search in case of FW trigger bug + // => trigger info appears N (should be 2) frames after trigger occurs + + SInt32 VFwTrigBugFirstFrameTrigInfAllowed; + SInt32 VFwTrigBugLastFrameTrigInfAllowed; + SInt32 VFwTrigBugLastFrameIdStored; + SInt32 VErrorsOnData; // 26/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // 09/06/2011 + + memset ( VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0], 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0][0]) ); + + memset ( VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0], 0, (EFRIO__MAX_FRAME_NB_PER_ACQ + 10) * sizeof (VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0][0]) ); + + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + VPtFwTrigBugFrameWithTrigTrigNb = VPtCont->FwTrigBugAAAcqFrameWithTrigTrigNb[0]; // 09/06/2011 + + VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2 = VPtCont->FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[0]; // 09/06/2011 + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + + +// Frame with trigger search loop in case of FW bug on trigger +// => Trigger info appears two frames after trigger + +#define FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + +#ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // ------------------------------------------------------------------ + // Trigger bug + // - Info in zero fields at end of frame are at the right place + // => The info extracted from zero fields are ok without any shift + // => Trigger Nb & the first three triggers are OK + // - But the triggers list stored in extra channel will appear two + // frames later + // ------------------------------------------------------------------ + // The frame which contains trigger (in data) must be in current acq + // = we don't want to handle trigger from one acq to the next one + // We take 3 frames after the one which contains trigger + // = constant EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is ignored + // ------------------------------------------------------------------ + // => we exit function if EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is <> 3 + // => we reject trigger if info appears on frame > FrameNbPerAcq - 4 + + + if ( EFRIO__FRAME_NB_TO_READ_AFTER_TRIG != 3 ) { + err_retfail ( -1, (ERR_OUT,"Abort => EFRIO__FRAME_NB_TO_READ_AFTER_TRIG=%d <> 3 => NOT handled in trig fw bug correction mode !", EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ); + } + + + VFwTrigBugFirstFrameTrigInfAllowed = 0; + VFwTrigBugLastFrameTrigInfAllowed = VPtBoard->FrameNbPerAcq - 4; + + VFwTrigBugLastFrameIdStored = -1; + + // Start search on first frame trigger info is allowed + + for ( VFrameId=VFwTrigBugFirstFrameTrigInfAllowed; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + +// -------------------- + + if ( (VTrigNb != 0) && (VFrameId <= VFwTrigBugLastFrameTrigInfAllowed) ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + + if ( VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] != 0 ) { + err_warning (( ERR_OUT, "Trigger error => Elt[%d] = frame %d already filled with %d", VFrameWithTrigCnt, VFrameId, VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] )); + } + + VPtFwTrigBugFrameWithTrigTrigNb[VFrameWithTrigCnt] = VTrigNb; // Store trigger cnt in frame which doesn't contain extra chan trig list + + VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[VFrameWithTrigCnt + 2] = 1; // Set flag "is trigger list" of frame No - 2 + + ++VFrameWithTrigCnt; + } + + else { + + if ( (VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + +// -------------------- + + } // End for ( ViFrame ) + + +// Frame with trigger search loop in case the is NO FW bug on trigger + +#else + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + +#endif + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + VPtFrameMinus2 = NULL; // 07/06/2011 + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + // 07/06/2011 + + if ( VPtFrList->TotFrameNb > 1 ) { + VPtFrameMinus2 = VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 2]; + } + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + // Test coherence of trigger nb list / current frame trigger nb info + + if ( (VTrigNb > 0) && (VPtFwTrigBugFrameWithTrigTrigNb[ViFrameWithTrig] != VTrigNb) ) { + err_warning (( ERR_OUT, "Trigger nb list error => ViFrameWithTrig=%d - FrameId=%d - TrigNb=%d <> Trig nb from list=%d", ViFrameWithTrig, VPtFrameWithTrigList[ViFrameWithTrig], VTrigNb, VPtFwTrigBugFrameWithTrigTrigNb[ViFrameWithTrig] )); + } + + + #ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + VPtFrame->Header.TrigStatus = VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[ViFrameWithTrig]; + #else + VPtFrame->Header.TrigStatus = 0; + #endif + + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; // 3; 08/06/2011 !!! Force 3 triggers !!! + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + ( /* !!! 08/06/2011 Force 3 triggers !!! */ VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + #ifdef FRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // If current frame contains triggers list of frame N-2 => Update frame N-2 + + if ( VPtFwTrigBugFrameWithTrigIsTrigListFrMinus2[ViFrameWithTrig] == 1 ) { + + // Do it only if pointer is valid + + if ( VPtFrameMinus2 != NULL ) { + + // Trigger record should have the same size as current frame because same trigger nb + // But check in case of ... + + VPtTrigRecFrameMinus2 = (EFRIO__TTriggerRec*) ( (UInt32) VPtFrameMinus2 + VPtFrameMinus2->TrigRecOffset ); + + if ( VPtTrigRecFrameMinus2->TotSz == VPtTmpTrigRec->TotSz ) { + memcpy ( VPtTrigRecFrameMinus2, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + } + + else { + err_warning (( ERR_OUT, "Abort update trig rec of Fr-2 because TrigRecSz=%d <> Current frame[%d] TrigRecSz=%d", VPtTrigRecFrameMinus2->TotSz, ViFrameWithTrig, VPtTmpTrigRec->TotSz )); + } + + } + + + } + + #endif + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : + Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 28/04/2011 ( Upgrade to 8 Mi26 from 03/11/2010 version handling 6 Mi26 ) + : +Rev : 30/12/2010 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 27/01/2011 + : - Improve sw robustness against corruped data from Flex RIO + : + : 15/02/2011 + : - Update MonitorCont record fields + : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : + : XX/05/2011 + : - Upgrade Mi26 function for Ultimate 1 + : + : 07/06/2011 + : - Modify frames with trigger search loop to solve FW trigger bug ( delayed by 2 frames ) + : + : 29/10/2013 + : - Upgrade the code for Ult1, previous code was a copy of Mi26 code + : + : 30/01/2014 + : - Add data test options, selection done from DAQ GUI "Enable data test" list + : -- 0 : No test + : -- 1 : Light (H, FC compare,T) => Test Header, Trailer, compare Frame Counter MAPS 0..7 but dont check increment + : -- 2 : Basic (H, FC increment,T) => Test Header, Trailer, check Frame Counter MAPS 0..7 increment during one Acq + : -- 3 : Data (Basic + Matrix) => Basic test + Compare matrix data to expected pattern calculated from JTAG + : + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V9FrameId; + UInt32 VADataLengthField[8]; + UInt32 VADataLengthW8[8]; + UInt16 VADataLengthW16[8]; + UInt32 VADataLengthW32[8]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + // SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[8]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + SInt8 ViMi26ChkDataLength; + SInt32 VErrorsOnData; // 26/04/2013 + + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ ) / 9; // Divide by 9 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + + // Frame with trigger search loop in case of FW bug on trigger + // => Trigger info appears two frames after trigger + +#ifdef EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + // ------------------------------------------------------------------ + // The frame which contains trigger (in data) must be in current acq + // = we don't want to handle trigger from one acq to the next one + // We take 3 frames after the one which contains trigger + // = constant EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is ignored + // ------------------------------------------------------------------ + // => we exit function if EFRIO__FRAME_NB_TO_READ_AFTER_TRIG is <> 3 + // => we reject trigger if info appears on frame no < 2 + // => we reject trigger if info appears on frame > FrameNbPerAcq - 3 + 1 + + + err_retfail ( -1, (ERR_OUT,"Abort => Correction for FW trigger bug NOT IMPLEMENTED yet !") ); + + +// Frame with trigger search loop in case the is NO FW bug on trigger + +#else + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V9FrameId = 9 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + +#endif + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 9 * ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V9FrameId = 9 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[6] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[7] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + VADataLengthW16[6] = (VADataLengthField[6] & 0x0000FFFF) + ((VADataLengthField[6] & 0xFFFF0000) >> 16); + VADataLengthW16[7] = (VADataLengthField[7] & 0x0000FFFF) + ((VADataLengthField[7] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 8 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViMi26ChkDataLength = 0; ViMi26ChkDataLength < 8; ViMi26ChkDataLength++ ) { + if ( VADataLengthW16[ViMi26ChkDataLength] > ULT1__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViMi26ChkDataLength, VADataLengthW16[ViMi26ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 8 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 8 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 8 * sizeof (VADataLengthW32[0]) ); + + /* Removed on 02/03/2011 + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = 0; + VADataLengthW16[ViMi26] = 0; + VADataLengthW32[ViMi26] = 0; + } + + */ + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + } + + else { + + for ( ViMi26=0; ViMi26 < 8; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + VPtFrame->Header.AMapsDataLength[6] = VADataLengthW8[6]; + VPtFrame->Header.AMapsDataLength[7] = VADataLengthW8[7]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 8; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + // WARNING 06/05/2011 => This part has been updated BUT not tested + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + VAPtCpyDestW32[6] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 6 * VDataLengthW32Max ) ); + VAPtCpyDestW32[7] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 7 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[6] = *VPtCpySrcW32; + ++VAPtCpyDestW32[6]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[7] = *VPtCpySrcW32; + ++VAPtCpyDestW32[7]; + ++VPtCpySrcW32; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 8; // Bypass Mi26 x 8 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 9; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (9 * ULT1__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * VADataLengthW32[0])]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 1 + (9 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 2 + (9 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 3 + (9 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 4 + (9 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 5 + (9 * VADataLengthW32[5])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[6] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 6 + (9 * VADataLengthW32[6])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[7] = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + 7 + (9 * VADataLengthW32[7])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; // 27 = 9 x 3 Fields nb before first data = Header, Frame cnt, Data length + } // 9 = 9 x 1 Trailer + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 9]; + + VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V9FrameId) + 27 + (9 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 18]; + + ViSrcW32 += 18; // 9 times 2 zero fields = 18 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // 30/01/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrameWithTrig, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrameWithTrig, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrameWithTrig, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + } + + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + // + // EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 8 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + if ( (VPtCont->RunCont.ResAcqCnt % 100) == 0 ) { + + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Run status %s - %s : %d Acq - %d Frames - %d Errors", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), VPtCont->RunCont.ResAcqCnt, VPtCont->RunCont.ResFrameCnt, VPtCont->TestOnDataCont.ResTotErrCnt )); + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataUlt1 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 27/03/2013 + : - Add param DataTestTotErrCnt and return it as run status in RunCont.ParDaqVersion + : using bits B00B23, bits B24B31 are reserved for Daq version. + : + : 31/01/14 + : - Bug fix on VPtTestCont->ResErrOnCurrentAcq handling + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataUlt1 ( SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode, UInt32 DataTestTotErrCnt ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + + + // 31/01/14 Bug fix : + // The bug fix is not here, it's done in data test functions on ResErrOnCurrentAcq handling + // but NOW we must reset data test "error(s) on current acq flag" at beginning of each acquisition + + VPtTestCont->ResErrOnCurrentAcq = 0; + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + // Emule frames if needed + + if ( EmuleMode != 0 ) { + + while (1) { + + if ( (DataConvertMode == EFRIO__TRF_MODE_IPHC) || (DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN)) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - IPHC / EUDET 1 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Emul - IPHC / EUDET 1 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData6Mi26NoEChan ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of Ultimate = %d is not handled for frame emulation WITHOUT extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_IPHC ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 2 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 2 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode2 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of Ultimate = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 3 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData1Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 6 : { + EFRIO__ULT1_FFRioEmulDeserData6Ult1EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Emul - EUDET 3 - %d Ultimates => Not hanled now !", Mi26Nb ) ); + EFRIO__MI26_FFRioEmulDeserData8Mi26EudetMode3 ( PtSrcW32AsPt, EltNb, &VEmuleFirstFrameNo, VEmuleFrameNb, EmuleMode ); + break; } + + default : { + err_warning (( ERR_OUT, "This number of M26 = %d is not handled for frame emulation WITH extra channel !", Mi26Nb )); + break; } + + } // End switch + + break; + } // End if ( EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) + + + } // End while + + } // End if ( EmuleMode == 1 ) + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC is not handled for Ultimate" ) ); + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet1Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + switch ( Mi26Nb ) { + + case 1 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + // err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi28 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode8Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + switch ( Mi26Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 6 : { + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode6Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + // err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi28 = %d is not handled now", Mi26Nb ) ); + VRet = EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode8Ult1 ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi28 = %d is not handled now", Mi26Nb ) ); + break; } + + } + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + // WARNING ! Use ParDaqVersion to return Data test total errors counter + // Overwrite the ParDaqVersion field with the errors count converted in a NEGATIVE NUMBER + + VPtCont->RunCont.ParDaqVersion = DataTestTotErrCnt & 0x00FFFFFF; // B24B31 reserved for Daq version + + + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 08/11/2013 + : - Add dev 0 selection to fix "JTAG GUI panel bug" when using only one MAPS + : following an advise from KKJ, but it solves nothing ... let in place, in case of ... + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagLoadFile ( char* FileName ) { + + HRESULT VRetCode; + WideString VStatus; + WideString VFileName; + +#ifdef EFRIO__INCLUDE_PARA_PORT + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + + if ( VJtag.IsBound () ) { + + VFileName = FileName; + + OleCheck( VRetCode = VJtag.MasterConfLoadFile( VFileName , &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Load JTAG file = %s failed !", FileName) ); + } + + + // 08/11/2013 + // Add dev 0 selection to fix "JTAG GUI panel bug" when using only one MAPS + // following an advise from KKJ, but it solves nothing ... let in place, in case of ... + + OleCheck( VRetCode = VJtag.MasterConfSetDevNum ( 0, &VStatus ) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"Set JTAG DevNum 0 failed !" ) ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 13/03/2013 +Rev : +: +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagLoadDefFile () { + + SInt32 VRet; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + char VFileName[GLB_FILE_PATH_SZ]; + + sprintf ( VFileName, "%s", "c:\\ccmos_sctrl\\Mimosa28_jtag\\config_files\\Default.mcf" ); + + msg (( MSG_OUT, "### EFRIO__ULT1_FJtagLoadDefFile (FileName=%s)", VFileName )); + + VRet = EFRIO__ULT1_FJtagLoadFile (VFileName); + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagReset ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfReset (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Reset chip failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); +#endif + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : + : 20/03/2013 + : - Exit if r/w errors detected on MasterConfReadBack () call + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__ULT1_FJtagLoadChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + SInt32 VRbErr; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + + + +#ifdef EFRIO__INCLUDE_JTAG + +// msg (( MSG_OUT, "EFRIO__ULT1_FJtagLoadChip ()")); + + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfUpdateAll (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + OleCheck( VRetCode = VJtag.MasterConfReadBack (&VRbErr, &VStatus) ); + +// msg (( MSG_OUT, "EFRIO__ULT1_FJtagLoadChip ( ) => Readback code=%d - errnb=%d", VRetCode, VRbErr )); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Read back chip parameters failed !") ); + } + + if ( VRbErr > 0 ) { + err_retfail ( -VRbErr, (ERR_OUT,"JTAG -> Read back chip => Write <> Read => %d errors !", VRbErr ) ); + } + + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + +#endif + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2010 +Rev : 04/02/2011 + : - Use a local ( in function ) JTAG COM object instance, global used before + : but this was incompatible with multithreading ( => application crash ) + : +Doc date : 09/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FJtagStartChip ( ) { + + HRESULT VRetCode; + WideString VStatus; + +#ifdef EFRIO__INCLUDE_JTAG + TCOMIMI28COM VJtag; + HRESULT VHrComErr; + WideString VStrComStatus; +#endif + + +#ifdef EFRIO__INCLUDE_JTAG + + // COM handling + + VHrComErr = CoInitialize (NULL); + + if ( FAILED (VHrComErr) ) { + err_retfail ( -1, (ERR_OUT,"CoInitialize failed !" ) ); + } + + VHrComErr = CoMI28COM::Create( VJtag ); + + if ( FAILED (VHrComErr) ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"CoMI26MasterConf::Create failed !" ) ); + } + + if ( VJtag.IsBound () ) { + + OleCheck( VRetCode = VJtag.MasterConfStart (&VStatus) ); + + if ( VRetCode != S_OK ) { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG -> Load chip parameters failed !") ); + } + + } + + else { + CoUninitialize(); + err_retfail ( -1, (ERR_OUT,"JTAG com interface problem") ); + } + + CoUninitialize(); + err_retok (( ERR_OUT, "" )); + +#else + + err_warning (( ERR_OUT, "JTAG control disabled by conditionnal compilation" )); + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2010 +Doc date : 10/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FHwStartChip ( SInt32 SpareS32Par ) { + + err_warning (( ERR_OUT, "EFRIO__MI26_FHwStartChip (Par=%d)", SpareS32Par )); + + // Start = D6, Speak = D7* + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD6 ( 0 /* Id */, 0 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 1 ); + PPO_FOutD6 ( 0 /* Id */, 0 ); + + #else + err_warning (( ERR_OUT, "HW start not done -> // port not enabled !" )); + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for one Mi26 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : DOIT ETRE A LA FIN DU FICHIER ! + : Suite a ouverture avec C++B, pose probleme a code source manager sinon !!! + : +Level : This is a user level function. +Date : 03/11/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Update fields ResAcqCnt, ResFrameCnt, ResEventCnt in a different way + : -- incement ResAcqCnt ONLY if there is at least one trigger in acq + : -- ResFrameCnt = number of frames with trigger + N following one + : -- ResEventCnt = ResFrameCnt + : + : + : - Add parameter TriggerHandlingMode + : - Always take first EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames if TriggerHandlingMode = 1 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FFRioAcqDeserDataEudet3Mode1Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + UInt32 VDataLengthField; + UInt32 VDataLengthW8; + UInt32 VDataLengthW16; + UInt32 VDataLengthW32; + SInt32 ViSrcW32; + SInt32 ViSrcW32BeforeDataCpyLoop; + SInt32 ViDataW32; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + + UInt16 VDbgDataLenghtD0; + UInt16 VDbgDataLenghtD1; + + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + + SInt16 ViFrameWithTrig; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + // err_trace (( ERR_OUT, "EFRIO__MI26_FFRioAcqDeserDataEudet1Mode1Mi26 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ ) / 2; // Divide by 2 because of extra channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * 2 ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + + // Print list of frames to extract + + /* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } + */ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VDataLengthField = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + VDataLengthW16 = (VDataLengthField & 0x0000FFFF) + ((VDataLengthField & 0xFFFF0000) >> 16); + + VDbgDataLenghtD0 = (VDataLengthField & 0x0000FFFF); + VDbgDataLenghtD1 = ((VDataLengthField & 0xFFFF0000) >> 16); + + if ( (VDbgDataLenghtD0 > 570) || (VDbgDataLenghtD1 > 570) ) { + VDataLengthW16 = 0; + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4d [D] - D1=%4d [D] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + err_error (( ERR_OUT, "HW error on data length - VFrameId=%d -> D0=%4x [H] - D1=%4x [H] -> Force 0 !", VFrameId, VDbgDataLenghtD0, VDbgDataLenghtD1 )); + } + + VDataLengthW8 = VDataLengthW16 * 2; + VDataLengthW32 = VDataLengthW16 / 2; + + + VPtFrame->Header.AMapsDataLength[0] = VDataLengthW16 * 2; + + // Copy only the useful data + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + VPtFrame->Data.TotSz = VDataLengthW8; + VPtFrame->Data.OneMapsSz = VDataLengthW8; + + + ViSrcW32BeforeDataCpyLoop = ViSrcW32; + + for ( ViDataW32=0; ViDataW32 < VDataLengthW32; ViDataW32++ ) { + VPtFrame->Data.ADataW32[ViDataW32] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + } + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // WARNING => Add test to avoid to read after end of current frame in case no last trigger info is found !!! + + ++ViSrcW32; // To bypass current W32 with is Mi26 data NOT trigger channel field + + do { + + VEChanTrigField = PtSrcW32[ViSrcW32]; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + ViSrcW32 += 2; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + // Update ViSrcW32 for following processing + + // ViSrcW32 = ViSrcW32 + ( MI26__ZS_FFRAME_RAW_MAX_W32 - VDataLengthW32 ); + + ViSrcW32 = ViSrcW32BeforeDataCpyLoop + ( 2 * MI26__ZS_FFRAME_RAW_MAX_W32 ); + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + VDataLengthW32))]; // 3 = Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; // Count Trailer field + ++ViSrcW32; // Count extra channel trigger field + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 1))]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + ++ViSrcW32; // Count Zero field + ++ViSrcW32; // Count extra channel trigger field + + VZero2 = PtSrcW32[(2 * MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * VFrameId) + (2 * (3 + MI26__ZS_FFRAME_RAW_MAX_W32 + 2))]; + ++ViSrcW32; // Count Zero2 field + ++ViSrcW32; // Count extra channel trigger field + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8 + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 1 /* Mi26Nb */ ); + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + + return (VTotAcqSz); + } + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) +: +Goal : print one frame content in log file +: +Inputs : PtRec - Pointer on the record +: +: PrintLevel - 0 -> Print nothing +: - > 0 -> print state list for each line +: +Ouputs : The function returns +: 0 if ok +: -1 if PtRec = NULL +: +Globals : +: +Remark : +: +Level : +Date : 22/12/2010 +Rev : 30/12/2010 +: - Add handling of N Mimosa 26 +: +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FConvTFrameToZsFFrame ( EFRIO__TFrame* PtRec, ULT1__TZsFFrame* APtDest[EFRIO__MAX_ASIC_NB], SInt8 Mi28DestBuffersNb, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + +// ULT1__TStatesLine VStatesLine; +// ULT1__TState VState; + + + ULT1__TStatesLine* VPtStatesLine; + ULT1__TState* VPtState; // [ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + + + SInt16 ViMi26; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + char VStrState[255]; + char VStrLine[255]; + + SInt32 VTimeBegMs; + SInt32 VTimeEndMs; + SInt32 VTimeExecMs; + + + // VTimeBegMs = GetTickCount (); + + // ------------------------------------- + // Check parameters + // ------------------------------------- + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL !") ); + + // Init pointers on TFrame sub records + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Check destination buffers nb + + if ( Mi28DestBuffersNb < VPtHead->MapsNb ) { + err_retfail ( -1, (ERR_OUT,"Abort : Not enought destination Mi28 buffers : %d allocated / %d require", Mi28DestBuffersNb, VPtHead->MapsNb) ); + } + + // Check destination buffers allocation + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb; ViMi26++ ) { + + if ( APtDest[ViMi26] == NULL ) { + err_retfail ( -1, (ERR_OUT,"Abort : Buffer [%d] for Mi28 not allocated (Ptr = NULL) !", ViMi26) ); + } + + } + + // ------------------------------------- + // Processing + // ------------------------------------- + + // Reset destination buffer + // Copy header, trailer, etc ... + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb; ViMi26++ ) { + + memset ( APtDest[ViMi26], 0, sizeof (ULT1__TZsFFrameRaw) ); + + APtDest[ViMi26]->SStatus.AsicNo = ViMi26; + APtDest[ViMi26]->SStatus.AcqNo = PtRec->Header.AcqId; + APtDest[ViMi26]->SStatus.FrameNoInAcq = PtRec->Header.FrameIdInAcq; + APtDest[ViMi26]->SStatus.FrameNoInRun = 0; // => Not yet calculated ! + APtDest[ViMi26]->SStatus.HitCnt = 0; // => Not yet calculated ! + + APtDest[ViMi26]->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = PtRec->Header.AMapsTrigInfo[0]; + + // ASIC__MI26_TRIG_RES__SIG_LINE + // ASIC__MI26_TRIG_RES__SIG_CLK + // ASIC__MI26_TRIG_RES__LINE + + APtDest[ViMi26]->Header = PtRec->Header.AMapsHeader[ViMi26]; + APtDest[ViMi26]->FrameCnt = PtRec->Header.AMapsFrameCnt[ViMi26]; + APtDest[ViMi26]->DataLength = PtRec->Header.AMapsDataLength[ViMi26]; + APtDest[ViMi26]->TrigSignalLine = PtRec->Header.AMapsTrigInfo[0]; + APtDest[ViMi26]->TrigSignalClk = 0; // => Not yet calculated ! + APtDest[ViMi26]->TrigLine = 0; // => Not yet calculated ! + APtDest[ViMi26]->Trailer = PtRec->Header.AMapsTrailer[ViMi26]; + APtDest[ViMi26]->Zero = 0; + APtDest[ViMi26]->Zero2 = 0; + + } + + // Process data + + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + +// msg (( MSG_OUT, "===================================================================================" )); +// msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); +// msg (( MSG_OUT, "===================================================================================" )); + + + ViStatesLine = 0; // 28/01/14 + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + // ViStatesLine = 0; // 28/01/14 : Moved before loop, otherwise StatesRecNb was set with a random value after loop if VDataW16Length == 0 !!! + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + VPtStatesLine = &APtDest[ViMi26]->AStatesRec[ViStatesLine].StatesLine; + VPtState = &APtDest[ViMi26]->AStatesRec[ViStatesLine].AStates[0]; // [ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + + // Copy StatesLine field + + VPtStatesLine->W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VPtStatesLine->F.StateNb; + + // sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VPtStatesLine->F.LineAddr, VPtStatesLine->F.StateNb, VPtStatesLine->F.Ovf ); + // + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + VPtState[ViState].W16 = VPtSrcW16[ViSrcW16]; + + // sprintf ( VStrState, "[Col %4d - %1d pixel(s)] ", VPtState[ViState].F.ColAddr, VPtState[ViState].F.HitNb + 1 ); + // + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrState )); + // } + + ++ViSrcW16; + } + + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + ++ViStatesLine; + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + APtDest[ViMi26]->StatesRecNb = ViStatesLine; + + } // End for ( ViMi26 ) + + // VTimeEndMs = GetTickCount (); + // VTimeExecMs = VTimeEndMs - VTimeBegMs; + + // msg (( MSG_OUT, "$$$$$ Convert maxtrix exec time = %d [ms]", VTimeExecMs )); + +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : print one frame content in log file +: +Inputs : PtRec - Pointer on the record +: +: PrintLevel - 0 -> Print nothing +: - > 0 -> print state list for each line +: +Ouputs : The function returns +: 0 if ok +: -1 if PtRec = NULL +: +Globals : +: +Remark : +: +Level : +Date : +Rev : +: - Add handling of N Mimosa 26 +: +Doc date : 31/01/2014 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__ULT1_FCheckTFrame ( EFRIO__TFrame* PtRec, SInt8 EmulErr ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTestOnDataCont* VPtTestCont = &EFRIO__VGContext.TestOnDataCont; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + + ULT1__TStatesLine VStatesLine; + SInt8 VStatesNbPerLine; + UInt16 VStatesLineAddr; + + SInt16 ViMi26; + SInt8 VErrors; + + static UInt32 VEmulErrW16Cnt = 1; + + + // ------------------------------------- + // Check parameters + // ------------------------------------- + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL !") ); + + // Init pointers on TFrame sub records + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + + // ------------------------------------- + // Processing + // ------------------------------------- + +/* + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb; ViMi26++ ) { + + memset ( APtDest[ViMi26], 0, sizeof (ULT1__TZsFFrameRaw) ); + + APtDest[ViMi26]->SStatus.AsicNo = ViMi26; + APtDest[ViMi26]->SStatus.AcqNo = PtRec->Header.AcqId; + APtDest[ViMi26]->SStatus.FrameNoInAcq = PtRec->Header.FrameIdInAcq; + APtDest[ViMi26]->SStatus.FrameNoInRun = 0; + APtDest[ViMi26]->SStatus.HitCnt = 0; + + APtDest[ViMi26]->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = PtRec->Header.AMapsTrigInfo[0]; + + APtDest[ViMi26]->Header = PtRec->Header.AMapsHeader[ViMi26]; + APtDest[ViMi26]->FrameCnt = PtRec->Header.AMapsFrameCnt[ViMi26]; + APtDest[ViMi26]->DataLength = PtRec->Header.AMapsDataLength[ViMi26]; + APtDest[ViMi26]->TrigSignalLine = PtRec->Header.AMapsTrigInfo[0]; + APtDest[ViMi26]->TrigSignalClk = 0; + APtDest[ViMi26]->TrigLine = 0; + APtDest[ViMi26]->Trailer = PtRec->Header.AMapsTrailer[ViMi26]; + APtDest[ViMi26]->Zero = 0; + APtDest[ViMi26]->Zero2 = 0; + + } + +*/ + + // Process data + + VErrors = 0; + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + + // msg (( MSG_OUT, "===================================================================================" )); + // msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); + // msg (( MSG_OUT, "===================================================================================" )); + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + // ViStatesLine = 0; // 28/01/14 : Moved before loop, otherwise StatesRecNb was set with a random value after loop if VDataW16Length == 0 !!! + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Emul errors + + if ( EmulErr ) { + + if ( (VEmulErrW16Cnt % 100000000) == 0 ) { + msg (( MSG_OUT, "$$$ Error emulated ! Acq %d - Frame %d - MAPS[%d]", VPtHead->AcqId, VPtHead->FrameIdInAcq, ViMi26 )); + VPtSrcW16[ViSrcW16] = 0xFFFF; + } + + ++VEmulErrW16Cnt; + + } + + + // Copy StatesLine field + + VStatesLine.W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VStatesLine.F.StateNb; + VStatesLineAddr = VStatesLine.F.LineAddr; + + + // msg (( MSG_OUT, "Frame %d : States/line nb = %d on MAPS[%d]", CurFrame, VStatesNbPerLine, ViMi26 )); + + if ( (VStatesNbPerLine == 0) || (VStatesNbPerLine > 9) || (VStatesLineAddr > 927) ) { + msg (( MSG_OUT, "StateLine error ! Acq %d - Frame %d - MAPS[%d] : Bad number of states/line = %d OR LineAddr = %d on MAPS[%d] - Jump to next MAPS", VPtHead->AcqId, VPtHead->FrameIdInAcq, ViMi26 , VStatesNbPerLine, VStatesLineAddr )); + + ++VPtTestCont->ResAMapsFrameCntErrCnt[ViMi26]; + ++VPtTestCont->ResAMapsErrCnt[ViMi26]; + ++VPtTestCont->ResTotErrCnt; + VErrors = 1; + + break; // => In order to exit while loop and jump to next Mi26 + } + + // Bypass states readout => jump to next state/line word + + ViSrcW16 += (VStatesNbPerLine + 1); + + // sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VPtStatesLine->F.LineAddr, VPtStatesLine->F.StateNb, VPtStatesLine->F.Ovf ); + // + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + } // End for ( ViMi26 ) + + + VPtTestCont->ResErrOnCurrentAcq = VPtTestCont->ResErrOnCurrentAcq || VErrors; + + if ( VPtTestCont->ParPrintLvl == 1 ) { + + } + + return (VErrors); +} + + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_usr.c b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.c new file mode 100755 index 0000000..13ae1a4 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.c @@ -0,0 +1,2240 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_usr.c +Goal : Functions of USER PART of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 11/11/2010 +Doc date : 11/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_USR_C +#define EUDET_FRIO_USR_C + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 11/11/2010 +Rev : 01/03/2013 + : - Add fields of EFRIO__USR_TContext and set their default values + : -- ParDisableRunCtrlMsgProcessing + : -- ParEnableRunCtrlMsgDisplay + : -- ResRunCtrlMsgReady + : -- ResRunCtrlMsgStr +Doc date : 11/11/2010 +Author : +E-mail : +Labo : */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FBegin () { + + EFRIO__USR_TContext* VPtCont = &EFRIO__USR_VGContext; + char* VPtLastMsgToGui = VPtCont->LastMsgToGui; + + + err_trace (( ERR_OUT, "" )); + + // Reset last message to GUI + // Fill with 0 to be sure to have 0 at end of string in case string is truncated by snprintf + + memset ( VPtLastMsgToGui, 0, GLB_CMT_SZ ); + +#ifdef EFRIO__INCLUDE_RUN_CTRL + + // 01/03/2013 + + VPtCont->ParDisableRunCtrlMsgProcessing = 0; + VPtCont->ParEnableRunCtrlMsgDisplay = 0; + VPtCont->ResRunCtrlMsgReady = 0; + sprintf ( VPtCont->ResRunCtrlMsgStr, "" ); + + + // Create event & thread to respond to run ctrl requests + + // Event + + VPtCont->InfEventRespondRunCtrlHnd = CreateEvent ( + NULL /* LPSECURITY_ATTRIBUTES */, + FALSE /* Manual Reset */, + FALSE /* Initial State */, + NULL /* Name STring */ ); + + if ( VPtCont->InfEventRespondRunCtrlHnd == NULL ) { + err_retfail ( -1, (ERR_OUT,"Create Event respond run ctrl failed ! - LastError=%d", GetLastError () ) ); + } + + // Thread + + VPtCont->InfThreadRespondRunCtrlHnd = CreateThread( NULL, NULL, EFRIO_USR__FThreadRespondRunCtrl, NULL, NULL, &VPtCont->InfThreadRespondRunCtrlId ); + + if ( VPtCont->InfThreadRespondRunCtrlHnd == NULL ) { + err_retfail ( -1, (ERR_OUT,"Create thread respond run ctrl failed ! - LastError=%d", GetLastError () ) ); + } + +#endif + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 11/11/2010 +Doc date : 11/11/2010 +Author : +E-mail : +Labo : */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FEnd () { + + EFRIO__USR_TContext* VPtCont = &EFRIO__USR_VGContext; + +#ifdef EFRIO__INCLUDE_RUN_CTRL + + // Kill respond run ctrl thread + + CloseHandle ( VPtCont->InfEventRespondRunCtrlHnd ); + + TerminateThread ( EFRIO_USR__FThreadRespondRunCtrl, 0 /* Thread exit code */ ); + +#endif + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FSetLineCmdPar ( char** CmdLinePar ) + : +Goal : This function + : + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : + : +Level : +Date : 26/01/2011 +Doc date : 26/01/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FGetLineCmdPar () { + + SInt8 Vi; + SInt32 VParamCnt; + + + VParamCnt = ParamCount(); + + msg (( MSG_OUT, "Line cmd param nb = %d", VParamCnt )); + + for ( Vi=0; Vi < (VParamCnt + 1); Vi++ ) { + msg (( MSG_OUT, "Par[%.2d] = %s", Vi, ParamStr (Vi) )); + } + + err_retval ( VParamCnt, ( ERR_OUT, "Line cmd param nb = %d", VParamCnt ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 03/02/2011 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifdef EFRIO__INCLUDE_RUN_CTRL + +SInt32 EFRIO_USR__FHandleRunCtrlMsg (UInt8* PtMsg, UInt32 MsgSz, UInt8* PtUsrData, UInt32 UsrDataSz ) { + + void* VPtMsg; + EFRIO__USR_TRunCtrlMsgHeader* VPtRunCtrlMsg; + EFRIO__TRunCont* VPtRunCont; + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + + if ( MsgSz <= 0 ) { + err_error (( ERR_OUT, "Msg received with MsgSz=%d <= 0", MsgSz )); + } + + VPtMsg = malloc ( UsrDataSz ); + + if ( VPtMsg == NULL ) { + err_error (( ERR_OUT, "Allocation of reception buffer failed !" )); + return (-1); + } + + VPtRunCtrlMsg = (EFRIO__USR_TRunCtrlMsgHeader*) VPtMsg; + + memcpy ( VPtMsg, PtUsrData, UsrDataSz ); + + switch ( VPtRunCtrlMsg->MsgCode ) { + + case EFRIO__USR_RUN_CTRL_MSG_CONF : { + VPtRunCont = (EFRIO__TRunCont*) &(VPtRunCtrlMsg->Data); + VPtUsrCont->InfFOnConfByRunCtrlRetCode = EFRIO_USR__FOnConfByRunCtrl ( VPtRunCont ); + break; + } + + case EFRIO__USR_RUN_CTRL_MSG_START_RUN : { + VPtUsrCont->InfFOnStartRunByRunCtrlRetCode = EFRIO_USR__FOnStartRunByRunCtrl (); + break; } + + case EFRIO__USR_RUN_CTRL_MSG_GET_RUN_STATUS_RQ : { + VPtUsrCont->InfFOnGetRunStatusByRunCtrl = EFRIO_USR__FOnGetRunStatusByRunCtrl (); + break; } + + case EFRIO__USR_RUN_CTRL_MSG_STOP_RUN : { + VPtUsrCont->InfFOnStopRunByRunCtrl = EFRIO_USR__FOnStopRunByRunCtrl (); + break; } + + } + + free ( VPtMsg ); + + err_retok (( ERR_OUT, "" )); + +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2011 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef EFRIO__INCLUDE_RUN_CTRL + +DWORD WINAPI EFRIO_USR__FThreadRespondRunCtrl ( LPVOID lpParam ) { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + void* VPtMsg; + EFRIO__USR_TRunCtrlMsgHeader* VPtRunCtrlMsg; + EFRIO__USR_TRunCtrlRunStatusAns* VPtRunStatusAns; + SInt32 VTotMsgSz; + + SInt32 VSendStatus; + + + while (1) { + + if ( VPtUsrCont->InfEventRespondRunCtrlHnd != NULL ) { + WaitForSingleObject ( VPtUsrCont->InfEventRespondRunCtrlHnd, INFINITE /* dwTimeout */ ); + } + + Sleep (100); + + // msg (( MSG_OUT, "Run ctrl request received" )); + + // ----------------------------------------------------------------------- + // Allocate message bloc + // ----------------------------------------------------------------------- + + VTotMsgSz = sizeof (EFRIO__USR_TRunCtrlMsgHeader) + sizeof (EFRIO__USR_TRunCtrlRunStatusAns); + + VPtMsg = malloc ( VTotMsgSz ); + + err_retnull ( VPtMsg, (ERR_OUT,"Allocation of buffer failed !") ); + + + VPtRunCtrlMsg = (EFRIO__USR_TRunCtrlMsgHeader*) VPtMsg; + VPtRunStatusAns = (EFRIO__USR_TRunCtrlRunStatusAns*) &(VPtRunCtrlMsg->Data); + + + // ----------------------------------------------------------------------- + // Fill answer record + // ----------------------------------------------------------------------- + + VPtRunStatusAns->RunCont = *VPtRunCont; + + // ----------------------------------------------------------------------- + // Prepare message + // ----------------------------------------------------------------------- + + + VPtRunCtrlMsg->TotMsgSz = VTotMsgSz; + VPtRunCtrlMsg->HeaderSz = sizeof (EFRIO__USR_TRunCtrlMsgHeader); + VPtRunCtrlMsg->MsgCode = EFRIO__USR_RUN_CTRL_MSG_GET_RUN_STATUS_ANS; + snprintf ( VPtRunCtrlMsg->StrMsgCode, EFRIO__USR_RUN_CTRL_MSG_CODE_STR_MAX_SZ - 1, "%s", "EFRIO__USR_RUN_CTRL_MSG_GET_RUN_STATUS_ANS" ); + + + VSendStatus = IAC__FSockSendShortMsg ( VPtUsrCont->InfRunCtrlSenderId, (UInt8*) VPtMsg /* PtMsg */, VPtRunCtrlMsg->TotMsgSz, NULL /* Caller */ ); + + + if ( VSendStatus < 0 ) { + err_error (( ERR_OUT, "Sending response to run status request failed !" )); + } + + // Freee message bloc + + free ( VPtMsg ); + + + } + + + return (0); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnAppStart () +: +Goal : This function is called when application is started. It will do all library +: initializations. +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. +: +Remark : It can use command line arguments to select operating modes, debug level, etc ... +: Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui +: +Level : +Date : 21/12/2010 +Doc date : 21/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FOnAppStart () { + + SInt32 VRet; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + // Variables to set error & messages log files parameters + + SInt8 VErrFileLogLvl; + char VErrLogFilePath[GLB_FILE_PATH_SZ]; + SInt8 VMsgFileLogLvl; + char VMsgLogFilePath[GLB_FILE_PATH_SZ]; + + SInt32 VMyVar = 10; // For error & general messages demo + + + // ----------------------------------------------------------------------- + // Default values for error & messages log files are hard coded here + // But they can be overwritten by parameters from command line for example + // ----------------------------------------------------------------------- + + VErrFileLogLvl = ERR_LOG_LVL_ERRORS; // ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + + sprintf ( VErrLogFilePath, "%s", "x:\\log\\err_eudet_dll.txt" ); + + VMsgFileLogLvl = 127; + + sprintf ( VMsgLogFilePath, "%s", "x:\\log\\msg_eudet_dll.txt" ); + + // ----------------------------------------------------------------------- + // Overwrite here variables to conf error & messages log files parameters + // Values from command line arguments can be use + // ----------------------------------------------------------------------- + + // VErrFileLogLvl = // ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + + // sprintf ( VErrLogFilePath, "%s", "" ); + + // VMsgFileLogLvl + + // sprintf ( VMsgLogFilePath, "%s", "" ); + + + // ----------------------------------------------------------------------- + // Flex rio lib init + // ----------------------------------------------------------------------- + + // Call init function + + VRet = EFRIO__FBegin ( VErrFileLogLvl, VErrLogFilePath, VMsgFileLogLvl, VMsgLogFilePath ); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - General init done :-)" ); + + // ----------------------------------------------------------------------- + // User part of flex rio lib init + // ----------------------------------------------------------------------- + + // Call init function + + VRet = EFRIO_USR__FBegin (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - General & user init done :-)" ); + + + // ----------------------------------------------------------------------- + // Error messages demo + // ----------------------------------------------------------------------- + + err_trace (( ERR_OUT, "This is a trace message from DLL - VMyVar=%d", VMyVar )); + err_warning (( ERR_OUT, "This is a warning message from DLL - VMyVar=%d", VMyVar )); + err_error (( ERR_OUT, "This is an error message from DLL - VMyVar=%d", VMyVar )); + + // ----------------------------------------------------------------------- + // General messages demo + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "This is a general message from DLL - with default LogLvl = 1 - VMyVar=%d", VMyVar )); + msgl (( MSG_OUT, "This is a general message from DLL - with LogLvl = 2 - VMyVar=%d", VMyVar ), 2 ); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnAppStartByRunCtrlExt ( SInt8 MapsName, char* RunCtrlIPAddr, SInt32 RunCtrlPort, SInt32 DaqPort ) + : +Goal : This function is called when application is started. It will do all library + : initializations. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : It can use command line arguments to select operating modes, debug level, etc ... + : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 03/02/2011 + : +Rev : 25/05/2011 + : - Renamed in EFRIO_USR__FOnAppStartByRunCtrlExt + : - Add parameter MapsName + : - Create a new EFRIO_USR__FOnAppStartByRunCtrl (...) which call EFRIO_USR__FOnAppStartByRunCtrlExt ( ASIC__MI26, ... ) + : This will keep compatibility with previous sw (EUDET), because EFRIO_USR__FOnAppStartByRunCtrl call + : will configure Mimosa 26 as ASIC as it was done for first version of EUDET library. + : + : 20/03/2013 + : - Add parameters ErrLogLvl and MsgLogLvl + : + : 26/03/2013 + : - Add parameters CrIndexFile and ReadoutMode + : +Doc date : 03/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef EFRIO__INCLUDE_RUN_CTRL + + SInt32 EFRIO_USR__FOnAppStartByRunCtrlExt ( SInt8 MapsName, char* RunCtrlIPAddr, SInt32 RunCtrlPort, SInt32 DaqPort, SInt8 CrIndexFile, SInt32 ReadoutMode, SInt8 ErrLogLvl, SInt8 MsgLogLvl ) { + + err_retfail ( -1, (ERR_OUT,"Function no available => EFRIO__INCLUDE_RUN_CTRL not define !") ); + + } + +#else + + SInt32 EFRIO_USR__FOnAppStartByRunCtrlExt ( SInt8 MapsName, char* RunCtrlIPAddr, SInt32 RunCtrlPort, SInt32 DaqPort, SInt8 CrIndexFile, SInt32 ReadoutMode, SInt8 ErrLogLvl, SInt8 MsgLogLvl ) { + + SInt32 VRet; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + EFRIO__USR_TContext* VPtUsrContext = &EFRIO__USR_VGContext; + + // Variables to set error & messages log files parameters + + SInt8 VErrFileLogLvl; + char VErrLogFilePath[GLB_FILE_PATH_SZ]; + SInt8 VMsgFileLogLvl; + char VMsgLogFilePath[GLB_FILE_PATH_SZ]; + + SInt32 VMyVar = 10; // For error & general messages demo + + + // Param settings - Moved here on 14/06/13 + + sprintf ( VPtUsrContext->ParRunCtrlIPAddr, "%s", RunCtrlIPAddr ); + + VPtUsrContext->ParRunCtrlPort = RunCtrlPort; + VPtUsrContext->ParDaqPort = DaqPort; + VPtUsrContext->ParCrIndexFile = CrIndexFile; + VPtUsrContext->ParReadoutMode = ReadoutMode; + + + // ----------------------------------------------------------------------- + // Default values for error & messages log files are hard coded here + // But they can be overwritten by parameters from command line for example + // ----------------------------------------------------------------------- + + VErrFileLogLvl = ErrLogLvl; // ERR_LOG_LVL_ALL; // 0 = ERR_LOG_LVL_NONE, 1 = ERR_LOG_LVL_ALL, 2 = ERR_LOG_LVL_WARNINGS_ERRORS, 3 = ERR_LOG_LVL_ERRORS + + sprintf ( VErrLogFilePath, "%s", "x:\\log\\err_eudet_dll.txt" ); + + VMsgFileLogLvl = MsgLogLvl; // 127; + + sprintf ( VMsgLogFilePath, "%s", "x:\\log\\msg_eudet_dll.txt" ); + + // ----------------------------------------------------------------------- + // Overwrite here variables to conf error & messages log files parameters + // Values from command line arguments can be use + // ----------------------------------------------------------------------- + + // VErrFileLogLvl = // ERR_LOG_LVL_NONE, ERR_LOG_LVL_ALL, ERR_LOG_LVL_WARNINGS_ERRORS, ERR_LOG_LVL_ERRORS + + // sprintf ( VErrLogFilePath, "%s", "" ); + + // VMsgFileLogLvl + + // sprintf ( VMsgLogFilePath, "%s", "" ); + + + // ----------------------------------------------------------------------- + // Flex rio lib init + // ----------------------------------------------------------------------- + + // Call init function + // 25/05/2011 => Replace EFRIO__FBegin call by EFRIO__FBeginExt in order to handle MapsName + + VRet = EFRIO__FBeginExt ( MapsName, VErrFileLogLvl, VErrLogFilePath, VMsgFileLogLvl, VMsgLogFilePath ); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - General init done :-)" ); + + // ----------------------------------------------------------------------- + // Run control handling initialization + // ----------------------------------------------------------------------- + + // Before 14/06/13 => Moved at beginning of function + +/* + sprintf ( VPtUsrContext->ParRunCtrlIPAddr, "%s", RunCtrlIPAddr ); + + VPtUsrContext->ParRunCtrlPort = RunCtrlPort; + VPtUsrContext->ParDaqPort = DaqPort; + VPtUsrContext->ParCrIndexFile = CrIndexFile; + VPtUsrContext->ParReadoutMode = ReadoutMode; +*/ + + // Conf sender + + VPtUsrContext->InfRunCtrlSenderId = IAC__FSockInstallSenderPort ( VPtUsrContext->ParRunCtrlIPAddr /* DestHost */, VPtUsrContext->ParDaqPort /* DestPort */, 0 /* LongMsg */, 10000 /* AckTimeOutMs */, 5 /* RetryNb */, NULL /* APP_FCheckSum */ /* FuncCheckSum */ ); + + // Start sender + + IAC__FSockStartSenderPort ( VPtUsrContext->InfRunCtrlSenderId ); + + // Conf receiver + + VPtUsrContext->InfRunCtrlReceiverId = IAC__FSockInstallReceiverPort ( VPtUsrContext->ParRunCtrlPort /* RecPort */, 0 /* LongMsg */, EFRIO_USR__FHandleRunCtrlMsg /* IAC__TFSockUsrHandleRecMsg */, NULL /* APP_FCheckSum */ /* FuncCheckSum */ ); + + // Start receiver + + IAC__FSockStartReceiverPort ( VPtUsrContext->InfRunCtrlReceiverId ); + + + // ----------------------------------------------------------------------- + // User part of flex rio lib init + // ----------------------------------------------------------------------- + + // Call init function + + VRet = EFRIO_USR__FBegin (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - General & user init done :-)" ); + + + // ----------------------------------------------------------------------- + // Error messages demo + // ----------------------------------------------------------------------- + + err_trace (( ERR_OUT, "This is a trace message from DLL - VMyVar=%d", VMyVar )); + err_warning (( ERR_OUT, "This is a warning message from DLL - VMyVar=%d", VMyVar )); + err_error (( ERR_OUT, "This is an error message from DLL - VMyVar=%d", VMyVar )); + + // ----------------------------------------------------------------------- + // General messages demo + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "This is a general message from DLL - with default LogLvl = 1 - VMyVar=%d", VMyVar )); + msgl (( MSG_OUT, "This is a general message from DLL - with LogLvl = 2 - VMyVar=%d", VMyVar ), 2 ); + + + msg (( MSG_OUT, "RunCtrlIPAddr=%s, RunCtrlPort=%d, DaqPort=%d, CrIndexFile=%d, ReadoutMode=%d, ParCrIndexFile=%d", RunCtrlIPAddr, RunCtrlPort, DaqPort, CrIndexFile, ReadoutMode, VPtUsrContext->ParCrIndexFile )); + + + err_retok (( ERR_OUT, "" )); + } + + +#endif + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnAppStartByRunCtrl ( char* RunCtrlIPAddr, SInt32 RunCtrlPort, SInt32 DaqPort ) + : +Goal : This function is called when application is started. It will do all library + : initializations. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : It can use command line arguments to select operating modes, debug level, etc ... + : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 03/02/2011 + : +Rev : 25/05/2011 + : - Body of function is " empty " => it has been moved in EFRIO_USR__FOnAppStartByRunCtrlExt (...) + : - Call EFRIO_USR__FOnAppStartByRunCtrlExt ( ASIC__MI26, ... ) + : - EFRIO_USR__FOnAppStartByRunCtrlExt (...) handles MapsName parameter ( Mi26 / Ultimate / ... ) + : EFRIO_USR__FOnAppStartByRunCtrl still configure Mimosa 26 as it was done in first version of lib. + : + : +Doc date : 03/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef EFRIO__INCLUDE_RUN_CTRL + +SInt32 EFRIO_USR__FOnAppStartByRunCtrl ( char* RunCtrlIPAddr, SInt32 RunCtrlPort, SInt32 DaqPort, SInt8 CrIndexFile, SInt32 ReadoutMode ) { + + err_retfail ( -1, (ERR_OUT,"Function no available => EFRIO__INCLUDE_RUN_CTRL not define !") ); + +} + +#else + +SInt32 EFRIO_USR__FOnAppStartByRunCtrl ( char* RunCtrlIPAddr, SInt32 RunCtrlPort, SInt32 DaqPort, SInt8 CrIndexFile, SInt32 ReadoutMode ) { + + return ( EFRIO_USR__FOnAppStartByRunCtrlExt ( ASIC__MI26, RunCtrlIPAddr, RunCtrlPort, DaqPort, CrIndexFile, ReadoutMode, ERR_LOG_LVL_ERRORS /* ErrLogLvl */, 127 /* MsgLogLvl */ ) ); + +// Before 14/06/13 return ( EFRIO_USR__FOnAppStartByRunCtrlExt ( ASIC__MI26, RunCtrlIPAddr, RunCtrlPort, DaqPort, 0 /* CrIndexFile */, 0 /* ReadoutMode */, ERR_LOG_LVL_ERRORS /* ErrLogLvl */, 127 /* MsgLogLvl */ ) ); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnConfExt ( SInt8 MapsName ) + : +Goal : This function is called by the EUDET event method which configure run parameters + : It will do all run initializations, including Mi26 configuration by JTAG. + : + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + : WARNING - THIS FUNCTION IS NOT USED ON IPHC DAQ, IT'S ONLY USED ON EUDET DEMO !!! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 21/12/2010 +Rev : 12/03/2011 + : - Exit if called while DAQ is taking data + : + : 12/05/2011 + : - Implement handling of different MAPS ( Mi26, Ultimate, ... ) + : -> Replace call to EFRIO__FConfRun by EFRIO__FConfRunExt ( new param MapsName ) + : -> Move the call to EFRIO__FConfRunExt BEFORE JTAG functions call because they + : use the ParMapsName field of run context record. + : -> Replace Mi26 JTAG functions by generic ones ( handling Mi26, Ult1, ... ) + : + : 23/05/2011 + : -> Configure Ultimate 1 for test purpose ( => Ult1 FW debug without run ctrl ) + : + : 25/05/2011 + : - Renamed in EFRIO_USR__FOnConfExt + : - Add parameter MapsName + : - Create a new EFRIO_USR__FOnConf (...) which call EFRIO_USR__FOnConfExt ( ASIC__MI26, ... ) + : This will keep compatibility with previous sw (EUDET), because EFRIO_USR__FOnConf call + : will configure Mimosa 26 as ASIC as it was done for first version of EUDET library. + : + : 29/10/2013 + : - ONLY on version V3.0 defined by CC => EFRIO__V30 in DLL cpp file + : Clock distrib board configuration and stop clock + : + : 28/11/2013 + : - Bug fix on clock distrib board configuration (29/10/13) configuration request + : was not executed, and therefore the board was not configured + : +Doc date : 21/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FOnConfExt ( SInt8 MapsName ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + SInt32 VRet; // Variable to store error code of functions called + + // JTAG file + + char VJtagConfFile[GLB_FILE_PATH_SZ]; // JTAG master conf file ( *.mcf ) + + // Run parameters + + SInt8 VMapsName; // Name of the MAPS ( ASIC__MI26, ASIC__ULT1, ... ) + SInt8 VMapsNb; // Number of MAPS + SInt32 VRunNo; // No of run + SInt32 VTotEvNb; // Total event number of run + SInt32 VEvNbPerFile; // Number of events per file + SInt32 VFrNbPerAcq; // Number of frames per acquisition + SInt8 VDataTrfMode; // Data transfer mode IPHC, EUDET 1, 2, 3 + + char VDestDir[GLB_FILE_PATH_SZ]; // Destination directory forrun file + char VFileNamePrefix[GLB_FILE_PATH_SZ]; // Run file name prefix, eg "RUN_666" => prefix = RUN_ + + SInt8 VSaveOnDisk; // If > 0 => save data on disk + // 1 => use multi threading in TCStreamFile class + // 2 => don't use multi threading in TCStreamFile class + + SInt8 VSendOnEth; // If > 0 send data on Ethernet + SInt8 VSendOnEthPCent; // % of event send on Ethernet + + + + // ----------------------------------------------------------------------- + // Debug message + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "EFRIO_USR__FOnConf (...) called" )); + + // ----------------------------------------------------------------------- + // Reject cmd if run is already running + // ----------------------------------------------------------------------- + + if ( VPtCont->RunCont.CmdRun != -1 ) { + err_retfail ( -1, (ERR_OUT,"Conf run cmd received - Abort => Because DAQ is already runnig !" ) ); + } + + // ----------------------------------------------------------------------- + // Set default value to JTAG configuration file + // ----------------------------------------------------------------------- + + + switch ( MapsName ) { + + case ASIC__MI26 : { + sprintf ( VJtagConfFile, "%s", "C:\\ccmos_sctrl\\MIMOSA26_JTAG\\config_files\\daq_test_2x80MHz_1_chip.mcf" ); + // sprintf ( VJtagConfFile, "%s", "C:\\ccmos_sctrl\\MIMOSA26_JTAG\\config_files\\daq_test_2x80MHz_6_chip.mcf" ); + break; } + + case ASIC__ULT1 : { + sprintf ( VJtagConfFile, "%s", "C:\\ccmos_sctrl\\MIMOSA28_JTAG\\config_files\\MI28_2x160MHz.mcf" ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + + + // ----------------------------------------------------------------------- + // Set default values to run parameters + // ----------------------------------------------------------------------- + +// VMapsName = ASIC__MI26; +// VMapsName = ASIC__ULT1; // 23/05/2011 => Ultimate fw debug + VMapsName = MapsName; // 25/05/11 => Use MapsName parameter + VMapsNb = 6; + VRunNo = 777; + VTotEvNb = 10000; + VEvNbPerFile = 1000; + + switch ( MapsName ) { + + case ASIC__MI26 : { + VFrNbPerAcq = 1800; + break; } + + case ASIC__ULT1 : { + VFrNbPerAcq = 400; + break; } + case ASIC__FSBB0 : { + VFrNbPerAcq = 200; + break; } + default : { + err_retfail ( -1, (ERR_OUT,"Unknown MAPS name = %d => Abort", MapsName) ); + break; } + + } + + + // VDataTrfMode = EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG; + VDataTrfMode = EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES; + + sprintf ( VDestDir , "%s", "c:\\data" ); + sprintf ( VFileNamePrefix, "%s", "RUN_" ); + + VSaveOnDisk = 0; // 0 = dont save, 1 = save multithreading, 2 = save NO multithreading + VSendOnEth = 1; + VSendOnEthPCent = 20; + + // ----------------------------------------------------------------------- + // Overwrite JTAG configuration file with name provided by EUDET DAQ + // ----------------------------------------------------------------------- + + // sprintf ( VJtagConfFile, "%s", "" ); + + // ----------------------------------------------------------------------- + // Overwrite here run parameters with values provided by EUDET DAQ + // ----------------------------------------------------------------------- + + // VMi26Nb = + // VRunNo = + // VTotEvNb = + // VEvNbPerFile = + // VFrNbPerAcq = + // VDataTrfMode = + + // sprintf ( VDestDir , "%s", "" ); + // sprintf ( VFileNamePrefix, "%s", "" ); + + // VSaveOnDisk = + // VSendOnEth = + // VSendOnEthPCent = + + // ----------------------------------------------------------------------- + // Call conf run function + // ----------------------------------------------------------------------- + // Moved here on 12/05/2011 + // ----------------------------------------------------------------------- + + // Call DLL run configuration function with parameters get from GUI + + VRet = EFRIO__FConfRunExt ( + VMapsName, + VMapsNb, + VRunNo, + VTotEvNb, + VEvNbPerFile, + VFrNbPerAcq, + VDataTrfMode, + 0 /* TrigMode */, + VDestDir, + VFileNamePrefix, + VSaveOnDisk, + VSendOnEth, + VSendOnEthPCent, + VJtagConfFile ); + + // ----------------------------------------------------------------------- + // Print run parameters in messages log file x:\log\msg_eudet_dll.txt + // ----------------------------------------------------------------------- + + EFRIO__FPrintRunCont (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + + // ----------------------------------------------------------------------- + // Configure clock distrib board and stop clock + // ----------------------------------------------------------------------- + // 29/10/13 : Implementation, but not tested in detail -> Hidden bug + // 28/11/13 : Add SPICD_FStartCom () call because otherwise the + // SPICD_FSendConf () is not exectuted => board not configured + // ----------------------------------------------------------------------- + + #ifdef EFRIO__V30 + msg (( MSG_OUT, "$$$ Clock distrib board config cmd sent" )); + SPICD_FStartCom (); // 28/11/13 Bug fix : SPICD_FStartCom () call needed otherwise SPICD_FSendConf () is not executed + SPICD_FSendConf (); + Sleep ( 1000 ); // Delay 1000 ms to be sure that board has been configured + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); // Stop clock + #endif + + // ----------------------------------------------------------------------- + // Print JTAG file name in messages log file x:\log\msg_eudet_dll.txt + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "JTAG configuration file = %s", VJtagConfFile )); + + // ----------------------------------------------------------------------- + // Load JTAG conf file, Reset & send parameters to Mi26 + // ----------------------------------------------------------------------- + + // Load file + + VRet = EFRIO__FJtagLoadFile ( VJtagConfFile ); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Reset Mi 26 + + VRet = EFRIO__FJtagReset (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Send parameters to Mimosa 26 registers + // If read back registers <> values sent => an error is generated => VRet < 0 + + VRet = EFRIO__FJtagLoadChip (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - JTAG parameters loaded to Mi26 :-)" ); + + + // ----------------------------------------------------------------------- + // Call conf run function + // ----------------------------------------------------------------------- + // Was here before 12/05/2011 + // Moved before JTAG functions call on 12/05/2011 + // because they need to know which MAPS is used ( Run context -> ParMapsName ) + // ----------------------------------------------------------------------- + + + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - Conf run done :-)" ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnConf () + : +Goal : This function is called by the EUDET event method which configure run parameters + : It will do all run initializations, including Mi26 configuration by JTAG. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 21/12/2010 +Rev : 12/03/2011 + : - Exit if called while DAQ is taking data + : + : 12/05/2011 + : - Implement handling of different MAPS ( Mi26, Ultimate, ... ) + : -> Replace call to EFRIO__FConfRun by EFRIO__FConfRunExt ( new param MapsName ) + : -> Move the call to EFRIO__FConfRunExt BEFORE JTAG functions call because they + : use the ParMapsName field of run context record. + : -> Replace Mi26 JTAG functions by generic ones ( handling Mi26, Ult1, ... ) + : + : 23/05/2011 + : -> Configure Ultimate 1 for test purpose ( => Ult1 FW debug without run ctrl ) + : + : 25/05/2011 + : - Body of function is " empty " => it has been moved in EFRIO_USR__FOnConfExt (...) + : - Call EFRIO_USR__FOnConfExt ( ASIC__MI26, ... ) + : - EFRIO_USR__FOnConfExt (...) handles MapsName parameter ( Mi26 / Ultimate / ... ) + : EFRIO_USR__FOnConf still configure Mimosa 26 as it was done in first version of lib. + : +Doc date : 21/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FOnConf () { + + return ( EFRIO_USR__FOnConfExt ( ASIC__FSBB0 ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnConfByRunCtrl ( EFRIO__TRunCont* PtRunCont ) + : +Goal : This function is called by the EUDET event method which configure run parameters + : It will do all run initializations, including Mi26 configuration by JTAG. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 03/02/2011 +Rev : 12/03/2011 + : - Exit if called while DAQ is taking data + : + : 12/05/2011 + : - Implement handling of different MAPS ( Mi26, Ultimate, ... ) + : -> Replace call to EFRIO__FConfRun by EFRIO__FConfRunExt ( new param MapsName ) + : -> Move the call to EFRIO__FConfRunExt BEFORE JTAG functions call because they + : use the ParMapsName field of run context record. + : -> Replace Mi26 JTAG functions by generic ones ( handling Mi26, Ult1, ... ) + : + : 01/03/2013 + : - Handle EFRIO__USR_VGContext.DisableRunCtrlMsgProcessing + : + : 28/11/2013 + : - ONLY on version V3.0 defined by CC => EFRIO__V30 in DLL cpp file + : Clock distrib board configuration and stop clock + : Copy of code from EFRIO_USR__FOnConfExt () 29/10/13 here, because it has been + : first implemented in EFRIO_USR__FOnConfExt () - EUDET demo sw - and I have + : forgotten to implement it here. A bug on board configuration has also been + : solved, see EFRIO_USR__FOnConfExt () text header. + : +Doc date : 03/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef EFRIO__INCLUDE_RUN_CTRL + +SInt32 EFRIO_USR__FOnConfByRunCtrl ( EFRIO__TRunCont* PtRunCont ) { + + err_retfail ( -1, (ERR_OUT,"Function no available => EFRIO__INCLUDE_RUN_CTRL not define !") ); + +} + +#else + +SInt32 EFRIO_USR__FOnConfByRunCtrl ( EFRIO__TRunCont* PtRunCont ) { + + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + SInt8 VMaxTryToConfMaps; + SInt8 VCptTryToConfMaps; + SInt32 VTimeMsBetweenTryToConfMaps; + SInt32 VRet; // Variable to store error code of functions called + + + + // ----------------------------------------------------------------------- + // Debug message + // ----------------------------------------------------------------------- + + VMaxTryToConfMaps = 10; // Nb max tentatives to configure MAPS + VTimeMsBetweenTryToConfMaps = 1000; + + msg (( MSG_OUT, "EFRIO_USR__FOnConfByRunCtrl (...) called - Try to conf MAPS %d times", VMaxTryToConfMaps )); + + // ----------------------------------------------------------------------- + // Display command if display is enabled + // Reject command if commands processing is disabled + // ----------------------------------------------------------------------- + + if ( VPtUsrCont->ParEnableRunCtrlMsgDisplay == 1 ) { + + if ( PtRunCont != NULL ) { + sprintf ( VPtUsrCont->ResRunCtrlMsgStr, "Run Ctrl command => Conf run : Conf param in msg.txt" ); + VPtUsrCont->ResRunCtrlMsgReady = 1; + EFRIO__FPrintRunContRec ( PtRunCont ); + } + + else { + sprintf ( VPtUsrCont->ResRunCtrlMsgStr, "Run Ctrl command => Conf run : No conf param (ptr NULL) !" ); + VPtUsrCont->ResRunCtrlMsgReady = 1; + } + + } + + if ( VPtUsrCont->ParDisableRunCtrlMsgProcessing == 1 ) { + err_retok (( ERR_OUT, "Exit => Run Ctrl cmd processing disabled !" )); + } + + // ----------------------------------------------------------------------- + // Reject command if run is already running + // ----------------------------------------------------------------------- + + if ( VPtCont->RunCont.CmdRun != -1 ) { + err_retfail ( -1, (ERR_OUT,"Conf run cmd received - Abort => Because DAQ is already runnig !" ) ); + } + + // ----------------------------------------------------------------------- + // Test run context pointer + // ----------------------------------------------------------------------- + + err_retnull ( PtRunCont, (ERR_OUT,"PtRunCont == NULL") ); + + + // ----------------------------------------------------------------------- + // Call conf run function + // ----------------------------------------------------------------------- + // Moved here on 12/05/2011 + // ----------------------------------------------------------------------- + + // ----------------------------------------------------------------------- + // Call conf run function + // ----------------------------------------------------------------------- + + // Call DLL run configuration function with parameters get from GUI + + msg (( MSG_OUT, "Call EFRIO__FConfRun" )); + + VRet = EFRIO__FConfRunExt ( + PtRunCont->ParMapsName, + PtRunCont->ParMi26Nb, + PtRunCont->ParRunNo, + PtRunCont->ParTotEvNb, + PtRunCont->ParEvNbPerFile, + PtRunCont->ParFrameNbPerAcq, + PtRunCont->ParDataTransferMode, + 0 /* TrigMode */, + PtRunCont->ParDestDir, + PtRunCont->ParFileNamePrefix, + PtRunCont->ParSaveOnDisk, + PtRunCont->ParSendOnEth, + PtRunCont->ParSendOnEthPCent, + PtRunCont->ParJtagFileName ); + + // ----------------------------------------------------------------------- + // Print run parameters in messages log file x:\log\msg_eudet_dll.txt + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "$CALL => EFRIO_USR__FOnConfByRunCtrl ()" )); // 01/03/2013 + + // EFRIO__FPrintRunCont (); + + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // ----------------------------------------------------------------------- + // Configure clock distrib board and stop clock + // Copy code from EFRIO_USR__FOnConfExt () 29/10/13 here + // ----------------------------------------------------------------------- + // 29/10/13 : Implementation, but not tested in detail -> Hidden bug + // 28/11/13 : Add SPICD_FStartCom () call because otherwise the + // SPICD_FSendConf () is not exectuted => board not configured + // ----------------------------------------------------------------------- + + #ifdef EFRIO__V30 + msg (( MSG_OUT, "$$$ Clock distrib board config cmd sent" )); + SPICD_FStartCom (); // 28/11/13 Bug fix : SPICD_FStartCom () call needed otherwise SPICD_FSendConf () is not executed + SPICD_FSendConf (); + Sleep ( 1000 ); // Delay 1000 ms to be sure that board has been configured + PPO_FOutD7 ( 0 /* Id */, 1 /* State */ ); // Stop clock + #endif + + + + // ----------------------------------------------------------------------- + // Print JTAG file name in messages log file x:\log\msg_eudet_dll.txt + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "RC => JTAG configuration file = %s", PtRunCont->ParJtagFileName )); + + // ----------------------------------------------------------------------- + // Load JTAG conf file, Reset & send parameters to Mi26 + // ----------------------------------------------------------------------- + + // Load file + + VRet = EFRIO__FJtagLoadFile ( PtRunCont->ParJtagFileName ); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Try to Reset & Configure MAPS - Before 30/04/13 it was done one time, there was no retry + + for ( VCptTryToConfMaps=0; VCptTryToConfMaps < VMaxTryToConfMaps; VCptTryToConfMaps++ ) { + + // Reset Maps + + VRet = EFRIO__FJtagReset (); + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + // Send parameters to Maps registers + // If read back registers <> values sent => retry + // Tries to oad two times after a reset + + VRet = EFRIO__FJtagLoadChip (); + + if ( VRet == 0 ) { + break; // MAPS loaded & readback OK + } + + VRet = EFRIO__FJtagLoadChip (); + + if ( VRet == 0 ) { + break; // MAPS loaded & readback OK + } + + // Wait before next try + + Sleep ( VTimeMsBetweenTryToConfMaps ); + + } // End for () + + + // Copy error message from err lib to last GUI message - user can write something else if more useful + + if ( VRet < 0 ) { + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ, "%s", ERR_FGetLastErrMsg () ); + return (VRet); + } + + + // Set last GUI message to "OK" + + msg (( MSG_OUT, "Set last GUI message" )); + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - JTAG parameters loaded to Mi26 :-)" ); + + + // ----------------------------------------------------------------------- + // Call conf run function + // ----------------------------------------------------------------------- + // Was here before 12/05/2011 + // Moved before JTAG functions call on 12/05/2011 + // because they need to know which MAPS is used ( Run context -> ParMapsName ) + // ----------------------------------------------------------------------- + + + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - Conf run done :-)" ); + + err_retok (( ERR_OUT, "" )); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnStartRun () + : +Goal : This function is called by the EUDET event method which start run. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 21/12/2010 +Rev : 07/03/2001 + : - Add reset & reload Mi26 + : 12/03/2011 + : - Exit if called while DAQ is taking data + : + : 12/05/2011 + : -> Replace Mi26 JTAG functions by generic ones ( handling Mi26, Ult1, ... ) + : +Doc date : 21/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FOnStartRun () { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + + // ----------------------------------------------------------------------- + // Debug message + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "EFRIO_USR__FOnStartRun (...) called" )); + + // ----------------------------------------------------------------------- + // Reject cmd if run is already running + // ----------------------------------------------------------------------- + + if ( VPtCont->RunCont.CmdRun != -1 ) { + err_retfail ( -1, (ERR_OUT,"Start run cmd received - Abort => Because DAQ is already runnig !" ) ); + } + + // --------------------------------------------------------------------- + // Reset and reload all Mi26 - 07/03/2011 + // --------------------------------------------------------------------- + + EFRIO__FJtagReset (); + + EFRIO__FJtagLoadChip (); + + // --------------------------------------------------------------------- + // If saving is enabled ( run par ) => create run conf/par & data files + // --------------------------------------------------------------------- + + EFRIO__FStartSavingOnFile (); + + // -------------------------------------------------------------------------------------- + // Set the flag CmdRun of record EFRIO__TRunCont which will be polled by DAQ application + // -------------------------------------------------------------------------------------- + + EFRIO__FSetCmdRun (1); + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - Run started :-)" ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnStartRunByRunCtrl ( ) +: +Goal : This function is called by the EUDET event method which start run. +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. +: +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui +: +Level : +Date : 03/02/2011 +Rev : 07/03/2001 + : - Add reset & reload Mi26 + : 12/03/2011 + : - Exit if called while DAQ is taking data + : + : 12/05/2011 + : -> Replace Mi26 JTAG functions by generic ones ( handling Mi26, Ult1, ... ) + : + : 16/07/2012 + : -> Removed JTAB access to implement Mi32 -> Mi26 BT run control + : + : 01/03/2013 + : - Handle EFRIO__USR_VGContext.DisableRunCtrlMsgProcessing + : +Doc date : 03/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef EFRIO__INCLUDE_RUN_CTRL + +SInt32 EFRIO_USR__FOnStartRunByRunCtrl () { + + err_retfail ( -1, (ERR_OUT,"Function no available => EFRIO__INCLUDE_RUN_CTRL not define !") ); + +} + +#else + +SInt32 EFRIO_USR__FOnStartRunByRunCtrl () { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + // ----------------------------------------------------------------------- + // Debug message + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "$CALL => EFRIO_USR__FOnStartRunByRunCtrl ()" )); // 01/03/2013 + + // ----------------------------------------------------------------------- + // Display command if display is enabled + // Reject command if commands processing is disabled + // ----------------------------------------------------------------------- + + if ( VPtUsrCont->ParEnableRunCtrlMsgDisplay == 1 ) { + sprintf ( VPtUsrCont->ResRunCtrlMsgStr, "Run Ctrl command => Start run" ); + VPtUsrCont->ResRunCtrlMsgReady = 1; + } + + if ( VPtUsrCont->ParDisableRunCtrlMsgProcessing == 1 ) { + err_retok (( ERR_OUT, "Exit => Run Ctrl cmd processing disabled !" )); + } + + + // ----------------------------------------------------------------------- + // Reject command if conf run has failed - 30/04/13 + // ----------------------------------------------------------------------- + + if ( VPtUsrCont->InfFOnConfByRunCtrlRetCode < 0 ) { + err_retfail ( -1, (ERR_OUT,"Start run cmd received - Abort => Because Conf run has failed !" ) ); + } + + // ----------------------------------------------------------------------- + // Reject command if run is already running + // ----------------------------------------------------------------------- + + if ( VPtCont->RunCont.CmdRun != -1 ) { + err_retfail ( -1, (ERR_OUT,"Start run cmd received - Abort => Because DAQ is already runnig !" ) ); + } + + // --------------------------------------------------------------------- + // Reset and reload all Mi26 - 07/03/2011 + // --------------------------------------------------------------------- + + // JTAG access removed on 16/07/2012 in order to implement Mi32A -> Mi26 DAQ BT run control + // JTAG reset & conf already done in EFRIO_USR__FOnConfByRunCtrl + // + // EFRIO__FJtagReset (); + // + // EFRIO__FJtagLoadChip (); + + // --------------------------------------------------------------------- + // If saving is enabled ( run par ) => create run conf/par & data files + // --------------------------------------------------------------------- + + EFRIO__FStartSavingOnFile (); + + // -------------------------------------------------------------------------------------- + // Set the flag CmdRun of record EFRIO__TRunCont which will be polled by DAQ application + // -------------------------------------------------------------------------------------- + + EFRIO__FSetCmdRun (1); + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - Run started :-)" ); + + err_retok (( ERR_OUT, "" )); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnGetRunStatus () + : +Goal : This function is called by the EUDET event method which request run status. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 21/12/2010 +Doc date : 21/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FOnGetRunStatus () { + + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + // Build last GUI message to with information about run status + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "Acquisitions Cnt = %d - Frames cnt = %d - Events cnt = %d", VPtRunCont->ResAcqCnt, VPtRunCont->ResFrameCnt, VPtRunCont->ResEventCnt ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnGetRunStatusByRunCtrl ( ) +: +Goal : This function is called by the EUDET event method which request run status. +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. +: +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui +: +Level : +Date : 03/02/2011 + : + : 01/03/2013 + : - Handle EFRIO__USR_VGContext.DisableRunCtrlMsgProcessing + : +Doc date : 03/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef EFRIO__INCLUDE_RUN_CTRL + +SInt32 EFRIO_USR__FOnGetRunStatusByRunCtrl () { + + err_retfail ( -1, (ERR_OUT,"Function no available => EFRIO__INCLUDE_RUN_CTRL not define !") ); + +} + +#else + +SInt32 EFRIO_USR__FOnGetRunStatusByRunCtrl () { + + + EFRIO__USR_TContext* VPtUsrContext = &EFRIO__USR_VGContext; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + + + + + // msg (( MSG_OUT, "$CALL => EFRIO_USR__FOnGetRunStatusByRunCtrl ()" )); // 01/03/2013 + // msg (( MSG_OUT, "$CALL => EFRIO_USR__FOnGetRunStatusByRunCtrl () - JTAG=%s", VPtRunCont->ParJtagFileName )); + + + // ----------------------------------------------------------------------- + // Display command if display is enabled + // DON'T Reject command if commands processing is disabled => Because HW is not needed to get run status ( AcqNb=0, FrNb=0, EvNb=0 ;-)) + // ----------------------------------------------------------------------- + + if (VPtUsrContext->ParEnableRunCtrlMsgDisplay == 1 ) { + sprintf ( VPtUsrContext->ResRunCtrlMsgStr, "Run Ctrl command => Get run status" ); + VPtUsrContext->ResRunCtrlMsgReady = 1; + } + +// if (VPtUsrContext->ParDisableRunCtrlMsgProcessing == 1 ) { +// err_retok (( ERR_OUT, "Exit => Run Ctrl cmd processing disabled !" )); +// } + + + // Build last GUI message to with information about run status + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "Acquisitions Cnt = %d - Frames cnt = %d - Events cnt = %d", VPtRunCont->ResAcqCnt, VPtRunCont->ResFrameCnt, VPtRunCont->ResEventCnt ); + + // msg (( MSG_OUT, "%s", VPtLastMsgToGui )); + + + if ( PulseEvent ( VPtUsrContext->InfEventRespondRunCtrlHnd ) != TRUE ) { + err_retfail ( -1, (ERR_OUT,"PulseEvent respond run ctrl failed ! - LastError=%d", GetLastError () ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +#endif + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnStopRun () + : +Goal : This function is called by the EUDET event method which stop run. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 21/12/2010 +Doc date : 21/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO_USR__FOnStopRun () { + + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + + // ---------------------------------------------- + // Stop saving on file ( if enabled in run par ) + // ---------------------------------------------- + + EFRIO__FStopSavingOnFile (); + + // ---------------------------------------------------------------------------------------- + // Reset the flag CmdRun of record EFRIO__TRunCont which will be polled by DAQ application + // ---------------------------------------------------------------------------------------- + + EFRIO__FSetCmdRun (-1); + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - Run stopped :-)" ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnStopRunByRunCtrl ( ) +: +Goal : This function is called by the EUDET event method which stop run. +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. +: +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui +: +Level : +Date : 03/02/2011 +Rev : 14/07/2012 + : - Reset Mimosa 26/28 for synchro between Telescope DAQ / DUT DAQ + : because the Mimosa frame cnt is used to tag events. Therefore it must + : stay to 0 until the DUT DAQ has resetted his Sync cnt => Reset Mimosa at end of run. + : It is done by setting TRSTB to 0 by a direct access to // port (No JTAG COM) + : The line TRSTB = D0 is set to 0 and keep in this state until JTAG SW will be + : launched by DAQ application. + : + : 01/03/2013 + : - Handle EFRIO__USR_VGContext.DisableRunCtrlMsgProcessing + : +Doc date : 03/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef EFRIO__INCLUDE_RUN_CTRL + +SInt32 EFRIO_USR__FOnStopRunByRunCtrl () { + + err_retfail ( -1, (ERR_OUT,"Function no available => EFRIO__INCLUDE_RUN_CTRL not define !") ); + +} + +#else + +SInt32 EFRIO_USR__FOnStopRunByRunCtrl () { + + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + // ----------------------------------------------------------------------- + // Debug message + // ----------------------------------------------------------------------- + + msg (( MSG_OUT, "$CALL => EFRIO_USR__FOnStopRunByRunCtrl ()" )); // 01/03/2013 + + + // ----------------------------------------------------------------------- + // Display command if display is enabled + // Reject command if commands processing is disabled + // ----------------------------------------------------------------------- + + if ( VPtUsrCont->ParEnableRunCtrlMsgDisplay == 1 ) { + sprintf ( VPtUsrCont->ResRunCtrlMsgStr, "Run Ctrl command => Stop run" ); + VPtUsrCont->ResRunCtrlMsgReady = 1; + } + + if ( VPtUsrCont->ParDisableRunCtrlMsgProcessing == 1 ) { + err_retok (( ERR_OUT, "Exit => Run Ctrl cmd processing disabled !" )); + } + + + // ---------------------------------------------- + // Stop saving on file ( if enabled in run par ) + // ---------------------------------------------- + + EFRIO__FStopSavingOnFile (); + + // ---------------------------------------------------------------------------------------- + // Reset the flag CmdRun of record EFRIO__TRunCont which will be polled by DAQ application + // ---------------------------------------------------------------------------------------- + + EFRIO__FSetCmdRun (-1); + + // ---------------------------------------------- + // Reset Mimosa (26/28) => Rev 14/07/2012 + // ---------------------------------------------- + + // Warning => Must wait until the stop run cmd has been seen by LabVIEW before performing reset + // otherwise the run will not be terminated in a propoer way and LabVIEW will not go back to "main loop" + + Sleep ( 2000 ); // Now an arbitrary delay is used (value to be confirmed) - A better way should be found later + + msg (( MSG_OUT, "EFRIO_USR__FOnStopRunByRunCtrl () => Reset Mimosa (Set TRSTB = 0)" )); + + PPO_FOutD0 ( 0 /* Id */, 0 /* State */ ); + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - Run stopped :-)" ); + + err_retok (( ERR_OUT, "" )); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnAppExit () + : +Goal : This function is called when application is stoped. + : It will free memory and so on ... + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui + : +Level : +Date : 21/12/2010 +Doc date : 21/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FOnAppExit () { + + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + + // Call lib user terminate function + + EFRIO_USR__FEnd (); + + // Call lib general terminate function + + EFRIO__FEnd (); + + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - Application exit - Do nothing now :-)" ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FOnAppExitByRunCtrl () +: +Goal : This function is called when application is stoped. +: It will free memory and so on ... +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if an error occurs +: +Globals : Write to EFRIO__USR_VGContext.LastMsgToGui. +: +Remark : Update the global variable GUI message -> EFRIO__USR_VGContext.LastMsgToGui +: +Level : +Date : 03/02/2011 +Rev : 15/02/2011 + : - Add stop receiver port by a call to IAC__FSockStopReceiverPort +Doc date : 03/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef EFRIO__INCLUDE_RUN_CTRL + +SInt32 EFRIO_USR__FOnAppExitByRunCtrl () { + + err_retfail ( -1, (ERR_OUT,"Function no available => EFRIO__INCLUDE_RUN_CTRL not define !") ); + +} + +#else + +SInt32 EFRIO_USR__FOnAppExitByRunCtrl () { + + EFRIO__USR_TContext* VPtUsrContext = &EFRIO__USR_VGContext; + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + + // Stop sender + + err_error (( ERR_OUT, "1" )); + + IAC__FSockStopSenderPort ( VPtUsrContext->InfRunCtrlSenderId ); + + err_error (( ERR_OUT, "2" )); + + IAC__FSockUnInstallSenderPort ( VPtUsrContext->InfRunCtrlSenderId ); // 10/03/2011 + + // Stop receiver + + err_error (( ERR_OUT, "3" )); + + IAC__FSockStopReceiverPort ( VPtUsrContext->InfRunCtrlReceiverId ); + + err_error (( ERR_OUT, "4" )); + + IAC__FSockUnInstallReceiverPort ( VPtUsrContext->InfRunCtrlReceiverId ); // 10/03/2011 + + // Call lib user terminate function + + err_error (( ERR_OUT, "5" )); + + EFRIO_USR__FEnd (); + + // Call lib general terminate function + + err_error (( ERR_OUT, "6" )); + + EFRIO__FEnd (); + + err_error (( ERR_OUT, "7" )); + + // Set last GUI message to "OK" + + snprintf ( VPtLastMsgToGui, GLB_CMT_SZ-1, "OK - Application exit - Do nothing now :-)" ); + + err_retok (( ERR_OUT, "" )); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO_USR__FGetAcqData () + : +Goal : Function which send data of current acquisition to EUDET DAQ. + : +Inputs : + : +Ouputs : + : +Globals : Read EFRIO__VGContext fields. + : +Remark : + : +Level : +Date : 22/12/2010 +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FGetAcqData () { + + EFRIO__TFrameList* VPtFrameList = EFRIO__VGContext.AAcqFrameList; + EFRIO__TFrame* VPtFrameBuff = EFRIO__VGContext.RunCont.PtFrame; + SInt32 VTotAcqSz = EFRIO__VGContext.RunCont.ResAcqFunctRetCode; + + + // ------------------------------------------------------------------------------------------------ + // Via VPtFrameList you can access at current acquisition frame by frame via an array of pointers + // ------------------------------------------------------------------------------------------------ + // The EFRIO__TFrameList type has the following fields + // + // SInt32 TotFrameNb; // Total frames nb in list + // EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + // UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + + // ------------------------------------------------------------------------------------------------ + // Via VPtFrameBuff you can access at current acquisition seen as a single memory block, the size + // of the bloc ( in bytes ) is given by VTotAcqSz which is a copy of the field ResAcqFunctRetCode + // of EFRIO__TRunCont. + // ------------------------------------------------------------------------------------------------ + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO_USR_FGetLastMsgToGui () + : +Goal : + : +Inputs : None + : +Ouputs : The function returns the last message (char*) for GUI + : +Globals : Read from EFRIO__USR_VGContext.LastMsgToGui. + : +Remark : + : +Level : +Date : 21/12/2010 +Doc date : 21/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO_USR__FGetLastMsgToGui () { + + char* VPtLastMsgToGui = EFRIO__USR_VGContext.LastMsgToGui; + + return (VPtLastMsgToGui); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/03/2013 +Doc date : 01/03/2013 +Author : +E-mail : +Labo : */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FSetRunCtrlMsgHandlingOptions ( SInt8 DisableRunCtrlMsgProcessing, SInt8 EnableRunCtrlMsgDisplay ) { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + + VPtUsrCont->ParDisableRunCtrlMsgProcessing = DisableRunCtrlMsgProcessing; + VPtUsrCont->ParEnableRunCtrlMsgDisplay = EnableRunCtrlMsgDisplay; + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/03/2013 +Doc date : 01/03/2013 +Author : +E-mail : +Labo : */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR__FIsRunCtrlMsgReady () { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + + if ( VPtUsrCont->ResRunCtrlMsgReady == 1 ) { + VPtUsrCont->ResRunCtrlMsgReady = 0; + return (1); + } + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/03/2013 +Doc date : 01/03/2013 +Author : +E-mail : +Labo : */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO_USR__FGetCtrlMsg () { + + EFRIO__USR_TContext* VPtUsrCont = &EFRIO__USR_VGContext; + + + return (VPtUsrCont->ResRunCtrlMsgStr); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 11/11/2010 +Doc date : 11/11/2010 +Author : +E-mail : +Labo : */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO_USR_FPriv () { + + err_retok (( ERR_OUT, "" )); +} + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_usr.def b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.def new file mode 100755 index 0000000..77d6586 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.def @@ -0,0 +1,66 @@ + + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_usr.def +Goal : Macros definition of USER PART of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 11/11/2010 +Doc date : 11/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_USR_DEF +#define EUDET_FRIO_USR_DEF + + +/* ======================= */ +/* Conditional compilation */ +/* ======================= */ + + +/* ================= */ +/* Macro */ +/* ================= */ + + + + +/* ================= */ +/* Constants */ +/* ================= */ + +#define EFRIO__USR_CONST 0 + +#define EFRIO__USR_RUN_CTRL_MSG_CODE_STR_MAX_SZ 50 + +typedef enum EFRIO__USR_ENUM { + EFRIO__USR_ENUM_ITEM_0, + EFRIO__USR_ENUM_ITEM_1, + EFRIO__USR_ENUM_ITEM_2, + EFRIO__USR_ENUM_ITEM_NB + +} EFRIO__USR_TUsrEnum; + + +typedef enum { + + EFRIO__USR_RUN_CTRL_MSG_CONF, + EFRIO__USR_RUN_CTRL_MSG_START_RUN, + EFRIO__USR_RUN_CTRL_MSG_GET_RUN_STATUS_RQ, + EFRIO__USR_RUN_CTRL_MSG_GET_RUN_STATUS_ANS, + EFRIO__USR_RUN_CTRL_MSG_STOP_RUN + +} EFRIO__USR_TMsgCode; + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_usr.h b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.h new file mode 100755 index 0000000..3fcaf4d --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.h @@ -0,0 +1,74 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_usr.h +Goal : Functions prototypes of USER PART of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 11/11/2010 +Doc date : 11/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_USR_H + +#include "func_header.def" + + + +// Publised functions via DLL interface -> Can be called by application using the DLL + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FBegin ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FEnd ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FGetLineCmdPar ();) + + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnAppStart ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnAppStartByRunCtrl ( char* RunCtrlIPAddr, SInt32 RunCtrlPort, SInt32 DaqPort, SInt8 CrIndexFile, SInt32 ReadoutMode );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnAppStartByRunCtrlExt ( SInt8 MapsName, char* RunCtrlIPAddr, SInt32 RunCtrlPort, SInt32 DaqPort, SInt8 CrIndexFile, SInt32 ReadoutMode, SInt8 ErrLogLvl, SInt8 MsgLogLvl );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnConf ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnConfExt ( SInt8 MapsName );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnConfByRunCtrl ( EFRIO__TRunCont* PtRunCont );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnStartRun ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnStartRunByRunCtrl ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnGetRunStatus ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnGetRunStatusByRunCtrl ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnStopRun ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnStopRunByRunCtrl ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnAppExit ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FOnAppExitByRunCtrl ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO_USR__FGetLastMsgToGui ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FSetRunCtrlMsgHandlingOptions ( SInt8 DisableRunCtrlMsgProcessing, SInt8 EnableRunCtrlMsgDisplay );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 EFRIO_USR__FIsRunCtrlMsgReady ();) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* EFRIO_USR__FGetCtrlMsg ();) + +// Private functions private -> Can't be called by application using the DLL + +FHEAD ( SInt32 EFRIO_USR_FPriv ();) +FHEAD ( DWORD WINAPI EFRIO_USR__FThreadRespondRunCtrl ( LPVOID lpParam );) + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef EUDET_FRIO_USR_H + #define EUDET_FRIO_USR_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_usr.typ b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.typ new file mode 100755 index 0000000..9bf7fbf --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.typ @@ -0,0 +1,105 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_usr.typ +Goal : Types definition of USER PART of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 11/11/2010 +Doc date : 11/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_USR_TYP +#define EUDET_FRIO_USR_TYP + + + +// 03/02/2011 + +typedef struct { + + SInt32 TotMsgSz; + SInt32 HeaderSz; + SInt8 MsgCode; + char StrMsgCode[EFRIO__USR_RUN_CTRL_MSG_CODE_STR_MAX_SZ]; + + UInt8 Data; + +} EFRIO__USR_TRunCtrlMsgHeader; + + + +// 16/02/2011 + +typedef struct { + + EFRIO__TRunCont RunCont; + +} EFRIO__USR_TRunCtrlRunStatusAns; + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : dd/mm/2010 */ +/* Doc date : dd/mm/2010 */ +/* Author : */ +/* E-mail : */ +/* Labo : */ +/* ============================================== */ + + +typedef struct { + + SInt8 InfInitDone; // Lib iit done or not + + char LastMsgToGui[GLB_CMT_SZ]; // Last message to GUI + +// Set in comment #ifdef EFRIO__INCLUDE_RUN_CTRL on 13/06/2013 +// Because otherwise the data plot application doesn't compile +// Dont' remember why this CC had been added ? + +// #ifdef EFRIO__INCLUDE_RUN_CTRL + + char ParRunCtrlIPAddr[GLB_FILE_PATH_SZ]; + SInt32 ParRunCtrlPort; + SInt32 ParDaqPort; + SInt8 ParCrIndexFile; // Create index file for synchro with DUT DAQ - 26/03/2013 + SInt32 ParReadoutMode; // Reserved for future use (data demux hard coded / free nb of Mimosa) - 26/03/2013 + + // 01/03/2013 + SInt8 ParDisableRunCtrlMsgProcessing; // Disable RC requests processing display only request in GUI if ParEnableRunCtrlMsgDisplay = 1 + // used to test a run ctrl application + SInt8 ParEnableRunCtrlMsgDisplay; // Enable RC requests display in GUI + + SInt32 InfRunCtrlSenderId; + SInt32 InfRunCtrlReceiverId; + DWORD InfThreadRespondRunCtrlId; + HANDLE InfThreadRespondRunCtrlHnd; + HANDLE InfEventRespondRunCtrlHnd; + SInt32 InfFOnConfByRunCtrlRetCode; + SInt32 InfFOnStartRunByRunCtrlRetCode; + SInt32 InfFOnGetRunStatusByRunCtrl; + SInt32 InfFOnStopRunByRunCtrl; + + SInt32 ResRunCtrlMsgReady; // Indicates that a Run Ctrl message has been received and can be read from ResRunCtrlMsgStr + char ResRunCtrlMsgStr[GLB_CMT_SZ]; // Last Run Ctrl message + + +// #endif + + +} EFRIO__USR_TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/eudet_frio_usr.var b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.var new file mode 100755 index 0000000..e30f7d0 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/eudet_frio_usr.var @@ -0,0 +1,34 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_usr.var +Goal : Variables definition of USER PART of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 11/11/2010 +Doc date : 11/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_USR_VAR +#define EUDET_FRIO_USR_VAR + + + + +/* ================= */ +/* Global variables */ +/* ================= */ + +EXTERN VAR_STATIC EFRIO__USR_TContext EFRIO__USR_VGContext; + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/files.c b/include/pxi_daq_lib_v.2.1/files.c new file mode 100755 index 0000000..02f3606 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/files.c @@ -0,0 +1,5127 @@ + +/******************************************************************************* +File : x:\lib\com\files\files.c +Goal : Functions of files library +Prj date : XX/XX/2003 +File date : XX/XX/2003 + : +Rev : 11/01/2012 + : - Plume BT bug fix in TCStreamFile(ProParBlocSz -> ProAParBlocSz) + : 12/01/2012 + : - Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed, these blocs will be removed from blocs index table + : - Save two index files : + : *.inf = normal without info on blocs not saved + : *.all.inf = default with all blocs info + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr + : +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FIL_C +#define FIL_C + + +#ifdef CC_UNIX + +UInt32 GetTickCount () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + + +SInt32 GetLastError () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + +#endif + +/******************************************************************************* +Prototype : SInt32 FIL_FFileExists ( char* FilePath ) +Goal : Test if the file exists. +Inputs : The file name ( full path if needed ). +Ouputs : 1 if the file exists, else 0. +Globals : +Remark : The result is not guaranted in case of multi application lock to file. +Level : This is a user level function. +Date : 17/04/2003 +Doc date : 17/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FFileExists ( char* FilePath ) { + + SInt32 VRet; + FILE* VPf; + + VPf = fopen ( FilePath, "r" ); + + if ( VPf == NULL ) { + VRet = 0; + } + + else { + fclose ( VPf ); + VRet = 1; + } + + + return (VRet); +} + +/* 13/10/2004 */ + +SInt32 FIL_FFileSize ( char* FilePath ) { + + FILE* VPf; + SInt32 VFileSz; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fopen fail !" ) )); + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fclose (VPf) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fclose fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "%d Bytes", VFileSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FCpyFile ( char* Src, char* Dest ) + : +Goal : Copy SrcFile to DestFile. + : +Inputs : Src - Source file + : Dest - Destination file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - fonction moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FCpyFile ( char* Src, char* Dest ) { + + FILE* VPfSrc; + FILE* VPfDest; + SInt8 VBuffer[512]; // Debug 02/06/2007 move storage class static to auto + SInt32 VReadBytesCnt; + SInt32 VTotBytesCnt; + SInt32 VRet; + + VPfSrc = fopen ( Src, "rb" ); + + err_retnull ( VPfSrc, (ERR_OUT,"Source file %d open failed", Src ) ); + + VPfDest = fopen ( Dest, "wb" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", VPfDest ) ); + + VTotBytesCnt = 0; + + while ( ( VReadBytesCnt = fread ( VBuffer, 1 /* byte size */ , 512 /* bytes number */, VPfSrc ) ) > 0 ) { + fwrite ( VBuffer, 1 /* byte size */, VReadBytesCnt, VPfDest ); + VTotBytesCnt += VReadBytesCnt; + } + + fclose (VPfSrc); + fclose (VPfDest); + + err_retok (( ERR_OUT, "file %s copied in %s => %d bytes", Src, Dest, VTotBytesCnt )); +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FRemoveFile ( char* FilePath ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FRemoveFile ( char* FilePath ) { + + SInt32 VRet; + char* VStrError; + + VRet = remove ( FilePath ); + + err_retfail ( VRet, (ERR_OUT,"Remove file=%s failed => %s", FilePath, _strerror ("")) ); + err_retok (( ERR_OUT, "")); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) + : +Goal : List the directory SrcDir and write the result in DestDirFile. + : +Inputs : SrcDir - The directory to list + : DestDirFile - The result file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - Function moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifdef CC_APP_WINDOWS + +#ifndef FILE__VCPP_COMPIL + +SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + + VPf = fopen ( DestDirFile, "wt" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT, "Dir file %s creation failed ", DestDirFile ) ); + } + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + ++VItemCnt; + fprintf( VPf, "%s\n", VFileInfo.ff_name); + VRet = findnext(&VFileInfo); + } + + fclose ( VPf ); + + return (0); +} + +#endif + +#endif + + +SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) { + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + return ( FIL_FDosDirOutFile ( SrcDir, DestDirFile ) ); + + #else + err_retfail ( -1, (ERR_OUT,"Function not handled under VC++") ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FDosDelDir ( char* SrcDir ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : Compiled only if CC_APP_WINDOWS is defined +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + +#ifdef CC_APP_WINDOWS + +#ifndef FILE__VCPP_COMPIL + +SInt32 FIL_FDosRmDirFiles ( char* SrcDir ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + char VFileToDelete[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + SInt32 VRetRemove; + SInt32 VFuncRet; + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VFuncRet = 0; + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + sprintf ( VFileToDelete, "%s\\%s", SrcDir, VFileInfo.ff_name ); + VRetRemove = FIL_FRemoveFile ( VFileToDelete ); + + if ( VRetRemove < 0 ) { + VFuncRet = -1; + err_error (( ERR_OUT, "Remove file=%s failed => %s", VFileToDelete, _strerror ("") )); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + + return (VFuncRet); +} + +#endif + +#endif + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDirFiles ( char* SrcDir ) +Goal : Remove all the files in directory SrcDir but let the direcory +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDirFiles ( char* SrcDir ) { + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + return ( FIL_FDosRmDirFiles (SrcDir) ); + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available under VC++ !", SrcDir) ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available !", SrcDir) ); +#endif + + +} + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDir ( char* SrcDir ) +Goal : Remove the directory SrcDir if empty +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDir ( char* SrcDir ) { + + SInt32 VRet; + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + + // VRet = _rtl_chmod( SrcDir, 1 , FA_NORMAL ); + // err_retfail ( VRet, (ERR_OUT,"Chmod failed on directory=%s", SrcDir) ); + + VRet = rmdir ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"Remove directory=%s failed => %s ", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"Function handled only under VC++") ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"Function handled only under Windows") ); +#endif + +} + +/******************************************************************************* +Prototype : +Goal : Delete direcory files and directory itself +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelDir ( char* SrcDir ) { + + SInt32 VRet; + char VNewName[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + + sprintf ( VNewName, "%s.old", SrcDir ); + + VRet = rename ( SrcDir, VNewName ); + + err_retfail ( VRet, (ERR_OUT,"Rename Dir=%s to %s failed !", SrcDir, VNewName ) ); + + err_warning (( ERR_OUT, "Directory %s renamed in %s because delete is impossible !", SrcDir, VNewName )); + + err_retok (( ERR_OUT, "" )); + +/* + VRet = FIL_FRmDirFiles ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDirFiles (%s) failed ", SrcDir) ); + + VRet = FIL_FRmDir ( VNewName ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDir (%s) failed ", SrcDir) ); + + err_retok (( ERR_OUT, "" )); +*/ + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FMkDir ( char* SrcDir ) { + + SInt32 VRet; + char VStrCmd[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + #ifdef APP_DAQ + + err_retfail ( -1, (ERR_OUT,"Function NOT available under LynxOS !") ); + + #endif + + #ifdef CC_APP_LINUX + sprintf ( VStrCmd, "mkdir %s", SrcDir ); + system ( VStrCmd ); + #endif + + + #ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + + VRet = mkdir ( SrcDir ); + + err_retfail ( VRet, (ERR_OUT,"Creation of directory=%s failed => %s", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"Function NOT available under VC++ !") ); + #endif + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FMkDir (SrcDir=%s) IS NOT available !", SrcDir) ); + #endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in + : the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT + : are not written in list. +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +#ifndef FILE__VCPP_COMPIL + +SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + +#endif + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in +: the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT +: are not written in list. +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +#ifndef FILE__VCPP_COMPIL + +SInt32 FIL_FExtDosListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\%s", SrcDir, Joker ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + +#endif + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + return ( FIl_FDosListDirFiles ( SrcDir, PtList ) ); + + #else + err_retfail ( -1, (ERR_OUT,"Function not handled under VC++") ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + return ( FIL_FExtDosListDirFiles ( SrcDir, Joker, PtList ) ); + + #else + err_retfail ( -1, (ERR_OUT,"Function not handled under VC++") ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList ) { + + SInt32 VRet; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + VFilesCnt = FIl_FListDirFiles ( VRmpDirPath, PtList ); + + return ( VFilesCnt ); +} + + + +#ifndef APP_DAQ + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Extended version which handles conf extension i,j,k +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtDelRmpFiles ( char* RmpDataPath, char ConfExt, SInt32 RunNo, SInt32 MaxFileCnt ) { + + SInt32 VRet; + SInt32 ViFile; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VInfoFilePath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VData0Filepath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + FIL_TDirFilesList VFilesList; // Debug 02/06/2007 move storage class static to auto + + + char VFileToDelete[GLB_FILE_PATH_SZ]; + + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + sprintf ( VInfoFilePath , "RUN_%d_%c.rz", RunNo, ConfExt ); + sprintf ( VData0Filepath, "RUN_%d_0.rz" , RunNo ); + + VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &VFilesList ); + + /* !!! DESY 20/09/05 !!! MUST BE CHECKED ! */ + /* previous line replaced by this one in order to be able to compile boards_db_man */ + /* VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &(VPtAFilesPath) ); */ + + err_retfail ( VFilesCnt, (ERR_OUT,"FIL_FCntRmpFiles (%s) failed Ret=%d", RmpDataPath, VFilesCnt ) ); + + if ( VFilesCnt < MaxFileCnt ) { + err_retok (( ERR_OUT, "Nothing to do VFilesCnt=%d < MaxFileCnt=%d", VFilesCnt, MaxFileCnt )); + } + + err_warning (( ERR_OUT, "%d RMP files are not deleted by monitoring => I will remove them", VFilesCnt )); + + for ( ViFile = 0; ViFile < VFilesCnt; ViFile++ ) { + + if ( strcmp ( VFilesList.AList[ViFile], VInfoFilePath ) == 0 ) { + continue; + } + + if ( strcmp ( VFilesList.AList[ViFile], VData0Filepath ) == 0 ) { + continue; + } + + sprintf ( VFileToDelete, "%s\\%s", VRmpDirPath, VFilesList.AList[ViFile] ); + + err_warning (( ERR_OUT, "FIL_FDelRmpFilesv => File = %s", VFileToDelete )); + + FIL_FRemoveFile ( VFileToDelete ); + + } + + return (0); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Creation of FIL_FExtDelRmpFiles to replace FIL_FDelRmpFiles + : - FIL_FDelRmpFiles call FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt ) { + return ( FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) ); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FFloatVectorsToTextFile ( float** SrcVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** VectorsNames, char DataSep, char* DestFile ) { + + char VFuncName[] = "FIL_FFloatVectorsToTextFile"; + + FILE* VPfDest; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + + + VPfDest = fopen ( DestFile, "wt" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", DestFile ) ); + + + if ( HeaderLine != NULL ) { + VRet = fprintf ( VPfDest, "%s \n", HeaderLine ); + } + + else { + VRet = fprintf ( VPfDest, "No header line \n", HeaderLine ); + } + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing Header line file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + + if ( VectorsNames != NULL ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + VRet = fprintf ( VPfDest, "%-21s", VectorsNames[ViVector]); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing vectors names line - Vector=%d file=%s => %s", ViVector, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + VRet = fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + } + + else { + fprintf ( VPfDest, "No vectors names line \n", HeaderLine ); + } + + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + VRet = fprintf ( VPfDest, "%.6f%c", SrcVectors[ViVector][ViLine], DataSep); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing line=%d in file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR line=%d file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + fflush (VPfDest); + fclose (VPfDest); + + err_retok (( ERR_OUT, "%d line written in file", EltNbPerVector, DestFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FTextFileToFloatVectors ( char* SrcFile, char DataSep, float** DestVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** AVectorsNames, char* StrVectorsNames ) { + + char VFuncName[] = "FIL_FTextFileToFloatVectors"; + + FILE* VPf; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet = 1; // Antonin Maire, proper initialisation of the return variable, 16 oct 2014 + char VStrCR[2]; + char VDataSep; + + /* Check parameters */ + + err_retnull ( SrcFile , (ERR_OUT,"SrcFile == NULL" ) ); + err_retnull ( DestVectors , (ERR_OUT,"DestVectors == NULL" ) ); + err_retnull ( HeaderLine , (ERR_OUT,"HeaderLine == NULL" ) ); + err_retnull ( AVectorsNames , (ERR_OUT,"AVectorsNames == NULL" ) ); + err_retnull ( StrVectorsNames , (ERR_OUT,"StrVectorsNames == NULL" ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 1" )); + + /* Try to open file */ + + VPf = fopen ( SrcFile, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFile ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read header line */ + + char *c = 0x0; + c = fgets( HeaderLine, 255, VPf ); + if( c == 0x0 ) VRet = 0; + c = 0x0; + // change Antonin Maire, 16 oct 2014 (cancel Jérôme Baudot's commit 1027) + // Was before : VRet = (SInt32) fgets( HeaderLine, 255, VPf ); + // Pb : Unlike fscanf, fgets return a char* and not an int... + // -> http://www.cplusplus.com/reference/cstdio/fgets/ + // gcc compilation does not like the cast char* to SInt32 VRet. + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read header line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + /* Read vectors names line */ + + c = fgets( StrVectorsNames, 255, VPf ); + // change Antonin Maire, 16 oct 2014 + if( c == 0x0 ) VRet = 0; + c = 0x0; + // change Antonin Maire, 16 oct 2014 (cancel Jérôme Baudot's commit 1027) + // Was before : VRet = (SInt32) fgets( StrVectorsNames, 255, VPf ); + // Pb : Unlike fscanf, fgets return a char* and not an int... + // -> http://www.cplusplus.com/reference/cstdio/fgets/ + // gcc compilation does not like the cast char* to SInt32 VRet. + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read vectors names line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + sprintf ( AVectorsNames[ViVector], "" ); + }; + + + /* Read vectors */ + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + if ( ViVector == VectorsNb-1 ) { + VRet = fscanf ( VPf, "%f%c", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + else { + VRet = fscanf ( VPf, "%f%c\n", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + + if ( VRet != 2 ) { + fflush (VPf); + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s", ViLine, SrcFile, VRet, _strerror ( "System says :" ) ) ); + } + + } + + } + + + fflush (VPf); + fclose (VPf); + + err_retok (( ERR_OUT, "%d line Read in file", EltNbPerVector, SrcFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__NO_GET_APP_RUN_DIR + + SInt32 FIL_FGetAppRunDir ( char* StrRunDir, TApplication* PtApp ) { + + char* VPtStrExeName; + AnsiString VAStrExeName; + char VExeDriveLetter; + char VExeDriveId; /* 0 = default, 1 = A, 2 = B ... */ + char VStrCurDir[GLB_FILE_PATH_SZ]; + char VStrCurDirPath[GLB_FILE_PATH_SZ]; + + err_retfailnull ( StrRunDir, (ERR_OUT,"StrRunDir == NULL") ); + + VPtStrExeName = FStr2PCh ( &(PtApp->ExeName) ); + + VExeDriveLetter = toupper ( VPtStrExeName[0] ); + + switch ( VExeDriveLetter ) { + + case 'A' : { + VExeDriveId = 1; + break; } + + case 'B' : { + VExeDriveId = 2; + break; } + + case 'C' : { + VExeDriveId = 3; + break; } + + case 'D' : { + VExeDriveId = 4; + break; } + + case 'E' : { + VExeDriveId = 5; + break; } + + case 'F' : { + VExeDriveId = 6; + break; } + + case 'G' : { + VExeDriveId = 7; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown drive id=%d", VExeDriveId) ); + VExeDriveId = 0; + } + + } + + getcurdir( VExeDriveId, VStrCurDir ); + + sprintf ( VStrCurDirPath, "%c:\\%s", VExeDriveLetter, VStrCurDir ); + sprintf ( StrRunDir, "%s", VStrCurDirPath ); + + // msg (( MSG_OUT, "VStrCurDirPath = %s", VStrCurDirPath )); + + err_retok (( ERR_OUT, "" )); + } + + #else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + + #endif + +#else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 07/03/2011 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FGetDiskSectorSz ( char* Drive ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported under Unix !" ) ); + +#else + + DWORD VDummyW; + DWORD VBytesPerSector; + BOOL VRetBool; + + // BOOL GetDiskFreeSpace( + // + // LPCTSTR lpRootPathName, // address of root path + // LPDWORD lpSectorsPerCluster, // address of sectors per cluster + // LPDWORD lpBytesPerSector, // address of bytes per sector + // LPDWORD lpNumberOfFreeClusters, // address of number of free clusters + // LPDWORD lpTotalNumberOfClusters // address of total number of clusters + // ); + + + VRetBool = GetDiskFreeSpace( + Drive, // address of root path + &VDummyW, // address of sectors per cluster + &VBytesPerSector, // address of bytes per sector + &VDummyW, // address of number of free clusters + &VDummyW // address of total number of clusters + ); + + if ( VRetBool == True ) { + return ( VBytesPerSector ); + } + + else { + return (-1); + } + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: ~FIL__TCBinFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + + // Variables for internal processing + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdEltId = 0; + ProCurRdSz = 0; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProPtFile = NULL; + + err_trace (( ERR_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + ProParRWBMode = RWBMode; + ProParMaxBlocSz = MaxBlocSz; + ProParBlocSz = BlocSz; + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + ProConfDone = 1; + + + // Allocate memory buffer for data read from file + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = MaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCBinFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProPtFile == NULL ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + + // Store current ( initial ) position in file + + if ( (VCurPos = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Goto end of file + + if ( fseek ( ProPtFile, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + // Get current position = END in file => it's file size + + if ( (VFileSz = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Restor initial position in file + + if ( fseek ( ProPtFile, VCurPos, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + + } // End file is already open + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFCreate () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProPtFile = fopen ( ProParDataFile, "wb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFOpen () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + ProPtFile = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz ) { + SInt8 VBlocNbWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can write to a file when RWB mode IS NOT Write !") ); + } + + ProCurWrSz = DataSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbWritten = fwrite ( PtrData, DataSz /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbWritten != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc write failed ! => System : %s", _strerror ("") ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + fflush ( ProPtFile ); + } + + ++ProCurWrEltId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", DataSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + if ( DataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > MaxDestSz=%d", DataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( DestPtr, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc read of %d bytes failed ! - VBlocNbRead = %d => System : %s", DataSzToRead, VBlocNbRead, _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + if ( DataSzToRead > ProParMaxBlocSz ) { + err_retfailnull ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > ProParMaxBlocSz=%d", DataSzToRead, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( ProPtrBuffRdData, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Bloc read failed ! => System : %s", _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGotoBloc ( SInt32 BlocNo ) { + + SInt32 VOffset; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + VOffset = BlocNo * ProParBlocSz; + + if ( fseek ( ProPtFile, VOffset, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Goto bloc %d => %d bytes from beginning failed !", BlocNo ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ) { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFFlush () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + fflush ( ProPtFile ); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFClose () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + fflush ( ProPtFile ); + } + + fclose ( ProPtFile ); + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + ProConfDone = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_WRITE, RecSz, RecSz, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFCreate (); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqWrite ( PtSrc, RecSz ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_READ, RecSz, RecSz, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFOpen(); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqRead ( PtDest, RecSz /* MaxDestSz */, RecSz /* DataSzToRead */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + + +// msg (( MSG_OUT, "Msg" )); + + + +// **************************** +// FIL__TCStreamFile +// **************************** + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl, DiskBlocSz ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: ~FIL__TCStreamFile () { + + // Free info record + + if ( ProPtRecInfFile != NULL ) { + free ( ProPtRecInfFile ); + } + + // Free info record cpy + + if ( ProPtRecInfFileCpy != NULL ) { + free ( ProPtRecInfFileCpy ); + } + + +#ifndef CC_UNIX + TerminateThread ( ProThreadHnd , 0 /* Thread exit code */ ); + + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + DeleteCriticalSection ( &ProCsPrintMsg ); + #endif + + +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : 05/11/2010 + : - Error handling on disk access is not properly done, a message is printed + : but the error is not propagated => MUST be done. +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ + : +Rev : 09/05/2010 + : - Circular buffer implementation + : 11/01/2012 + : - "Plume BT bug" fix, using new field ProAParBlocSz instead of ProABlocSz + : 12/01/2012 + : - Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed, these blocs will be removed from blocs index table + : +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef CC_UNIX + +DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ) { + + FIL__TCStreamFile* VPtObj = (FIL__TCStreamFile*) lpParam; + + SInt32 VRet; + DWORD VBuffFull; + UInt32 VNbBytesToWrite; + UInt32 VNbBytesWritten; + char VStrMsg[GLB_CMT_SZ]; + + static SInt32 VDbgSaveCnt = 0; + + #ifdef FIL__DEBUG + EFRIO__TFrame* VDbgPtFrame; + #endif + + + while (1) { + + + // Wait on buffer to read + + VBuffFull = WaitForSingleObject ( VPtObj->ProSemRdBuffHnd, INFINITE ); + + switch ( VBuffFull ) { + + case WAIT_OBJECT_0 : { + + VNbBytesToWrite = VPtObj->ProAParBlocSz[VPtObj->ProIndexRdBuff]; // 11/01/2012 Plume BT bug fix + + // Emulates error during write on RAID 1 each 100 access + // It's DISABLED now + + ++VDbgSaveCnt; + + if ( 0 /* (VDbgSaveCnt % 100) == 0 */ ) { // + VNbBytesWritten = 0; + } + + else { + + WriteFile( + VPtObj->ProFileHnd, // handle to file to write to + VPtObj->ProABuff[VPtObj->ProIndexRdBuff], // pointer to data to write to file + VNbBytesToWrite, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + } + + + if ( VNbBytesWritten != VNbBytesToWrite ) { + + // 12/01/2012 + // - Tag an error maker on the bloc = set its size to negative value + // - This tag will be used by ProFUpdateIndexTable () in PubFClose () to remove blocs not saved from blocs table + + *(VPtObj->ProAPtBlocSz[VPtObj->ProIndexRdBuff]) = -(*(VPtObj->ProAPtBlocSz[VPtObj->ProIndexRdBuff])); + + // Log error + + sprintf ( VStrMsg, "ThreadDisk => Writing buff %d error !", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg, FIL__TCStreamFile_LOG_ERR_ERROR ); + } + + else { + sprintf ( VStrMsg, "ThreadDisk => Buffer %d save to disk", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg, FIL__TCStreamFile_LOG_ERR_TRACE ); + } + + if ( VPtObj->ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( VPtObj->ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + ++VPtObj->ProIndexRdBuff; + + err_retfail ( VPtObj->ProIndexRdBuff, (ERR_OUT,"Bad variable size => ProIndexRdBuff=%d < 0", VPtObj->ProIndexRdBuff) ); + + if ( VPtObj->ProIndexRdBuff >= FIL__TCStreamFile_MAX_BUFF_NB ) { + VPtObj->ProIndexRdBuff = 0; + } + + ReleaseSemaphore ( VPtObj->ProSemWrBuffHnd, 1, NULL ); + + + break; } + + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFull )); + break; } + + } + + + + } // End while (1) + + return 0; +} + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 05/11/2010 +Doc date : 05/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFCalcProParBlocSz ( SInt32 DataSz ) { + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VRecInfSz; + + VNotIntegerDiskBlocNb = DataSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (DataSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = DataSz; + } + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + SInt8 ViBuff; + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + ProParDiskBlocSz = DiskBlocSz; + + // Parameters from conf + + sprintf ( ProParDataFile , "" ); + sprintf ( ProInfFileName , "" ); + sprintf ( ProInfFileNameAll, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + ProParFixedBlocSzMode = 1; + + // Parameter used for multithreading data saving mode + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProAParBlocSz[FIL__TCStreamFile_MAX_BUFF_NB] = 0; + } + + // Variables for internal processing + + ProUseThread = 0; + + ProFileHasBeenClosed = 0; + + ProFileHnd = INVALID_HANDLE_VALUE; + ProPtInfFile = NULL; + ProPtInfFileAll = NULL; + +#ifndef CC_UNIX + + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + InitializeCriticalSection ( &ProCsPrintMsg ); + #endif + +#endif + + ProThreadHnd = INVALID_HANDLE_VALUE; + ProThreadId = 0; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProABuff[ViBuff] = NULL; + ProAPtBlocSz[ViBuff] = NULL; + } + + ProSemWrBuffHnd = INVALID_HANDLE_VALUE; + ProSemRdBuffHnd = INVALID_HANDLE_VALUE; + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + ProBuffSz = 0; + + ProPtRecInfFile = NULL; + ProPtRecInfFileCpy = NULL; + ProRecInfSz = 0; + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdBlocId = 0; + ProCurRdSz = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProResWrBlocFailCnt = 0; + + + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetDiskSectorSz ( SInt32 DiskBlocSz ) { + + ProParDiskBlocSz = DiskBlocSz; + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetDiskSectorSz () { + + return (ProParDiskBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : Msg - The message string + : MsgLevel - It can be + : - FIL__TCStreamFile_LOG_GENERAL_MSG + : - FIL__TCStreamFile_LOG_ERR_TRACE + : - FIL__TCStreamFile_LOG_ERR_WARNING + : - FIL__TCStreamFile_LOG_ERR_ERROR + : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void FIL__TCStreamFile :: PubFPrintMsg ( char* Msg, SInt8 MsgLevel ) { + +#ifndef CC_UNIX + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + EnterCriticalSection( &ProCsPrintMsg ); + #endif +#endif + + switch ( MsgLevel ) { + + case FIL__TCStreamFile_LOG_GENERAL_MSG : { + msg (( MSG_OUT, "%s", Msg )); + break; } + + case FIL__TCStreamFile_LOG_ERR_TRACE : { + err_trace (( ERR_OUT, "%s", Msg )); + break; } + + case FIL__TCStreamFile_LOG_ERR_WARNING : { + err_warning (( ERR_OUT, "%s", Msg )); + break; } + + case FIL__TCStreamFile_LOG_ERR_ERROR : { + err_error (( ERR_OUT, "%s", Msg )); + break; } + + default : { + msg (( MSG_OUT, "%s", Msg )); + break; } + + } + + +#ifndef CC_UNIX + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + LeaveCriticalSection( &ProCsPrintMsg ); + #endif +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : +Rev : 11/01/2012 + : - "Plume BT bug" fix, add cpy of RecInfFile => ProPtRecInfFileCpy + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt8 ViBuff; + SInt32 VNotIntegerDiskBlocNb; + +#ifndef CC_UNIX + #ifndef FILE__NO_DATE_TIME_HANDLING + TDateTime VODateTime; + #endif +#endif + + + + // ------------------------------------------------------- + // Set class parameters from PubFConf parameters list + // ------------------------------------------------------- + + err_retnull ( PtMyself, (ERR_OUT,"PtMyself == NULL") ); + + PriPtMyself = PtMyself; + + ProUseThread = UseThread; + + sprintf ( ProParDataFile, "%s", DataFile ); + + sprintf ( ProInfFileName, "%s.inf", ProParDataFile ); + + sprintf ( ProInfFileNameAll, "%s.all.inf", ProParDataFile ); + + ProParRWBMode = RWBMode; + + ProParFixedBlocSzMode = FixedBlocSzMode; + + ProParRequestedBlocSz = BlocSz; + + VNotIntegerDiskBlocNb = ProParRequestedBlocSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (ProParRequestedBlocSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = ProParRequestedBlocSz; + } + + err_trace (( ERR_OUT, "RequestedBlocSz=%d - BlocSz=%d", ProParRequestedBlocSz, ProParBlocSz )); + + + ProParRequestedMaxBlocSz = MaxBlocSz; + + if ( ProParRequestedMaxBlocSz >= ProParBlocSz ) { + ProParMaxBlocSz = ProParRequestedMaxBlocSz; + } + + else { + err_warning (( ERR_OUT, "ProParMaxBlocSz=%d must be adjusted -> Set to ProParBlocSz=%d", ProParMaxBlocSz, ProParBlocSz )); + ProParMaxBlocSz = ProParBlocSz; + } + + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + // ------------------------------------------------------- + // Alloc information file record + // ------------------------------------------------------- + + if ( ProParFixedBlocSzMode == 1 ) { + ProRecInfSz = sizeof (FIL__TCStreamFile_Old_TRecInfFile); + } + + else { + + // BUG ? + + // ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (UInt64) ); + + ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (FIL__TCStreamFile_TBlocInf) ); + + } + + err_warning (( ERR_OUT, "ProRecInfSz=%d ", ProRecInfSz )); // added, JB 2014/10/16 + + ProPtRecInfFile = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFile, (ERR_OUT,"Allocation of info record failed !") ); + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // Add cpy of RecInfFile on 11/01/2012 + + ProPtRecInfFileCpy = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFileCpy, (ERR_OUT,"Allocation of info record cpy failed !") ); + + memset ( ProPtRecInfFileCpy, 0, ProRecInfSz ); + + + // ------------------------------------------------------- + // Create or open information file + // ------------------------------------------------------- + + // Write mode => Create info file + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProPtRecInfFile->Version = 1; + ProPtRecInfFile->FixedBlocSz = ProParFixedBlocSzMode; + ProPtRecInfFile->MaxBlocSz = ProParMaxBlocSz; + ProPtRecInfFile->BlocSz = ProParBlocSz; + ProPtRecInfFile->BlocNb = 0; + ProPtRecInfFile->ABlocInf[0].Offset = 0; + ProPtRecInfFile->ABlocInf[0].Sz = 0; + +#ifndef CC_UNIX + #ifndef FILE__NO_DATE_TIME_HANDLING + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateCreate = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeCreate = TIME__FConvDateTime2Time ( VODateTime ); + #endif +#else + ProPtRecInfFile->DateCreate.W32 = 0; + ProPtRecInfFile->TimeCreate.W32 = 0; +#endif + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Creation of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + err_trace (( ERR_OUT, "Info file=%s created", ProInfFileName )); + } + + // Read mode => Open info file + + else { + + ProPtInfFile = fopen ( ProInfFileName, "rb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Open info file %s failed => system : %s", ProInfFileName, _strerror ( "" ) )); + err_trace (( ERR_OUT, "Info file=%s read", ProInfFileName )); + + if ( fread ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Read info file %s failed => system : %s", ProInfFileName, _strerror ( "" )) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + // Print info file + + PubFPrintInfFile (); + + // Set bloc size + + ProParBlocSz = ProPtRecInfFile->BlocSz; + + if ( ProParRequestedBlocSz != ProParBlocSz ) { + err_warning (( ERR_OUT, "Requested bloc sz=%d <> Info file bloc sz=%d => Use Info file bloc sz", ProParRequestedBlocSz, ProParBlocSz )); + } + + } + + + // ------------------------------------------------------------- + // Write mode => Allocate buffers, create semaphores and thread + // ------------------------------------------------------------- + + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + if ( FIL__TCStreamFile_MAX_BUFF_NB > 4 ) { + err_retfail ( -1, (ERR_OUT,"FIL__TCStreamFile_MAX_BUFF_NB = %d ! Handling of more than 4 buffers is NOT implemented !", FIL__TCStreamFile_MAX_BUFF_NB) ); + } + + // Allocate buffers + + ProBuffSz = ProParMaxBlocSz; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + // If already allocated => Free + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + } + + // Allocate + + ProABuff[ViBuff] = (UInt8*) malloc ( ProBuffSz ); + + err_retnull ( ProABuff[ViBuff], (ERR_OUT,"Allocation buffer[%d] of %d bytes failed !", ViBuff, ProBuffSz ) ); + err_trace (( ERR_OUT, "Buffer[%d] of %d bytes allocated", ViBuff, ProBuffSz )); + + // Reset content with $FF + + memset ( ProABuff[ViBuff], 0xFF, ProBuffSz ); + } + + // Create & init semaphores + + #ifndef CC_UNIX + ProSemWrBuffHnd = CreateSemaphore( NULL, FIL__TCStreamFile_MAX_BUFF_NB, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = Max = Max buff nb + + err_retnull ( ProSemWrBuffHnd, (ERR_OUT,"Create SemWrBuff failed ! - LastError=%d", GetLastError ()) ); + + ProSemRdBuffHnd = CreateSemaphore( NULL, 0, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = 0, Max = Max buff nb + + err_retnull ( ProSemRdBuffHnd, (ERR_OUT,"Create SemRdBuff failed ! - LastError=%d", GetLastError ()) ); + #endif + + // Init buffers index + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + // Create thread + + #ifndef CC_UNIX + ProThreadHnd = CreateThread ( NULL, 0, FIL__TCStreamFile_FThread, (void*) PriPtMyself /* Param */ , 0, &ProThreadId ); + err_retnull ( ProThreadHnd, (ERR_OUT,"Thread creation failed ! LastError=%d", GetLastError ()) ); + #endif + + } + + // ------------------------------------------------------------- + // Read mode => Allocate memory buffer for data read from file + // ------------------------------------------------------------- + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = ProParMaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : Prints record passed as parameter, not the one of the class like PubFPrintInfFile () + : It's also possible to add a comment and a "tag string" at the beginning of each line. +Level : +Date : 13/01/2012 +Doc date : 13/01/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFileRec ( FIL__TCStreamFile_TRecInfFile* Pt, char* Cmt, char* TagStr ) { + + SInt32 ViBloc; + SInt16 ViSpareW32Info; + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "$" )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record - %s", Cmt )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "%s Version = %d", TagStr, Pt->Version )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "%s Date create = %s", TagStr, TIME__FDateL2Str ( Pt->DateCreate, NULL, 0 ) )); + msg (( MSG_OUT, "%s Time create = %s", TagStr, TIME__FTime2Str ( Pt->TimeCreate, NULL, 0 ) )); + msg (( MSG_OUT, "%s Date close = %s", TagStr, TIME__FDateL2Str ( Pt->DateClose , NULL, 0 ) )); + msg (( MSG_OUT, "%s Time close = %s", TagStr, TIME__FTime2Str ( Pt->TimeClose , NULL, 0 ) )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "%s FixedBlocSz = %d", TagStr, Pt->FixedBlocSz )); + msg (( MSG_OUT, "%s MaxBlocSz = %d", TagStr, Pt->MaxBlocSz )); + msg (( MSG_OUT, "%s BlocSz = %d", TagStr, Pt->BlocSz )); + msg (( MSG_OUT, "%s BlocNb = %d", TagStr, Pt->BlocNb )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "%s ABlocInf[0].Offset = %Lu" , TagStr, Pt->ABlocInf[0].Offset )); + msg (( MSG_OUT, "%s ABlocInf[0].Sz = %d ", TagStr, Pt->ABlocInf[0].Sz )); + msg (( MSG_OUT, "%s ABlocInf[0].SpareW32InfoFormat = %d ", TagStr, Pt->ABlocInf[0].SpareW32InfoFormat )); + msg (( MSG_OUT, "%s ABlocInf[0].SpareW32InfoNb = %d ", TagStr, Pt->ABlocInf[0].SpareW32InfoNb )); + + for ( ViSpareW32Info=0; ViSpareW32Info < Pt->ABlocInf[0].SpareW32InfoNb; ViSpareW32Info++ ) { + msg (( MSG_OUT, "%s ABlocInf[0].ASpareW32Info[%.2d] = %d ", TagStr, ViSpareW32Info, Pt->ABlocInf[0].ASpareW32Info[ViSpareW32Info] )); + } + + + if ( Pt->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < 200 /* Pt->BlocNb */; ViBloc++ ) { + msg (( MSG_OUT, "%s Bloc[%.4d] : Offset=%.12Lu - Sz=%.8d [Bytes] - ASpare [0]=%.4d [1]=%.4d [2]=%.4d [3]=%.4d", TagStr, ViBloc, Pt->ABlocInf[ViBloc].Offset, Pt->ABlocInf[ViBloc].Sz, Pt->ABlocInf[ViBloc].ASpareW32Info[0], Pt->ABlocInf[ViBloc].ASpareW32Info[1], Pt->ABlocInf[ViBloc].ASpareW32Info[2], Pt->ABlocInf[ViBloc].ASpareW32Info[3] )); + } + + } + + msg (( MSG_OUT, "#" )); + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 20/05/2010 +Doc date : 20/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFile () { + + SInt32 ViBloc; + SInt16 ViSpareW32Info; + + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record " )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Version = %d", ProPtRecInfFile->Version )); + msg (( MSG_OUT, "-------------------------" )); + //msg (( MSG_OUT, "Date create = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateCreate, NULL, 0 ) )); + //msg (( MSG_OUT, "Time create = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeCreate, NULL, 0 ) )); + //msg (( MSG_OUT, "Date close = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateClose , NULL, 0 ) )); + //msg (( MSG_OUT, "Time close = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeClose , NULL, 0 ) )); + //msg (( MSG_OUT, "-------------------------" )); + //msg (( MSG_OUT, "FixedBlocSz = %d", ProPtRecInfFile->FixedBlocSz )); + //msg (( MSG_OUT, "MaxBlocSz = %d", ProPtRecInfFile->MaxBlocSz )); + //msg (( MSG_OUT, "BlocSz = %d", ProPtRecInfFile->BlocSz )); + //msg (( MSG_OUT, "BlocNb = %d", ProPtRecInfFile->BlocNb )); + //msg (( MSG_OUT, "-------------------------" )); + //msg (( MSG_OUT, "ABlocInf[0].Offset = %Lu", ProPtRecInfFile->ABlocInf[0].Offset )); + //msg (( MSG_OUT, "ABlocInf[0].Sz = %d ", ProPtRecInfFile->ABlocInf[0].Sz )); + //msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoFormat = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoFormat )); + //msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoNb = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb )); + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb; ViSpareW32Info++ ) { + msg (( MSG_OUT, "ABlocInf[0].ASpareW32Info[%.2d] = %d ", ViSpareW32Info, ProPtRecInfFile->ABlocInf[0].ASpareW32Info[ViSpareW32Info] )); + } + + + if ( ProPtRecInfFile->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < ProPtRecInfFile->BlocNb; ViBloc++ ) { + msg (( MSG_OUT, "Bloc[%.4d] : Offset=%.12Lu - Sz=%.8d [Bytes] - ASpare [0]=%.4d [1]=%.4d [2]=%.4d [3]=%.4d", ViBloc, ProPtRecInfFile->ABlocInf[ViBloc].Offset, ProPtRecInfFile->ABlocInf[ViBloc].Sz, ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[0], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[1], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[2], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[3] )); + } + + } + + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + err_retfail ( -1, (ERR_OUT,"File is opened => Get file size not coded in this state (TOB ...)") ); + } + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 + : - Calculation => file size / block size +Rev : 20/05/2010 + : - Read from info file field BlocNb + : +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + +/* Before 20/05/2010 + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + +*/ + + VBlocNb = ProPtRecInfFile->BlocNb; + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 13/01/2012 + : - Add handling of flag ProFileHasBeenClosed, needed for Robustness + : improvment of data saving on RAID implemented on 12/01/2012. + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFCreate () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't create a file when RWB mode IS NOT Write !") ); + } + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_WRITE | GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = 1; + ProReadyToRead = -1; + ProFileHasBeenClosed = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 13/01/2012 + : - Add handling of flag ProFileHasBeenClosed, needed for Robustness + : improvment of data saving on RAID implemented on 12/01/2012. + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFOpen () { + +#ifdef CC_UNIX + + ProFilePtUx = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProFilePtUx, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + ProFileHasBeenClosed = 0; + + err_retok (( ERR_OUT, "" )); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#endif +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation + : + : 24/02/2011 + : - Handle SpareW32Info as an array now => New parameters + : + : 11/01/2012 + : - Plume BT bug fix (corrupted data while saving in multithreading mode) + : - Bloc size saving per bloc was not implemented, it was done for one bloc + : - Implementation done via ProAParBlocSz array. + : + : 12/01/2012 + : - Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed, these blocs will be removed from blocs index table + : + : +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + SInt16 ViSpareW32Info; + DWORD VBuffFree; + UInt32 VNbBytesWritten; + + #ifdef FIL__DEBUG + EFRIO__TFrame* VDbgPtFrame; + EFRIO__TFileSpareW32Info* VDbgPtSpareW32Info; + #endif + + + + #ifdef FIL__DEBUG + VDbgPtFrame = (EFRIO__TFrame*) PtrData; + VDbgPtSpareW32Info = (EFRIO__TFileSpareW32Info*) PtSpareW32Info; + #endif + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + err_retnull ( PtSpareW32Info, (ERR_OUT,"PtSpareW32Info == NULL") ); + + if ( SpareW32InfoNb > FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"SpareW32InfoNb=%d > Max=%d", SpareW32InfoNb, FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Cant write to a file when RWB mode IS NOT Write !") ); + } + + // If variable bloc sz mode => Test max nb of blocs allowed & Adjust ProParBlocSz + + if ( ProParFixedBlocSzMode == 0 ) { + + if ( ProPtRecInfFile->BlocNb >= FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE ) { + err_retfail ( -2, (ERR_OUT,"$$$ Max bloc nb = %d reached in variable bloc sz mode !", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE) ); + } + + ProFCalcProParBlocSz ( DataSz ); + } + + // err_error (( ERR_OUT, "DataSz=%d - ProParBlocSz=%d bytes", DataSz, ProParBlocSz )); + + ProCurWrSz = ProParBlocSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + // Let thread write data to disk in background task + + if ( ProUseThread == 1 ) { + + + // Wait on buffer to write + + VBuffFree = WaitForSingleObject ( ProSemWrBuffHnd, 1 /* ms */ ); + + switch ( VBuffFree ) { + + case WAIT_TIMEOUT : { + ++ProResWrBlocFailCnt; + err_retfail ( -1, (ERR_OUT,"Write failed for the %d time -> No buffer available - DbgCallPar=%d !", ProResWrBlocFailCnt, DbgCallPar ) ); + break; } + + case WAIT_OBJECT_0 : { + + // Update index file table => Code moved here on 12/01/2012 + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ProAPtBlocSz[ProIndexWrBuff] = &ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz; // Store ptr on bloc size + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + // Update index file table => Code moved here on 12/01/2012 + + ProAParBlocSz[ProIndexWrBuff] = ProParBlocSz; // 11/01/2012 Plume BT bug fix + + memcpy ( ProABuff[ProIndexWrBuff], PtrData, DataSz ); + + + // PubFPrintMsg ( "Thread => Buffer %d filled", ProIndexWrBuff ); + err_trace (( ERR_OUT, "Thread => Buffer %d filled - DbgCallPar=%d", ProIndexWrBuff, DbgCallPar )); + + ++ProIndexWrBuff; + + err_retfail ( ProIndexWrBuff, (ERR_OUT,"Bad variable size => ProIndexWrBuff=%d < 0", ProIndexWrBuff) ); + + if ( ProIndexWrBuff >= FIL__TCStreamFile_MAX_BUFF_NB) { + ProIndexWrBuff = 0; + } + + ReleaseSemaphore ( ProSemRdBuffHnd, 1, NULL ); + break; } + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFree )); + break; } + + } + + } + + // Write NOW data to disk + + else { + + // Copy to buffer -> "Automatically" add padding bytes + + memcpy ( ProABuff[0], PtrData, DataSz ); + + // Warning => Write ProParBlocSz bytes AND NOT the value passed via parameter DataSz + // because non buffered I/O functions MUST write multiple of DISK bloc size + + WriteFile( + ProFileHnd, // handle to file to write to + ProABuff[0], // pointer to data to write to file + ProParBlocSz, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != ProParBlocSz ) { + err_retfail ( VRet, (ERR_OUT,"Writing block %d failed %d bytes written - %d bytes requested ! - %s", ProCurWrBlocId, VNbBytesWritten, ProParBlocSz, strerror ( errno ) ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + } // END "else write now data on disk" + + +/* Modified on 12/01/2012 + => This part can not be common for non multithreading and multithreading data saving mode + => Because it must be executed before before data saving code in case of multithreading and after otherwise + => Therefore, it has been dupplicated in the part of source code which handles each mode + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + +*/ + + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + + if ( ProUseThread == 1 ) { + err_trace (( ERR_OUT, "Copy bloc of %d bytes done in %d [ms]", DataSz, ProTimeExec )); + } + + else { + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", VNbBytesWritten, ProTimeExec )); + } + + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + +#ifdef CC_UNIX + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + SInt32 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VBlocNbRead = fread ( DestPtr, VDataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProFilePtUx ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed of %d bytes ! - %s", ProCurRdBlocId, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#else + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + UInt32 VNbBytesRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + ReadFile( + ProFileHnd, // handle of file to read + DestPtr, // address of buffer that receives data + VDataSzToRead, // number of bytes to read + &VNbBytesRead, // address of number of bytes read + NULL // address of structure for data + ); + + if ( VNbBytesRead != VDataSzToRead ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed : %d bytes read - %d bytes requested ! - %s", ProCurRdBlocId, VNbBytesRead, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( ProPtrBuffRdData, ProSzBuffRdData, DataSzToRead ); + + err_retfailnull ( VRet, (ERR_OUT,"PubFSeqRead failed !") ); + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : Limited to 4 GB files + : +Rev : 09/05/2010 + : - Use W64 offset => Not limited to 4 GB file +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGotoBloc ( SInt32 BlocNo ) { + +#ifdef CC_UNIX + + SInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = fseeko ( ProFilePtUx, (off_t) VOffsetW64, SEEK_SET ); + + err_retfail ( VRet, (ERR_OUT,"Bloc %d read failed ! => System : %s", BlocNo, _strerror ("") ) ); + + err_retok (( ERR_OUT, "" )); + +#else + + UInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = SetFilePointer ( + ProFileHnd, // handle of file + *VPtOffsetLow32, // number of bytes to move file pointer + (SInt32*) VPtOffsetHigh32, // address of high-order word of distance to move + // lpDistanceToMoveHigh = 0 => Limited to 4 GB + FILE_BEGIN // how to move + ); + + + if ( VRet == 0xFFFFFFFF ) { + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &VMsgBuf, + 0, + NULL + ); + + err_retfail ( -1, (ERR_OUT,"Goto bloc %d failed => %s", BlocNo, VMsgBuf ) ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 24/02/2011 + : - Handle SpareW32Info as and array ASpareW32Info now => New parameters + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ) { + + SInt32 VRet; + SInt16 ViSpareW32Info; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + + if ( (PtSpareW32InfoFormat != NULL) && (PtSpareW32Info != NULL) && (ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb <= MaxSpareW32InfoNb) ) { + + *PtSpareW32InfoFormat = ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoFormat; + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb; ViSpareW32Info++ ) { + PtSpareW32Info[ViSpareW32Info] = ProPtRecInfFile->ABlocInf[BlocNo].ASpareW32Info[ViSpareW32Info]; + } + + } + + else { + err_warning (( ERR_OUT, "ASpareInfo bloc not updated ! Pointer NULL or Dest size too small ?" )); + } + + } + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + return (ProParBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + } + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 13/01/2012 + : - Add handling of flag ProFileHasBeenClosed, needed for Robustness + : improvment of data saving on RAID implemented on 12/01/2012. + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFFlush () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProFileHasBeenClosed == 1 ) { + err_warning (( ERR_OUT, "File has already been closed !" )); + return (0); + } + + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : Remove the blocs which have not been saved (write on RAID has failed) + : from blocs table. +Inputs : +Ouputs : +Globals : +Remark : Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed (FIL__TCStreamFile_FThread), these blocs will be removed + : from blocs index table. + : +Level : +Date : 12/01/2012 + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFUpdateIndexTable () { + + SInt32 VRet; + SInt32 ViSrcBloc; + SInt32 ViDestBloc; + SInt32 VSrcTotBlocsNb; + SInt32 VDestGoodBlocsNb; + SInt32 VOffsetCorrection; + + + // Copy normal table in temporary record + + memcpy ( ProPtRecInfFileCpy, ProPtRecInfFile, ProRecInfSz ); + + // Reset normal table + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // Restor fields - We want to reset bloc list not "header fields" + + ProPtRecInfFile->Version = ProPtRecInfFileCpy->Version; + ProPtRecInfFile->DateCreate = ProPtRecInfFileCpy->DateCreate; + ProPtRecInfFile->TimeCreate = ProPtRecInfFileCpy->TimeCreate; + ProPtRecInfFile->DateClose = ProPtRecInfFileCpy->DateClose; + ProPtRecInfFile->TimeClose = ProPtRecInfFileCpy->TimeClose; + ProPtRecInfFile->FixedBlocSz = ProPtRecInfFileCpy->FixedBlocSz; + ProPtRecInfFile->MaxBlocSz = ProPtRecInfFileCpy->MaxBlocSz; + ProPtRecInfFile->BlocSz = ProPtRecInfFileCpy->BlocSz; + ProPtRecInfFile->BlocNb = ProPtRecInfFileCpy->BlocNb; + + + // Rebuild normal table with blocs non corrupted + + VOffsetCorrection = 0; + VSrcTotBlocsNb = ProPtRecInfFileCpy->BlocNb; + VDestGoodBlocsNb = 0; + ViDestBloc = 0; + + for ( ViSrcBloc=0; ViSrcBloc < VSrcTotBlocsNb; ViSrcBloc++ ) { + + if ( ProPtRecInfFileCpy->ABlocInf[ViSrcBloc].Sz > 0 ) { + ProPtRecInfFile->ABlocInf[ViDestBloc] = ProPtRecInfFileCpy->ABlocInf[ViSrcBloc]; + ProPtRecInfFile->ABlocInf[ViDestBloc].Offset = ProPtRecInfFileCpy->ABlocInf[ViSrcBloc].Offset + VOffsetCorrection; + ++ViDestBloc; + } + + else { + VOffsetCorrection = VOffsetCorrection + ProPtRecInfFileCpy->ABlocInf[ViSrcBloc].Sz; // Add negative size + } + + } // End for + + VDestGoodBlocsNb = ViDestBloc; + + // Overwrite normal table blocs nb with good blocs nb + + ProPtRecInfFile->BlocNb = VDestGoodBlocsNb; + + + err_retok (( ERR_OUT, "" )); +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 12/01/2012 + : - Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed, these blocs will be removed from blocs index table + : - Call ProFUpdateIndexTable () + : - Save two index files : + : *.inf = normal without info on blocs not saved + : *.all.inf = default with all blocs info + : + : 13/01/2012 + : - Add flag ProFileHasBeenClosed, in order to avoid multiple calls + : of this function, because it's NOT allowed with the new handling of + : index table (suppression of bad blocs). + : + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFClose () { + + SInt32 VRet; + SInt8 ViBuff; + +#ifndef CC_UNIX + #ifndef FILE__NO_DATE_TIME_HANDLING + TDateTime VODateTime; + #endif +#endif + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProFileHasBeenClosed == 1 ) { + err_warning (( ERR_OUT, "File has already been closed !" )); + return (0); + } + + ProFileHasBeenClosed = 1; + + if ( ProReadyToWrite == 1 ) { + PubFFlush (); + } + + ProConfDone = 0; + +#ifndef CC_UNIX + CloseHandle ( ProFileHnd ); +#endif + + // Free read buffers + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + // Free write buffers + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + ProABuff[ViBuff] = NULL; + } + + } + + + // Get close date & time + +#ifndef CC_UNIX + #ifndef FILE__NO_DATE_TIME_HANDLING + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateClose = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeClose = TIME__FConvDateTime2Time ( VODateTime ); + #endif +#else + ProPtRecInfFile->DateClose.W32 = 0; + ProPtRecInfFile->TimeClose.W32 = 0; +#endif + + + + + ProFUpdateIndexTable (); + + + if ( ProReadyToWrite == 1 ) { + + // ------------------------------- + // Save updated index file table + // ------------------------------- + + // Overwrite info file with update close time & date + bloc nb + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Overwrite of info file %s failed !", ProInfFileName) ); + + err_error (( ERR_OUT, "TRACE ProPtRecInfFile = %X", ProPtRecInfFile )); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file failed => System : %s", strerror ( errno ) ) ); + } + + // ------------------------------- + // Save default index file table = with all blocs info + // ------------------------------- + + // Create info file + + ProPtInfFileAll = fopen ( ProInfFileNameAll, "wb" ); + + err_retnull ( ProPtInfFileAll, (ERR_OUT,"Create of info file ALL %s failed !", ProInfFileNameAll) ); + + err_error (( ERR_OUT, "TRACE ProPtRecInfFile = %X", ProPtRecInfFile )); + + if ( fwrite ( ProPtRecInfFileCpy, ProRecInfSz, 1, ProPtInfFileAll ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileNameAll) ); + } + + if ( fclose (ProPtInfFileAll) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file ALL failed => System : %s", strerror ( errno ) ) ); + } + + } + + err_retok (( ERR_OUT, "" )); +} + +// $$$ + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 09/07/2012 +Rev : 12/11/2012 + : - Add index file cpy +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileDutCreate ( char* FilePath ) { + + char VFuncName[] = "FIL_FIndexFileDutCreate"; + FIL__TIndexFileDut* VPtCont = &FIL__VGIndexFileDut; + SInt32 VRet; + + // Normal file + + sprintf ( VPtCont->FilePath, "%s", FilePath ); + + VPtCont->PfDest = fopen ( VPtCont->FilePath, "wb" ); + + err_retnull ( VPtCont->PfDest, (ERR_OUT,"Destination file %s creation failed => %s", VPtCont->FilePath, _strerror ( "System says :" )) ); + + VPtCont->EltCnt = 0; + + fclose (VPtCont->PfDest); + +#ifdef AFRIO__CREATE_INDEX_FILE_CPY + + // Cpy file + + VPtCont->PfDestCpy = fopen ( FIL__DUT_INDEX_FILE_CPY_NAME, "wb" ); + + err_retnull ( VPtCont->PfDestCpy, (ERR_OUT,"Destination file %s creation failed => %s", FIL__DUT_INDEX_FILE_CPY_NAME, _strerror ( "System says :" )) ); + + fclose (VPtCont->PfDestCpy); + +#endif + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 09/07/2012 +Rev : 12/11/2012 + : - Add index file cpy +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileDutAddEv ( UInt32 EvId, UInt32 EvTag, UInt32 TrigLine, UInt32 TrigFrame, UInt32 TrigNbTot, UInt32 TrigNbAccepted, UInt32 SpareU32 ) { + + char VFuncName[] = "FIL_FIndexFileDutAddEv"; + FIL__TIndexFileDut* VPtCont = &FIL__VGIndexFileDut; + UInt32 VAFields[8]; + SInt32 VRet; + + + // Normal file + + // Add elt + + VPtCont->PfDest = fopen ( VPtCont->FilePath, "ab" ); + + err_retnull ( VPtCont->PfDest, (ERR_OUT,"Destination file %s open for append failed => %s", VPtCont->FilePath, _strerror ( "System says :" ) )); + + VAFields[0] = 1; // Version + VAFields[1] = EvId; + VAFields[2] = EvTag; + VAFields[3] = TrigLine; + VAFields[4] = TrigFrame; + VAFields[5] = TrigNbTot; + VAFields[6] = TrigNbAccepted; + VAFields[7] = SpareU32; + + VRet = fwrite ( VAFields, 32 /* size = 8 x U32 */, 1 /* Elt nb */, VPtCont->PfDest ); + + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error writing record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + VRet = fflush ( VPtCont->PfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error flush record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPtCont->PfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + ++VPtCont->EltCnt; + + // Cpy file + // Rq : In case of error => log error BUT don't return < 0 error code because w/r conflict may happen + // on the cpy index file and must not stop run + +#ifdef AFRIO__CREATE_INDEX_FILE_CPY + if ( 1 ) { +#else + if ( 0 ) { +#endif + + while (1) { + + VPtCont->PfDestCpy = fopen ( FIL__DUT_INDEX_FILE_CPY_NAME, "ab" ); + + if ( VPtCont->PfDestCpy == NULL ) { + err_warning (( ERR_OUT, "Destination file %s open for append failed => %s", FIL__DUT_INDEX_FILE_CPY_NAME, _strerror ( "System says :" ) )); + break; + } + + VRet = fwrite ( VAFields, 32 /* size = 8 x U32 */, 1 /* Elt nb */, VPtCont->PfDestCpy ); + + if ( VRet != 1 ) { + err_warning (( ERR_OUT, "Error writing record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + VRet = fflush ( VPtCont->PfDestCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT, "Error flush record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + VRet = fclose ( VPtCont->PfDestCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT, "Error fclose record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + break; + + } // End while (1) + + } + + return (0); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 09/07/2012 +Rev : 13/11/2012 + : - Fill destination buffer with 0 before reading file +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileDutRead ( char* FilePath, UInt32* PtDest, SInt32 DestSz ) { + + char VFuncName[] = "FIL_FIndexFileDutRead"; + + FILE* VPfDest; + SInt32 VFileSz; + UInt32 VAFields[5]; + SInt32 VRet; + + + // Measure file size + + VFileSz = FIL_FFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + err_retfail ( -1, (ERR_OUT,"Buffer size=%d < File size=%d", DestSz, VFileSz ) ); + } + + err_error (( ERR_OUT, "TRACE => FileSize=%d", VFileSz )); + + // Fill destination buffer with 0 + + memset ( PtDest, 0, DestSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + err_retnull ( VPfDest, (ERR_OUT,"Source file %s open failed => %s", FilePath, _strerror ( "System says :" ) )); + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error reading source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + // Return record nb + + return ( VFileSz / 32 ); + +} + +// ##### + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 10/07/2012 +Rev : 12/11/2012 + : - Add index file cpy +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileTelCreate ( char* FilePath ) { + + char VFuncName[] = "FIL_FIndexFileTelCreate"; + FIL__TIndexFileTel* VPtCont = &FIL__VGIndexFileTel; + SInt32 VRet; + + + // Normal file + + sprintf ( VPtCont->FilePath, "%s", FilePath ); + + VPtCont->PfDest = fopen ( VPtCont->FilePath, "wb" ); + + err_retnull ( VPtCont->PfDest, (ERR_OUT,"Destination file %s creation failed => %s", VPtCont->FilePath, _strerror ( "System says :" )) ); + + VPtCont->EltCnt = 0; + + fclose (VPtCont->PfDest); + + +#ifdef EFRIO__CREATE_INDEX_FILE_CPY + + // Cpy file + + VPtCont->PfDestCpy = fopen ( FIL__TEL_INDEX_FILE_CPY_NAME, "wb" ); + + err_retnull ( VPtCont->PfDestCpy, (ERR_OUT,"Destination file %s creation failed => %s", FIL__TEL_INDEX_FILE_CPY_NAME, _strerror ( "System says :" )) ); + + fclose (VPtCont->PfDestCpy); + +#endif + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 10/07/2012 +Rev : 12/11/2012 + : - Add index file cpy +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileTelAddEv ( UInt32 EvId, UInt32 AcqId, UInt32 FrId, UInt32 EvTag, UInt16 Trig0, UInt16 Trig1, UInt16 Trig2, UInt16 FrTrigNb, UInt32 SpareU32 ) { + + char VFuncName[] = "FIL_FIndexFileTelAddEv"; + FIL__TIndexFileTel* VPtCont = &FIL__VGIndexFileTel; + UInt32 VAFields[10]; + SInt32 VRet; + + // Normal file + + // Add elt + + VPtCont->PfDest = fopen ( VPtCont->FilePath, "ab" ); + + err_retnull ( VPtCont->PfDest, (ERR_OUT,"Destination file %s open for append failed => %s", VPtCont->FilePath, _strerror ( "System says :" ) )); + + VAFields[0] = 1; // Version + VAFields[1] = EvId; + VAFields[2] = AcqId; + VAFields[3] = FrId; + VAFields[4] = EvTag; + VAFields[5] = Trig0; + VAFields[6] = Trig1; + VAFields[7] = Trig2; + VAFields[8] = FrTrigNb; + VAFields[9] = SpareU32; + + VRet = fwrite ( VAFields, 40 /* size = 10 x U32 */, 1 /* Elt nb */, VPtCont->PfDest ); + + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error writing record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + VRet = fflush ( VPtCont->PfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error flush record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPtCont->PfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + ++VPtCont->EltCnt; + + // Cpy file + // Rq : In case of error => log error BUT don't return < 0 error code because w/r conflict may happen + // on the cpy index file and must not stop run + + +#ifdef EFRIO__CREATE_INDEX_FILE_CPY + if ( 1 ) { +#else + if ( 0 ) { +#endif + + while (1) { + + VPtCont->PfDestCpy = fopen ( FIL__TEL_INDEX_FILE_CPY_NAME, "ab" ); + + if ( VPtCont->PfDestCpy == NULL ) { + err_warning (( ERR_OUT, "Destination file %s open for append failed => %s", FIL__TEL_INDEX_FILE_CPY_NAME, _strerror ( "System says :" ) )); + break; + } + + VRet = fwrite ( VAFields, 40 /* size = 10 x U32 */, 1 /* Elt nb */, VPtCont->PfDestCpy ); + + if ( VRet != 1 ) { + err_warning (( ERR_OUT, "Error writing record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + VRet = fflush ( VPtCont->PfDestCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT,"Error flush record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + VRet = fclose ( VPtCont->PfDestCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT,"Error fclose record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + break; + } // End while (1) + + } + + return (0); + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 09/07/2012 +Rev : 13/11/2012 + : - Fill destination buffer with 0 before reading file +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileTelRead ( char* FilePath, UInt32* PtDest, SInt32 DestSz ) { + + char VFuncName[] = "FIL_FIndexFileTelRead"; + + FILE* VPfDest; + SInt32 VFileSz; + UInt32 VAFields[9]; + SInt32 VRet; + + + // Measure file size + + VFileSz = FIL_FFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + err_retfail ( -1, (ERR_OUT,"Buffer size=%d < File size=%d", DestSz, VFileSz ) ); + } + + err_error (( ERR_OUT, "TRACE => FileSize=%d", VFileSz )); + + // Fill destination buffer with 0 + + memset ( PtDest, 0, DestSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + err_retnull ( VPfDest, (ERR_OUT,"Source file %s open failed => %s", FilePath, _strerror ( "System says :" ) )); + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error reading source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + // Return record nb + + return ( VFileSz / 40 ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 10/07/2012 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileSyncWrite ( char* FilePath, UInt8* PtSrc, SInt32 SrcSz ) { + + char VFuncName[] = "FIL_FIndexFileSyncWrite"; + SInt32 VRet; + FILE* VPf; + + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL !") ); + + // try to create + + VPf = fopen ( FilePath, "wb" ); + + err_retnull ( VPf, (ERR_OUT,"Sync index file %s creation failed => %s", FilePath, _strerror ( "System says :" )) ); + + + // Try to write + + VRet = fwrite ( PtSrc, SrcSz, 1 /* Elt nb */, VPf ); + + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error writing sync file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fflush ( VPf ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error flush sync file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPf ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose sync file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 10/07/2012 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileSyncRead ( char* FilePath, UInt8* PtDest, SInt32 DestSz ) { + + char VFuncName[] = "FIL_FIndexFileSyncRead"; + SInt32 VRet; + FILE* VPfDest; + SInt32 VFileSz; + + + // Check param + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL !") ); + + // Measure file size + + VFileSz = FIL_FFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + err_retfail ( -1, (ERR_OUT,"Buffer size=%d < File size=%d", DestSz, VFileSz ) ); + } + + err_error (( ERR_OUT, "TRACE => FileSize=%d", VFileSz )); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + err_retnull ( VPfDest, (ERR_OUT,"Source file %s open failed => %s", FilePath, _strerror ( "System says :" ) )); + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error reading source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + + // Return record nb + + return ( VFileSz / 76 ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/07/2012 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FMi32aBTIneffEvFileRead ( char* SrcFilePath, FIL__TMi32ABTIneffEvRec* PtDest, SInt32 DestEltSz ) { + + char VFuncName[] = "FIL_FMi32ABTIneffEvFileRead"; + SInt32 VRet; + FILE* VPf; + SInt32 ViLine; + char VStrCR[2]; + char VDataSep; + SInt8 VEndOfFileReached; + + + + /* Check parameters */ + + err_retnull ( SrcFilePath, (ERR_OUT,"SrcFilePath == NULL" ) ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL" ) ); + + + /* Try to open file */ + + VPf = fopen ( SrcFilePath, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFilePath ) ); + + // err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read lines */ + + VEndOfFileReached = 0; + + for ( ViLine=0; ViLine < DestEltSz; ViLine++ ) { + + VRet = fscanf ( VPf, "%d%c%d\n", &PtDest[ViLine].EventNo, &VDataSep, &PtDest[ViLine].TrigLine ); + + if ( VRet == EOF ) { + VEndOfFileReached = 1; + fclose (VPf); + err_trace (( ERR_OUT, "End of file reached : %d lines = records read", ViLine + 1 )); + break; + } + + if ( VRet != 3 ) { + fclose (VPf); + break; + // err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s => Abort", ViLine, SrcFilePath, VRet, _strerror ( "System says :" ) ) ); + } + + if ( VDataSep != '-' ) { + err_warning (( ERR_OUT, "Warning reading line=%d in file=%s => Bad separator = %c", ViLine, VDataSep )); + } + + + } + + + if ( VEndOfFileReached = 0 ) { + err_error (( ERR_OUT, "Reading of file %s stopped after %d lines = records because max buffer size reached", SrcFilePath, ViLine )); + } + + fclose (VPf); + + + // Return nb of lines = records + + return ( ViLine ); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/07/2012 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FMi32aBTIneffEvPrint ( FIL__TMi32ABTIneffEvRec* PtSrc, SInt32 RecordsNb ) { + + char VFuncName[] = "FIL_FMi32ABTIneffEvPrint"; + SInt32 VRet; + SInt32 ViRec; + + + msg (( MSG_OUT, "=====================================" )); + msg (( MSG_OUT, "Print list of ineff events : %d record", RecordsNb )); + msg (( MSG_OUT, "=====================================" )); + msg (( MSG_OUT, "" )); + + + + for ( ViRec=0; ViRec < RecordsNb; ViRec++ ) { + msg (( MSG_OUT, "Record[%.4d] : Event=%.6d - TrigLine=%.3d", ViRec, PtSrc[ViRec].EventNo, PtSrc[ViRec].TrigLine )); + } + + return (0); +} + + + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/files.def b/include/pxi_daq_lib_v.2.1/files.def new file mode 100755 index 0000000..629f7d9 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/files.def @@ -0,0 +1,51 @@ +/* 24/02/05 */ + + +#ifndef FIL_DEF +#define FIL_DEF + +#define FIL_DIR_FILES_LIST_MAX_CNT 100 + +#define FIL__TCBinFile_MEAS_TIME +#define FIL__TCStreamFile_MEAS_TIME + +#define FIL__TCBinFile_RWB_MODE_WRITE 0 +#define FIL__TCBinFile_RWB_MODE_READ 1 +#define FIL__TCBinFile_RWB_MODE_BOTH 2 + +// 07/03/2009 +// Macro removed because they are not supported under ROOT ... +// => Macro "calls" had been replaced by the macro code below in files.c +// => For new implementations : a copy paste of the macro code below must be done for each "flag test" +// +// #define FIL__TCBinFile_CHK_CONF_DONE {err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_WR {err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_RD {err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );} + + +#define FIL__TCStreamFile_MAX_BUFF_NB 4 + +// #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 // Before 07/11/12 => 50 000 - Maximum number of blocs in variable bloc size mode + +// #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 200000 // 200000 From 07/11/12 to 22/06/13 + +#define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 400000 // 400000 since 22/06/13 + +#define FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB 20 + + +#define FIL__TCStreamFile_LOG_GENERAL_MSG 0 +#define FIL__TCStreamFile_LOG_ERR_TRACE 1 +#define FIL__TCStreamFile_LOG_ERR_WARNING 2 +#define FIL__TCStreamFile_LOG_ERR_ERROR 3 + + +// Copy of DU & Telescope index files used to get on-line run status + +#define FIL__DUT_INDEX_FILE_CPY_NAME "s:/data/cur_run_dut_index.bin" +#define FIL__TEL_INDEX_FILE_CPY_NAME "s:/data/cur_run_tel_index.bin" + + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/files.h b/include/pxi_daq_lib_v.2.1/files.h new file mode 100755 index 0000000..25cec12 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/files.h @@ -0,0 +1,62 @@ +/* 24/02/05 */ + + +#ifndef FIL_H + +#include "func_header.def" + +#include "files.def" +#include "files.typ" + + +FHEAD ( SInt32 FIL_FFileExists ( char* FilePath );) +FHEAD ( SInt32 FIL_FFileSize ( char* FilePath );) + +FHEAD ( SInt32 FIL_FCpyFile ( char* Src, char* Dest );) +FHEAD ( SInt32 FIL_FRemoveFile ( char* FilePath );) +FHEAD ( SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile );) +FHEAD ( SInt32 FIL_FRmDirFiles ( char* SrcDir );) +FHEAD ( SInt32 FIL_FRmDir ( char* SrcDir );) +FHEAD ( SInt32 FIL_FDelDir ( char* SrcDir );) +FHEAD ( SInt32 FIL_FMkDir ( char* SrcDir );) +FHEAD ( SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList );) +FHEAD ( SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList );) +FHEAD ( SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz );) +FHEAD ( SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz );) + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz );) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz );) + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) + +// SInt32 FIL_FIndexFileDutCreate ( char* FilePath ); +// SInt32 FIL_FIndexFileDutAddEv ( UInt32 EvId, UInt32 EvTag, UInt32 TrigLine, UInt32 TrigFrame, UInt32 TrigNbTot, UInt32 TrigNbAccepted, UInt32 SpareU32 ); +// SInt32 FIL_FIndexFileDutRead ( char* FilePath, UInt32* PtDest, SInt32 DestSz ); + +// SInt32 FIL_FIndexFileTelCreate ( char* FilePath ); +// SInt32 FIL_FIndexFileTelAddEv ( UInt32 EvId, UInt32 AcqId, UInt32 FrId, UInt32 EvTag, UInt16 Trig0, UInt16 Trig1, UInt16 Trig2, UInt16 FrTrigNb, UInt32 SpareU32 ); +// SInt32 FIL_FIndexFileTelRead ( char* FilePath, UInt32* PtDest, SInt32 DestSz ); + + +#ifdef CC_APP_WINDOWS + FHEAD ( SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile );) + FHEAD ( SInt32 FIL_FDosRmDirFiles ( char* SrcDir );) + FHEAD ( SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList );) +#endif + + +#ifndef APP_DAQ + FHEAD ( SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt );) +#endif + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef FIL_H + #define FIL_H + #endif +#endif + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/files.typ b/include/pxi_daq_lib_v.2.1/files.typ new file mode 100755 index 0000000..bdf3ab7 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/files.typ @@ -0,0 +1,341 @@ +/* 24/02/05 */ + + +#ifndef FIL_TYP +#define FIL_TYP + +/* char FIL_TADirFilesList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; */ + + +typedef struct { + char AList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; +} FIL_TDirFilesList; + + +// 30/01/2009 + +class FIL__TCBinFile { + + + private : + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + // Parameters from conf + + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParMaxBlocSz; + SInt32 ProParBlocSz; + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + + SInt32 ProCurRdEltId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrEltId; + UInt64 ProCurWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + UInt64 ProTotWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + FILE* ProPtFile; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + + + public : + + FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~FIL__TCBinFile (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + SInt32 PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz ); + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + +// 01/05/2010 + +typedef struct { + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + UInt32 ABlocSz[1]; + +} FIL__TCStreamFile_Old_TRecInfFile; + +// 05/11/10 + +typedef struct { + + UInt64 Offset; + + // UInt32 Sz; + + SInt32 Sz; // NEW 12/01/2012 + + SInt32 SpareW32InfoFormat; // Number which identifies the meaning ASpareW32Info + SInt32 SpareW32InfoNb; // Number of spare parameters + SInt32 ASpareW32Info[FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB]; // Array for user parameters + + UInt32 Dummy; // For alignment + +} FIL__TCStreamFile_TBlocInf; + + +// 05/11/10 + +typedef struct { + + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + + UInt32 Dummy; // For alignment + + FIL__TCStreamFile_TBlocInf ABlocInf[1]; + + +} FIL__TCStreamFile_TRecInfFile; + + +class FIL__TCStreamFile { + + + private : + + FIL__TCStreamFile* PriPtMyself; + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + SInt32 ProParDiskBlocSz; + SInt8 ProParFixedBlocSzMode; + + // Parameters from conf + + SInt8 ProUseThread; + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParRequestedMaxBlocSz; // Bloc size value asked by user + SInt32 ProParMaxBlocSz; // Adjusted depending on ProParBlocSz + + SInt32 ProParRequestedBlocSz; // Bloc size value asked by user + SInt32 ProParBlocSz; // Bloc size value used ( multiple of disk bloc size ) + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + SInt32 ProAParBlocSz[FIL__TCStreamFile_MAX_BUFF_NB]; // 11/01/2012 NEW DBG + + // Variables for internal processing + + SInt8 ProFileHasBeenClosed; // 13/01/2012 + + HANDLE ProFileHnd; + +#ifdef CC_UNIX + FILE* ProFilePtUx; // Pointer to data file for Linux / Unix +#endif + + // 12/01/2012 - Now two index table are used + char ProInfFileName[GLB_FILE_PATH_SZ]; // Store updated index table file = table with non saved blocs info removed + char ProInfFileNameAll[GLB_FILE_PATH_SZ]; // Store default index table file = table with ALL blocs info = included non saved + FILE* ProPtInfFile; + FILE* ProPtInfFileAll; + + FIL__TCStreamFile_TRecInfFile* ProPtRecInfFile; + FIL__TCStreamFile_TRecInfFile* ProPtRecInfFileCpy; // NEW 12/01/2012 copy of RecInfFile record used to update table = to remove blocs on which saved has failed + SInt32 ProRecInfSz; + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + +#ifndef CC_UNIX + + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + CRITICAL_SECTION ProCsPrintMsg; + #endif + +#endif + + HANDLE ProThreadHnd; + DWORD ProThreadId; + + HANDLE ProSemWrBuffHnd; + HANDLE ProSemRdBuffHnd; + + SInt16 ProIndexWrBuff; + SInt16 ProIndexRdBuff; + + UInt8* ProABuff[FIL__TCStreamFile_MAX_BUFF_NB]; + SInt32 ProBuffSz; + + SInt32* ProAPtBlocSz[FIL__TCStreamFile_MAX_BUFF_NB]; // Pointer to the "sz" field of FIL__TCStreamFile_TBlocInf + // PubFSeqWrite fill the field of FIL__TCStreamFile_TBlocInf with size of block + // If writing to disk in thread functions failed, a "-" is added to this size + // This will be used by the function which updates the index file table in order + // to skip blocs not saved and ajust offset list + + + SInt32 ProCurRdBlocId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrBlocId; + SInt32 ProCurWrSz; + SInt64 ProTotWrSz; + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + // Results + + SInt32 ProResWrBlocFailCnt; + + SInt32 ProFCalcProParBlocSz ( SInt32 DataSz ); + + SInt32 ProFUpdateIndexTable (); + + public : + + FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + ~FIL__TCStreamFile (); + + friend DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + SInt32 PubFSetDiskSectorSz ( SInt32 DiskBlocSz ); + SInt32 PubFGetDiskSectorSz (); + + void PubFPrintMsg ( char* Msg, SInt8 MsgLevel ); + SInt32 PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFPrintInfFileRec ( FIL__TCStreamFile_TRecInfFile* Pt, char* Cmt, char* TagStr ); + SInt32 PubFPrintInfFile (); + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + // SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 SpareInfo ); + + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ); + + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + + +// 09/07/2012 + +typedef struct { + + char FilePath[GLB_FILE_PATH_SZ]; + FILE* PfDest; + FILE* PfDestCpy; + + SInt32 EltCnt; + + +} FIL__TIndexFileDut; + + +// 09/07/2012 + +typedef struct { + + char FilePath[GLB_FILE_PATH_SZ]; + FILE* PfDest; + FILE* PfDestCpy; + + SInt32 EltCnt; + + +} FIL__TIndexFileTel; + + +// 24/07/2012 + +typedef struct { + + SInt32 EventNo; + SInt32 TrigLine; + +} FIL__TMi32ABTIneffEvRec; + + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/files.var b/include/pxi_daq_lib_v.2.1/files.var new file mode 100755 index 0000000..a7432e1 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/files.var @@ -0,0 +1,21 @@ +/* 24/02/05 */ + + +#ifndef FIL_VAR +#define FIL_VAR + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +// Examples +// +// VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +// VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + + +EXTERN VAR_STATIC FIL__TIndexFileDut FIL__VGIndexFileDut; +EXTERN VAR_STATIC FIL__TIndexFileTel FIL__VGIndexFileTel; + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/files__090112.c b/include/pxi_daq_lib_v.2.1/files__090112.c new file mode 100755 index 0000000..f2fb8c0 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/files__090112.c @@ -0,0 +1,3744 @@ + +#ifndef FIL_C +#define FIL_C + + +#ifdef CC_UNIX + +UInt32 GetTickCount () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + + +SInt32 GetLastError () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + +#endif + +/******************************************************************************* +Prototype : SInt32 FIL_FFileExists ( char* FilePath ) +Goal : Test if the file exists. +Inputs : The file name ( full path if needed ). +Ouputs : 1 if the file exists, else 0. +Globals : +Remark : The result is not guaranted in case of multi application lock to file. +Level : This is a user level function. +Date : 17/04/2003 +Doc date : 17/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FFileExists ( char* FilePath ) { + + SInt32 VRet; + FILE* VPf; + + VPf = fopen ( FilePath, "r" ); + + if ( VPf == NULL ) { + VRet = 0; + } + + else { + fclose ( VPf ); + VRet = 1; + } + + + return (VRet); +} + +/* 13/10/2004 */ + +SInt32 FIL_FFileSize ( char* FilePath ) { + + FILE* VPf; + SInt32 VFileSz; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fopen fail !" ) )); + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fclose (VPf) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fclose fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "%d Bytes", VFileSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FCpyFile ( char* Src, char* Dest ) + : +Goal : Copy SrcFile to DestFile. + : +Inputs : Src - Source file + : Dest - Destination file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - fonction moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FCpyFile ( char* Src, char* Dest ) { + + FILE* VPfSrc; + FILE* VPfDest; + SInt8 VBuffer[512]; // Debug 02/06/2007 move storage class static to auto + SInt32 VReadBytesCnt; + SInt32 VTotBytesCnt; + SInt32 VRet; + + VPfSrc = fopen ( Src, "rb" ); + + err_retnull ( VPfSrc, (ERR_OUT,"Source file %d open failed", Src ) ); + + VPfDest = fopen ( Dest, "wb" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", VPfDest ) ); + + VTotBytesCnt = 0; + + while ( ( VReadBytesCnt = fread ( VBuffer, 1 /* byte size */ , 512 /* bytes number */, VPfSrc ) ) > 0 ) { + fwrite ( VBuffer, 1 /* byte size */, VReadBytesCnt, VPfDest ); + VTotBytesCnt += VReadBytesCnt; + } + + fclose (VPfSrc); + fclose (VPfDest); + + err_retok (( ERR_OUT, "file %s copied in %s => %d bytes", Src, Dest, VTotBytesCnt )); +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FRemoveFile ( char* FilePath ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FRemoveFile ( char* FilePath ) { + + SInt32 VRet; + char* VStrError; + + VRet = remove ( FilePath ); + + err_retfail ( VRet, (ERR_OUT,"Remove file=%s failed => %s", FilePath, _strerror ("")) ); + err_retok (( ERR_OUT, "")); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) + : +Goal : List the directory SrcDir and write the result in DestDirFile. + : +Inputs : SrcDir - The directory to list + : DestDirFile - The result file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - Function moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + + VPf = fopen ( DestDirFile, "wt" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT, "Dir file %s creation failed ", DestDirFile ) ); + } + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + ++VItemCnt; + fprintf( VPf, "%s\n", VFileInfo.ff_name); + VRet = findnext(&VFileInfo); + } + + fclose ( VPf ); + + return (0); +} + + +#endif + + +SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosDirOutFile ( SrcDir, DestDirFile ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FDosDelDir ( char* SrcDir ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : Compiled only if CC_APP_WINDOWS is defined +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosRmDirFiles ( char* SrcDir ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + char VFileToDelete[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + SInt32 VRetRemove; + SInt32 VFuncRet; + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VFuncRet = 0; + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + sprintf ( VFileToDelete, "%s\\%s", SrcDir, VFileInfo.ff_name ); + VRetRemove = FIL_FRemoveFile ( VFileToDelete ); + + if ( VRetRemove < 0 ) { + VFuncRet = -1; + err_error (( ERR_OUT, "Remove file=%s failed => %s", VFileToDelete, _strerror ("") )); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + + return (VFuncRet); +} + +#endif + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDirFiles ( char* SrcDir ) +Goal : Remove all the files in directory SrcDir but let the direcory +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDirFiles ( char* SrcDir ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosRmDirFiles (SrcDir) ); + +#else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available !", SrcDir) ); +#endif + + +} + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDir ( char* SrcDir ) +Goal : Remove the directory SrcDir if empty +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDir ( char* SrcDir ) { + + SInt32 VRet; + +#ifdef CC_APP_WINDOWS + + // VRet = _rtl_chmod( SrcDir, 1 , FA_NORMAL ); + // err_retfail ( VRet, (ERR_OUT,"Chmod failed on directory=%s", SrcDir) ); + + VRet = rmdir ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"Remove directory=%s failed => %s ", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + +#else + err_retfail ( -1, (ERR_OUT,"Function handled only under Windows") ); +#endif + +} + +/******************************************************************************* +Prototype : +Goal : Delete direcory files and directory itself +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelDir ( char* SrcDir ) { + + SInt32 VRet; + char VNewName[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + + sprintf ( VNewName, "%s.old", SrcDir ); + + VRet = rename ( SrcDir, VNewName ); + + err_retfail ( VRet, (ERR_OUT,"Rename Dir=%s to %s failed !", SrcDir, VNewName ) ); + + err_warning (( ERR_OUT, "Directory %s renamed in %s because delete is impossible !", SrcDir, VNewName )); + + err_retok (( ERR_OUT, "" )); + +/* + VRet = FIL_FRmDirFiles ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDirFiles (%s) failed ", SrcDir) ); + + VRet = FIL_FRmDir ( VNewName ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDir (%s) failed ", SrcDir) ); + + err_retok (( ERR_OUT, "" )); +*/ + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FMkDir ( char* SrcDir ) { + + SInt32 VRet; + char VStrCmd[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + #ifdef APP_DAQ + + err_retfail ( -1, (ERR_OUT,"Function NOT available under LynxOS !") ); + + #endif + + #ifdef CC_APP_LINUX + sprintf ( VStrCmd, "mkdir %s", SrcDir ); + system ( VStrCmd ); + #endif + + + #ifdef CC_APP_WINDOWS + VRet = mkdir ( SrcDir ); + + err_retfail ( VRet, (ERR_OUT,"Creation of directory=%s failed => %s", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FMkDir (SrcDir=%s) IS NOT available !", SrcDir) ); + #endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in + : the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT + : are not written in list. +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in +: the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT +: are not written in list. +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIL_FExtDosListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\%s", SrcDir, Joker ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIl_FDosListDirFiles ( SrcDir, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIL_FExtDosListDirFiles ( SrcDir, Joker, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList ) { + + SInt32 VRet; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + VFilesCnt = FIl_FListDirFiles ( VRmpDirPath, PtList ); + + return ( VFilesCnt ); +} + + + +#ifndef APP_DAQ + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Extended version which handles conf extension i,j,k +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtDelRmpFiles ( char* RmpDataPath, char ConfExt, SInt32 RunNo, SInt32 MaxFileCnt ) { + + SInt32 VRet; + SInt32 ViFile; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VInfoFilePath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VData0Filepath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + FIL_TDirFilesList VFilesList; // Debug 02/06/2007 move storage class static to auto + + + char VFileToDelete[GLB_FILE_PATH_SZ]; + + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + sprintf ( VInfoFilePath , "RUN_%d_%c.rz", RunNo, ConfExt ); + sprintf ( VData0Filepath, "RUN_%d_0.rz" , RunNo ); + + VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &VFilesList ); + + /* !!! DESY 20/09/05 !!! MUST BE CHECKED ! */ + /* previous line replaced by this one in order to be able to compile boards_db_man */ + /* VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &(VPtAFilesPath) ); */ + + err_retfail ( VFilesCnt, (ERR_OUT,"FIL_FCntRmpFiles (%s) failed Ret=%d", RmpDataPath, VFilesCnt ) ); + + if ( VFilesCnt < MaxFileCnt ) { + err_retok (( ERR_OUT, "Nothing to do VFilesCnt=%d < MaxFileCnt=%d", VFilesCnt, MaxFileCnt )); + } + + err_warning (( ERR_OUT, "%d RMP files are not deleted by monitoring => I will remove them", VFilesCnt )); + + for ( ViFile = 0; ViFile < VFilesCnt; ViFile++ ) { + + if ( strcmp ( VFilesList.AList[ViFile], VInfoFilePath ) == 0 ) { + continue; + } + + if ( strcmp ( VFilesList.AList[ViFile], VData0Filepath ) == 0 ) { + continue; + } + + sprintf ( VFileToDelete, "%s\\%s", VRmpDirPath, VFilesList.AList[ViFile] ); + + err_warning (( ERR_OUT, "FIL_FDelRmpFilesv => File = %s", VFileToDelete )); + + FIL_FRemoveFile ( VFileToDelete ); + + } + + return (0); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Creation of FIL_FExtDelRmpFiles to replace FIL_FDelRmpFiles + : - FIL_FDelRmpFiles call FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt ) { + return ( FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) ); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FFloatVectorsToTextFile ( float** SrcVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** VectorsNames, char DataSep, char* DestFile ) { + + char VFuncName[] = "FIL_FFloatVectorsToTextFile"; + + FILE* VPfDest; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + + + VPfDest = fopen ( DestFile, "wt" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", DestFile ) ); + + + if ( HeaderLine != NULL ) { + VRet = fprintf ( VPfDest, "%s \n", HeaderLine ); + } + + else { + VRet = fprintf ( VPfDest, "No header line \n", HeaderLine ); + } + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing Header line file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + + if ( VectorsNames != NULL ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + VRet = fprintf ( VPfDest, "%-21s", VectorsNames[ViVector]); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing vectors names line - Vector=%d file=%s => %s", ViVector, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + VRet = fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + } + + else { + fprintf ( VPfDest, "No vectors names line \n", HeaderLine ); + } + + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + VRet = fprintf ( VPfDest, "%.6f%c", SrcVectors[ViVector][ViLine], DataSep); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing line=%d in file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR line=%d file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + fflush (VPfDest); + fclose (VPfDest); + + err_retok (( ERR_OUT, "%d line written in file", EltNbPerVector, DestFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FTextFileToFloatVectors ( char* SrcFile, char DataSep, float** DestVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** AVectorsNames, char* StrVectorsNames ) { + + char VFuncName[] = "FIL_FTextFileToFloatVectors"; + + FILE* VPf; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + char VStrCR[2]; + char VDataSep; + + /* Check parameters */ + + err_retnull ( SrcFile , (ERR_OUT,"SrcFile == NULL" ) ); + err_retnull ( DestVectors , (ERR_OUT,"DestVectors == NULL" ) ); + err_retnull ( HeaderLine , (ERR_OUT,"HeaderLine == NULL" ) ); + err_retnull ( AVectorsNames , (ERR_OUT,"AVectorsNames == NULL" ) ); + err_retnull ( StrVectorsNames , (ERR_OUT,"StrVectorsNames == NULL" ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 1" )); + + /* Try to open file */ + + VPf = fopen ( SrcFile, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFile ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read header line */ + + VRet = (SInt32) fgets( HeaderLine, 255, VPf ); + + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read header line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + /* Read vectors names line */ + + + VRet = (SInt32) fgets( StrVectorsNames, 255, VPf ); + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read vectors names line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + sprintf ( AVectorsNames[ViVector], "" ); + }; + + + /* Read vectors */ + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + if ( ViVector == VectorsNb-1 ) { + VRet = fscanf ( VPf, "%f%c", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + else { + VRet = fscanf ( VPf, "%f%c\n", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + + if ( VRet != 2 ) { + fflush (VPf); + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s", ViLine, SrcFile, VRet, _strerror ( "System says :" ) ) ); + } + + } + + } + + + fflush (VPf); + fclose (VPf); + + err_retok (( ERR_OUT, "%d line Read in file", EltNbPerVector, SrcFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef CC_APP_WINDOWS + + SInt32 FIL_FGetAppRunDir ( char* StrRunDir, TApplication* PtApp ) { + + char* VPtStrExeName; + AnsiString VAStrExeName; + char VExeDriveLetter; + char VExeDriveId; /* 0 = default, 1 = A, 2 = B ... */ + char VStrCurDir[GLB_FILE_PATH_SZ]; + char VStrCurDirPath[GLB_FILE_PATH_SZ]; + + err_retfailnull ( StrRunDir, (ERR_OUT,"StrRunDir == NULL") ); + + VPtStrExeName = FStr2PCh ( &(PtApp->ExeName) ); + + VExeDriveLetter = toupper ( VPtStrExeName[0] ); + + switch ( VExeDriveLetter ) { + + case 'A' : { + VExeDriveId = 1; + break; } + + case 'B' : { + VExeDriveId = 2; + break; } + + case 'C' : { + VExeDriveId = 3; + break; } + + case 'D' : { + VExeDriveId = 4; + break; } + + case 'E' : { + VExeDriveId = 5; + break; } + + case 'F' : { + VExeDriveId = 6; + break; } + + case 'G' : { + VExeDriveId = 7; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown drive id=%d", VExeDriveId) ); + VExeDriveId = 0; + } + + } + + getcurdir( VExeDriveId, VStrCurDir ); + + sprintf ( VStrCurDirPath, "%c:\\%s", VExeDriveLetter, VStrCurDir ); + sprintf ( StrRunDir, "%s", VStrCurDirPath ); + + // msg (( MSG_OUT, "VStrCurDirPath = %s", VStrCurDirPath )); + + err_retok (( ERR_OUT, "" )); + } + +#else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 07/03/2011 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FGetDiskSectorSz ( char* Drive ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported under Unix !" ) ); + +#else + + DWORD VDummyW; + DWORD VBytesPerSector; + BOOL VRetBool; + + + // BOOL GetDiskFreeSpace( + // + // LPCTSTR lpRootPathName, // address of root path + // LPDWORD lpSectorsPerCluster, // address of sectors per cluster + // LPDWORD lpBytesPerSector, // address of bytes per sector + // LPDWORD lpNumberOfFreeClusters, // address of number of free clusters + // LPDWORD lpTotalNumberOfClusters // address of total number of clusters + // ); + + + VRetBool = GetDiskFreeSpace( + Drive, // address of root path + &VDummyW, // address of sectors per cluster + &VBytesPerSector, // address of bytes per sector + &VDummyW, // address of number of free clusters + &VDummyW // address of total number of clusters + ); + + if ( VRetBool == True ) { + return ( VBytesPerSector ); + } + + else { + return (-1); + } + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: ~FIL__TCBinFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + + // Variables for internal processing + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdEltId = 0; + ProCurRdSz = 0; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProPtFile = NULL; + + err_trace (( ERR_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + ProParRWBMode = RWBMode; + ProParMaxBlocSz = MaxBlocSz; + ProParBlocSz = BlocSz; + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + ProConfDone = 1; + + + // Allocate memory buffer for data read from file + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = MaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCBinFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProPtFile == NULL ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + + // Store current ( initial ) position in file + + if ( (VCurPos = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Goto end of file + + if ( fseek ( ProPtFile, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + // Get current position = END in file => it's file size + + if ( (VFileSz = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Restor initial position in file + + if ( fseek ( ProPtFile, VCurPos, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + + } // End file is already open + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFCreate () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProPtFile = fopen ( ProParDataFile, "wb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFOpen () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + ProPtFile = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz ) { + SInt8 VBlocNbWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can write to a file when RWB mode IS NOT Write !") ); + } + + ProCurWrSz = DataSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbWritten = fwrite ( PtrData, DataSz /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbWritten != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc write failed ! => System : %s", _strerror ("") ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + fflush ( ProPtFile ); + } + + ++ProCurWrEltId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", DataSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + if ( DataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > MaxDestSz=%d", DataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( DestPtr, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc read of %d bytes failed ! - VBlocNbRead = %d => System : %s", DataSzToRead, VBlocNbRead, _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + if ( DataSzToRead > ProParMaxBlocSz ) { + err_retfailnull ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > ProParMaxBlocSz=%d", DataSzToRead, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( ProPtrBuffRdData, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Bloc read failed ! => System : %s", _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGotoBloc ( SInt32 BlocNo ) { + + SInt32 VOffset; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + VOffset = BlocNo * ProParBlocSz; + + if ( fseek ( ProPtFile, VOffset, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Goto bloc %d => %d bytes from beginning failed !", BlocNo ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ) { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFFlush () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + fflush ( ProPtFile ); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFClose () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + fflush ( ProPtFile ); + } + + fclose ( ProPtFile ); + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + ProConfDone = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_WRITE, RecSz, RecSz, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFCreate (); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqWrite ( PtSrc, RecSz ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_READ, RecSz, RecSz, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFOpen(); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqRead ( PtDest, RecSz /* MaxDestSz */, RecSz /* DataSzToRead */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + + +// msg (( MSG_OUT, "Msg" )); + + + +// **************************** +// FIL__TCStreamFile +// **************************** + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl, DiskBlocSz ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: ~FIL__TCStreamFile () { + + // Free info record + + if ( ProPtRecInfFile != NULL ) { + free ( ProPtRecInfFile ); + } + +#ifndef CC_UNIX + TerminateThread ( ProThreadHnd , 0 /* Thread exit code */ ); + + DeleteCriticalSection ( &ProCsPrintMsg ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : 05/11/2010 + : - Error handling on disk access is not properly done, a message is printed + : but the error is not propagated => MUST be done. +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef CC_UNIX + +DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ) { + + FIL__TCStreamFile* VPtObj = (FIL__TCStreamFile*) lpParam; + + SInt32 VRet; + DWORD VBuffFull; + UInt32 VNbBytesToWrite; + UInt32 VNbBytesWritten; + char VStrMsg[GLB_CMT_SZ]; + + + while (1) { + + // Wait on buffer to read + + VBuffFull = WaitForSingleObject ( VPtObj->ProSemRdBuffHnd, INFINITE ); + + switch ( VBuffFull ) { + + case WAIT_OBJECT_0 : { + + + VNbBytesToWrite = VPtObj->ProParBlocSz; + + WriteFile( + VPtObj->ProFileHnd, // handle to file to write to + VPtObj->ProABuff[VPtObj->ProIndexRdBuff], // pointer to data to write to file + VNbBytesToWrite, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != VNbBytesToWrite ) { + sprintf ( VStrMsg, "ThreadDisk => Writing buff %d error !", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + else { + sprintf ( VStrMsg, "ThreadDisk => Buffer %d save to disk", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + if ( VPtObj->ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( VPtObj->ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + ++VPtObj->ProIndexRdBuff; + + err_retfail ( VPtObj->ProIndexRdBuff, (ERR_OUT,"Bad variable size => ProIndexRdBuff=%d < 0", VPtObj->ProIndexRdBuff) ); + + if ( VPtObj->ProIndexRdBuff >= FIL__TCStreamFile_MAX_BUFF_NB ) { + VPtObj->ProIndexRdBuff = 0; + } + + ReleaseSemaphore ( VPtObj->ProSemWrBuffHnd, 1, NULL ); + + + break; } + + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFull )); + break; } + + } + + + + } // End while (1) + + return 0; +} + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 05/11/2010 +Doc date : 05/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFCalcProParBlocSz ( SInt32 DataSz ) { + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VRecInfSz; + + VNotIntegerDiskBlocNb = DataSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (DataSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = DataSz; + } + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + SInt8 ViBuff; + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + ProParDiskBlocSz = DiskBlocSz; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + sprintf ( ProInfFileName, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + ProParFixedBlocSzMode = 1; + + // Variables for internal processing + + ProUseThread = 0; + + ProFileHnd = INVALID_HANDLE_VALUE; + ProPtInfFile = NULL; + +#ifndef CC_UNIX + InitializeCriticalSection ( &ProCsPrintMsg ); +#endif + + ProThreadHnd = INVALID_HANDLE_VALUE; + ProThreadId = 0; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProABuff[ViBuff] = NULL; + } + + ProSemWrBuffHnd = INVALID_HANDLE_VALUE; + ProSemRdBuffHnd = INVALID_HANDLE_VALUE; + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + ProBuffSz = 0; + + ProPtRecInfFile = NULL; + ProRecInfSz = 0; + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdBlocId = 0; + ProCurRdSz = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetDiskSectorSz ( SInt32 DiskBlocSz ) { + + ProParDiskBlocSz = DiskBlocSz; + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetDiskSectorSz () { + + return (ProParDiskBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void FIL__TCStreamFile :: PubFPrintMsg ( char* Msg ) { + +#ifndef CC_UNIX + EnterCriticalSection( &ProCsPrintMsg ); +#endif + err_trace (( ERR_OUT, "%s", Msg )); + +#ifndef CC_UNIX + LeaveCriticalSection( &ProCsPrintMsg ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt8 ViBuff; + SInt32 VNotIntegerDiskBlocNb; +#ifndef CC_UNIX + TDateTime VODateTime; +#endif + + + + // ------------------------------------------------------- + // Set class parameters from PubFConf parameters list + // ------------------------------------------------------- + + err_retnull ( PtMyself, (ERR_OUT,"PtMyself == NULL") ); + + PriPtMyself = PtMyself; + + ProUseThread = UseThread; + + sprintf ( ProParDataFile, "%s", DataFile ); + + sprintf ( ProInfFileName, "%s.inf", ProParDataFile ); + + ProParRWBMode = RWBMode; + + ProParFixedBlocSzMode = FixedBlocSzMode; + + ProParRequestedBlocSz = BlocSz; + + VNotIntegerDiskBlocNb = ProParRequestedBlocSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (ProParRequestedBlocSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = ProParRequestedBlocSz; + } + + err_trace (( ERR_OUT, "RequestedBlocSz=%d - BlocSz=%d", ProParRequestedBlocSz, ProParBlocSz )); + + + ProParRequestedMaxBlocSz = MaxBlocSz; + + if ( ProParRequestedMaxBlocSz >= ProParBlocSz ) { + ProParMaxBlocSz = ProParRequestedMaxBlocSz; + } + + else { + err_warning (( ERR_OUT, "ProParMaxBlocSz=%d must be adjusted -> Set to ProParBlocSz=%d", ProParMaxBlocSz, ProParBlocSz )); + ProParMaxBlocSz = ProParBlocSz; + } + + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + // ------------------------------------------------------- + // Alloc information file record + // ------------------------------------------------------- + + if ( ProParFixedBlocSzMode == 1 ) { + ProRecInfSz = sizeof (FIL__TCStreamFile_Old_TRecInfFile); + } + + else { + + // BUG ? + + // ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (UInt64) ); + + ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (FIL__TCStreamFile_TBlocInf) ); + + } + + ProPtRecInfFile = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFile, (ERR_OUT,"Allocation of info record failed !") ); + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // ------------------------------------------------------- + // Create or open information file + // ------------------------------------------------------- + + // Write mode => Create info file + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProPtRecInfFile->Version = 1; + ProPtRecInfFile->FixedBlocSz = ProParFixedBlocSzMode; + ProPtRecInfFile->MaxBlocSz = ProParMaxBlocSz; + ProPtRecInfFile->BlocSz = ProParBlocSz; + ProPtRecInfFile->BlocNb = 0; + ProPtRecInfFile->ABlocInf[0].Offset = 0; + ProPtRecInfFile->ABlocInf[0].Sz = 0; + +#ifndef CC_UNIX + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateCreate = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeCreate = TIME__FConvDateTime2Time ( VODateTime ); +#else + ProPtRecInfFile->DateCreate.W32 = 0; + ProPtRecInfFile->TimeCreate.W32 = 0; +#endif + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Creation of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + err_trace (( ERR_OUT, "Info file=%s created", ProInfFileName )); + } + + // Read mode => Open info file + + else { + + ProPtInfFile = fopen ( ProInfFileName, "rb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Open info file %s failed => system : %s", ProInfFileName, _strerror ( "" ) )); + err_trace (( ERR_OUT, "Info file=%s read", ProInfFileName )); + + if ( fread ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Read info file %s failed => system : %s", ProInfFileName, _strerror ( "" )) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + // Print info file + + PubFPrintInfFile (); + + // Set bloc size + + ProParBlocSz = ProPtRecInfFile->BlocSz; + + if ( ProParRequestedBlocSz != ProParBlocSz ) { + err_warning (( ERR_OUT, "Requested bloc sz=%d <> Info file bloc sz=%d => Use Info file bloc sz", ProParRequestedBlocSz, ProParBlocSz )); + } + + } + + + // ------------------------------------------------------------- + // Write mode => Allocate buffers, create semaphores and thread + // ------------------------------------------------------------- + + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + if ( FIL__TCStreamFile_MAX_BUFF_NB > 4 ) { + err_retfail ( -1, (ERR_OUT,"FIL__TCStreamFile_MAX_BUFF_NB = %d ! Handling of more than 4 buffers is NOT implemented !", FIL__TCStreamFile_MAX_BUFF_NB) ); + } + + // Allocate buffers + + ProBuffSz = ProParMaxBlocSz; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + // If already allocated => Free + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + } + + // Allocate + + ProABuff[ViBuff] = (UInt8*) malloc ( ProBuffSz ); + + err_retnull ( ProABuff[ViBuff], (ERR_OUT,"Allocation buffer[%d] of %d bytes failed !", ViBuff, ProBuffSz ) ); + err_trace (( ERR_OUT, "Buffer[%d] of %d bytes allocated", ViBuff, ProBuffSz )); + + // Reset content with $FF + + memset ( ProABuff[ViBuff], 0xFF, ProBuffSz ); + } + + // Create & init semaphores + + #ifndef CC_UNIX + ProSemWrBuffHnd = CreateSemaphore( NULL, FIL__TCStreamFile_MAX_BUFF_NB, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = Max = Max buff nb + + err_retnull ( ProSemWrBuffHnd, (ERR_OUT,"Create SemWrBuff failed ! - LastError=%d", GetLastError ()) ); + + ProSemRdBuffHnd = CreateSemaphore( NULL, 0, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = 0, Max = Max buff nb + + err_retnull ( ProSemRdBuffHnd, (ERR_OUT,"Create SemRdBuff failed ! - LastError=%d", GetLastError ()) ); + #endif + + // Init buffers index + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + // Create thread + + #ifndef CC_UNIX + ProThreadHnd = CreateThread ( NULL, 0, FIL__TCStreamFile_FThread, (void*) PriPtMyself /* Param */ , 0, &ProThreadId ); + err_retnull ( ProThreadHnd, (ERR_OUT,"Thread creation failed ! LastError=%d", GetLastError ()) ); + #endif + + } + + // ------------------------------------------------------------- + // Read mode => Allocate memory buffer for data read from file + // ------------------------------------------------------------- + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = ProParMaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 20/05/2010 +Doc date : 20/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFile () { + + SInt32 ViBloc; + SInt16 ViSpareW32Info; + + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record " )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Version = %d", ProPtRecInfFile->Version )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Date create = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateCreate, NULL, 0 ) )); + msg (( MSG_OUT, "Time create = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeCreate, NULL, 0 ) )); + msg (( MSG_OUT, "Date close = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateClose , NULL, 0 ) )); + msg (( MSG_OUT, "Time close = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeClose , NULL, 0 ) )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "FixedBlocSz = %d", ProPtRecInfFile->FixedBlocSz )); + msg (( MSG_OUT, "MaxBlocSz = %d", ProPtRecInfFile->MaxBlocSz )); + msg (( MSG_OUT, "BlocSz = %d", ProPtRecInfFile->BlocSz )); + msg (( MSG_OUT, "BlocNb = %d", ProPtRecInfFile->BlocNb )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "ABlocInf[0].Offset = %Lu", ProPtRecInfFile->ABlocInf[0].Offset )); + msg (( MSG_OUT, "ABlocInf[0].Sz = %d ", ProPtRecInfFile->ABlocInf[0].Sz )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoFormat = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoFormat )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoNb = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb )); + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb; ViSpareW32Info++ ) { + msg (( MSG_OUT, "ABlocInf[0].ASpareW32Info[%.2d] = %d ", ViSpareW32Info, ProPtRecInfFile->ABlocInf[0].ASpareW32Info[ViSpareW32Info] )); + } + + + if ( ProPtRecInfFile->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < ProPtRecInfFile->BlocNb; ViBloc++ ) { + msg (( MSG_OUT, "Bloc[%.4d] : Offset=%.12Lu - Sz=%.8d [Bytes] - ASpare [0]=%.4d [1]=%.4d [2]=%.4d [3]=%.4d", ViBloc, ProPtRecInfFile->ABlocInf[ViBloc].Offset, ProPtRecInfFile->ABlocInf[ViBloc].Sz, ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[0], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[1], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[2], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[3] )); + } + + } + + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + err_retfail ( -1, (ERR_OUT,"File is opened => Get file size not coded in this state (TOB ...)") ); + } + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 + : - Calculation => file size / block size +Rev : 20/05/2010 + : - Read from info file field BlocNb + : +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + +/* Before 20/05/2010 + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + +*/ + + VBlocNb = ProPtRecInfFile->BlocNb; + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFCreate () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_WRITE | GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFOpen () { + +#ifdef CC_UNIX + + ProFilePtUx = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProFilePtUx, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#endif +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation + : + : 24/02/2011 + : - Handle SpareW32Info as an array now => New parameters + : +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + SInt16 ViSpareW32Info; + DWORD VBuffFree; + UInt32 VNbBytesWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + err_retnull ( PtSpareW32Info, (ERR_OUT,"PtSpareW32Info == NULL") ); + + if ( SpareW32InfoNb > FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"SpareW32InfoNb=%d > Max=%d", SpareW32InfoNb, FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Cant write to a file when RWB mode IS NOT Write !") ); + } + + // If variable bloc sz mode => Test max nb of blocs allowed & Adjust ProParBlocSz + + if ( ProParFixedBlocSzMode == 0 ) { + + if ( ProPtRecInfFile->BlocNb >= FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE ) { + err_retfail ( -1, (ERR_OUT,"Max bloc nb = %d reached in variable bloc sz mode !", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE) ); + } + + ProFCalcProParBlocSz ( DataSz ); + } + + // err_error (( ERR_OUT, "DataSz=%d - ProParBlocSz=%d bytes", DataSz, ProParBlocSz )); + + ProCurWrSz = ProParBlocSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + // Let thread write data to disk in background task + + if ( ProUseThread == 1 ) { + + // Wait on buffer to write + + VBuffFree = WaitForSingleObject ( ProSemWrBuffHnd, 1 /* ms */ ); + + switch ( VBuffFree ) { + + case WAIT_TIMEOUT : { + ++ProResWrBlocFailCnt; + err_retfail ( -1, (ERR_OUT,"Write failed for the %d time -> No buffer available - DbgCallPar=%d !", ProResWrBlocFailCnt, DbgCallPar ) ); + break; } + + case WAIT_OBJECT_0 : { + + memcpy ( ProABuff[ProIndexWrBuff], PtrData, DataSz ); + + // PubFPrintMsg ( "Thread => Buffer %d filled", ProIndexWrBuff ); + err_trace (( ERR_OUT, "Thread => Buffer %d filled - DbgCallPar=%d", ProIndexWrBuff, DbgCallPar )); + + ++ProIndexWrBuff; + + err_retfail ( ProIndexWrBuff, (ERR_OUT,"Bad variable size => ProIndexWrBuff=%d < 0", ProIndexWrBuff) ); + + if ( ProIndexWrBuff >= FIL__TCStreamFile_MAX_BUFF_NB) { + ProIndexWrBuff = 0; + } + + ReleaseSemaphore ( ProSemRdBuffHnd, 1, NULL ); + break; } + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFree )); + break; } + + } + + } + + // Write NOW data to disk + + else { + + // Copy to buffer -> "Automatically" add padding bytes + + memcpy ( ProABuff[0], PtrData, DataSz ); + + // Warning => Write ProParBlocSz bytes AND NOT the value passed via parameter DataSz + // because non buffered I/O functions MUST write multiple of DISK bloc size + + WriteFile( + ProFileHnd, // handle to file to write to + ProABuff[0], // pointer to data to write to file + ProParBlocSz, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != ProParBlocSz ) { + err_retfail ( VRet, (ERR_OUT,"Writing block %d failed %d bytes written - %d bytes requested ! - %s", ProCurWrBlocId, VNbBytesWritten, ProParBlocSz, strerror ( errno ) ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + } + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + + if ( ProUseThread == 1 ) { + err_trace (( ERR_OUT, "Copy bloc of %d bytes done in %d [ms]", DataSz, ProTimeExec )); + } + + else { + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", VNbBytesWritten, ProTimeExec )); + } + + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + +#ifdef CC_UNIX + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + SInt32 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VBlocNbRead = fread ( DestPtr, VDataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProFilePtUx ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed of %d bytes ! - %s", ProCurRdBlocId, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#else + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + UInt32 VNbBytesRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + ReadFile( + ProFileHnd, // handle of file to read + DestPtr, // address of buffer that receives data + VDataSzToRead, // number of bytes to read + &VNbBytesRead, // address of number of bytes read + NULL // address of structure for data + ); + + if ( VNbBytesRead != VDataSzToRead ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed : %d bytes read - %d bytes requested ! - %s", ProCurRdBlocId, VNbBytesRead, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( ProPtrBuffRdData, ProSzBuffRdData, DataSzToRead ); + + err_retfailnull ( VRet, (ERR_OUT,"PubFSeqRead failed !") ); + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : Limited to 4 GB files + : +Rev : 09/05/2010 + : - Use W64 offset => Not limited to 4 GB file +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGotoBloc ( SInt32 BlocNo ) { + +#ifdef CC_UNIX + + SInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = fseeko ( ProFilePtUx, (off_t) VOffsetW64, SEEK_SET ); + + err_retfail ( VRet, (ERR_OUT,"Bloc %d read failed ! => System : %s", BlocNo, _strerror ("") ) ); + + err_retok (( ERR_OUT, "" )); + +#else + + UInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = SetFilePointer ( + ProFileHnd, // handle of file + *VPtOffsetLow32, // number of bytes to move file pointer + (SInt32*) VPtOffsetHigh32, // address of high-order word of distance to move + // lpDistanceToMoveHigh = 0 => Limited to 4 GB + FILE_BEGIN // how to move + ); + + + if ( VRet == 0xFFFFFFFF ) { + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &VMsgBuf, + 0, + NULL + ); + + err_retfail ( -1, (ERR_OUT,"Goto bloc %d failed => %s", BlocNo, VMsgBuf ) ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 24/02/2011 + : - Handle SpareW32Info as and array ASpareW32Info now => New parameters + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ) { + + SInt32 VRet; + SInt16 ViSpareW32Info; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + + if ( (PtSpareW32InfoFormat != NULL) && (PtSpareW32Info != NULL) && (ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb <= MaxSpareW32InfoNb) ) { + + *PtSpareW32InfoFormat = ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoFormat; + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb; ViSpareW32Info++ ) { + PtSpareW32Info[ViSpareW32Info] = ProPtRecInfFile->ABlocInf[BlocNo].ASpareW32Info[ViSpareW32Info]; + } + + } + + else { + err_warning (( ERR_OUT, "ASpareInfo bloc not updated ! Pointer NULL or Dest size too small ?" )); + } + + } + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + return (ProParBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + } + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFFlush () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFClose () { + + SInt32 VRet; + SInt8 ViBuff; +#ifndef CC_UNIX + TDateTime VODateTime; +#endif + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + PubFFlush (); + } + + ProConfDone = 0; + +#ifndef CC_UNIX + CloseHandle ( ProFileHnd ); +#endif + + // Free read buffers + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + // Free write buffers + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + ProABuff[ViBuff] = NULL; + } + + } + + + // Get close date & time + +#ifndef CC_UNIX + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateClose = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeClose = TIME__FConvDateTime2Time ( VODateTime ); +#else + ProPtRecInfFile->DateClose.W32 = 0; + ProPtRecInfFile->TimeClose.W32 = 0; +#endif + + + if ( ProReadyToWrite == 1 ) { + + // Overwrite info file with update close time & date + bloc nb + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Overwrite of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file failed => System : %s", strerror ( errno ) ) ); + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/fsbb0.c b/include/pxi_daq_lib_v.2.1/fsbb0.c new file mode 100755 index 0000000..7755a46 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0.c @@ -0,0 +1,7972 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.c +Goal : Functions of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_C +#define FSBB0_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// $ SInt32 FSBB0__FBegin ( SInt8 FileErrLogLvl, char* FileErrFile ) { + +// $ FSBB0__VGContext.FileErrLogLvl = FileErrLogLvl; +// $ strcpy ( FSBB0__VGContext.FileErrFile, FileErrFile ); + +// $ err_retok (( ERR_OUT, "" )); +// $} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// $SInt32 FSBB0__FEnd () { + + +// $ err_retok (( ERR_OUT, "" )); +// $} + + + +/* ------------------------------ */ +/* General functions for MAPS */ +/* ------------------------------ */ + + + +/******************************************************************************* +Prototype : SInt8 SUZE02_FHammingDecoder8_4(UInt8 CodedIn) + +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 10/07/2013 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + + UInt8 FSBB0_FHammingDecoder8_4(UInt8 CodedIn) + { + UInt8 VResult; + + // 27/06/2014 - MS replaced the hamming code ( which doesn't seem to be working for FSBB) by the converting the code received according to the mail from GD + // have to investigate when there will be some spare time........ + + switch (CodedIn){ + case 0:{ + VResult = 0; + break; + } + case 0x87:{ + VResult = 1; + break; + } + case 0x99:{ + VResult = 2; + break; + } + case 0x1e:{ + VResult = 3; + break; + } + case 0xaa:{ + VResult = 4; + break; + } + case 0x2d:{ + VResult = 5; + break; + } + case 0x33:{ + VResult = 6; + break; + } + case 0xb4:{ + VResult = 7; + break; + } + case 0x4b:{ + VResult = 8; + break; + } + case 0xcc:{ + VResult = 9; + break; + } + case 0xd2:{ + VResult = 0xa; + break; + } + case 0x55:{ + VResult = 0xb; + break; + } + case 0xe1:{ + VResult = 0xc; + break; + } + case 0x66:{ + VResult = 0xd; + break; + } + case 0x78:{ + VResult = 0xe; + break; + } + case 0xff:{ + VResult = 0xf; + break; + } + + }/* end switch G0 */ + + + +/* UInt8 VSyndrome; + UInt8 VParity; + UInt8 VTempResult; + UInt8 VError; + + VSyndrome = ((((CodedIn & 0x8)>>3)^((CodedIn & 0x10)>>4)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6))<<2 + + (((CodedIn & 0x2)>>1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6))<<1 + + ((CodedIn & 0x1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x10)>>4)^((CodedIn & 0x40)>>6))); + // Parity bit + + VParity = (CodedIn & 0x1)^((CodedIn & 0x2)>>1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x8)>>3)^((CodedIn & 0x10)>>4)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6); + VTempResult = CodedIn; + switch (VSyndrome ) + { + case 0 : { + // No Trans Error + // Nothing to do + break; + } + case 1 :{ + // Error on bit 0 + VTempResult ^= 0x1; + break; + } + case 2 : { + // Error on bit 1 + VTempResult ^= 0x2; + break; + } + case 3 : { + // Error on bit 2 + VTempResult ^= 0x4; + break; + } + case 4 : { + // Error on bit 3 + VTempResult ^= 0x8; + break; + } + case 5 : { + // Error on bit 4 + VTempResult ^= 0x10; + break; + } + case 6 : { + // Error on bit 5 + VTempResult ^= 0x20; + break; + } + default : { + // Error on bit 6 + VTempResult ^= 0x40; + break; + } + }*/ /* end switch */ + // ------------------------------------------------------------- // +/* if (VSyndrome == 0){ + VError = 0; + } + else{ + if (VParity == ((CodedIn & 0x80)>>7)){ + VError = 5; + } + else{ + VError = 3; + } + } + VResult = ((VTempResult & 2)>>2) + ((VTempResult & 16)>>3) + ((VTempResult & 32)>>3) + ((VTempResult & 64)>>3); + err_trace (( ERR_OUT, "FSBB0_FHammingDecoder8_4, result :%X, Error code : %X",VResult,VError ));*/ + + return (VResult); + +} /* End FSBB0_FHammingDecoder8_4 */ + + + + +/******************************************************************************* +Prototype : SInt32 FSBB0_FDecodeString(char * Buffer, SInt16 DataType) + +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 23/06/2014 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0_FDecodeString (char * Buffer, SInt16 DataType){ + SInt32 VReturn; + SInt32 VIndex; + SInt8 VNumberIndex; + SInt8 VMajorNumberDone; + SInt32 VCurrentNumber; + SInt8 VJunkDone; + + VIndex = 0; + VNumberIndex = 0; + VMajorNumberDone = 0; + VCurrentNumber = 0; + VReturn = 0; + VJunkDone = 0; + switch (DataType){ + case 0:{ // Configuration + while((Buffer[VIndex]!=0xa)&&(VIndex < strlen(Buffer))){ + if ((Buffer[VIndex] >=0x30) &&(Buffer[VIndex] <= 0x39)){ + VReturn = Buffer[VIndex] - 0x30; + return( VReturn); + } + VIndex++; + }/* end while not end of line*/ + break; + } + case 1:{ // Pattern File Number + while((Buffer[VIndex]!=0xa)&&(VIndex < strlen(Buffer))){ + if (Buffer[VIndex] == 0x3A){ + VJunkDone = 1; + } + if ((VJunkDone != 0 )){ + if ((Buffer[VIndex] >=0x30) &&(Buffer[VIndex] <= 0x39)){ + VCurrentNumber = (VCurrentNumber * 10) + (Buffer[VIndex] - 0x30); + VNumberIndex++; + } + else{ + if ((VNumberIndex != 0)){ + VMajorNumberDone = 1; + VReturn = VCurrentNumber << 16; + VCurrentNumber = 0; + VNumberIndex = 0; + } + } + } + VIndex++; + if ((Buffer[VIndex]==0xa)||(VIndex >= strlen(Buffer))){ + if (VMajorNumberDone == 0){ + VReturn = VCurrentNumber << 16; + } + else{ + VReturn = VReturn + VCurrentNumber; + } + return (VReturn); + } + }/* end while not end of line*/ + break; + } + case 2:{ // Line Number + while((Buffer[VIndex]!=0xa)&&(VIndex < strlen(Buffer))){ + if ((Buffer[VIndex] >=0x30) &&(Buffer[VIndex] <= 0x39)){ + VReturn = Buffer[VIndex] - 0x30; + return( VReturn); + } + VIndex++; + } + break; + } + case 3:{ // Pattern + while((Buffer[VIndex]!=0xa)&&(VIndex < strlen(Buffer))){ + switch (Buffer[VIndex]){ + case 0x30: + case 0x31: + case 0x32: + case 0x33: + case 0x34: + case 0x35: + case 0x36: + case 0x37: + case 0x38: + case 0x39:{ + + VCurrentNumber = (VCurrentNumber << 4) + (Buffer[VIndex] - 0x30); + VNumberIndex++; + + break; + } + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46:{ + + VCurrentNumber = (VCurrentNumber << 4) + (Buffer[VIndex] - 0x37); + VNumberIndex++; + + break; + } + case 0x61: + case 0x62: + case 0x63: + case 0x64: + case 0x65: + case 0x66:{ + + VCurrentNumber = (VCurrentNumber << 4) + (Buffer[VIndex] - 0x57); + VNumberIndex++; + + break; + } + default:{ + if (VNumberIndex == 8){ + return (VCurrentNumber); + } + else{ + VCurrentNumber = 0; + VNumberIndex = 0; + } + break; + } + } /* end switch Buffer[Index]*/ + VIndex++; + if ((Buffer[VIndex]==0xa)||(VIndex >= strlen(Buffer))){ + break; + } + } /* end while not end of line*/ + + break; + } + case 4:{ // Zone + while((Buffer[VIndex]!=0xa)&&(VIndex < strlen(Buffer))){ + if (Buffer[VIndex] == 0x3A){ + VJunkDone = 1; + } + if ((VJunkDone != 0 )&&((Buffer[VIndex] >=0x30) &&(Buffer[VIndex] <= 0x39))){ + VCurrentNumber = (VCurrentNumber * 10) + (Buffer[VIndex] - 0x30); + VNumberIndex++; + } + VIndex++; + if ((Buffer[VIndex]==0xa)||(VIndex >= strlen(Buffer))){ + return (VCurrentNumber); + } + }/* end while not end of line*/ + + break; + } + default :{ + break; + } + + } /* end switch DataType */ + return( VReturn); + +}/* end FSBB0_FDecodeString */ + +/******************************************************************************* +Prototype : SInt32 FSBB0_FReadConfigFile(char * FilePath) + +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 18/06/2014 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + + FSBB0__TTestPattern FSBB0_FReadConfigFile(char * FilePath, SInt8 PrintLevel) + { + FILE * pSourceFile; + char VBuffer[128]; + SInt32 VDataW32; + SInt8 ViLineIndex; + SInt8 ViColIndex; + FSBB0__TTestPattern VTestPattern; + + // Open source file + + err_error (( ERR_OUT, "FilePath : %s",FilePath )); + + + pSourceFile = fopen ( FilePath , "rb"); + if(pSourceFile==NULL) { + err_error (( ERR_OUT, "Error: can't open config file." )); + printf("Error: can't open source file.\n"); + VTestPattern.ConfigIndex = -1; + return VTestPattern; + } + + // read first line : Configuration:X + fgets(VBuffer,40, pSourceFile); + VTestPattern.ConfigIndex = FSBB0_FDecodeString (VBuffer, 0); + if ((PrintLevel == 6)||(PrintLevel == 7)){ + err_error (( ERR_OUT, "VTestPattern.ConfigIndex : %d",VTestPattern.ConfigIndex )); + } + + // read two comments lines + fgets(VBuffer,40, pSourceFile); + fgets(VBuffer,40, pSourceFile); + // read the file pattern number + fgets(VBuffer,100, pSourceFile); + VDataW32 = FSBB0_FDecodeString (VBuffer, 1); + VTestPattern.FileNumberMajor = (VDataW32 & 0xffff0000)>>16; + VTestPattern.FileNumberMinor = VDataW32 & 0xffff; + if ((PrintLevel == 6)||(PrintLevel == 7)){ + err_error (( ERR_OUT, "VTestPattern.FileNumberMajor:%d ,VTestPattern.FileNumberMinor:%d",VTestPattern.FileNumberMajor,VTestPattern.FileNumberMinor )); + } + // read the 8 lines pattern registers + for (ViLineIndex = 0; ViLineIndex < 8 ; ViLineIndex++){ + // read the line number + fgets(VBuffer,40, pSourceFile); + // read the pattern registers value + for (ViColIndex = 0 ; ViColIndex < 13 ; ViColIndex++){ + fgets(VBuffer,40, pSourceFile); + VTestPattern.Pattern[ViLineIndex][ViColIndex] = FSBB0_FDecodeString (VBuffer, 3); + }/* End for ViColIndex */ + } /* End for ViLineIndex */ + // read one comments lines + fgets(VBuffer,40, pSourceFile); + // read the zone definition + fgets(VBuffer,40, pSourceFile); + VTestPattern.Zone00 = FSBB0_FDecodeString (VBuffer, 4); + if ((PrintLevel == 6)||(PrintLevel == 7)){ + err_error (( ERR_OUT, "Zone00 : %d",VTestPattern.Zone00 )); + } + fgets(VBuffer,40, pSourceFile); + VTestPattern.Zone01 = FSBB0_FDecodeString (VBuffer, 4); + if ((PrintLevel == 6)||(PrintLevel == 7)){ + err_error (( ERR_OUT, "Zone01 : %d",VTestPattern.Zone01 )); + } + fgets(VBuffer,40, pSourceFile); + VTestPattern.Zone10 = FSBB0_FDecodeString (VBuffer, 4); + if ((PrintLevel == 6)||(PrintLevel == 7)){ + err_error (( ERR_OUT, "Zone10 : %d",VTestPattern.Zone10 )); + } + fgets(VBuffer,40, pSourceFile); + VTestPattern.Zone11 = FSBB0_FDecodeString (VBuffer, 4); + if ((PrintLevel == 6)||(PrintLevel == 7)){ + err_error (( ERR_OUT, "Zone11 : %d",VTestPattern.Zone11 )); + } + + fclose(pSourceFile); + + return (VTestPattern); + +} /* end FSBB0_FReadConfigFile */ + +/******************************************************************************* +Prototype : SInt32 FSBB0_FReadConfigFile(char * FilePath) + +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 24/06/2014 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + +char * FSBB0_FGetConfigName(SInt16 ConfigNr) + { + FILE * pSourceFile; + char VBuffer[200]; + char VReturnBuffer[50]; + SInt8 ViLineIndex; + + + + // Open source file + + pSourceFile = fopen ( ".\\GD_Files\\description_test_pat.txt" , "rb"); + if(pSourceFile==NULL) { + err_error (( ERR_OUT, "Error: can't open config file." )); + printf("Error: can't open source file.\n"); + //VTestPattern.ConfigIndex = -1; + return ""; + } + // read first line : comments + fgets(VBuffer,80, pSourceFile); + // Ignore ConfigNr lines + if (ConfigNr > 0){ + for (ViLineIndex = 0 ; ViLineIndex < ConfigNr ; ViLineIndex++){ + fgets(VBuffer,200, pSourceFile); + } + } + // get the wanted line + fgets(VBuffer,200, pSourceFile); + + strncpy ( VReturnBuffer , VBuffer , 50); + + fclose(pSourceFile); + + return (VReturnBuffer); + +} /* end FSBB0_FReadConfigFile */ + + +/******************************************************************************* +Prototype : SInt32 FSBB0_FReadResultBitFile(char * FilePath) + +Goal : +Inputs : +Ouputs : returns the number of bit at 1 of the matrix +Globals : +Remark : +Level : +Date : 18/06/2014 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + + FSBB0__TMatDiscriBit FSBB0_FReadResultBitFile(char * FilePath, SInt8 PrintLevel) + { + SInt32 VResult; + FILE * pSourceFile; + char VBuffer[420]; + char VReadChar; + SInt32 VDataW32; + SInt16 ViLineIndex; + SInt16 ViColIndex; + FSBB0__TMatDiscriBit VMatResult; + SInt16 FileNumberMajor; + SInt16 FileNumberMinor; + + // Open source file + pSourceFile = fopen ( FilePath , "rb"); + if(pSourceFile==NULL) { + err_error (( ERR_OUT, "Error: can't open result bit file." )); + printf("Error: can't open source file.\n"); + VMatResult.AALineCol[0][0] = -1; + return VMatResult; + } + err_error (( ERR_OUT, "Filename: %s",FilePath )); + + VResult = 0; + // read first line : comments + fgets(VBuffer,80, pSourceFile); + // read second line : image nr + fgets(VBuffer,40, pSourceFile); + VDataW32 = FSBB0_FDecodeString (VBuffer, 1); + FileNumberMajor = (VDataW32 & 0xffff0000)>>16; + FileNumberMinor = VDataW32 & 0xffff; + if ((PrintLevel == 6)||(PrintLevel == 7)){ + err_error (( ERR_OUT, "FileNumberMajor:%d ,FileNumberMinor:%d",FileNumberMajor,FileNumberMinor )); + } + // read third line : comments + fgets(VBuffer,140, pSourceFile); + // read the 416 lines of 416 bits + // 26/06/2014 - MS : line number were starting from 0 to 416 abd it should be from 416 to 0 + for (ViLineIndex = (FSBB0__MAT_DISCRI_USEFUL_LINES_NB - 1); ViLineIndex >= 0 ; ViLineIndex--){ + // read the line of 416 bits + fgets(VBuffer,418, pSourceFile); + for (ViColIndex = 0 ; ViColIndex < FSBB0__MAT_DISCRI_COL_NB ; ViColIndex++){ + VReadChar = VBuffer[ViColIndex]; + if (VReadChar == 0x31){ + VMatResult.AALineCol[ViLineIndex][(FSBB0__MAT_DISCRI_COL_NB - 1) - ViColIndex] = 1; + VResult++; + if ((PrintLevel == 6)||(PrintLevel == 7)){ + err_error (( ERR_OUT, "Hit Line :%d, col:%d",ViLineIndex,(FSBB0__MAT_DISCRI_COL_NB - 1) - ViColIndex )); + } + } + else{ + VMatResult.AALineCol[ViLineIndex][(FSBB0__MAT_DISCRI_COL_NB - 1) - ViColIndex] = 0; + } + }/* End for ViColIndex */ + + } /* End for ViLineIndex */ + + fclose(pSourceFile); + return (VMatResult); + +} /* end FSBB0_FReadResultBitFile */ + + + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__MAPS__FRegDiscriCumulResetHit ( SInt32* PtDestCumul, SInt16 DiscriNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + PtDestCumul[Vi] = 0; + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__MAPS__FRegDiscriCumulAddHit ( SInt8* PtSrcDiscri, SInt32* PtDestCumul, SInt16 DiscriNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + + if ( PtSrcDiscri[Vi] == 1 ) { + ++PtDestCumul[Vi]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__MAPS__FRegDiscriCumulCalcPercent ( SInt32* PtSrcCumul, float* PtDestPercent, SInt16 DiscriNb, SInt16 EvNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + PtDestPercent[Vi] = 100* ((float) PtSrcCumul[Vi] / (float) EvNb); + } + + err_retok (( ERR_OUT, "" )); +} + + +// 25/02/2009 + +SInt32 FSBB0__MAPS__FRegDiscriCumulCountHits ( SInt32* PtSrcCumul, float* PtDestPercent, SInt16 DiscriNb, SInt16 EvNb ) { + + SInt16 Vi; + SInt32 VHiCnt; + + VHiCnt = 0; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + VHiCnt = VHiCnt + PtSrcCumul[Vi]; + PtDestPercent[Vi] = PtSrcCumul[Vi]; + } + + // err_retok (( ERR_OUT, "" )); + + return (VHiCnt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Set parameter FirstW16 or LastW16 to -1 to avoid data W16 printing +: +Level : +Date : 16/02/2009 +Rev : 17/06/2009 + : - Print Triger + +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0_FPrintZsFFrameRawHeader ( FSBB0__TZsFFrameRaw* Pt ) { + + UInt16 Vi; + + err_retnull ( Pt, (ERR_OUT,"Pt == NULL") ); + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "AsicNo = %4d [D]", Pt->SStatus.AsicNo )); + msg (( MSG_OUT, "AcqNo = %4d [D]", Pt->SStatus.AcqNo )); + msg (( MSG_OUT, "FrameNoInAcq = %4d [D]", Pt->SStatus.FrameNoInAcq )); + msg (( MSG_OUT, "FrameNoInRun = %4d [D]", Pt->SStatus.FrameNoInRun )); +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + msg (( MSG_OUT, "TrigSignalLine = %4d [D]", Pt->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE] )); + msg (( MSG_OUT, "TrigSignalClk = %4d [D]", Pt->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK] )); + msg (( MSG_OUT, "TrigLine = %4d [D]", Pt->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__LINE] )); + msg (( MSG_OUT, "TotTrigNb = %4d [D]", Pt->SStatus.ATrigRes[ASIC__FSBB0_TRIG_TOT_NB] )); +//#endif + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, "Header = %4x [H]", Pt->Header )); + msg (( MSG_OUT, "Trigger = %4x [h]", Pt->Trigger )); + msg (( MSG_OUT, "FrameCnt = %4d [D]", Pt->DataLengthRemFrCnt.F.FrameCnt )); + msg (( MSG_OUT, "UsefulDataLengthW30 = %4d [D]", Pt->UsefulDataLengthW30 )); + msg (( MSG_OUT, " - DataLength = %4d [D]", Pt->DataLengthRemFrCnt.F.DataLength )); + msg (( MSG_OUT, " - Rem = %4d [D]", Pt->DataLengthRemFrCnt.F.Rem )); + msg (( MSG_OUT, "Trailer = %4x [H]", Pt->Trailer )); + msg (( MSG_OUT, "=======================================" )); + + msg (( MSG_OUT, "" )); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Set parameter FirstW16 or LastW16 to -1 to avoid data W16 printing +: +Level : +Date : 09/12/2008 +Rev : 22/05/2014 - MS + : Applied the modifications from GC in fsrr_usr.typ and fsbb_usr.def +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0_FPrintZsFFrameRaw ( FSBB0__TZsFFrameRaw* Pt, SInt16 FirstW32, SInt16 LastW32 ) { + + UInt16 Vi; + + err_retnull ( Pt, (ERR_OUT,"Pt == NULL") ); + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "Header = %4x [H]", Pt->Header )); + msg (( MSG_OUT, "FrameCnt = %4x [H]", Pt->DataLengthRemFrCnt.F.FrameCnt )); + msg (( MSG_OUT, "UsefulDataLengthW30 = %4d [D]", Pt->UsefulDataLengthW30 )); + msg (( MSG_OUT, " - DataLength = %4d [D]", Pt->DataLengthRemFrCnt.F.DataLength )); + msg (( MSG_OUT, " - Rem = %4d [D]", Pt->DataLengthRemFrCnt.F.Rem )); + msg (( MSG_OUT, "Trailer = %4x [H]", Pt->Trailer )); + msg (( MSG_OUT, "=======================================" )); + + if ( (FirstW32 < 0) || (LastW32 < 0) || (LastW32 < FirstW32) ) { + err_retok (( ERR_OUT, "No W32 to print OR bad parameters ? FirstW32=%d - LastW32=%d", FirstW32, LastW32 )); + } + + for ( Vi=FirstW32; Vi <= LastW32; Vi++ ) { + msg (( MSG_OUT, "[W %4d] = %4x [H] - %4d [D]", Vi, Pt->ADataW32[Vi], Pt->ADataW32[Vi] )); + } + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* ------------------------------ */ +/* Specific functions for FSBB0 */ +/* ------------------------------ */ + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FRegDiscriConvBitToW32 ( SInt8* PtSrc, UInt32* PtDest, SInt16 DiscriW32Sz ) { + + + SInt32 ViDiscri; + SInt32 ViDestW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViDestW32=0; ViDestW32 < DiscriW32Sz; ViDestW32++ ) { + + PtDest[ViDestW32] = 0; + VMask = 1; + + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + + if ( PtSrc[ViDiscri] == 1 ) { + PtDest[ViDestW32] = PtDest[ViDestW32] + VMask; + } + + VMask = VMask << 1; + ++ViDiscri; + } + + } + + //err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FRegDiscriConvW32ToBit ( UInt32* PtSrc, SInt8* PtDest, SInt16 DiscriW32Sz ) { + + + SInt32 ViDiscri; + SInt32 ViSrcW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViSrcW32=0; ViSrcW32 < DiscriW32Sz; ViSrcW32++ ) { + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (PtSrc[ViSrcW32] & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + } + + return (0); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FRegDiscriConvW32ToBitAsW32 ( UInt32* PtSrc, SInt32* PtDest, SInt16 DiscriW32Sz ) { + + char VFuncName[] = "FSBB0__FRegDiscriConvW32ToBitAsW32"; + + SInt32 ViDiscri; + SInt32 ViSrcW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViSrcW32=0; ViSrcW32 < DiscriW32Sz; ViSrcW32++ ) { + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (PtSrc[ViSrcW32] & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + } + + return (0); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriConvW32ToBit ( FSBB0__TMatDiscriW32* PtSrc, FSBB0__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + FSBB0__FRegDiscriConvW32ToBit ( PtSrc->AALineW32[ViLine], PtDest->AALineCol[ViLine], FSBB0__REG_DISCRI_W32_SZ ); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 + : 20/05/2014 - MS : replaced 1152 by FSBB0__MAT_DISCRI_COL_NB in the line multiplicator +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriConvW32ToBitAsW32 ( FSBB0__TMatDiscriW32* PtSrc, SInt32* PtDest ) { + + char VFuncName[] = "FSBB0__FMatDiscriConvW32ToBitAsW32"; + + SInt32 ViLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + FSBB0__FRegDiscriConvW32ToBitAsW32 ( PtSrc->AALineW32[ViLine], &PtDest[ViLine * FSBB0__MAT_DISCRI_COL_NB], FSBB0__REG_DISCRI_W32_SZ ); + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FSubMatDiscriBitAsW32Copy ( SInt32* PtSrc, SInt32* PtDest, SInt8 Matrix ) { + + char VFuncName[] = "FSBB0__FSubMatDiscriBitAsW32Copy"; + + SInt32 ViLine; + SInt32 ViCol; + SInt32 ViPixSrc; + SInt32 ViPixDest; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + ViPixDest = 0; + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB / FSBB0__SUB_MAT_NB); ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + ViPixSrc = (ViLine * FSBB0__REG_DISCRI_BIT_SZ) + ViCol; + PtDest[ViPixDest] = PtSrc[ViPixSrc]; + ++ViPixDest; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriEmulHit ( FSBB0__TMatDiscriW32* PtDest, SInt16 HitPattern, SInt16 Hit0Line, SInt16 Hit0Col, SInt16 Hit1Line, SInt16 Hit1Col, SInt16 Hit2Line, SInt16 Hit2Col, SInt16 Hits0AllCol, SInt16 Hits1AllCol, SInt16 Hits2AllCol ) { + + SInt32 ViLine; + SInt32 ViCol; + FSBB0__TMatDiscriBit* PtDestBit; + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + // Reset all hits + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, start" )); + PtDestBit = (FSBB0__TMatDiscriBit*)malloc(sizeof (FSBB0__TMatDiscriBit)); + memset ( PtDestBit, 0, sizeof (FSBB0__TMatDiscriBit) ); + + switch (HitPattern){ + case FSBB0_EMUL_HITS:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_HITS" )); + + // Hit 0 + + if ( (Hit0Line >= 0) && (Hit0Col >= 0) ) { + PtDestBit->AALineCol[Hit0Line][Hit0Col] = 1; + } + + // Hit 1 + + if ( (Hit1Line >= 0) && (Hit1Col >= 0) ) { + PtDestBit->AALineCol[Hit1Line][Hit1Col] = 1; + } + + // Hit 2 + + if ( (Hit2Line >= 0) && (Hit2Col >= 0) ) { + PtDestBit->AALineCol[Hit2Line][Hit2Col] = 1; + } + + // Hits 0 on all lines of one col + + if ( Hits0AllCol >= 0 ) { + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + PtDestBit->AALineCol[ViLine][Hits0AllCol] = 1; + } + } + + // Hits 1 on all lines of one col + + if ( Hits1AllCol >= 0 ) { + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + PtDestBit->AALineCol[ViLine][Hits1AllCol] = 1; + } + } + + // Hits 2 on all lines of one col + + if ( Hits2AllCol >= 0 ) { + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + PtDestBit->AALineCol[ViLine][Hits2AllCol] = 1; + } + } + break; } + case FSBB0_EMUL_ALL_ZERO:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_ALL_ZERO" )); + // doing nothing because the matrix has been resetted + break;} + case FSBB0_EMUL_ALL_ONE:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_ALL_ONE" )); + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + for ( ViCol=0; ViCol < FSBB0__MAT_DISCRI_COL_NB; ViCol++ ) { + PtDestBit->AALineCol[ViLine][ViCol] = 1; + } + } + break;} + case FSBB0_EMUL_CROSS:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_CROSS" )); + ViCol = 0; + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + PtDestBit->AALineCol[ViLine][ViCol] = 1; + PtDestBit->AALineCol[ViLine][FSBB0__MAT_DISCRI_COL_NB - 1- ViCol] = 1; + ViCol++; + } + break;} + case FSBB0_EMUL_BORDER:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_BORDER" )); + // first line and last line + for ( ViCol=0; ViCol < FSBB0__MAT_DISCRI_COL_NB; ViCol++ ) { + PtDestBit->AALineCol[0][ViCol] = 1; + PtDestBit->AALineCol[FSBB0__MAT_DISCRI_USEFUL_LINES_NB - 1][ViCol] = 1; + } + // first col and last col + for ( ViLine=1; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB - 1; ViLine++ ) { + PtDestBit->AALineCol[ViLine][0] = 1; + PtDestBit->AALineCol[ViLine][FSBB0__MAT_DISCRI_COL_NB - 1] = 1; + ViCol++; + } + break;} + } /* end switch */ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, Emulation done in bits" )); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + FSBB0__FRegDiscriConvBitToW32 ( PtDestBit->AALineCol[ViLine], PtDest->AALineW32[ViLine], FSBB0__REG_DISCRI_W32_SZ ); + } + + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, emulation bit converted to W32" )); + + free (PtDestBit); + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FRegDiscriResetHit ( SInt8* PtDest, SInt16 DiscriBitSz ) { + + SInt16 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // Reset row + + for ( ViCol=0; ViCol < DiscriBitSz; ViCol++ ) { + PtDest[ViCol] = 0; + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FRegDiscriPrintHit ( SInt8* PtSrc ) { + + SInt16 ViCol; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + + msg (( MSG_OUT, "*************************************" )); + msg (( MSG_OUT, "* Print coordinates pixels with hit *" )); + msg (( MSG_OUT, "*************************************" )); + + // Scan row => Print coordinates if hit + + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc[ViCol] == 1 ) { + msg (( MSG_OUT, "Hit => Col [%.4d]", ViCol )); + } + + } + + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FRegDiscriCompare ( SInt8* PtSrc, SInt8* PtRef, SInt8 PrintErrors ) { + + SInt16 ViCol; + SInt32 VErrCnt; + + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtRef, (ERR_OUT,"PtRef == NULL") ); + + // Scan row => Print if error + + VErrCnt = 0; + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc[ViCol] != PtRef[ViCol] ) { + + ++VErrCnt; + + if ( PrintErrors ) { + msg (( MSG_OUT, "Error => Col [%.4d] Read=%d - Must be=%d", ViCol, PtSrc[ViCol], PtRef[ViCol] )); + } + + } + + } + + + err_retval ( VErrCnt, ( ERR_OUT, "Compare done %d errors found !", VErrCnt ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriResetHit ( FSBB0__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + // Scan matrix => Reset hits + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 0; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriPrintHit ( char* CmtStrTitle, SInt8 CmtSInt8MapsId, FSBB0__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + msg (( MSG_OUT, "***************************************************************************" )); + msg (( MSG_OUT, "* FSBB M [%d] %s : Coordinates pixels with hit *", CmtSInt8MapsId, CmtStrTitle )); + msg (( MSG_OUT, "***************************************************************************" )); + + // Scan matrix => Print coordinates if hit + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtDest->AALineCol[ViLine][ViCol] == 1 ) { + msg (( MSG_OUT, "Hit => Line [%.4d] - Col [%.4d]", ViLine, ViCol )); + } + + } + + } + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FMatDiscriCumulResetHit ( FSBB0__TMatDiscriCumul* PtDest ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 0; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FMatDiscriCumulAddHit ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriCumul* PtDest ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + ++ PtDest->AALineCol[ViLine][ViCol]; + } + + } + + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FMatDiscriCumulCalcPercent ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 100 * ( (float) PtSrc->AALineCol[ViLine][ViCol] / (float) EvNb); + } + + } + + err_retok (( ERR_OUT, "" )); +} + +// 06/03/2009 +// Return mean % value of whole matrix +// 23/01/2013 +// - Calculates VMatPerCent on the whole matrix, before it was done on 1/4 matrix assuming +// that Ultimate was tested matrix by matrix = threshold set to 255 on the three matrices not tested + +float FSBB0__FExtMatDiscriCumulCalcPercent ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + float VPixPerCent; + float VSumPerCent; + float VMatPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + VSumPerCent = 0; + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + VPixPerCent = ( (float) PtSrc->AALineCol[ViLine][ViCol] / (float) EvNb); + PtDest->AALineCol[ViLine][ViCol] = 100 * VPixPerCent; + VSumPerCent = VSumPerCent + VPixPerCent; + } + + } + + // 23/01/2013 + + VMatPerCent = 100 * ( (float) VSumPerCent / (float) (FSBB0__MAT_DISCRI_COL_NB * FSBB0__MAT_DISCRI_USEFUL_LINES_NB) ); + + err_retval ( VMatPerCent, ( ERR_OUT, "Matrix %d [%]", VMatPerCent ) ); +} + + +// 25/02/2009 + +SInt32 FSBB0__FMatDiscriCumulCountHits ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + SInt32 VHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + VHitCnt = 0; + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + VHitCnt = VHitCnt + PtSrc->AALineCol[ViLine][ViCol]; + PtDest->AALineCol[ViLine][ViCol] = PtSrc->AALineCol[ViLine][ViCol]; + } + + } + + // err_retok (( ERR_OUT, "" )); + + // msg (( MSG_OUT, "VHitCnt = %d", VHitCnt )); + + return (VHitCnt); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriCopySubMatBit ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TSubMatDiscriBit* PtDest, SInt8 SubMatId ) { + + SInt16 ViLine; + SInt16 ViCol; + SInt16 VColOffset; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + switch (SubMatId){ + case 0:{ + VColOffset = 0; + break; } + case 1:{ + VColOffset = FSBB0__REG_DISCRI_BIT_SZ / FSBB0__SUB_MAT_NB; + break; } + default :{ + err_retfail ( -1, (ERR_OUT,"Unknown sub mat id = %d <> 0, 1", SubMatId) ); + break; } + + + }/* end switch */ + + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + + for ( ViCol=0; ViCol <= (FSBB0__REG_DISCRI_BIT_SZ/ FSBB0__SUB_MAT_NB); ViCol++) { + + PtDest->AALineCol[ViLine ][ViCol] = PtSrc->AALineCol[ViLine][ViCol + VColOffset]; + + } /* End for ViCol */ + + + } /* End for ViLine */ + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvBitToColState ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriColor* PtDest, FSBB0__TColor ColorStateZero, FSBB0__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatFullScaleConvCoinBitToColState ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriColor* PtDest, FSBB0__TColor ColorZeroHit, FSBB0__TColor* AColorOneHit, FSBB0__TColor ColorMultiHit, SInt8 RevertLineDirection ) { + + UInt16 VMatLineNb = FSBB0__MAT_DISCRI_USEFUL_LINES_NB; + UInt16 VMatColNb = FSBB0__REG_DISCRI_BIT_SZ; + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPixState; + FSBB0__TColor VPixColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + /* --------------------- */ + /* Revert line direction */ + /* --------------------- */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][VMatColNb - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* --------------------------- */ + /* Don't revert line direction */ + /* --------------------------- */ + + else { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCoinBitToColStateHalfScale ( FSBB0__TMatDiscriBitHalfScale* PtSrc, FSBB0__TMatDiscriColorHalfScale* PtDest, FSBB0__TColor ColorZeroHit, FSBB0__TColor* AColorOneHit, FSBB0__TColor ColorMultiHit, SInt8 RevertLineDirection ) { + + UInt16 VMatLineNb = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + UInt16 VMatColNb = FSBB0__REG_DISCRI_BIT_SZ / 2; + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPixState; + FSBB0__TColor VPixColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + /* --------------------- */ + /* Revert line direction */ + /* --------------------- */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][VMatColNb - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* --------------------------- */ + /* Don't revert line direction */ + /* --------------------------- */ + + else { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvBitToColStateHalfScale ( FSBB0__TMatDiscriBitHalfScale* PtSrc, FSBB0__TMatDiscriColorHalfScale* PtDest, FSBB0__TColor ColorStateZero, FSBB0__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + SInt32 VMaxCol; + SInt32 VMaxLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + VMaxCol = FSBB0__REG_DISCRI_BIT_SZ / 2; + VMaxLine = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMaxLine; ViLine++ ) { + + for ( ViCol=0; ViCol < VMaxCol; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][VMaxCol - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][VMaxCol - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < VMaxLine; ViLine++ ) { + + for ( ViCol=0; ViCol < VMaxCol; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriSubMatConvBitToColState ( FSBB0__TSubMatDiscriBit* PtSrc, FSBB0__TSubMatDiscriColor* PtDest, FSBB0__TColor ColorStateZero, FSBB0__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB ); ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / FSBB0__SUB_MAT_NB) ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ ) - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ ) - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB); ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / FSBB0__SUB_MAT_NB) ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriCopySubMatPerCent ( FSBB0__TMatDiscriPerCent* PtSrc, FSBB0__TSubMatDiscriPerCent* PtDest, SInt8 SubMatId ) { + + SInt16 ViLine; + SInt16 ViCol; + SInt16 VColOffset; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + switch (SubMatId){ + case 0:{ + VColOffset = 0; + break; } + case 1:{ + VColOffset = FSBB0__REG_DISCRI_BIT_SZ / FSBB0__SUB_MAT_NB; + break; } + default :{ + err_retfail ( -1, (ERR_OUT,"Unknown sub mat id = %d <> 0, 1", SubMatId) ); + break; } + + + }/* end switch */ + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB); ViLine++ ) { + + for ( ViCol=0; ViCol <= (FSBB0__REG_DISCRI_BIT_SZ/ FSBB0__SUB_MAT_NB); ViCol++) { + + PtDest->AALineCol[ViLine ][ViCol] = PtSrc->AALineCol[ViLine][ViCol + VColOffset]; + + } /* End for ViColSrc */ + + + } /* End for ViLine */ + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvPerCentToColVal ( FSBB0__TMatDiscriPerCent* PtSrc, FSBB0__TMatDiscriColor* PtDest, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCumulToColVal ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriColor* PtDest, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + FSBB0__TColor VHitStateColor; + FSBB0__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + if ( GrayOrBlueLevels == 0) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ) - 1 - ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCumulToColValHalfScale ( FSBB0__TMatDiscriCumulHalfScale* PtSrc, FSBB0__TMatDiscriColorHalfScale* PtDest, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection, SInt8 PrintLvl ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + FSBB0__TColor VHitStateColor; + FSBB0__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "==============================================" )); + err_error (( ERR_OUT, "= FSBB0__FDiscriMatConvCumulToColValHalfScale =" )); + err_error (( ERR_OUT, "==============================================" )); + } + + + if ( GrayOrBlueLevels == 0) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + err_error (( ERR_OUT, "Blue=%d - HitCnt=%d", GrayOrBlueLevels, PlotHitOrHitCnt )); + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ / 2) - 1 - ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FFFF00 + ( (255-VPixHitCnt) << 8 ); // Blue = 255 / Green = 255 / Red = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + err_error (( ERR_OUT, "==============================================" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCumulCoinOrToColVal ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriColor* PtDest, FSBB0__TColor* AColorOneHit, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + FSBB0__TColor VPixColor; + FSBB0__TColor VHitStateColor; + FSBB0__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( GrayOrBlueLevels == 0 ) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCumulCoinOrToColValHalfScale ( FSBB0__TMatDiscriCumulHalfScale* PtSrc, FSBB0__TMatDiscriColorHalfScale* PtDest, FSBB0__TColor* AColorOneHit, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection, SInt8 PrintLvl ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + FSBB0__TColor VPixColor; + FSBB0__TColor VHitStateColor; + FSBB0__TColor VHitColor; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "====================================================" )); + err_error (( ERR_OUT, "= FSBB0__FDiscriMatConvCumulCoinOrToColValHalfScale =" )); + err_error (( ERR_OUT, "====================================================" )); + } + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ / 2) - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + err_error (( ERR_OUT, "==============================================" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FPrintMatDiscriCumul ( FSBB0__TMatDiscriCumul* PtSrc ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + + err_error (( ERR_OUT, "===============================" )); + err_error (( ERR_OUT, "= Print FSBB0__TMatDiscriCumul =" )); + err_error (( ERR_OUT, "===============================" )); + + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] != 0 ) { + err_error (( ERR_OUT, "Hit cnt [L:%4d][C:%4d] = %4d", ViLine, ViCol, PtSrc->AALineCol[ViLine][ViCol] )); + } + + } + + } + + err_error (( ERR_OUT, "===============================" )); + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FPrintMatDiscriCumulHalfScale ( FSBB0__TMatDiscriCumulHalfScale* PtSrc ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + + err_error (( ERR_OUT, "========================================" )); + err_error (( ERR_OUT, "= Print FSBB0__TMatDiscriCumulHalfScale =" )); + err_error (( ERR_OUT, "========================================" )); + + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ / 2; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] != 0 ) { + err_error (( ERR_OUT, "Hit cnt [L:%4d][C:%4d] = %4d", ViLine, ViCol, PtSrc->AALineCol[ViLine][ViCol] )); + } + + } + + } + + err_error (( ERR_OUT, "========================================" )); + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriSubMatConvCumulToColVal ( FSBB0__TSubMatDiscriPerCent* PtSrc, FSBB0__TSubMatDiscriColor* PtDest, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB ); ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ/ FSBB0__SUB_MAT_NB ); ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ ) - 1 - ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ ) - 1 - ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB); ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / FSBB0__SUB_MAT_NB ); ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][ViCol] = (VPerCent << 8) + (VPerCent << 16);; + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : convert 32 word of 8 bits to a word of 32 bits +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Mathieu GOFFE +E-mail : mathieu.goffe@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef FSBB0__MG_DEV + +SInt32 FSBB0__FnameDiscriConvBitToW32 ( UInt8* PtDest, UInt32 word ) { + + + SInt32 ViDiscri; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( word, (ERR_OUT,"word == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (word & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + msg (( MSG_OUT, "valeur du mot de 32 bit = %d", word )); + return (0); +} + +#else + +SInt32 FSBB0__FnameDiscriConvBitToW32 ( UInt8* PtDest, UInt32 word ) { + return (0); +} + +#endif + + + + + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 17/03/2009 +Doc date : 17/03/2009 +Rev : 04/05/2009 + : - Add a check of data length, if > 1140, force 1140, done to avoid bad + : data length due to transmission errors. + : + : 05/05/2009 + : - Add handling of odd number of W16 ( FSBB0 add one bad W16 in this case ) + : Not done at beginning because FSBB0 documentation was not clear enough + : ( bad translation of " impair " in even ! ) and it was not needed for + : tests done with emulated patterns. + : : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameRawToZsFFrame ( FSBB0__TZsFFrameRaw* Src, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) { + + SInt32 VRetW30Length; + SInt32 ViData; + UInt16 VDataW30Length; + UInt16 VLastW30; + SInt16 ViSrcW30; + + FSBB0__TStatesLine VStatesLine; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbG0; + SInt8 VStatesNbG1; + SInt16 VPrevLine; + SInt8 VG0Overflow; + SInt8 VG1Overflow; + + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Get useful data length + VDataW30Length = Src->UsefulDataLengthW30; + + VRetW30Length = VDataW30Length; + + if ( (PrintLvl == 5) || (PrintLvl == 6) || (PrintLvl == 7)/*||(PrintLvl == 8)*/ ) { + msg (( MSG_OUT, "TOTAL frame length : %d W30", VDataW30Length )); + msg (( MSG_OUT, "" )); + } + + // Add a check of data length, if > FSBB0__ZS_FFRAME_RAW_MAX_W30, force 0 and continue processing ( no exit on error ) + + if ( VDataW30Length > FSBB0__ZS_FFRAME_RAW_MAX_W32 /* 1140 */ ) { + err_error (( ERR_OUT, "Bad data length get from FSBB0 = %d W30 => Force 0 W30", VDataW30Length )); + VDataW30Length = 0; + Src->UsefulDataLengthW30 = 0; + VRetW30Length = -1; + } + + // Copy information fields + + Dest->SStatus = Src->SStatus; + + Dest->Header = Src->Header; + Dest->FrameCnt = Src->DataLengthRemFrCnt.F.FrameCnt; + Dest->DataLength = Src->UsefulDataLengthW30; + Dest->Trailer = Src->Trailer; +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + Dest->TrigSignalLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; + Dest->TrigSignalClk = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__LINE]; +//#endif + + // Process frame + + ViSrcW30 = 0; + ViStatesLine = 0; + VPrevLine = -1; + + if ( PrintLvl == 4 ) { + msg (( MSG_OUT, "Frame data length = %d [W30]", VDataW30Length )); + msg (( MSG_OUT, "" )); + } + +//#ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + + if ( VDataW30Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W30 nb handling ! + // + // It can seem strange that this can be done by processing one W30 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W30 number is odd, FSBB0 add one more bad W30 to get an even W30 number. + // This bad W30 will be seen as a StatesLine field followed by NO state because it is the last W30. + // Therefore if at the beginning of the while loop there is only one W30 to process, this W30 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W30 at the beginning of loop is the index of last W30 this W30 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W30 number, after processing of last + // state of last line the index of W30 equal W30 number, therefore is > of index of last W30, and + // we don't enter the loop. + + //VLastW30 = VDataW30Length - 1; + + while ( ViSrcW30 < VDataW30Length ) { // Odd W30 nb handling => Don't process last W30 + + // Copy StatesLine field + VStatesLine.W32 = Src->ADataW32[ViSrcW30]; + Dest->AStatesRec[ViStatesLine].StatesLine = VStatesLine; + VG0Overflow = 0; + VG1Overflow = 0; + + VStatesNbG0 = FSBB0_FHammingDecoder8_4(VStatesLine.F.HitNbG0); + VStatesNbG1 = FSBB0_FHammingDecoder8_4(VStatesLine.F.HitNbG1); + //msg (( MSG_OUT, " ViStatesLine :%d :VStatesLine.F.HitNbG0 : %X - VStatesNbG0 : %x - VStatesLine.F.HitNbG1 : %X - VStatesNbG1 : %x ", ViStatesLine, VStatesLine.F.HitNbG0,VStatesNbG0,VStatesLine.F.HitNbG1,VStatesNbG1 )); + + Dest->AStatesRec[ViStatesLine].NbWinG0 = VStatesNbG0; + Dest->AStatesRec[ViStatesLine].NbWinG1 = VStatesNbG1; + Dest->AStatesRec[ViStatesLine].NbWinTot = VStatesNbG0 + VStatesNbG1; + + if (VStatesNbG0 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ){ + VG0Overflow =VStatesNbG0; + VStatesNbG0 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + } + if (VStatesNbG1 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ){ + VG1Overflow =VStatesNbG1; + VStatesNbG1 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + } + // VStatesNbPerLine = VStatesLine.F.StateNb; + + + if ( (PrintLvl == 5) || (PrintLvl == 7) ) { + msg (( MSG_OUT, " ViStatesLine :%d :VStatesLine.W32 : %X - NbWinG0 : %d - NbWinG1 : %d ", ViStatesLine, VStatesLine.W32,Dest->AStatesRec[ViStatesLine].NbWinG0,Dest->AStatesRec[ViStatesLine].NbWinG1 )); + + //msg (( MSG_OUT, "NbWinG0 : %4d - NbWinG1 : %d - NbWinTot : %d ", Dest->AStatesRec[ViStatesLine].NbWinG0, Dest->AStatesRec[ViStatesLine].NbWinG1,Dest->AStatesRec[ViStatesLine].NbWinTot )); + + msg (( MSG_OUT, "Line %4d - %d HitNbG0 (Ovf:%d) - %d HitNbG1 (Ovf:%d)", VStatesLine.F.SLineAddr, VStatesNbG0, VG0Overflow,VStatesNbG1,VG1Overflow )); + + /* Print to show missing handling of odd W30 nb + + if ( VStatesLine.F.LineAddr <= VPrevLine ) { + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ===============> ERROR odd W30 nb NOT HANDLED ! ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + } + + else { + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + VPrevLine = VStatesLine.F.LineAddr; + } + + */ + + } + + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + + // Copy states G1 + if (VStatesNbG1 > 0){ + for ( ViState=0; ViState < VStatesNbG1; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].W32 = Src->ADataW32[ViSrcW30]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "-->G1: State %d : Delta : %d - Col %4d - %X pixels", ViState, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Delta , Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code )); + if ( (PrintLvl == 8)&&(((Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code)& 0xFFFFF) == 0)&&(ViSrcW30 < VDataW30Length) ) { + msg (( MSG_OUT, " G1 : Frame :%d ,Word : %d of %d, SLineAddr :%d : Window word : %X - Code = 0, %d state out of %d ", Dest->FrameCnt, ViSrcW30,VDataW30Length, VStatesLine.F.SLineAddr, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].W32,ViState ,VStatesNbG0 )); + } + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + } + } + // Copy states G0 + + if (VStatesNbG0 > 0){ + for ( ViState=0; ViState < VStatesNbG0; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].W32 = Src->ADataW32[ViSrcW30]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "-->G0: State %d : Delta : %d - Col %4d - %X pixels", ViState, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Delta , Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code )); + if ( (PrintLvl == 8)&&(((Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code)& 0xFFFFF) == 0)&&(ViSrcW30 < VDataW30Length) ) { + msg (( MSG_OUT, " G0 : Frame :%d ,Word : %d out of %d, SLineAddr :%d : Window word : %X - Code = 0, %d state out of %d ", Dest->FrameCnt, ViSrcW30,VDataW30Length, VStatesLine.F.SLineAddr, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].W32,ViState ,VStatesNbG0 )); + } + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + } + } + + ++ViStatesLine; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + + // Add on 25/03/2011 during test with random frame size + with all data = 0 + + if ( ViStatesLine >= FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "Max number of states reached = %d => Abort => Corrupted data !", FSBB0__ZS_FFRAME_MAX_STATES_REC )); + break; + } + + } // End while + + } // End if ( VDataW30Length != 0 ) + + Dest->StatesRecNb = ViStatesLine; + +//#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + if ( (PrintLvl == 5)/* || (PrintLvl == 6)*/|| (PrintLvl == 7) /*|| (PrintLvl == 8)*/ ) { + msg (( MSG_OUT, "Conv : %d StatesLines", Dest->StatesRecNb )); + msg (( MSG_OUT, "" )); + } + + return (VRetW30Length); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 14/08/2009 +Doc date : +: +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameRawToZsFFrameHandleTrigger ( SInt8 MapsNb, SInt32 EvNo, SInt32 TotEvNb, FSBB0__TZsFFrameRaw* Src, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) { + + FSBB0__TZsFFrameRaw* VPtSrcEv; + SInt32 VTrigPosFromDaq; + SInt32 VTrigLine; + SInt8 VFirstEvent; + static FSBB0__TZsFFrame VASrcZsFFrameEv[2]; + SInt32 VLine; + SInt32 ViSrcStateRec; + SInt32 ViDestStateRec; + + // Check parameters + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Four events after this one are required => Abort if it's not the case + + if ( EvNo + 4 >= TotEvNb ) { + err_retfail ( -1, (ERR_OUT,"Processing stop on event %d => Less than 4 events after it !" ,EvNo) ); + } + + + // Trigger position ? +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VTrigPosFromDaq = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; +//#endif + + + if ( (VTrigPosFromDaq < 0) || (VTrigPosFromDaq > 575) ) { + err_retfail ( -1, (ERR_OUT,"Bad trigger pos from DAQ = %d <> [0..575] !", VTrigPosFromDaq) ); + } + + + // Set VPtEv on the first event to process + // - Pos < 572 => Pos correspond to current event + 1 ( next event ) + // - Pos >= 572 => Pos correspond to current event + 2 + +/* ORIGINAL => 1 plane + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 1; + } + + else { + VPtSrcEv = Src + 2; + } + +*/ + +/* 6 planes + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 7; + } + + else { + VPtSrcEv = Src + 8; + } + +*/ + + // N planes + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 1 + MapsNb; + } + + else { + VPtSrcEv = Src + 2 + MapsNb; + } + + + // Real trigger line = trigger position + 4 modulo 576 + + VTrigLine = (VTrigPosFromDaq + 4) % 576; + + // Debug print + + if ( PrintLvl == 1 ) { + // msg (( MSG_OUT, "=> Trig on Ev=%4d P=%4d L=%4d => Proc Ev=%4d - Ev=%4d", EvNo, VTrigPosFromDaq, VTrigLine, VPtSrcEv[0].SStatus.FrameNoInRun, VPtSrcEv[1].SStatus.FrameNoInRun )); + err_error (( ERR_OUT, "=> Trig on Ev=%4d - P=%4d - L=%4d => Proc Ev=%4d - Ev=%4d", EvNo, VTrigPosFromDaq, VTrigLine, VPtSrcEv[0].SStatus.FrameNoInRun, VPtSrcEv[1].SStatus.FrameNoInRun )); + } + + // Convert each event from ZsFFrameRaw to ZsFFrame + + FSBB0__FConvZsFFrameRawToZsFFrame ( VPtSrcEv , VASrcZsFFrameEv , 0 /* PrintLvl */ ); + FSBB0__FConvZsFFrameRawToZsFFrame ( VPtSrcEv + 1, VASrcZsFFrameEv + 1, 0 /* PrintLvl */ ); + + // ------------------------- + // Build destination event + // ------------------------- + + // Reset record + + memset ( Dest, 0, sizeof (FSBB0__TZsFFrame) ); + + // Copy information fields + + Dest->SStatus = Src->SStatus; + + Dest->Header = Src->Header; + Dest->FrameCnt = Src->DataLengthRemFrCnt.F.FrameCnt; + Dest->DataLength = Src->UsefulDataLengthW30; + Dest->Trailer = Src->Trailer; + //Dest->Zero = Src->Zero; + //Dest->Zero2 = Src->Zero2; +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + Dest->TrigSignalLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; + Dest->TrigSignalClk = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__LINE]; +//#endif + + // Extract lines + + ViDestStateRec = 0; + + // First event => Copy lines >= trigger pos to dest + + for ( ViSrcStateRec=0; ViSrcStateRec < VASrcZsFFrameEv->StatesRecNb; ViSrcStateRec++ ) { + + VLine = VASrcZsFFrameEv->AStatesRec[ViSrcStateRec].StatesLine.F.SLineAddr; + + if ( VLine >= VTrigLine ) { + Dest->AStatesRec[ViDestStateRec] = VASrcZsFFrameEv->AStatesRec[ViSrcStateRec]; + ++ViDestStateRec; + } + + } + + if ( VTrigLine == 0 ) { + Dest->StatesRecNb = ViDestStateRec; + return (0); + } + + // Second event => Copy lines < trigger pos to dest + + for ( ViSrcStateRec=0; ViSrcStateRec < VASrcZsFFrameEv[1].StatesRecNb; ViSrcStateRec++ ) { + + VLine = VASrcZsFFrameEv[1].AStatesRec[ViSrcStateRec].StatesLine.F.SLineAddr; + + if ( VLine < VTrigLine ) { + Dest->AStatesRec[ViDestStateRec] = VASrcZsFFrameEv[1].AStatesRec[ViSrcStateRec]; + ++ViDestStateRec; + } + + } + + // Update nb of StateRec + + Dest->StatesRecNb = ViDestStateRec; + + return (0); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 17/03/2009 +Rev : 22/07/2009 + : - Return number of hits found +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameToMatDiscriBit ( FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDest, SInt32* PtOvfCnt, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 ViFirstLine; + SInt16 ViTopLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesLine; + SInt16 ViState; + SInt16 VStatesNbG0; + SInt16 VStatesNbG1; + SInt32 VHitCnt; + SInt32 VOfvCnt; + SInt32 VMask; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (FSBB0__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + // StatesRec loop + + VHitCnt = 0; + VOfvCnt = 0; + + if ( PtSrc->StatesRecNb > FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + err_error (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + PtSrc->StatesRecNb = FSBB0__ZS_FFRAME_MAX_STATES_REC; + } + + +//#ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + if (PtSrc->StatesRecNb > 0){ + + for ( ViStatesLine=0; ViStatesLine < PtSrc->StatesRecNb; ViStatesLine++ ) { + + VStatesNbG0 = PtSrc->AStatesRec[ViStatesLine].NbWinG0; + VStatesNbG1 = PtSrc->AStatesRec[ViStatesLine].NbWinG1; + ViTopLine = ((PtSrc->AStatesRec[ViStatesLine].StatesLine.F.SLineAddr + 1) * 4) - 1 ; + + //msg (( MSG_OUT, " ViStatesLine :%d :ViTopLine : %d - VStatesNbG0 : %d - VStatesNbG1 : %d ", ViStatesLine, ViTopLine,VStatesNbG0,VStatesNbG1 )); + + + /*if (( PtSrc->AStatesRec[ViStatesLine].StatesLine.F.HitNbG0 > 9 )||( PtSrc->AStatesRec[ViStatesLine].StatesLine.F.HitNbG1 > 9 )) { + ++VOfvCnt; + // err_error (( ERR_OUT, "Ovf ! Count=%d", VOfvCnt )); + }*/ + // States in one StateRec loop + + // WARNING => Will slow down execution + + if ( VStatesNbG0 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNbG0, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP )); + VStatesNbG0 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + ++VOfvCnt; + } + if ( VStatesNbG1 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNbG1, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP )); + VStatesNbG1 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + ++VOfvCnt; + } + + // WARNING => Will slow down execution + + if ( ViTopLine >= FSBB0__MAT_DISCRI_LINES_NB) { + err_warning (( ERR_OUT, "ViTopLine=%d >= FSBB0__MAT_DISCRI_LINES_NB=%d => Force %d", ViTopLine, FSBB0__MAT_DISCRI_LINES_NB, FSBB0__MAT_DISCRI_LINES_NB - 1 )); + ViTopLine = FSBB0__MAT_DISCRI_LINES_NB - 1; + } + // Decode Hits for Group 1 + if ( VStatesNbG1 > 0 ){ + for ( ViState = 0; ViState < VStatesNbG1; ViState++ ) { + + VFirstCol = (PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.ColAddr) + 224; + // WARNING => Will slow down execution + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + + + // Hits in one State loop + ViFirstLine = ViTopLine - (PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Delta); + VMask = 0x80000; + for (ViLine = ViFirstLine; ViLine > (ViFirstLine - 4); ViLine-- ){ + if (ViLine < 0){ + break; + } + for ( ViCol = VFirstCol; ViCol > VFirstCol - 5; ViCol-- ) { + if (ViCol < 0){ + break; + } + if ( ((PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code) & VMask) != 0){ + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + // 01/08/2014 - MS : removed the printing of the decoding of the data words + /* + if (PrintLvl ==7){ + msg (( MSG_OUT, " G1 : ViStatesLine :%d :ViTopLine : %d : ViState:%d - Hit Line : %d - Col : %d , VMask :0x%X ", ViStatesLine, ViTopLine,ViState, ViLine,ViCol,VMask )); + }*/ + } + else{ + PtDest->AALineCol[ViLine][ViCol] = 0; + + } + VMask = VMask >> 1; + + } // End For ViCol + } // End For ViLine + + } // End States in one StateRec loop for G1 + } /* end decoding groups for G1 */ + + // Decode Hits for Group 0 + if ( VStatesNbG0 > 0 ){ + for ( ViState=0; ViState < VStatesNbG0; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.ColAddr ; + //VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + // WARNING => Will slow down execution + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + + // Hits in one State loop + ViFirstLine = ViTopLine - (PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Delta); + VMask = 0x80000; + for (ViLine = ViFirstLine; ViLine > ViFirstLine - 4; ViLine-- ){ + if (ViLine < 0){ + break; + } + for ( ViCol=VFirstCol; ViCol > VFirstCol - 5; ViCol-- ) { + if (ViCol < 0){ + break; + } + //msg (( MSG_OUT, " ViStatesLine :%d :ViLine : %d - ViCol : %d - PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code : %d ", ViStatesLine, ViLine,ViCol,PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code )); + if ( (PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code & VMask) != 0){ + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + // 01/08/2014 - MS : removed the printing of the decoding of the data words + /* + if (PrintLvl ==7){ + msg (( MSG_OUT, " G0 : ViStatesLine :%d :ViTopLine : %d : ViState:%d - Hit Line : %d - Col : %d , VMask :0x%x ", ViStatesLine, ViTopLine,ViState, ViLine,ViCol,VMask )); + }*/ + } + VMask = VMask >> 1; + + } // End For ViCol + } // End For ViLine + + } // End States in one StateRec loop for G0 + } /* end decoding groups for G0 */ + } // End StatesRec loop + } /* end if (PtSrc->StatesRecNb > 0)*/ + +//#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + if ( PtOvfCnt != NULL ) { + *PtOvfCnt = VOfvCnt; + } + + + // err_error (( ERR_OUT, "TRACE - VHitCnt=%d", VHitCnt )); // 13/02/2013 + + + return (VHitCnt); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : If UpdMatCumul = 0 +: - Don't update cumul matrix +: - BUT count hits => function return Hit nb +Level : +Date : 17/03/2009 +Rev : 22/07/2009 +: - Return number of hits found +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 OLD___FSBB0__FConvZsFFrameToMatDiscriBitAndCumul ( FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDest, SInt8 UpdMatCumul, FSBB0__TMatDiscriCumul* PtDestCum, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesRec; + SInt8 ViState; + SInt8 VStatesNb; + SInt32 VHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + if ( UpdMatCumul ) { + err_retnull ( PtDestCum, (ERR_OUT,"PtDestCum == NULL") ); + } + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (FSBB0__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "---------------------------------" )); + err_error (( ERR_OUT, " Print cumul" )); + err_error (( ERR_OUT, "---------------------------------" )); + } + + + +#ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + // StatesRec loop + + VHitCnt = 0; + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + PtDest->AALineCol[ViLine][ViCol] = 1; + + if ( UpdMatCumul ) { + ++ PtDestCum->AALineCol[ViLine][ViCol]; + + if ( PrintLvl ) { + err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, ViCol, PtDestCum->AALineCol[ViLine][ViCol] )); + } + + } + + ++VHitCnt; + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + +#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "-------------------------------" )); + } + + + + return (VHitCnt); +} + + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : - PtDestFrameBit -> Bit matrix of source frame + : - PtDestCoinBit -> Coin matrix of ONE frame of ALL selected planes + : - PtDestFrameCum -> Cumul matrix of ALL frames of CURRENT plane + : - PtDestCoinCum -> Cumul matrix of ALL frames of ALL selected planes + : +Globals : +Remark : This function is written in a strange way ... code duplication and + : something which looks like a " goto ". This is to avoid to have + : tests excuted in loop and therefore save execution time. + : + : + : +Level : +Date : 17/03/2009 +Rev : 22/07/2009 + : - Return number of hits found + : 25/07/2009 + : - Add Mode parameter => Handling of coincidence modes + : 02/08/2009 + : - Moved in class FSBB0__TCTelMon +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef ROOT_ROOT + +SInt32 FSBB0__TCTelMon::PrivFConvZsFFrameToMatDiscriBitAndCumul ( SInt32 DbgEvNo, SInt8 Mode, SInt8 PlaneNo, SInt8 PlaneSelForCoin, SInt8 EvNo, SInt8 EvSelForPlot, FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDestFrameBit, FSBB0__TMatDiscriBit* PtDestCoinBit, FSBB0__TMatDiscriCumul* PtDestFrameCum, FSBB0__TMatDiscriCumul* PtDestCoinCum, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesRec; + SInt8 ViState; + SInt8 VStatesNb; + SInt32 VHitCnt; + SInt8 VPlaneNoP1; + SInt8 VFlagRevertColDir; + SInt16 VDirRevCol; + SInt32 VEvNoInRun; + + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDestFrameBit, (ERR_OUT,"PtDestFrameBit == NULL") ); + err_retnull ( PtDestCoinBit , (ERR_OUT,"PtDestCoinBit == NULL") ); + err_retnull ( PtDestFrameCum, (ERR_OUT,"PtDestFrameCum == NULL") ); + err_retnull ( PtDestCoinCum , (ERR_OUT,"PtDestCoinCum == NULL") ); + + // Init intermediate variables + + // --------------------------------------------------------------- + // Revert or not X Dir ( columns ) depending of plane parameters + // --------------------------------------------------------------- + + VFlagRevertColDir = ProAPlanePar[PlaneNo].RevertXDir; + + VPlaneNoP1 = PlaneNo + 1; + + VEvNoInRun = PtSrc->SStatus.FrameNoInRun; + + // -------------------------------------------- + // Reset frame bit destination matrix + // -------------------------------------------- + + memset ( PtDestFrameBit, 0, sizeof (FSBB0__TMatDiscriBit) ); + + + +#ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + + VHitCnt = 0; + + while (1) { + + //--------------------------------------------------------------- + // Cumul all frames + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL ) { + + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++PtDestFrameCum->AALineCol[ViLine][VDirRevCol]; + + // err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, VDirRevCol, PtDestFrameCum->AALineCol[ViLine][VDirRevCol] )); + + ++VHitCnt; + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + + } // End MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL + + //--------------------------------------------------------------- + // Plot coincidence of selected planeS of ONE frame ( 6 colors ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS ) { + + if ( (PlaneSelForCoin == 1) && (EvNo == EvSelForPlot) ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++VHitCnt; + + while (1) { + + // If no hit from other plane => Set Plane Id + 1 (1..6) + + if ( PtDestCoinBit->AALineCol[ViLine][VDirRevCol] == 0 ) { + PtDestCoinBit->AALineCol[ViLine][VDirRevCol] = VPlaneNoP1; + break; + } + + // If already ONE hit from other plane => Set Base + hit count = 10 + 2 = 12 + + if ( PtDestCoinBit->AALineCol[ViLine][VDirRevCol] <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + PtDestCoinBit->AALineCol[ViLine][VDirRevCol] = 12; + break; + } + + // If already > ONE hit from other plane => Increment ( Rq : Hit count = value - 10 ) + + ++PtDestCoinBit->AALineCol[ViLine][VDirRevCol]; + break; + + } // End while (1) + + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + + //--------------------------------------------------------------- + // Plot coincidence cumul of selected planeS of all frames ( 1 color ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR ) { + + if ( PlaneSelForCoin ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++PtDestFrameCum->AALineCol[ViLine][VDirRevCol]; // Not useful => But keep processing of per plane cumul + // err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, VDirRevCol, PtDestFrameCum->AALineCol[ViLine][VDirRevCol] )); + ++VHitCnt; + ++PtDestCoinCum->AALineCol[ViLine][VDirRevCol]; + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + + //--------------------------------------------------------------- + // Plot coincidence cumul of selected planes of all frames ( 6 colors ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) { + + if ( PlaneSelForCoin ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++VHitCnt; + + // Res run update + + // err_error (( ERR_OUT, "ProcOnlyFrWithHitOnAllPlanes = %d", ProPar.ProcOnlyFrWithHitOnAllPlanes )); + + if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) && (PrivPtResRun != NULL) ) { + + if ( PrivPtResRun->EvNb < MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB) { + + SInt32 VBHitIndex = PrivPtResRun->ATracks[PrivPtResRun->EvNb].AHitsNbPerPlane[PlaneNo]; + + err_error (( ERR_OUT, "TRACE : Coin - Ev %4d - Fr %4d - Plane %d - StatesNb %d", DbgEvNo, PtSrc->FrameCnt, PlaneNo, VStatesNb )); + + if ( VBHitIndex < MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE ) { + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AAHits[PlaneNo][VBHitIndex].x = VDirRevCol; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AAHits[PlaneNo][VBHitIndex].y = ViLine; + ++VBHitIndex; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AHitsNbPerPlane[PlaneNo] = VBHitIndex; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].EvNoInRun = VEvNoInRun; + } + + + } + + else { + PrivPtResRun->Full = 1; + } + + } + + + // Res run update END + + while (1) { + + // If no hit from other plane => Set Plane Id + 1 (1..6) + + if ( (PtDestCoinCum->AALineCol[ViLine][VDirRevCol] == 0) || (PtDestCoinCum->AALineCol[ViLine][VDirRevCol] == VPlaneNoP1) ) { + PtDestCoinCum->AALineCol[ViLine][VDirRevCol] = VPlaneNoP1; + break; + } + + // If already ONE hit from other plane / other frame => Set Base + hit count = 10 + 2 = 12 + + if ( PtDestCoinCum->AALineCol[ViLine][VDirRevCol] <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + PtDestCoinCum->AALineCol[ViLine][VDirRevCol] = 12; + break; + } + + // If already > ONE hit from other plane / other frame => Increment ( Rq : Hit count = value - 10 ) + + ++PtDestCoinCum->AALineCol[ViLine][VDirRevCol]; + break; + + } // End while (1) + + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + + // If this is last plane selected for coincidence => Update Res run event counter + // Rq : If no plane is selected for coin => ProInf.LastPlaneSelForCoin == -1 therefore above condition is never true + + if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) && (PrivPtResRun != NULL) && (PlaneNo == ProInf.LastPlaneSelForCoin) ) { + ++PrivPtResRun->EvNb; + err_error (( ERR_OUT, "TRACE : Inc Res Run EvNb done => EvNb=%4d - EvNo=%4d - PlaneNo=%d", PrivPtResRun->EvNb, DbgEvNo, PlaneNo )); + } + + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + + + //--------------------------------------------------------------- + // Plot only frame + //--------------------------------------------------------------- + // MUST BE LAST ONE OF While (1) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + + + if (EvNo == EvSelForPlot) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + } + + ++VHitCnt; + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME + + + } // End while (1) + + +#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + if ( PrintLvl ) { + err_error (( ERR_OUT, "-------------------------------" )); + } + + + + return (VHitCnt); +} + + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 23/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvMatDiscriBitToMatDiscriBitHalfScale ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriBitHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = FSBB0__REG_DISCRI_BIT_SZ / 2; + VyDestMax = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] || PtSrc->AALineCol[V2yDest][V2xDestP1] || PtSrc->AALineCol[V2yDestP1][V2xDest] || PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 26/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvMatDiscriBitCoinToMatDiscriBitCoinHalfScale ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriBitHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + UInt8 VPixState0; + UInt8 VPixState1; + UInt8 VPixState2; + UInt8 VPixState3; + + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = FSBB0__REG_DISCRI_BIT_SZ / 2; + VyDestMax = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + VPixState0 = (PtSrc->AALineCol[V2yDest ][V2xDest ] != 0); + VPixState1 = (PtSrc->AALineCol[V2yDest ][V2xDestP1] != 0); + VPixState2 = (PtSrc->AALineCol[V2yDestP1][V2xDest ] != 0); + VPixState3 = (PtSrc->AALineCol[V2yDestP1][V2xDestP1] != 0); + + + while (1) { + + // If no pixel at 1 => set 0 + + if ( (VPixState0 | VPixState1 | VPixState2 | VPixState3) == 0 ) { + PtDest->AALineCol[VyDest][VxDest] = 0; + break; + } + + // If one pixel at 1 and ONLY one => Make or of values = or of PlaneID + 1 + + if ( (VPixState0 ^ VPixState1 ^ VPixState2 ^ VPixState3) == 1 ) { + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] | PtSrc->AALineCol[V2yDest][V2xDestP1] | PtSrc->AALineCol[V2yDestP1][V2xDest] | PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + break; + } + + // If more than one pixel at 1 => Base + Sum pixels states = 10 + Sum + + PtDest->AALineCol[VyDest][VxDest] = 10 + (VPixState0 + VPixState1 + VPixState2 + VPixState3); + break; + + } // End while (1) + + } // End for ( VxDest ... ) + + } // End for ( VyDest ... ) + + err_retok (( ERR_OUT, "" )); +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 23/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvMatDiscriCumToMatDiscriCumHalfScale ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriCumulHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = FSBB0__REG_DISCRI_BIT_SZ / 2; + VyDestMax = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] + PtSrc->AALineCol[V2yDest][V2xDestP1] + PtSrc->AALineCol[V2yDestP1][V2xDest] + PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 30/04/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FBuildMatDiscriW32FromLinePatReg ( FSBB0__TRegDiscriW32* PtLinePatReg0, FSBB0__TRegDiscriW32* PtLinePatReg1, FSBB0__TMatDiscriW32* PtDest ) { + + SInt16 ViLine; + + err_retnull ( PtLinePatReg0, (ERR_OUT,"PtLinePatReg0 == NULL !") ); + err_retnull ( PtLinePatReg1, (ERR_OUT,"PtLinePatReg1 == NULL !") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL !") ); + + ViLine= 0; + + do { + + memcpy ( PtDest->AALineW32[ViLine], PtLinePatReg0, FSBB0__REG_DISCRI_W32_SZ * 4 ); + ++ViLine; + memcpy ( PtDest->AALineW32[ViLine], PtLinePatReg1, FSBB0__REG_DISCRI_W32_SZ * 4 ); + ++ViLine; + + } while ( ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/05/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FCompareMatDiscriBit ( SInt16 LineNbToCompare, FSBB0__TMatDiscriBit* PtMat, FSBB0__TMatDiscriBit* PtMatRef, SInt8 PrintLvl, SInt8 PrintMimosaId, SInt32 PrintAcqId, SInt16 PrintFrameId ) { + + SInt32 ViLine; + SInt32 ViCol; + SInt8 VPixState; + SInt8 VRefPixState; + SInt32 VErrCnt; + + + if ( (LineNbToCompare <= 0) || (LineNbToCompare > FSBB0__MAT_DISCRI_USEFUL_LINES_NB) ) { + err_error (( ERR_OUT, "Bad line nb to compare = %d MUST be 1..%d", LineNbToCompare, FSBB0__MAT_DISCRI_USEFUL_LINES_NB )); + return (0); + } + + VErrCnt = 0; + + for ( ViLine=0; ViLine < LineNbToCompare; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ /* 580 for Test LP003 */; ViCol++ ) { + VPixState = PtMat->AALineCol[ViLine][ViCol]; + VRefPixState = PtMatRef->AALineCol[ViLine][ViCol]; + + if ( VPixState != VRefPixState ) { + ++VErrCnt; + // 24 06 2014 - MS commented the message to make the log file easier to read + if ( PrintLvl == 2 ) msg (( MSG_OUT, "Error => FSBB0[%d] Line %4d - Col %4d : Pixel = %d <> Expected = %d", PrintMimosaId, ViLine, ViCol, VPixState, VRefPixState )); + } + + } // End for ViCol + + } // End for ViLine + + if ( (PrintLvl >= 1) && (VErrCnt != 0) ) msg (( MSG_OUT, "For this event Acq[%3d] Frame [%6d] %d errors on Mimosa [%d]", PrintAcqId, PrintFrameId, VErrCnt, PrintMimosaId )); + + return ( VErrCnt ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TCDiscriFile :: FSBB0__TCDiscriFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) : FIL__TCBinFile ( ErrLogFile, EnableErrLog, ErrLogLvl ) { + + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFSetFileName ( char* DataFile ) { + + return ( FIL__TCBinFile :: PubFSetFileName (DataFile) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + return ( FIL__TCBinFile :: PubFSetFlushMode (FlushAfterWrite) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TCDiscriFile :: ~FSBB0__TCDiscriFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFConf ( char* DataFile, SInt8 WriteRead, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt32 VRet; + SInt32 VRWBMode; + SInt32 VMaxBlocSz; + SInt32 VBlocSz; + + switch ( WriteRead ) { + + case 0 : { + VRWBMode = FIL__TCBinFile_RWB_MODE_WRITE; + break; } + + case 1 : { + VRWBMode = FIL__TCBinFile_RWB_MODE_READ; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Bad WriteRead param = %d <> 0..1", WriteRead ) ); + break; } + + } + + VMaxBlocSz = VBlocSz = sizeof (FSBB0__TMatDiscriW32); + + VRet = FIL__TCBinFile::PubFConf ( DataFile, VRWBMode, VMaxBlocSz, VBlocSz, FlushAfterWrite, MeasTime ); + + // msg (( MSG_OUT, "PubFConf => FlushAfterWrite=%d", FlushAfterWrite )); + + return (VRet); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFGetFileSz () { + return ( FIL__TCBinFile::PubFGetFileSz () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFGetEvNb () { + return ( FIL__TCBinFile::PubFGetBlocNb () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFCreate () { + return ( FIL__TCBinFile::PubFCreate () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFOpen () { + return ( FIL__TCBinFile::PubFOpen () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFWriteEv ( FSBB0__TMatDiscriW32* PtSrcMat ) { + + SInt32 VRet; +// SInt32 VRet; // modif 2009_03_04 MG + + VRet = PubFSeqWrite ( (void*) PtSrcMat, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Write event failed !") ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFReadNextEv ( FSBB0__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( (void*) PtDestMat, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read event failed !") ); + err_retok (( ERR_OUT, "" )); + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TMatDiscriW32* FSBB0__TCDiscriFile :: PubFReadNextEv () { + + FSBB0__TMatDiscriW32* VPtEv; + + VPtEv = (FSBB0__TMatDiscriW32*) PubFSeqRead ( ProParBlocSz ); + + if ( VPtEv == NULL ) { + err_error (( ERR_OUT, "Read event failed !" )); + } + + err_retval ( VPtEv, ( ERR_OUT, "" ) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFGotoEv ( SInt32 EvNo ) { + + SInt32 VRet; + + VRet = PubFGotoBloc ( EvNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto event [%d] failed !", EvNo ) ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFReadEv ( SInt32 EvNo, FSBB0__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ) { + + SInt32 VRet; + + VRet = PubFBlocRead ( EvNo, PtDestMat, MaxDestSz ); + + err_retfail ( VRet, (ERR_OUT,"Read event [%d] failed !", EvNo ) ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TMatDiscriW32* FSBB0__TCDiscriFile :: PubFReadEv ( SInt32 EvNo ) { + + FSBB0__TMatDiscriW32* VPtEv; + + + VPtEv = (FSBB0__TMatDiscriW32*) PubFBlocRead ( EvNo ); + + if ( VPtEv == NULL ) { + err_error (( ERR_OUT, "Read event [%d] failed !", EvNo )); + } + + err_retval ( VPtEv, ( ERR_OUT, "" ) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFFlush () { + return ( FIL__TCBinFile::PubFFlush () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFClose () { + return ( FIL__TCBinFile::PubFClose () ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FWriteZSRunCnf ( char* FileName, FSBB0__TZSRunCnf* PtSrc ) { + + SInt32 VRecSz; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (FSBB0__TZSRunCnf); + + err_retfail ( FIL_FWriteRecord ( FileName, PtSrc, VRecSz ), (ERR_OUT,"Write failed !") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FReadZSRunCnf ( char* FileName, FSBB0__TZSRunCnf* PtDest ) { + + SInt32 VRecSz; + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (FSBB0__TZSRunCnf); + + err_retfail ( FIL_FReadRecord ( FileName, PtDest, VRecSz ) , (ERR_OUT,"Read failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FPrintZSRunCnf ( FSBB0__TZSRunCnf* PtSrc ) { + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + msg (( MSG_OUT, "================================================" )); + msg (( MSG_OUT, "RunNo %6d", PtSrc->RunNo )); + msg (( MSG_OUT, "RunSave %6d", PtSrc->RunSave )); + msg (( MSG_OUT, "RunSaveMode %6d", PtSrc->RunSaveMode )); + msg (( MSG_OUT, "RunEvNb %6d", PtSrc->RunEvNb )); + msg (( MSG_OUT, "RunFileEvNb %6d", PtSrc->RunFileEvNb )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "StartDate %s", TIME__FDateS2Str ( PtSrc->StartDate, NULL, 0 ) )); + msg (( MSG_OUT, "StartTime %s", TIME__FTime2Str ( PtSrc->StartTime, NULL, 0 ) )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "AsicName %6d", PtSrc->AsicName )); + msg (( MSG_OUT, "AsicNb %6d", PtSrc->AsicNb )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "SwTrigEnabled %6d", PtSrc->SwTrigEnabled )); + msg (( MSG_OUT, "HwTrigModeSavedData %6d", PtSrc->HwTrigModeSavedData )); + msg (( MSG_OUT, "HwTrigPar[DPXI__HW_TRIG_PAR__OFFSET] %6d", PtSrc->HwTrigPar[0/*DPXI__HW_TRIG_PAR__OFFSET*/] )); + msg (( MSG_OUT, "HwTrigPar[DPXI__HW_TRIG_PAR__WINDOW] %6d", PtSrc->HwTrigPar[1/*DPXI__HW_TRIG_PAR__WINDOW*/] )); + msg (( MSG_OUT, "================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FWriteZSRunRes ( char* FileName, FSBB0__TZSRunRes* PtSrc ) { + + SInt32 VRecSz; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (FSBB0__TZSRunRes); + + err_retfail ( FIL_FWriteRecord ( FileName, PtSrc, VRecSz ), (ERR_OUT,"Write failed !") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FReadZSRunRes ( char* FileName, FSBB0__TZSRunRes* PtDest ) { + + SInt32 VRecSz; + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (FSBB0__TZSRunRes); + + err_retfail ( FIL_FReadRecord ( FileName, PtDest, VRecSz ) , (ERR_OUT,"Read failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FPrintZSRunRes ( FSBB0__TZSRunRes* PtSrc ) { + + SInt32 Vi; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + + msg (( MSG_OUT, "================================================" )); + msg (( MSG_OUT, "StopDate %s", TIME__FDateS2Str ( PtSrc->StopDate, NULL, 0 ) )); + msg (( MSG_OUT, "StopTime %s", TIME__FTime2Str ( PtSrc->StopTime, NULL, 0 ) )); + msg (( MSG_OUT, "EvNbTaken %6d", PtSrc->EvNbTaken )); + msg (( MSG_OUT, "RejAcqNb %6d", PtSrc->RejAcqNb )); + msg (( MSG_OUT, "================================================" )); + + for ( Vi=0; Vi < PtSrc->RejAcqNb; Vi++ ) { + msg (( MSG_OUT, "Acq [%6d] rejected !", PtSrc->ARejAcqList[Vi] )); + } + + msg (( MSG_OUT, "================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TCZsRunRW :: FSBB0__TCZsRunRW () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TCZsRunRW :: ~FSBB0__TCZsRunRW () { + + delete ProPtBinFile; + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : All fields BUT NOT + : - errors handling and log file + : - messages and event header print flags +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PrivFInitForNewRunLoading () { + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + + // Parameters from conf + + sprintf ( ProParRunDir, "" ); + ProParRunNo = 0; + ProParCurFSBB0No = 0; + ProParCurEvNo = 0; + + // Informations + + ProInfRunFSBB0Nb = 0; + ProInfRunEvNb = 0; + ProInfRunFileSz = 0; + ProInfRunEvNbPerFile = 0; + ProInfRunBlocNbPerFile = 0; + + // Variables for internal processing + + ProLastEvAccessDoneInOneFSBB0Mode = 1; + + ProCurBlocNoInRun = 0; + ProCurFileNo = 0; + ProCurBlocNoInFile = 0; + sprintf ( ProCurFileName, "" ); + + ProPtFFrameRaw = NULL; + + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + + // Conf done & errors log + // Parameters from constructor + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // Frame size + + ProInfZsFFrameRawSz = sizeof (FSBB0__TZsFFrameRaw); + + // Print ctrl fields + + ProParMeasTime = 0; + ProParPrintMsg = 0; + ProParPrintEvHeader = 0; + + + PrivFInitForNewRunLoading (); + + // Res + + // TCBinFile + + ProPtBinFile = new FIL__TCBinFile ( "x:\\log\\err_TCBinFile.txt", 0 /* EnableErrLog */, ERR_LOG_LVL_NONE ); + + err_retnull ( ProPtBinFile, (ERR_OUT,"Allocation of ProPtBinFile failed !!! => Abort") ); + + ProPtBinFile->PubFConf ( "", FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFSetMeasTime ( SInt8 Yes ) { + ProParMeasTime = Yes; + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFSetPrintMsg ( SInt8 Print ) { + ProParPrintMsg = Print; + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFSetPrintEvHeader ( SInt8 Print ) { + ProParPrintEvHeader = Print; + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetMeasTime () { + return (ProParMeasTime); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetPrintMsg () { + return ( ProParPrintMsg ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetPrintEvHeader () { + return ( ProParPrintEvHeader ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetFSBB0Nb () { + return ( ProInfRunFSBB0Nb ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetEvNb () { + return ( ProInfRunEvNb ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetEvNbPerFile () { + return ( ProInfRunEvNbPerFile ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Rev : 29/07/2009 + : - Two kinds of events handling : OneFSBB0 / AllFSBB0 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFLoadRun ( char* RunDir, UInt32 RunNo ) { + + SInt32 VRet; + + FSBB0__TCZsRunRW__CHK_INIT (); + + err_retnull ( RunDir, (ERR_OUT,"RunDir == NULL !") ); + + + // Set run dir and run no + + sprintf ( ProParRunDir, "%s", RunDir ); + + ProParRunNo = RunNo; + + // Load and print run conf + // Must be loaded here because fiels of VRunCnfFile are used later + + sprintf ( ProRunCnfFile, "%s\\run_%.4d_cnf.bin", ProParRunDir, ProParRunNo ); + + FSBB0__FReadZSRunCnf ( ProRunCnfFile, &ProRecZSRunCnf ); + FSBB0__FPrintZSRunCnf ( &ProRecZSRunCnf ); + + // Load and print run res + + sprintf ( ProRunResFile, "%s\\run_%.4d_res.bin", ProParRunDir, ProParRunNo ); + + FSBB0__FReadZSRunRes ( ProRunResFile, &ProRecZSRunRes ); + FSBB0__FPrintZSRunRes ( &ProRecZSRunRes ); + + // Update information fields + + ProInfRunFSBB0Nb = ProRecZSRunCnf.AsicNb; + ProInfRunEvNb = ProRecZSRunCnf.RunEvNb; + ProInfRunEvNbPerFile = ProRecZSRunCnf.RunFileEvNb; + + // ---------------------------------- + // WARNING - Upgrade on 29/07/2009 + // ---------------------------------- + // - Now class can provide two kinds of events pointer via PubFGotoEvOneFSBB0 / PubFGotoEvAllFSBB0 + // -> PubFGotoEvOneFSBB0 : Pointer to ONE plane of FSBB0 telescope + // -> PubFGotoEvAllFSBB0 : Pointer to ALL planes of FSBB0 telescope + // + // => ProInfRunBlocNbPerFile depend on which kind off event we want to access + // Therefore ProInfRunBlocNbPerFile is ovewritten in PubFGotoEvOneFSBB0 / PubFGotoEvAllFSBB0 + // By default it is set HERE for "PubFGotoEvOneFSBB0" kind of events + // + // The first call to ProPtBinFile->PubFConf done at the end of this function also configure + // buffer size for "PubFGotoEvOneFSBB0" kind of events. + + ProInfRunBlocNbPerFile = ProInfRunFSBB0Nb * ProInfRunEvNbPerFile; + + // Set flag to memorize last ev access mode + + ProLastEvAccessDoneInOneFSBB0Mode = 1; + + // Set cur event to first one, first FSBB0 + + ProParCurFSBB0No = 0; + ProParCurEvNo = 0; + + // Open file for first event + + ProCurBlocNoInRun = 0; + ProCurFileNo = 0; + ProCurBlocNoInFile = 0; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Load run try to open first file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + + // Try to open file + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + + + if ( VRet < 0 ) { + ProInfRunFileSz = 0; + err_retfail ( -1, (ERR_OUT,"Open file %s for event %d failed !", ProCurFileName, ProParCurEvNo ) ); + } + + ProInfRunFileSz = ProPtBinFile->PubFGetFileSz (); + + + err_retok (( ERR_OUT, "Open file %s done :-)", ProCurFileName )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TZsFFrameRaw* FSBB0__TCZsRunRW :: PubFGotoEvOneFSBB0 ( SInt8 FSBB0No, SInt32 EvNo ) { + + SInt32 VRet = 0; + SInt32 VNewFileNo; + + ProParCurFSBB0No = FSBB0No; + ProParCurEvNo = EvNo; + + // Calculate Nb of bloc per file ( Rq : value is different for PubFGotoEvAllFSBB0 ) + + ProInfRunBlocNbPerFile = ProInfRunFSBB0Nb * ProInfRunEvNbPerFile; + + // Calculate bloc no and file to access + + ProCurBlocNoInRun = ( ProParCurEvNo * ProInfRunFSBB0Nb ) + ProParCurFSBB0No; + VNewFileNo = ProCurBlocNoInRun / ProInfRunBlocNbPerFile; + ProCurBlocNoInFile = ProCurBlocNoInRun % ProInfRunBlocNbPerFile; + + // If last ev acces done in AllFSBB0 mode ( -> TCBin file MUST be reconfigured ) + // If event is not in current file + // => close current file & open new one + + if ( (ProLastEvAccessDoneInOneFSBB0Mode == 0) || (VNewFileNo != ProCurFileNo) ) { + + ProLastEvAccessDoneInOneFSBB0Mode = 1; + + // Close current file + + ProPtBinFile->PubFClose (); + + // Open new file + + ProCurFileNo = VNewFileNo; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d - FSBB0No=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProParCurFSBB0No, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "Try to open file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + err_retfailnull ( VRet, (ERR_OUT,"Open file %s failed !", ProCurFileName) ); + } + + else { + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d - FSBB0No=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProParCurFSBB0No, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + } + + // Try to read event + + ProPtFFrameRaw = (FSBB0__TZsFFrameRaw*) ProPtBinFile->PubFBlocRead ( ProCurBlocNoInFile ); + + if ( ProParPrintEvHeader ) { + FSBB0_FPrintZsFFrameRawHeader ( ProPtFFrameRaw ); + } + + return ( ProPtFFrameRaw ); +} + + + + +/******************************************************************************* +Prototype : +Goal : Retun pointeur to first plane of Telescope => size = Nb plane * ProInfZsFFrameRawSz +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 28/07/2009 +Doc date : 28/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TZsFFrameRaw* FSBB0__TCZsRunRW :: PubFGotoEvAllFSBB0 ( SInt32 EvNo ) { + + SInt32 VRet = 0; + SInt32 VNewFileNo; + SInt32 VEventSz; + SInt32 Vi; + + + ProParCurEvNo = EvNo; + VEventSz = ProInfRunFSBB0Nb * ProInfZsFFrameRawSz; + + // Calculate Nb of bloc per file ( Rq : value is different for PubFGotoEvOneFSBB0 ) + + ProInfRunBlocNbPerFile = ProInfRunEvNbPerFile; + + // Calculate bloc no and file to access + + ProCurBlocNoInRun = ProParCurEvNo; // * ProInfRunFSBB0Nb; + VNewFileNo = ProCurBlocNoInRun / ProInfRunBlocNbPerFile; + ProCurBlocNoInFile = ProCurBlocNoInRun % ProInfRunBlocNbPerFile; + + // If last ev acces done in OneFSBB0 mode ( -> TCBin file MUST be reconfigured ) + // If event is not in current file + // => close current file & open new one + + if ( (ProLastEvAccessDoneInOneFSBB0Mode == 1) || (VNewFileNo != ProCurFileNo) ) { + + ProLastEvAccessDoneInOneFSBB0Mode = 0; + + // Close current file + + ProPtBinFile->PubFClose (); + + // Open new file + + ProCurFileNo = VNewFileNo; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "Try to open file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, VEventSz /* Max bloc sz */ , VEventSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + + err_retfailnull ( VRet, (ERR_OUT,"Open file %s failed !", ProCurFileName) ); + } + + else { + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + } + + // Try to read event + + ProPtFFrameRaw = (FSBB0__TZsFFrameRaw*) ProPtBinFile->PubFBlocRead ( ProCurBlocNoInFile ); + + if ( ProParPrintEvHeader ) { + + for ( Vi=0; Vi < ProInfRunFSBB0Nb; Vi++ ) { + FSBB0_FPrintZsFFrameRawHeader ( &ProPtFFrameRaw[Vi] ); + } + + } + + return ( ProPtFFrameRaw ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFCloseRun () { + + ProPtBinFile->PubFClose (); + PrivFInitForNewRunLoading (); + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + + + + +// ************************************* +// ************************************* +// FSBB0__TCTelMon +// ************************************* +// ************************************* + + +#ifndef ROOT_ROOT + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PrivFInit () { + + SInt32 Vi; + + + // Plane & MAPS settings for FSBB0 + + ProPar.PlaneNb = 6; + + MAPS__TCDigTelMon_CHK_PLANE_NB (ProPar.PlaneNb); + + + ProPar.MapsName = ASIC__FSBB0; + ProPar.MapsNb = 6; + + // Planes conf + // - Id = Index of plane : seem's to be strange and redundant => can be useful later + // - plot color + // - revert or not X direction + + ProAPlanePar[0].MapsId = 0; + ProAPlanePar[0].PlotColor = FSBB0__TCTelMon__COL_PLANE_0; + ProAPlanePar[0].RevertXDir = 1; + + ProAPlanePar[1].MapsId = 1; + ProAPlanePar[1].PlotColor = FSBB0__TCTelMon__COL_PLANE_1; + ProAPlanePar[1].RevertXDir = 0; + + ProAPlanePar[2].MapsId = 2; + ProAPlanePar[2].PlotColor = FSBB0__TCTelMon__COL_PLANE_2; + ProAPlanePar[2].RevertXDir = 1; + + ProAPlanePar[3].MapsId = 3; + ProAPlanePar[3].PlotColor = FSBB0__TCTelMon__COL_PLANE_3; + ProAPlanePar[3].RevertXDir = 0; + + ProAPlanePar[4].MapsId = 4; + ProAPlanePar[4].PlotColor = FSBB0__TCTelMon__COL_PLANE_4; + ProAPlanePar[4].RevertXDir = 1; + + ProAPlanePar[5].MapsId = 5; + ProAPlanePar[5].PlotColor = FSBB0__TCTelMon__COL_PLANE_5; + ProAPlanePar[5].RevertXDir = 0; + + + for ( Vi=0; Vi < MAPS__TCDigTelMon_MAX_PLANE_NB; Vi++ ) { + PrivAPlanePlotColor[Vi] = ProAPlanePar[Vi].PlotColor; + } + + + + + // Frames record reset + + memset ( &PrivZsFFrame , 0, sizeof (FSBB0__TZsFFrame) ); + + memset ( &PrivMatDiscriCoin , 0, sizeof (FSBB0__TMatDiscriBit) ); + memset ( &PrivMatDiscriCoinCum , 0, sizeof (FSBB0__TMatDiscriCumul) ); + memset ( &PrivMatDispColor , 0, sizeof (FSBB0__TMatDiscriColor) ); + + memset ( &PrivMatDiscriBitHalfScale, 0, sizeof (FSBB0__TMatDiscriBitHalfScale) ); + memset ( &PrivMatDiscriCumHalfScale, 0, sizeof (FSBB0__TMatDiscriCumulHalfScale) ); + memset ( &PrivMatDispColorHalfScale, 0, sizeof (FSBB0__TMatDiscriColorHalfScale) ); + + + // Events list allocation & reset + + PriEnListEvWitHitUpdate = 1; + PriEnListEvWithTrigUpdate = 1; + + // Allocation & reset + + for ( Vi=0; Vi < FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB; Vi++ ) { + + PrivAAListEvWithTrig[Vi] = (ASIC__TFrameStatus*) malloc ( FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + err_retnull ( PrivAAListEvWithTrig[Vi], (ERR_OUT,"Allocation of trigger list elt=%d failed !", Vi) ); + + memset ( PrivAAListEvWithTrig[Vi], 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + + + PrivAAListEvWithHit[Vi] = (ASIC__TFrameStatus*) malloc ( FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + err_retnull ( PrivAAListEvWithHit[Vi], (ERR_OUT,"Allocation of hit list elt=%d failed !", Vi) ); + + memset ( PrivAAListEvWithHit[Vi], 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + + } + + PrivAListEvWithHitAllPlanes = (FSBB0__TCTelMon_TEltListEvWithHitAllPlanes*) malloc ( FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (FSBB0__TCTelMon_TEltListEvWithHitAllPlanes) ); + + err_retnull ( PrivAListEvWithHitAllPlanes, (ERR_OUT,"Allocation of hit all planes failed !") ); + + memset ( PrivAListEvWithHitAllPlanes, 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (FSBB0__TCTelMon_TEltListEvWithHitAllPlanes) ); + + + // Reset + + PrivListEvWithTrigIndex = 0; + PrivListEvWithTrigFull = 0; + + PrivListEvWithHitIndex = 0; + PrivListEvWithHitFull = 0; + + PrivListEvWithHitAllPlanesIndex = 0; + PrivListEvWithHitAllPlanesFull = 0; + + // Variables reset + + PrivPtAcqData = NULL; + PrivAcqEvNb = 0; + + PrivPtResRun = NULL; + + PubAcqOffLineProcOrRunOffLineProc = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Rev : 31/07/2009 + : - Add multi planes handling +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PrivFAddEvInListEvWithTrig ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt ) { + + err_retnull ( PtFrStatus, (ERR_OUT,"PtFrStatus == NULL") ); + + if ( PriEnListEvWithTrigUpdate == 0 ) { + return (0); + } + + if ( PrivListEvWithTrigIndex < FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB ) { + PtFrStatus->HitCnt = HitCnt; + PrivAAListEvWithTrig[PlaneNo][PrivListEvWithTrigIndex] = *PtFrStatus; + ++PrivListEvWithTrigIndex; + } + + else { + PrivListEvWithTrigFull = 1; + err_retfail (-1, (ERR_OUT,"List full %d elt", PrivListEvWithTrigIndex ) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : This function MUST always be called one time / ev with PlaneNo = FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL + : because list index is ONLY updated when PlaneNo = FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL + : +Date : 26/07/2009 +Rev : 31/07/2009 + : - Add multi planes handling +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PrivFAddEvInListEvWithHit ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt, SInt8 HitOnAllPlanes, SInt8 SingleHitOnEachPlane ) { + + err_retnull ( PtFrStatus, (ERR_OUT,"PtFrStatus == NULL") ); + + if ( PriEnListEvWitHitUpdate == 0 ) { + return (0); + } + + // Check PlaneNo + + if ( (PlaneNo < 0) || (PlaneNo > FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB) ) { + err_retfail ( -1, (ERR_OUT,"Bad Plane No = %d MUST be [0..%d]", PlaneNo, FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL ) ); + } + + // Update hit count field of FrStatus which already contains information about acq no, ev no, FSBB0 no etc ... + + PtFrStatus->HitCnt = HitCnt; + + // Copy FrStatus in plane array + + PrivAAListEvWithHit[PlaneNo][PrivListEvWithHitIndex] = *PtFrStatus; + + // Update list index ONLY if PlaneNo == FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL + + if ( PlaneNo == FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL ) { + + // Update hit on all planes list + + // Rq : Decision to add event in list or not is done in two steps ( two tests ) and not by a single test in order to save execution time + // -> First test ( HitOnAllPlanes == 1 ) cost less => Is there hits on all planes ? Yes / No ? + // -> Second test cost much and therefore is only done if first one has passed + + if ( HitOnAllPlanes == 1 ) { + + // Add or not event in list depending of list mode + // -> List events with hit(s) ( at least one per plane ) on all planes => Yes + // -> List events with single hit in each plane => Yes if SingleHitOnEachPlane parameter is set / otherwise No + + if ( (ProPar.ListHitAllPlanesMode == MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES ) || ( (ProPar.ListHitAllPlanesMode == MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE) && (SingleHitOnEachPlane == 1) ) ) { + + PrivAListEvWithHitAllPlanes[PrivListEvWithHitAllPlanesIndex].FrStatus = *PtFrStatus; + PrivAListEvWithHitAllPlanes[PrivListEvWithHitAllPlanesIndex].IndexInEvWithHitList = PrivListEvWithHitIndex; // Store ev with trig list index + + if ( PrivListEvWithHitAllPlanesIndex < FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB ) { + ++PrivListEvWithHitAllPlanesIndex; + } + + else { + PrivListEvWithHitAllPlanesFull = 1; + } + } + + + } // End if ( HitOnAllPlanes == 1 ) + + // Update PrivListEvWithHitIndex + + if ( PrivListEvWithHitIndex < FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB ) { + ++PrivListEvWithHitIndex; + } + + else { + PrivListEvWithHitFull = 1; + err_retfail (-1, (ERR_OUT,"List full %d elt", PrivListEvWithHitIndex ) ); + } + + + + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : Hit count +Remark : +Date : 22/07/2009 +Rev : 20/05/2010 + : - Add CumTotTrigNb & CumFrameTrigNb handling + : +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::ProFProcessPlane ( SInt32 DbgEvNo, SInt8 Id, FSBB0__TZsFFrameRaw* PtSrc ) { + + FSBB0__TMatDiscriBit* VPtFrMatDiscriBit; + FSBB0__TMatDiscriCumul* VPtFrMatCumTotHitCnt; + SInt32 VHitCnt; + SInt8 VUpdateMatCumul; + SInt8 VRequestPlot; + SInt8 VGoodFrame; + + // Check plane id + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + + VRequestPlot = 0; // Used to store plot request and move it at END of function AFTER ALL processings + + // Init pointers + + VPtFrMatDiscriBit = (FSBB0__TMatDiscriBit*) ProAPlaneRes[Id].PtMatDiscriBit; + VPtFrMatCumTotHitCnt = (FSBB0__TMatDiscriCumul*) ProAPlaneRes[Id].PtMatCumTotHitCnt; + + // If first event of analysis + // -> Reset all results of plane + + if ( ProInf.CurEvToProc == 0 ) { + ProAPlaneRes[Id].FrameNbWithTrig = 0; + ProAPlaneRes[Id].FramePCentWithTrig = 0; + ProAPlaneRes[Id].CumTotTrigNb = 0; + ProAPlaneRes[Id].CumFrameTrigNb = 0; + + ProAPlaneRes[Id].FrameNbWithHit = 0; + ProAPlaneRes[Id].FramePCentWithHit = 0; + ProAPlaneRes[Id].CumTotHitNb = 0; + ProAPlaneRes[Id].CumFrHitNb = 0; + FSBB0__FMatDiscriCumulResetHit ( VPtFrMatCumTotHitCnt ); + + msg (( MSG_OUT, "----------> ProFProcessPlane => Reset - Plane %d", Id )); + } + + VGoodFrame = 1; + + // Convert ZsFFrameRaw to ZsFFrame and store result in class tmp var PrivZsFFrame + + if ( ProPar.HandleTrigPos == 0 ) { + FSBB0__FConvZsFFrameRawToZsFFrame ( PtSrc, &PrivZsFFrame, 0 /* DbgPrintLvl */ ); + } + + // Trigger pos handling + + else { + if ( FSBB0__FConvZsFFrameRawToZsFFrameHandleTrigger ( ProPar.MapsNb, DbgEvNo, PrivAcqEvNb, PtSrc, &PrivZsFFrame, 1 /* DbgPrintLvl */ ) < 0 ) { +// msg (( MSG_OUT, "***********************************************************************************" )); +// msg (( MSG_OUT, "=> Event %4d has no trigger => Abort ! Plot may be false ! ( it's previous event ) ", DbgEvNo )); +// msg (( MSG_OUT, "**********************************************************************************" )); + +// return (0); + + VGoodFrame = 0; + } + } + + // Convert ZsFFrameRaw to Pixels matrix AND Process cumul AT THE SAME TIME + + VUpdateMatCumul = ProAPlanePar[Id].PlotCum || ProAPlanePar[Id].PlotCoin; + + // ****************************************************************************************************** + // WARNING !!! TODAY 25/07/2009 Update matrix cumul is ALWAYS done => flag VUpdateMatCumul IS NOT used + // => Use flag later AND check ! + // ****************************************************************************************************** + +if ( VGoodFrame == 1 ) { + + VHitCnt = PrivFConvZsFFrameToMatDiscriBitAndCumul ( + DbgEvNo, + ProPar.ProcMode /* Mode */, + Id /* PlaneNo */, + ProAPlanePar[Id].PlotCoin /* PlaneSelForCoin */, + ProInf.CurEvToProc /* EvNo */, + ProPar.GotoRawFrNo /* EvSelForPlot */, + &PrivZsFFrame /* PtSrc */, + VPtFrMatDiscriBit /* PtDestFrameBit */, // Plane pixel matrix as "bit = state" + &PrivMatDiscriCoin /* PtDestCoinBit */, // Common coincidence pixel matrix as "bit = state" + VPtFrMatCumTotHitCnt /* PtDestFrameCum */, // Plane pixel cumul matrix as "count" + &PrivMatDiscriCoinCum /* PtDestCoinCum */, // Common coincidence cumul matrix as "count" + 0 /* PrintLvl */ ); + + // Increment counter of frames with trigger + + if ( PrivZsFFrame.TrigSignalLine >= 0 ) { + ++ProAPlaneRes[Id].FrameNbWithTrig; + } + + // Increment counter of triggers +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + if ( PrivZsFFrame.SStatus.ATrigRes[ASIC__FSBB0_TRIG_TOT_NB] > 0 ) { + ProAPlaneRes[Id].CumTotTrigNb += PrivZsFFrame.SStatus.ATrigRes[ASIC__FSBB0_TRIG_TOT_NB]; + } +//#endif + + // Increment counter of frames with hits + + if ( VHitCnt > 0 ) { + ++ProAPlaneRes[Id].FrameNbWithHit; + ProAPlaneRes[Id].CumTotHitNb += VHitCnt; + } + + +} // End if ( VGoodFrame == 1 ) + + + // ------------------------------------------------ + // Plot frame + // ------------------------------------------------ + + if ( (ProAPlanePar[Id].PlotFrame ) && (ProPar.GotoRawFrNo >= 0) && (ProPar.GotoRawFrNo == ProInf.CurEvToProc) ) { + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatConvBitToColState ( VPtFrMatDiscriBit, &PrivMatDispColor, clWhite /* ColorStateZero */, ProAPlanePar[Id].PlotColor, 0 /* RevertLineDirection */ ); + } + + else { + FSBB0__FConvMatDiscriBitToMatDiscriBitHalfScale ( VPtFrMatDiscriBit, &PrivMatDiscriBitHalfScale ); + FSBB0__FDiscriMatConvBitToColStateHalfScale ( &PrivMatDiscriBitHalfScale, &PrivMatDispColorHalfScale, clWhite /* ColorStateZero */, ProAPlanePar[Id].PlotColor, 0 /* RevertLineDirection */ ); + + FSBB0_FPrintZsFFrameRawHeader ( PtSrc ); + FSBB0__FMatDiscriPrintHit ( "Plane", Id, VPtFrMatDiscriBit ); + + // err_error (( ERR_OUT, "---> ---> Plot frame request 1/2 matrix - Plane %d", Id )); + } + + VRequestPlot = 1; // PLot request will be done at end of function + + } // End if Plot frame + + + + // Copy to buffer if required + + if ( ProPar.StoreEvents == 1 ) { + + err_error (( ERR_OUT, "Copy of event to buffer NOT IMPLEMENTED" )); + + } // Enf if copy to buffer + + + // ================================================ + // Last event => calculate results & display + // ================================================ + + if ( (PrivStopProc == 1) || (ProInf.CurEvToProc >= (ProInf.LastEvToProc) ) ) { + + msg (( MSG_OUT, "----------> ProFProcessPlane => Last event => Calc" )); + + err_error (( ERR_OUT, "----------> ProFProcessPlane => Last event => Calc" )); + + ProAPlaneRes[Id].FramePCentWithTrig = ( (float) ProAPlaneRes[Id].FrameNbWithTrig / (float) ProInf.EvNbToProc ) * 100; + + ProAPlaneRes[Id].FramePCentWithHit = ( (float) ProAPlaneRes[Id].FrameNbWithHit / (float) ProInf.EvNbToProc ) * 100; + + if ( ProAPlaneRes[Id].FrameNbWithTrig != 0 ) { + ProAPlaneRes[Id].CumFrameTrigNb = (float) ProAPlaneRes[Id].CumTotTrigNb / (float) ProAPlaneRes[Id].FrameNbWithTrig; + } + + else { + ProAPlaneRes[Id].CumFrameTrigNb = 0; + } + + + if ( ProAPlaneRes[Id].FrameNbWithHit != 0 ) { + ProAPlaneRes[Id].CumFrHitNb = ( (float) ProAPlaneRes[Id].CumTotHitNb / (float) ProAPlaneRes[Id].FrameNbWithHit ); + } + + else { + ProAPlaneRes[Id].CumFrHitNb = 0; + } + + + PubFPrintPlaneRes (Id); + + while (1) { + + // ------------------------------------------------ + // Plot cumul + // ------------------------------------------------ + + if ( ProAPlanePar[Id].PlotCum ) { + + // FSBB0__FPrintMatDiscriCumul ( VPtFrMatCumTotHitCnt ); + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatConvCumulToColVal ( VPtFrMatCumTotHitCnt, &PrivMatDispColor, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + err_error (( ERR_OUT, "---> Plot cumul request FULL matrix - Plane %d", Id )); + } + + else { + FSBB0__FConvMatDiscriCumToMatDiscriCumHalfScale ( VPtFrMatCumTotHitCnt, &PrivMatDiscriCumHalfScale ); + + // FSBB0__FPrintMatDiscriCumulHalfScale ( &PrivMatDiscriCumHalfScale ); + + FSBB0__FDiscriMatConvCumulToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + err_error (( ERR_OUT, "---> Plot cumul request 1/2 matrix - Plane %d", Id )); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCum) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS) ) { + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatFullScaleConvCoinBitToColState ( &PrivMatDiscriCoin, &PrivMatDispColor, clWhite /* ColorZeroHit */, PrivAPlanePlotColor /* AColorOneHit */, clBlack /* ColorMultiHit */, 0 /* RevertLineDirection */ ); + } + + else { + FSBB0__FConvMatDiscriBitCoinToMatDiscriBitCoinHalfScale ( &PrivMatDiscriCoin, &PrivMatDiscriBitHalfScale ); + FSBB0__FDiscriMatConvCoinBitToColStateHalfScale ( &PrivMatDiscriBitHalfScale, &PrivMatDispColorHalfScale, clWhite /* ColorZeroHit */, PrivAPlanePlotColor /* AColorOneHit */, clBlack /* ColorMultiHit */, 0 /* RevertLineDirection */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR) ) { + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatConvCumulToColVal ( &PrivMatDiscriCoinCum, &PrivMatDispColor, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + } + + else { + FSBB0__FConvMatDiscriCumToMatDiscriCumHalfScale ( &PrivMatDiscriCoinCum, &PrivMatDiscriCumHalfScale ); + FSBB0__FDiscriMatConvCumulToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) ) { + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatConvCumulCoinOrToColVal ( &PrivMatDiscriCoinCum, &PrivMatDispColor, PrivAPlanePlotColor /* AColorOneHit */, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + } + + else { + FSBB0__FConvMatDiscriCumToMatDiscriCumHalfScale ( &PrivMatDiscriCoinCum, &PrivMatDiscriCumHalfScale ); + FSBB0__FDiscriMatConvCumulCoinOrToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, PrivAPlanePlotColor /* AColorOneHit */, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) + + + break; + } // End while (1) + + + } // End if Last event + + + // ------------------ + // Plot request + // ------------------ + + if ( VRequestPlot ) { + + if ( ProRequestPlot == 0 ) { + ProRequestPlot = 1; + } + + } + + + return (VHitCnt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +FSBB0__TCTelMon::FSBB0__TCTelMon () : MAPS__TCDigTelMon () { + + err_error (( ERR_OUT, "TRACE - ProPar.PlaneNb=%d", ProPar.PlaneNb )); + + PrivFInit (); + + err_error (( ERR_OUT, "TRACE - ProPar.PlaneNb=%d", ProPar.PlaneNb )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +FSBB0__TCTelMon::~FSBB0__TCTelMon () { + + SInt32 Vi; + + // Free + + for ( Vi=0; Vi < FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB; Vi++ ) { + free ( PrivAAListEvWithTrig[Vi] ); + free ( PrivAAListEvWithHit[Vi] ); + } + + free ( PrivAListEvWithHitAllPlanes ); + + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 MaxBuffEvNb ) { + + if ( MaxBuffEvNb > MAPS__TCDigTelMon_MAX_EV_NB ) { + err_retfail ( -1, (ERR_OUT,"MaxBuffEvNb=%d > MAPS__TCDigTelMon_MAX_EV_NB=%d", MaxBuffEvNb, MAPS__TCDigTelMon_MAX_EV_NB ) ); + } + + ProPar.MaxBuffEvNb = MaxBuffEvNb; + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFConnectGui () { + + MAPS__TCDigTelMon::PubFConnectGui (); + + PubPt_ALbPlane[0]->Font->Color = FSBB0__TCTelMon__COL_PLANE_0; + PubPt_ALbPlane[1]->Font->Color = FSBB0__TCTelMon__COL_PLANE_1; + PubPt_ALbPlane[2]->Font->Color = FSBB0__TCTelMon__COL_PLANE_2; + PubPt_ALbPlane[3]->Font->Color = FSBB0__TCTelMon__COL_PLANE_3; + PubPt_ALbPlane[4]->Font->Color = FSBB0__TCTelMon__COL_PLANE_4; + PubPt_ALbPlane[5]->Font->Color = FSBB0__TCTelMon__COL_PLANE_5; + + PubPt_GrpTelMon->Color = clSilver; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGetGuiPar () { + + // -------------------------- + // Get parameters from GUI + // -------------------------- + + MAPS__TCDigTelMon::PubFGetGuiPar (); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 FSBB0__TCTelMon::PubFStartRun ( SInt8 MapsNb) { + + SInt8 ViPlane; + SInt32 ViEv; + void* VPtMat; + + + // --------------------- + // Run in progress + // --------------------- + + ProInf.RunInProgress = 1; + + // --------------------- + // Set MAPS nb + // --------------------- + + ProPar.MapsNb = MapsNb; + + // --------------------- + // Reset Ev No to process + // --------------------- + + ProInf.CurEvToProc = 0; + + // --------------------- + // Allocate memory + // --------------------- + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + // Intermediate buffers + + ProAPlaneRes[ViPlane].PtMatDiscriBit = malloc ( sizeof (FSBB0__TMatDiscriBit) ); + err_retnull ( ProAPlaneRes[ViPlane].PtMatDiscriBit, (ERR_OUT,"Allocation of PtMatDiscriBit plane [%d] failed !", ViPlane) ); + + ProAPlaneRes[ViPlane].PtMatCumTotHitCnt = malloc ( sizeof (FSBB0__TMatDiscriCumul)); + err_retnull ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt, (ERR_OUT,"Allocation of PtMatCumTotHitCnt plane [%d] failed !", ViPlane) ); + + // Events + + if ( ProPar.StoreEvents == 1 ) { + + for ( ViEv=0; ViEv < ProPar.MaxBuffEvNb; ViEv++ ) { + VPtMat = malloc ( sizeof (FSBB0__TMatDiscriBit) ); + + if ( VPtMat = NULL) { + err_retfail ( -1, (ERR_OUT,"Allocation of plane[%d] event[%d] failed !",ViPlane, ViEv) ); + } + + ProAPlaneData[ViPlane].AEvPt[ViEv] = VPtMat; + + } // End for ViEv + + } // End if StoreEvents + + } // End for + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFStopRun () { + + SInt8 ViPlane; + SInt32 ViEv; + + // --------------------- + // Run stopped + // --------------------- + + ProInf.RunInProgress = 0; + + // --------------------- + // DeAllocate memory + // --------------------- + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + // Intermediate buffers + + if ( ProAPlaneRes[ViPlane].PtMatDiscriBit != NULL ) free ( ProAPlaneRes[ViPlane].PtMatDiscriBit ); + if ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt != NULL ) free ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt ); + + // Events + + for ( ViEv=0; ViEv < MAPS__TCDigTelMon_MAX_EV_NB; ViEv++ ) { + if ( ProAPlaneData[ViPlane].AEvPt != NULL ) { + free ( ProAPlaneData[ViPlane].AEvPt ); + } + } + + } // End for + + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFStartMon () { + + ProPar.MonEnabled = 1; + + PubFSetGuiPar (); + + PubPt_GrpTelMon->Color = clBtnFace; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFStopMon () { + + ProPar.MonEnabled = 0; + + PubFSetGuiPar (); + + PubPt_GrpTelMon->Color = clSilver; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ) { + + ProPar.ProcOnlyFrWithHitOnAllPlanes = Yes; + PriEnListEvWitHitUpdate = !Yes; + PriEnListEvWithTrigUpdate = !Yes; + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 - 06/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt32 EvNb, FSBB0__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ) { + + SInt8 ViPlane; + SInt32 ViFramePlane0ofEvent; + SInt32 ViFrame; + SInt32 ViEvInAcq; + SInt32 VTrigSigLine; + SInt32 VEvHitCnt; + SInt32 VPlaneHitCnt; + SInt8 VFlgHitOnAllPlane; + SInt8 VFlgSingleHitOnEachPlane; + SInt32 VLocalCpySz; + ASIC__TFrameStatus* VPtEvStatus; + static UInt32 VTimeBeg; + static UInt32 VTimeEnd; + + SInt8 ViDbgMaps; + UInt16 VDbgTrigNb; + UInt16 VADbgTrigVal[3]; + UInt16 VADbgTrigLine[3]; + UInt16 VADbgTrigClock[3]; + + err_error (( ERR_OUT, "MapsName=%d - MapsNb=%d - EvNb=%d", MapsName, MapsNb, EvNb )); + err_error (( ERR_OUT, "" )); + + + +#ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + + for ( ViDbgMaps=0; ViDbgMaps < MapsNb; ViDbgMaps++ ) { +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VDbgTrigNb = (PtSrc[ViDbgMaps].Zero & 0xFFFF0000) >> 16; + VADbgTrigVal[0] = (PtSrc[ViDbgMaps].Zero & 0x0000FFFF); + VADbgTrigVal[1] = (PtSrc[ViDbgMaps].Zero2 & 0xFFFF0000) >> 16; + VADbgTrigVal[2] = (PtSrc[ViDbgMaps].Zero2 & 0x0000FFFF); +#endif + + VADbgTrigLine[0] = VADbgTrigVal[0] / 16; + VADbgTrigLine[1] = VADbgTrigVal[1] / 16; + VADbgTrigLine[2] = VADbgTrigVal[2] / 16; + + VADbgTrigClock[0] = VADbgTrigVal[0] % 16; + VADbgTrigClock[1] = VADbgTrigVal[1] % 16; + VADbgTrigClock[2] = VADbgTrigVal[2] % 16; + + err_error (( ERR_OUT, "=======================================================================================" )); + err_error (( ERR_OUT, "ViDbgMaps=%d : AsicNo=%d - AcqNo=%d - Header=%x", ViDbgMaps, PtSrc[ViDbgMaps].SStatus.AsicNo, PtSrc[ViDbgMaps].SStatus.AcqNo, PtSrc[ViDbgMaps].Header )); +// err_error (( ERR_OUT, "--> Trailer=%x", PtSrc[ViDbgMaps].Trailer )); +// err_error (( ERR_OUT, "--> Zero H=%d - Zero L=%d", (PtSrc[ViDbgMaps].Zero & 0xFFFF0000) >> 16, (PtSrc[ViDbgMaps].Zero & 0x0000FFFF) )); +// err_error (( ERR_OUT, "--> Zero2 H=%d - Zero2 L=%d", (PtSrc[ViDbgMaps].Zero2 & 0xFFFF0000) >> 16, (PtSrc[ViDbgMaps].Zero2 & 0x0000FFFF) )); + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "--> Trig Nb = %d", VDbgTrigNb )); + err_error (( ERR_OUT, "--> Trig [0] : Line %4d - clock %4d", VADbgTrigLine[0], VADbgTrigClock[0] )); + err_error (( ERR_OUT, "--> Trig [1] : Line %4d - clock %4d", VADbgTrigLine[1], VADbgTrigClock[1] )); + err_error (( ERR_OUT, "--> Trig [2] : Line %4d - clock %4d", VADbgTrigLine[2], VADbgTrigClock[2] )); + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + err_error (( ERR_OUT, "Info Trigger : Line %4d - clock %4d", PtSrc[ViDbgMaps].SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], PtSrc[ViDbgMaps].SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK] )); +//#endif + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); + + } + + err_error (( ERR_OUT, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" )); + + if ( (ProPar.MonEnabled == 0) && (OffLineCall == 0) ) { + return (0); + } + + // Check parameters + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc = NULL") ); + + if ( MapsName != ProPar.MapsName ) { + err_retfail ( -1, (ERR_OUT,"Bad MapsName=%d <> ProPar.MapsName=%d", MapsName, ProPar.MapsName ) ); + } + + if ( MapsNb != ProPar.MapsNb ) { + err_retfail ( -1, (ERR_OUT,"Bad MapsNb=%d <> ProPar.MapsNb=%d", MapsNb, ProPar.MapsNb ) ); + } + + // make a copy of Acq event nb, for off-line processing call of this function + + PrivAcqEvNb = EvNb; + + // Make a local copy if required + + if ( MakeLocalCpy ) { + + if ( PrivPtAcqData != NULL ) { + free ( PrivPtAcqData ); + } + + VLocalCpySz = MapsNb * EvNb * sizeof (FSBB0__TZsFFrameRaw); + + PrivPtAcqData = (FSBB0__TZsFFrameRaw*) malloc ( VLocalCpySz ); + + if ( PrivPtAcqData == NULL ) { + err_error (( ERR_OUT, "Allocation of buffer for local copy of %d bytes ... failed !", VLocalCpySz )); + } + + else { + memcpy ( PrivPtAcqData, PtSrc, VLocalCpySz ); + msg (( MSG_OUT, "Allocation of buffer AND local copy of %d Kbytes done :-)", VLocalCpySz / 1024 )); + err_error (( ERR_OUT, "Allocation of buffer for local copy of %d Kbytes done :-)", VLocalCpySz / 1024 )); + } + + } + + // Read GUI parameters + + PubFGetGuiPar (); + + + // Update processing mode flags + + PrivListEvWithHitAllPlanesCurProcMode = ProPar.ListHitAllPlanesMode; + + // ---------------------------------------- + // If beginning of processing + // ---------------------------------------- + + + if ( ProInf.CurEvToProc == 0 ) { + + PrivStopProc = 0; + + VTimeBeg = GetTickCount (); // Get time of beginning of processing + + msg (( MSG_OUT, "----------> PubFAddEvents => Reset all results" )); + + // Reset all coin destination matrices ( common for all planes ) + + memset ( &PrivMatDiscriCoin , 0, sizeof (FSBB0__TMatDiscriBit) ); + memset ( &PrivMatDiscriCoinCum, 0, sizeof (FSBB0__TMatDiscriCumul) ); + + // Reset list & list index & full flag + // + // -> Must be done HERE + // -> MUST NOT be done at end of this function when ProInf.EvNbToProc is reached + // because user will want to plot theses results at end of processing + + if ( PriEnListEvWithTrigUpdate == 1 ) { + + for ( ViPlane=0; ViPlane < FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB; ViPlane++ ) { + memset ( PrivAAListEvWithTrig[ViPlane], 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + } + + PrivListEvWithTrigIndex = 0; + PrivListEvWithTrigFull = 0; + } // End if ( PriEnListUpdate == 1 ) + + if ( PriEnListEvWitHitUpdate == 1 ) { + + for ( ViPlane=0; ViPlane < FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB; ViPlane++ ) { + memset ( PrivAAListEvWithHit[ViPlane], 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + } + + memset ( PrivAListEvWithHitAllPlanes, 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (FSBB0__TCTelMon_TEltListEvWithHitAllPlanes) ); + + PrivListEvWithHitIndex = 0; + PrivListEvWithHitFull = 0; + + PrivListEvWithHitAllPlanesIndex = 0; + PrivListEvWithHitAllPlanesFull = 0; + + } // End if ( PriEnListUpdate == 1 ) + + + } + + // Results set + + ProRes.AcqFrNb = EvNb; + + // Processing mode selection + // - One acq => number of events received by server + // - Events number from GUI => can be less or more than one Acq + + if ( ProPar.ProcOneAcq ) { + ProInf.EvNbToProc = EvNb; + } + + else { + ProInf.EvNbToProc = ProPar.ProcEvNb; + } + + ProInf.LastEvToProc = ProInf.EvNbToProc - 1; + + msg (( MSG_OUT, "PubFAddEvents => MapsName=%d - MapsNb=%d - EvNb=%d (DAQ) - ProcOneAcq=%d - EvNbToProc=%d", MapsName, MapsNb, EvNb, ProPar.ProcOneAcq, ProInf.EvNbToProc )); + + // Process events + + + for ( ViEvInAcq=0; ViEvInAcq < EvNb; ViEvInAcq++ ) { + + if ( ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) { + PrivStopProc = PubFIsEvLastOfListEvWithHitOnAllPlanes ( ViEvInAcq ); + } + + else { + PrivStopProc = 0; + } + + + VFlgHitOnAllPlane = 1; + VFlgSingleHitOnEachPlane = 1; + + if ( ProInf.CurEvToProc < ProInf.EvNbToProc ) { + + if ( ViEvInAcq % 100 == 0 ) { + FDecInt2Edit ( ViEvInAcq, PubPt_DispCurProcFr ); + Application->ProcessMessages (); + } + + ViFramePlane0ofEvent = MapsNb * ViEvInAcq; + VTrigSigLine = PtSrc[ViFramePlane0ofEvent].SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; + VPtEvStatus = &PtSrc[ViFramePlane0ofEvent].SStatus; + + // If Process all frames OR Process frame with trigger AND there is a Trigger on this frame + + // if ( (ProPar.ProcOnlyFrWithTrig == 0) || (VTrigSigLine >= 0) ) { + // if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 0) || (PubFIsEvInListEvWithHitOnAllPlanes (ViEvInAcq) == 1) ) { + + if ( ((ProPar.ProcOnlyFrWithTrig == 0) || (VTrigSigLine >= 0)) && ((ProPar.ProcOnlyFrWithHitOnAllPlanes == 0) || (PubFIsEvInListEvWithHitOnAllPlanes (ViEvInAcq) == 1)) ) { + + // Reset event hits counter + + VEvHitCnt = 0; + + // Loop on all selected planes + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + if ( ProAPlanePar[ViPlane].Process == 1 ) { + + ViFrame = ViFramePlane0ofEvent + ViPlane; + VPlaneHitCnt = ProFProcessPlane ( ViEvInAcq, ViPlane, &PtSrc[ViFrame] ); + VEvHitCnt += VPlaneHitCnt; + + if ( VPlaneHitCnt != 1 ) { + VFlgSingleHitOnEachPlane = 0; + } + + if ( VPlaneHitCnt > 0 ) { + PrivFAddEvInListEvWithHit ( ViPlane, VPtEvStatus, VPlaneHitCnt, 0 /* HitOnAllPlanes */, 0 /* SingleHitOnEachPlane */ ); + } + + else { + VFlgHitOnAllPlane = 0; // Reset flag in at least one plane is without hit + } + + } + } + + // If trigger ( -1 => no trigger ) => store in list + + if ( VTrigSigLine >= 0 ) { + PrivFAddEvInListEvWithTrig ( FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL, VPtEvStatus, VEvHitCnt ); + } + + // If hits => store in list + + if ( VEvHitCnt > 0 ) { + PrivFAddEvInListEvWithHit ( FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL, VPtEvStatus, VEvHitCnt, VFlgHitOnAllPlane, VFlgSingleHitOnEachPlane ); + } + + // Results + + ProRes.ProFrNo = ProInf.CurEvToProc; + + ++ProInf.CurEvToProc; + + } + + + } + + else { + break; // End of processing => We can reach ProInf.EvNbToProc while all events of current Acq are not needed for processing + } + + } // End for + + // If end of processing => Reset event index + + if ( ProInf.CurEvToProc >= ProInf.EvNbToProc ) { + + msg (( MSG_OUT, "----------> PubFAddEvents => Print results" )); + + ProInf.CurEvToProc = 0; + + // Get time of end of processing + + VTimeEnd = GetTickCount (); + ProRes.ProTimeMs = VTimeEnd - VTimeBeg; + + // Display results + + PubFSetGuiRes (); + + // Stop monitoring if required + + if ( ProPar.StopAtEndOfProc ) { + PubFStopMon (); + } + + } + + +#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + // Display status + + PubFSetGuiStatus (); + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFProcessOffLineCurAcq () { + + + // Stop on-line monitoring + + PubFStopMon (); + + // Get GUI parameters => In order to get user choices + + PubFGetGuiPar (); + + // Force mode to "Process one Acq" AND update GUI fields + + ProPar.ProcOneAcq = 1; + + PubFSetGuiPar (); + + // Don't update list if processing of ONLY events with trigger + + if ( ProPar.ProcOnlyFrWithTrig == 1 ) { + PriEnListEvWithTrigUpdate = 0; + } + + else { + PriEnListEvWithTrigUpdate = 1; + } + + // Check buffer of current acq data + + err_retnull ( PrivPtAcqData, (ERR_OUT,"No data in buffer => PrivPtAcqData == NULL !") ); + + // ---------------------------------------------------------------------------------------------------------------------- + // Reset Ev No to process + // ---------------------------------------------------------------------------------------------------------------------- + // Because on some processing it may not be reset at end of processing, in case event nb to process has not been reached + // for example : processing of only events with trigger + // ---------------------------------------------------------------------------------------------------------------------- + // + // WARNING => IT MUST BE CHECKED if this init DONE HERE IS compatible WITH ALL sw operating modes !!! + // => It may CAUSE BUGS in other operating modes !!! + // + // 15/08/09 + // ---------------------------------------------------------------------------------------------------------------------- + + ProInf.CurEvToProc = 0; + + + // Execute PubFAddEvents (...) in off-line mode + + PubFAddEvents ( ProPar.MapsName, ProPar.MapsNb, PrivAcqEvNb, PrivPtAcqData/* PtSrc */, 0 /* MakeLocalCpy */, 1 /* OffLineCall */ ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFProcessOffLineCurAcq2 () { + + // Stop on-line monitoring + + PubFStopMon (); + + // Force mode to "Process one Acq" AND update GUI fields + + ProPar.ProcOneAcq = 1; + + // Execute PubFAddEvents (...) in off-line mode + + PubFAddEvents ( ProPar.MapsName, ProPar.MapsNb, PrivAcqEvNb, PrivPtAcqData/* PtSrc */, 0 /* MakeLocalCpy */, 1 /* OffLineCall */ ); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGotoFirstFrame () { + + ProPar.GotoRawFrNo = 0; + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGotoPrevFrame () { + + if ( ProPar.GotoRawFrNo > 0 ) { + --ProPar.GotoRawFrNo; + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGotoNextFrame () { + + if ( ProPar.GotoRawFrNo < PrivAcqEvNb ) { + ++ProPar.GotoRawFrNo; + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGotoLastFrame () { + + if ( PrivAcqEvNb > 0 ) { + ProPar.GotoRawFrNo = PrivAcqEvNb-1; + } + + else { + ProPar.GotoRawFrNo = -1; // No frame available, < 0 tested when we try to access data + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubPrintListEvWithTrig ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPt; + + + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "- Print events with trigger -" )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithTrigIndex, PrivListEvWithTrigFull )); + msg (( MSG_OUT, "-----------------------------" )); + + VPt = PrivAAListEvWithTrig[FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL]; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithTrigIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithTrigIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - TSigLine=%4d - HitCnt=%4d", Vi, VPt->FrameNoInRun, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubPrintListEvWithHit ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPtPlane0; + ASIC__TFrameStatus* VPtPlane1; + ASIC__TFrameStatus* VPt; + + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "- Print events with hit -" )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithHitIndex, PrivListEvWithHitFull )); + msg (( MSG_OUT, "-----------------------------" )); + + + VPtPlane0 = PrivAAListEvWithHit[0]; + VPtPlane1 = PrivAAListEvWithHit[1]; + VPt = PrivAAListEvWithHit[FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL]; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithHitIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt[C]=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + ++VPtPlane0; + ++VPtPlane1; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithHitIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - TSigLine=%4d - HitCnt [0]=%4d / [1]=%4d / [C]=%4d", Vi, VPt->FrameNoInRun, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPtPlane0->HitCnt, VPtPlane1->HitCnt, VPt->HitCnt )); + ++VPt; + ++VPtPlane0; + ++VPtPlane1; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubPrintListEvWithHitOnAllPlanes ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPtP0; + ASIC__TFrameStatus* VPtP1; + ASIC__TFrameStatus* VPt; + FSBB0__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + if ( ProPar.ListHitAllPlanesMode != PrivListEvWithHitAllPlanesCurProcMode ) { + msg (( MSG_OUT, "----------------------------------------------------------" )); + msg (( MSG_OUT, "- Please process data before with button -" )); + msg (( MSG_OUT, "----------------------------------------------------------" )); + err_retok (( ERR_OUT, "" )); + } + + + msg (( MSG_OUT, "--------------------------------------" )); + + + switch ( ProPar.ListHitAllPlanesMode ) { + + case MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES : { + msg (( MSG_OUT, "- Print events with hit on ALL planes -" )); + break; } + + case MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE : { + msg (( MSG_OUT, "- Print events with single hit on EACH plane -" )); + break; } + + default : { + msg (( MSG_OUT, "- Error => Unknown list mode = %d -", ProPar.ListHitAllPlanesMode )); + break; } + + } + + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithHitAllPlanesIndex, PrivListEvWithHitAllPlanesFull )); + msg (( MSG_OUT, "------------------------------------------------------" )); + + + VPtRec = PrivAListEvWithHitAllPlanes; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + VPt = &VPtRec->FrStatus; + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt[C]=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPtRec; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + VPt = &VPtRec->FrStatus; + + if ( (VPtRec->IndexInEvWithHitList >=0) && (VPtRec->IndexInEvWithHitList < PrivListEvWithHitIndex) ) { + VPtP0 = &PrivAAListEvWithHit[0][VPtRec->IndexInEvWithHitList]; + VPtP1 = &PrivAAListEvWithHit[1][VPtRec->IndexInEvWithHitList]; + msg (( MSG_OUT, "[%4d] : EvInAcq=%4d - TSigLine=%4d - HitCnt [0]=%4d / [1]=%4d / [C]=%4d", Vi, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPtP0->HitCnt, VPtP1->HitCnt, VPt->HitCnt )); + } + + else { + msg (( MSG_OUT, "[%4d] : EvInAcq=%4d - TSigLine=%4d - HitCnt [0]=! / [1]=! / [C]=%4d", Vi, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + } + + ++VPtRec; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubAllocResRun () { + + // Res run alloc / free handling + + if ( PrivPtResRun != NULL ) { + free ( PrivPtResRun ); + } + + + PrivPtResRun = (FSBB0__TCTelMon_TResRun*) malloc ( sizeof (FSBB0__TCTelMon_TResRun) ); + + if ( PrivPtResRun == NULL ) { + err_error (( ERR_OUT, "Allocation of result run failed !" )); + } + + else { + + memset ( PrivPtResRun, 0, sizeof (FSBB0__TCTelMon_TResRun) ); + + PrivPtResRun->EvNb = 0; + PrivPtResRun->PlaneNb = 2; + } + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 06/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFreeResRun () { + + if ( PrivPtResRun != NULL ) { + free ( PrivPtResRun ); + } + + + PrivPtResRun = NULL; + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubPrintResRun () { + + SInt32 ViEv; + SInt32 ViHit; + FSBB0__TCTelMon_TTrack* VPt; + + if ( PrivPtResRun == NULL ) { + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "- ERROR => Res run is NOT allocated - " )); + msg (( MSG_OUT, "-------------------------------------" )); + err_retfail ( -1, (ERR_OUT,"PrivPtResRun == NULL") ); + } + + msg (( MSG_OUT, "--------------------------------------" )); + msg (( MSG_OUT, "- Result run -" )); + msg (( MSG_OUT, "--------------------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivPtResRun->EvNb, PrivPtResRun->Full )); + msg (( MSG_OUT, "--------------------------------------" )); + + + for ( ViEv=0; ViEv < PrivPtResRun->EvNb; ViEv++) { + + VPt = &PrivPtResRun->ATracks[ViEv]; + + if ( VPt->AHitsNbPerPlane[0] != VPt->AHitsNbPerPlane[1] ) { + msg (( MSG_OUT, "WARNING : Hit nb P0 = %d <> Hit nb P1 = %d => Use P0 for print", VPt->AHitsNbPerPlane[0], VPt->AHitsNbPerPlane[1] )); + } + + msg (( MSG_OUT, "=================================================================" )); + + for ( ViHit=0; ViHit < VPt->AHitsNbPerPlane[0]; ViHit++) { + msg (( MSG_OUT, "Ev %4d - EvInRun %4d - Hit %4d : P0 [x=%4d, y=%4d] - P1[x=%4d, y=%4d]", ViEv, VPt->EvNoInRun, ViHit, VPt->AAHits[0][ViHit].x, VPt->AAHits[0][ViHit].y, VPt->AAHits[1][ViHit].x, VPt->AAHits[1][ViHit].y )); + } + + } + + + msg (( MSG_OUT, "-----------------------------" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubSaveResRun ( char* FileName ) { + + SInt32 VTotResRecordSz; + + if ( PrivPtResRun == NULL ) { + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "- ERROR => Res run is NOT allocated - " )); + msg (( MSG_OUT, "-------------------------------------" )); + err_retfail ( -1, (ERR_OUT,"PrivPtResRun == NULL") ); + } + + FIL__TCBinFile VResFile ( "x:\\log\\err_TCBinFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_WARNINGS_ERRORS ); + + err_retnull ( FileName, (ERR_OUT,"FileName == NULL") ); + + VTotResRecordSz = sizeof (FSBB0__TCTelMon_TResRun); + + VResFile.PubFConf ( FileName, 0 /* WriteRead => 0=Write 1=Read */ , VTotResRecordSz /* MaxBlocSz */, VTotResRecordSz /* BlocSz */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VResFile.PubFCreate (); + VResFile.PubFSeqWrite ( PrivPtResRun, VTotResRecordSz ); + + VResFile.PubFClose (); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFIsEvInListEvWithHitOnAllPlanes ( SInt32 EvNo ) { + + SInt8 VFound; + SInt32 Vi; + FSBB0__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + VPtRec = PrivAListEvWithHitAllPlanes; + + VFound = 0; + + // Acq processing + + if ( PubAcqOffLineProcOrRunOffLineProc == 0 ) { + + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + if ( EvNo == VPtRec->FrStatus.FrameNoInRun ) { + err_error (( ERR_OUT, "TRACE : EltNo %4d - EvNo %4d - FrNoInAcq %4d => Hit on all planes", Vi, VPtRec->FrStatus.FrameNoInRun, VPtRec->FrStatus.FrameNoInAcq )); + VFound = 1; + break; + } + ++VPtRec; + } + + } + + // Run processing via N Acq processing + + else { + + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + if ( EvNo == VPtRec->FrStatus.FrameNoInAcq ) { + err_error (( ERR_OUT, "TRACE : EltNo %4d - EvNo %4d - FrNoInAcq %4d => Hit on all planes", Vi, VPtRec->FrStatus.FrameNoInRun, VPtRec->FrStatus.FrameNoInAcq )); + VFound = 1; + break; + } + ++VPtRec; + } + + } + + + return (VFound); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFIsEvLastOfListEvWithHitOnAllPlanes ( SInt32 EvNo ) { + + SInt32 Vi; + FSBB0__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + VPtRec = PrivAListEvWithHitAllPlanes; + + if ( EvNo == VPtRec[PrivListEvWithHitAllPlanesIndex - 1].FrStatus.FrameNoInRun ) { + return (1); + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt8* FSBB0__TCTelMon::PubFGetPtDispFullMatrix () { + return ( &ProPar.DispFullMatrix ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +FSBB0__TMatDiscriColor* FSBB0__TCTelMon::PubFGetPtFullMatCol () { + return ( &PrivMatDispColor ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +FSBB0__TMatDiscriColorHalfScale* FSBB0__TCTelMon::PubFGetPtHalfMatCol () { + return ( &PrivMatDispColorHalfScale ); +} + +#endif + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/fsbb0.def b/include/pxi_daq_lib_v.2.1/fsbb0.def new file mode 100755 index 0000000..1f79998 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0.def @@ -0,0 +1,204 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_DEF +#define FSBB0_DEF + +#define FSBB0__APP_IGNORE_GC_MOD_220514 + +#define FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + +#ifdef FSBB0__APP_DLL_TEST_ULT1 + #include "fsbb0_test_ult1.def" +#else + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define FSBB0__REG_DISCRI_BIT_SZ 416 // Ult1 = 960 // Mi26 = 1152 +#define FSBB0__REG_DISCRI_W32_SZ 13 // Ult1 = 30 // Mi26 = 36 + + + + + // Size in CLK unit of the frame which contains the readout of ONE line + #define FSBB0__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 832 // Single line = nop scanning mode + #define FSBB0__DISCRI_RO_SCAN_FRAME_CLK_NB 836 // Scanning mode + + + + + +// This register is not implemented on Ultimate +// +// #define FSBB0__REG_AFTER_ZS_BIT_SZ 160 +// #define FSBB0__REG_AFTER_ZS_W32_SZ 5 + +#define FSBB0__REG_AFTER_MUX_BIT_SZ 160 // Mi26 = 160 +#define FSBB0__REG_AFTER_MUX_W32_SZ 5 // Mi26 = 5 + +#define FSBB0__MAT_DISCRI_COL_NB 416 // 23/01/2013 +#define FSBB0__MAT_DISCRI_LINES_NB 424 // +#define FSBB0__MAT_DISCRI_USEFUL_LINES_NB 416 // 23/01/2013 - Without the two markers lines + + +#define FSBB0__ZS_FFRAME_MODE0_1X80MHZ 0 +#define FSBB0__ZS_FFRAME_MODE1_2X80MHZ 1 +#define FSBB0__ZS_FFRAME_MODE2_1X160MHZ 2 +#define FSBB0__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 13312 // 832 W16 // Ult1 = 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 13312 // 832 W16 // Ult1 = 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 13312 //26624 // 1772 W16 // Ult1 = 29696 // 1856 W16 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 13312 //26624 // 1772 W16 // Ult1 = 29696 // 1856 W16 + + + +// #define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +/* +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 416 // Ult1 = 928 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 416 // Ult1 = 928 // Mi26 = 576 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 832 // Ult1 = 1856 // Mi26 = 576 + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 208// Ult1 = 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 208// Ult1 = 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 416// Ult1 = 928 // Mi26 = 144 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 416// Ult1 = 928 // Mi26 = 288*/ + + +// Id to select FSBB0 register + +#define FSBB0__REG_DISCRI 0 +// #define FSBB0__REG_AFTER_ZS 1 -> Not implemented on Ultimate +//#define FSBB0__REG_AFTER_MUX 1 -> not implemented on fsbb +#define FSBB0__REG_DISCRI_SCAN 1 + +#define FSBB0__REG_DISCRI_SCAN__SRC_CLK_160MHZ 2 // 23/06/2010 + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define FSBB0__REG_BIAS_NB 19 + +// $ #define FSBB0__REG_BIAS_ICLPDISC 0 +// $ #define FSBB0__REG_BIAS_IPWRSW 1 +// $ #define FSBB0__REG_BIAS_IBUF 2 +// $ #define FSBB0__REG_BIAS_ID1PWRS 3 +// $ #define FSBB0__REG_BIAS_ID2PWRS 4 +// $ #define FSBB0__REG_BIAS_ILVDSTX 5 +// $ #define FSBB0__REG_BIAS_ILVDSRX 6 +// $ #define FSBB0__REG_BIAS_IVTST1 7 +// $ #define FSBB0__REG_BIAS_IVTST2 8 +// $ #define FSBB0__REG_BIAS_IANABUF 9 +// $ #define FSBB0__REG_BIAS_IVDREF1D 10 +// $ #define FSBB0__REG_BIAS_IVDREF1C 11 +// $ #define FSBB0__REG_BIAS_IVDREF1B 12 +// $ #define FSBB0__REG_BIAS_IVDREF1A 13 +// $ #define FSBB0__REG_BIAS_IVDREF2 14 +// $ #define FSBB0__REG_BIAS_IDIS1 15 +// $ #define FSBB0__REG_BIAS_IDIS2 16 +// $ #define FSBB0__REG_BIAS_IPXI 17 +// $ #define FSBB0__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define FSBB0__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define FSBB0__DIS_MEAS_STEP_PAR_FIRST 0 +#define FSBB0__DIS_MEAS_STEP_PAR_LAST (FSBB0__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define FSBB0__DIS_TEST_MAX_STEP_NB 50 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define FSBB0__NB_MAX_FSBB0_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define FSBB0__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define FSBB0__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define FSBB0__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// FSBB0__TCTelMon +// -------------------- + +#define FSBB0__COLOR_BROWN 0x000066CC +#define FSBB0__COLOR_ORANGE 0x0000A5FF +#define FSBB0__COLOR_YELLOW 0x0000FFFF +#define FSBB0__COLOR_GREEN 0x0000FF00 +#define FSBB0__COLOR_BLUE 0x00FF0000 +#define FSBB0__COLOR_VIOLET 0x00990066 + +#define FSBB0__TCTelMon__COL_PLANE_0 (TColor) FSBB0__COLOR_ORANGE +#define FSBB0__TCTelMon__COL_PLANE_1 (TColor) FSBB0__COLOR_BLUE +#define FSBB0__TCTelMon__COL_PLANE_2 (TColor) FSBB0__COLOR_BROWN +#define FSBB0__TCTelMon__COL_PLANE_3 (TColor) FSBB0__COLOR_YELLOW +#define FSBB0__TCTelMon__COL_PLANE_4 (TColor) FSBB0__COLOR_GREEN +#define FSBB0__TCTelMon__COL_PLANE_5 (TColor) FSBB0__COLOR_VIOLET + + +#define FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0.h b/include/pxi_daq_lib_v.2.1/fsbb0.h new file mode 100755 index 0000000..4bbebc7 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0.h @@ -0,0 +1,58 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.h +Goal : Functions prototypes of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* FSBB0_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + +// $ FHEAD ( SInt32 FSBB0_FBegin ( SInt8 FileErrLogLvl, char* FileErrFile );) +// $ FHEAD ( SInt32 FSBB0_FEnd ();) +FHEAD ( UInt8 FSBB0_FHammingDecoder8_4(UInt8 CodedIn);) +FHEAD ( char * FSBB0_FGetConfigName(SInt16 ConfigNr);) +FHEAD ( FSBB0__TTestPattern FSBB0_FReadConfigFile(char * FilePath, SInt8 PrintLevel);) +FHEAD ( FSBB0__TMatDiscriBit FSBB0_FReadResultBitFile(char * FilePath, SInt8 PrintLevel);) +FHEAD ( SInt32 FSBB0_FPrintZsFFrameRawHeader ( FSBB0__TZsFFrameRaw* Pt );) +FHEAD ( SInt32 FSBB0_FPrintZsFFrameRaw ( FSBB0__TZsFFrameRaw* Pt, SInt16 FirstW32, SInt16 LastW32 );) + +FHEAD ( SInt32 FSBB0__FRegDiscriConvW32ToBit ( UInt32* PtSrc, SInt8* PtDest, SInt16 DiscriW32Sz );) +FHEAD ( SInt32 FSBB0__FRegDiscriConvBitToW32 ( SInt8* PtSrc, UInt32* PtDest, SInt16 DiscriW32Sz );) +FHEAD ( SInt32 FSBB0__FDiscriMatConvW32ToBit ( FSBB0__TMatDiscriW32* PtSrc, FSBB0__TMatDiscriBit* PtDest );) +FHEAD ( SInt32 FSBB0__FDiscriMatConvBitToW32 ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriW32* PtDest );) + +FHEAD ( SInt32 FSBB0__FDiscriMatPrintHit ( FSBB0__TMatDiscriBit* PtMat, UInt32 Line, UInt32 FirstCol, UInt32 LastCol );) +FHEAD ( SInt32 FSBB0__FDiscriEmulHit ( FSBB0__TMatDiscriW32* PtDest, SInt16 HitPattern, SInt16 Hit0Line, SInt16 Hit0Col, SInt16 Hit1Line, SInt16 Hit1Col, SInt16 Hit2Line, SInt16 Hit2Col, SInt16 Hits0AllCol, SInt16 Hits1AllCol, SInt16 Hits2AllCol );) + +FHEAD ( SInt32 FSBB0__FMatDiscriPrintHit ( char* CmtStrTitle, SInt8 CmtSInt8MapsId, FSBB0__TMatDiscriBit* PtDest );) + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef FSBB0_H + #define FSBB0_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0.typ b/include/pxi_daq_lib_v.2.1/fsbb0.typ new file mode 100755 index 0000000..c464c9f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0.typ @@ -0,0 +1,1233 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_TYP +#define FSBB0_TYP + +#ifdef ROOT_ROOT + typedef UInt32 FSBB0__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor FSBB0__TColor; +#endif + + + + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +// $ typedef struct { +// $ +// $ SInt8 FileErrLogLvl; +// $ char FileErrFile[GLB_FILE_PATH_SZ]; +// $ +// $} FSBB0__TContext; + +/* ============================================================================ */ +/* Discri register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[FSBB0__REG_DISCRI_W32_SZ]; + SInt8 ADataBit[FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TRegDiscri; + +/* ============================================================================ */ +/* Discri register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[FSBB0__REG_DISCRI_W32_SZ]; + +} FSBB0__TRegDiscriW32; + + +/* ============================================================================ */ +/* Discri register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TRegDiscriBit; + + +/* ============================================================================ */ +/* Discri matrix dual view : W32 or Bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + FSBB0__TRegDiscri ALine[FSBB0__MAT_DISCRI_LINES_NB]; + +} FSBB0__TMatDiscri; + +/* ============================================================================ */ +/* Discri matrix view as W32 array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AALineW32[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_W32_SZ]; + +} FSBB0__TMatDiscriW32; + +/* ============================================================================ */ +/* Discri matrix view as bit array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriBit; + + +typedef struct { + + float AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriBitf; + + +/* ============================================================================ */ +/* Discri matrix view as bit array - BUT scale 1/4 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 23/07/2009 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[FSBB0__MAT_DISCRI_LINES_NB / 2][FSBB0__REG_DISCRI_BIT_SZ / 2]; + +} FSBB0__TMatDiscriBitHalfScale; + + + +/* ============================================================================ */ +/* After Zero Sup register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + UInt32 ADataW32[FSBB0__REG_AFTER_ZS_W32_SZ]; + SInt8 ADataBit[FSBB0__REG_AFTER_ZS_BIT_SZ]; + +} FSBB0__TRegAfterZs; +*/ + +/* ============================================================================ */ +/* After Zero Sup register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + UInt32 AW32[FSBB0__REG_AFTER_ZS_W32_SZ]; + +} FSBB0__TRegAfterZsW32; +*/ + +/* ============================================================================ */ +/* After Zero Sup register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + SInt8 ABit[FSBB0__REG_AFTER_ZS_BIT_SZ]; + +} FSBB0__TRegAfterZsBit; +*/ + +/* ============================================================================ */ +/* After Mux register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[FSBB0__REG_AFTER_MUX_W32_SZ]; + SInt8 ADataBit[FSBB0__REG_AFTER_MUX_BIT_SZ]; + +} FSBB0__TRegAfterMux; + +/* ============================================================================ */ +/* After Mux register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[FSBB0__REG_AFTER_MUX_W32_SZ]; + +} FSBB0__TRegAfterMuxW32; + + +/* ============================================================================ */ +/* After Mux register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[FSBB0__REG_AFTER_MUX_BIT_SZ]; + +} FSBB0__TRegAfterMuxBit; + + + +/* ======================================================= */ +/* Frame provided by FSBB0 DAQ, it's independent of output */ +/* mode BUT data are not organized as in FSBB0__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by FSBB0__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +/* typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + + + UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + + } FSBB0__TZsFFrameRaw; */ + + + + + + //typedef struct { + // + // ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + // UInt32 Header; // Header of Mimosa 26 frame + // UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + // UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + // UInt32 Trailer; // Trailer of Mimosa 26 frame + + // UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + // UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + //} FSBB0__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + + //typedef union { + + // UInt16 W16; + + // struct { + + // UInt16 StateNb : 4; + // UInt16 LineAddr : 11; + // UInt16 Ovf : 1; + + // } F; + + //} FSBB0__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +// typedef union { + +// UInt16 W16; + +// struct { + +// UInt16 HitNb : 2; +// UInt16 ColAddr : 11; +// UInt16 NotUsed : 3; + +// } F; + +// } FSBB0__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +// typedef struct { + +// FSBB0__TStatesLine StatesLine; +// FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +// } FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by FSBB0, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +//typedef struct { + +//ASIC__TFrameStatus SStatus; + +//UInt32 Header; +//UInt32 FrameCnt; +//UInt32 DataLength; +// SInt16 TrigSignalLine; +//SInt8 TrigSignalClk; +// SInt16 TrigLine; + +// UInt32 StatesRecNb; // It's NOT a FSBB0 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + +// FSBB0__TZsFStatesRec AStatesRec[FSBB0__ZS_FFRAME_MAX_STATES_REC]; + +// UInt32 Trailer; +// UInt32 Zero; +// UInt32 Zero2; + +// } FSBB0__TZsFFrame; // F in FFrame means Fixed size frame + + + + +#ifndef APP__RMV_FSBB0__TCDiscriFile +#ifndef APP__RMV_CLASSES + +// 31/01/2009 + +class FSBB0__TCDiscriFile : public FIL__TCBinFile { + + + private : + + protected : + + + public : + + FSBB0__TCDiscriFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~FSBB0__TCDiscriFile (); + + SInt32 PubFConf ( char* DataFile, SInt8 WriteRead, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetEvNb (); + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + SInt32 PubFWriteEv ( FSBB0__TMatDiscriW32* PtSrcMat ); + SInt32 PubFReadNextEv ( FSBB0__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + FSBB0__TMatDiscriW32* PubFReadNextEv (); + SInt32 PubFGotoEv ( SInt32 EvNo ); + SInt32 PubFReadEv ( SInt32 EvNo, FSBB0__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + FSBB0__TMatDiscriW32* PubFReadEv ( SInt32 EvNo ); + + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + +#endif +#endif + +/* ==================================================== */ +/* Discriminators test information file record */ +/* */ +/* - Test no */ +/* - Chip no / comment */ +/* - Number of steps */ +/* - Events nb / step */ +/* - Run no associated to each step */ +/* - Bias used for each step */ +/* - User defined parameters for each step */ +/* The can be used to convert udac / mv etc ... */ +/* */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.cnf contains the structure */ +/* FSBB0__TDisTestCnfFile */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + +// A copy of bias used for the current run +// 10/02/2009 + +typedef struct { + + UInt8 ABias[FSBB0__REG_BIAS_NB]; + +} FSBB0__TBiasCnf; + + +// All information about current discri measurement step +// 10/02/2009 + +typedef struct { + + SInt32 RunNo; + FSBB0__TBiasCnf Bias; + float APar[FSBB0__DIS_MEAS_STEP_MAX_PAR_NB]; + +} FSBB0__TDisMeasStep; + + +// Format of file discri_test_NNNN.cnf +// 10/02/2009 + +/*typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to FSBB0__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + +} FSBB0__TDisMeasHeader; + +typedef struct { + FSBB0__TDisMeasHeader Head; + FSBB0__TDisMeasStep AStep[FSBB0__DIS_TEST_MAX_STEP_NB]; +}FSBB0__TDisTestCnfFile;*/ + + +typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to FSBB0__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + + FSBB0__TDisMeasStep AStep[FSBB0__DIS_TEST_MAX_STEP_NB]; + + +} FSBB0__TDisTestCnfFile; + + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in sub matrices view mode => sub A, B, C, D */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 3D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED per submatrix. */ +/* => Header.SubMatView = 1 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* FSBB0__TDisHitCntAllSubMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of FSBB0__TDisHitCntAllSubMatStepData */ +/* - init a FSBB0__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + SInt32 TestNo; + SInt8 SubMatView; // 0 => whole matrix as single data piece + // 1 => submatrices A, B, C, D + SInt32 StepNb; + char CnfFileName[GLB_FILE_PATH_SZ]; + + +} FSBB0__TDisHitCntHeader; + + +typedef struct { + + float AAASubMat[FSBB0__SUB_MAT_NB][FSBB0__MAT_DISCRI_LINES_NB/ FSBB0__SUB_MAT_NB][FSBB0__REG_DISCRI_BIT_SZ ]; + +} FSBB0__TDisHitCntAllSubMatStepData; + +typedef struct { + + float AAAASubMat [FSBB0__DIS_TEST_MAX_STEP_NB][FSBB0__SUB_MAT_NB][FSBB0__MAT_DISCRI_LINES_NB / FSBB0__SUB_MAT_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TDisHitCntAllSubMatStepDataMG; + +typedef struct { + + FSBB0__TDisHitCntHeader Header; + FSBB0__TDisHitCntAllSubMatStepData FirstStepData; + +} FSBB0__TDisHitCntAllSubMatFile; + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in whole matrix view mode */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 2D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED as ONE matrix. */ +/* => Header.SubMatView = 0 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* FSBB0__TDisHitCntMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of FSBB0__TDisHitCntMatStepData */ +/* - init a FSBB0__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + float AAMat[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TDisHitCntMatStepData; + + +typedef struct { + + FSBB0__TDisHitCntHeader Header; + FSBB0__TDisHitCntMatStepData FirstStepData; + +} FSBB0__TDisHitCntMatFile; + + + +typedef struct { + + SInt8 AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ/ FSBB0__SUB_MAT_NB ]; + +} FSBB0__TSubMatDiscriBit; + +typedef struct { + + FSBB0__TColor AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriColor; + + +typedef struct { + + FSBB0__TColor AALineCol[FSBB0__MAT_DISCRI_LINES_NB / 2][FSBB0__REG_DISCRI_BIT_SZ / 2]; + +} FSBB0__TMatDiscriColorHalfScale; + + +typedef struct { + + FSBB0__TColor AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ / FSBB0__SUB_MAT_NB]; + +} FSBB0__TSubMatDiscriColor; + + +// To store "1" count on each discri for N events + +typedef struct { + + SInt32 ABit[FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TRegDiscriCumul; + + +// To store % of "1" on each discri for N events + +typedef struct { + + float ABit[FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TRegDiscriPerCent; + +// To store "1" count on whole matrix for N events + +typedef struct { + + UInt16 AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriCumul; + + +typedef struct { + + UInt16 AALineCol[FSBB0__MAT_DISCRI_LINES_NB / 2][FSBB0__REG_DISCRI_BIT_SZ / 2]; + +} FSBB0__TMatDiscriCumulHalfScale; + + +// To store % of "1" on whole matrix for N events + +typedef struct { + + float AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriPerCent; + + +typedef struct { + + float AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ/ FSBB0__SUB_MAT_NB]; + +} FSBB0__TSubMatDiscriPerCent; + + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + + +// DPXI__FSBB0_NB_MAX_FSBB0_PER_DAQ + +typedef FSBB0__TZsFFrame FSBB0__TAZsFFrame[FSBB0__NB_MAX_FSBB0_PER_DAQ]; + + + +typedef struct { + + // Date & Time + + UInt32 StartDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StartTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Asic conf + + UInt8 AsicName; // Value of enumerated ASIC__TEAsicName defined in asic.def + SInt8 AsicNb; // Number of Asic read by DAQ + + // Trigger mode + + SInt8 SwTrigEnabled; // Enable automatic start of acquisition on first trigger of a spill + // - 0 => Board starts upon acquisition request command, don't care about trigger + // - 1 => After acquisition request command, board wait on first trigger to start + // Trigger detection is done by sw, therefore it has a latency of N x 15 ms + + SInt8 HwTrigModeSavedData; // Trigger mode + // - 0 => Run contains all frames : with OR without trigger + // - 1 => Run contains ONLY frames with a trigger + // - More trigger modes may be defined later + + SInt32 HwTrigPar[FSBB0__TZSRunCnf__HW_TRIG_PAR_NB]; // Parameter about trigger handling -> enumerated DPXI__TEHwTrigPar in daq_pix.def + // - DPXI__HW_TRIG_PAR__OFFSET -> Offset which must be added to trigger position to get real position + // - DPXI__HW_TRIG_PAR__WINDOW -> Number of frame acquired after trigger + // - DPXI__HW_TRIG_PAR_NB -> Max parameters number + + + // Run parameters + + SInt32 RunNo; // Run number + SInt8 RunSave; // Save (1) or Not (0) data + SInt8 RunSaveMode; // Save mode -> Reserved for future use + SInt32 RunEvNb; // Event number in run + SInt32 RunFileEvNb; // Event number per file + +} FSBB0__TZSRunCnf; + + +typedef struct { + + // Date & Time + + UInt32 StopDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StopTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Status + + SInt32 EvNbTaken; // Real number of events taken must be <= FSBB0__TZSRunCnf.RunEvNb + SInt32 RejAcqNb; // Number of acquistion rejected in case of Mimosa 26 data error ( bad header, trailer etc ... ) + + SInt32 ARejAcqList[FSBB0__TZSRunRes__MAX_ACQ_REJ_NB]; // List of rejected acquisition + +} FSBB0__TZSRunRes; + + +// 09/07/2009 + +#ifndef APP__RMV_CLASSES + +class FSBB0__TCZsRunRW { + + private: + + SInt32 PrivFInitForNewRunLoading (); + + // Object + + FIL__TCBinFile* ProPtBinFile; + + protected: + + // Parameters + + char ProParRunDir[GLB_FILE_PATH_SZ]; + SInt32 ProParRunNo; + SInt32 ProParCurFSBB0No; + SInt32 ProParCurEvNo; + + SInt8 ProParMeasTime; + SInt8 ProParPrintMsg; + SInt8 ProParPrintEvHeader; + + // Informations from run conf file OR calculated + + char ProRunCnfFile[GLB_FILE_PATH_SZ]; + char ProRunResFile[GLB_FILE_PATH_SZ]; + + FSBB0__TZSRunCnf ProRecZSRunCnf; + FSBB0__TZSRunRes ProRecZSRunRes; + + SInt32 ProInfRunFSBB0Nb; + SInt32 ProInfRunEvNb; + SInt32 ProInfRunFileSz; + SInt32 ProInfRunEvNbPerFile; + SInt32 ProInfRunBlocNbPerFile; + SInt32 ProInfZsFFrameRawSz; + + // Intermediate variables for processing + + SInt8 ProConfDone; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + + + SInt8 ProLastEvAccessDoneInOneFSBB0Mode; + SInt32 ProCurBlocNoInRun; + SInt32 ProCurFileNo; + SInt32 ProCurBlocNoInFile; + char ProCurFileName[GLB_FILE_PATH_SZ]; + + FSBB0__TZsFFrameRaw* ProPtFFrameRaw; + + + public: + + FSBB0__TCZsRunRW (); + ~FSBB0__TCZsRunRW (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + SInt32 PubFSetMeasTime ( SInt8 Yes ); + SInt32 PubFSetPrintMsg ( SInt8 Print ); + SInt32 PubFSetPrintEvHeader ( SInt8 Print ); + + SInt32 PubFGetMeasTime (); + SInt32 PubFGetPrintMsg (); + SInt32 PubFGetPrintEvHeader (); + + SInt32 PubFGetFSBB0Nb (); + SInt32 PubFGetEvNb (); + SInt32 PubFGetEvNbPerFile (); + + SInt32 PubFLoadRun ( char* RunDir, UInt32 RunNo ); + + FSBB0__TZsFFrameRaw* PubFGotoEvOneFSBB0 ( SInt8 FSBB0No, SInt32 EvNo ); + FSBB0__TZsFFrameRaw* PubFGotoEvAllFSBB0 ( SInt32 EvNo ); + + SInt32 PubFCloseRun (); + +}; + +#endif + +// 01/08/09 + +typedef struct { + + UInt32 IndexInEvWithHitList; + ASIC__TFrameStatus FrStatus; + +} FSBB0__TCTelMon_TEltListEvWithHitAllPlanes; + + +// 02/08/09 + +typedef struct { + + SInt16 x; + SInt16 y; + +} FSBB0__TCTelMon_THit; + +// 02/08/09 + +typedef struct { + + FSBB0__TCTelMon_THit AAHits[MAPS__TCDigTelMon_MAX_PLANE_NB][MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE]; + SInt32 AHitsNbPerPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + SInt32 EvNoInRun; + +} FSBB0__TCTelMon_TTrack; + +// 02/08/09 + +typedef struct { + + SInt8 Full; + SInt8 PlaneNb; + SInt32 EvNb; + FSBB0__TCTelMon_TTrack ATracks[MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB]; + + +} FSBB0__TCTelMon_TResRun; + + +// 17/07/09 + +#ifndef ROOT_ROOT + +#ifndef APP__RMV_CLASSES + +class FSBB0__TCTelMon : public MAPS__TCDigTelMon { + + private: + + SInt8 PrivStopProc; + + // ------------------------------------------- + // Plot colors of planes for coincidence mode + // ------------------------------------------- + + FSBB0__TColor PrivAPlanePlotColor[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // ------------------------------------------------------ + // Variables to store frames : pixel, cumul, plot color + // ------------------------------------------------------ + + FSBB0__TZsFFrameRaw* PrivPtAcqData; // Copy of Acq data, enabled if MakeLocalCpy parameter of PubFAddEvents (...) is set + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, FSBB0__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + SInt32 PrivAcqEvNb; // Event nb of current Acq = parameter EvNb of last PubFAddEvents (...) call + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, FSBB0__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + + FSBB0__TZsFFrame PrivZsFFrame; // Tmp var to store ZsFFrameRaw converted to ZsFFrame + // Used for each frame converted + + FSBB0__TMatDiscriBit PrivMatDiscriCoin; // Result for planeS coin plot AS PIXELS full scale matrix + FSBB0__TMatDiscriCumul PrivMatDiscriCoinCum; // Result for planeS coin cumul plot AS COUNT full scale matrix + + FSBB0__TMatDiscriBitHalfScale PrivMatDiscriBitHalfScale; // Result for planeS coin plot AS PIXELS 1/2 scale matrix + FSBB0__TMatDiscriCumulHalfScale PrivMatDiscriCumHalfScale; // Result for planeS coin cumul plot AS COUNT 1/2 scale matrix + + FSBB0__TMatDiscriColor PrivMatDispColor; // Result in matrix color data for ALL KINDS of plots + FSBB0__TMatDiscriColorHalfScale PrivMatDispColorHalfScale; // Result in 1/2 scale matrix color data for ALL KINDS of plots + + // ===================================================================== + // Lists to store informations results of events processing + // ===================================================================== + + // Flag to enable / disable list update + // It's useful to disable list update for data re-processing ( off-line ) with information of list + // because list informations should not been updates while using them for current data processing ... + // + // The following methods set this flag to one + // - PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ) + + SInt8 PriEnListEvWitHitUpdate; + SInt8 PriEnListEvWithTrigUpdate; + + // --------------------------- + // List of events with trigger + // --------------------------- + + SInt32 PrivListEvWithTrigIndex; // Current elt index + SInt8 PrivListEvWithTrigFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithTrig[FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB]; + + // --------------------------- + // List of events with hit(s) + // --------------------------- + + SInt32 PrivListEvWithHitIndex; // Current elt index + SInt8 PrivListEvWithHitFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithHit[FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB]; // List + + // ----------------------------------------- + // List of events with hit(s) on all planes + // ----------------------------------------- + + SInt32 PrivListEvWithHitAllPlanesIndex; // Currenr elt index + SInt8 PrivListEvWithHitAllPlanesFull; // Full flag + SInt8 PrivListEvWithHitAllPlanesCurProcMode; // Current processing mode + // Uses to know if data must be reprocessed in cas user + // has changed list mode via ProPar.ListHitAllPlanesMode + + // The list array ( dynamic allocation ) + + FSBB0__TCTelMon_TEltListEvWithHitAllPlanes* PrivAListEvWithHitAllPlanes; + + // --------------------------------------------------------------------- + // Result run after data processing + // --------------------------------------------------------------------- + + FSBB0__TCTelMon_TResRun* PrivPtResRun; + + // --------------------------------------------------------------------- + // General init function : reset all variables, called by constructor + // --------------------------------------------------------------------- + + SInt32 PrivFInit (); + + // --------------------------------------------------------------------- + // Processing function + // --------------------------------------------------------------------- + + SInt32 PrivFConvZsFFrameToMatDiscriBitAndCumul ( SInt32 DbgEvNo, SInt8 Mode, SInt8 PlaneNo, SInt8 PlaneSelForCoin, SInt8 EvNo, SInt8 EvSelForPlot, FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDestFrameBit, FSBB0__TMatDiscriBit* PtDestCoinBit, FSBB0__TMatDiscriCumul* PtDestFrameCum, FSBB0__TMatDiscriCumul* PtDestCoinCum, SInt8 PrintLvl ); + + + // --------------------------------------------------------------------- + // Lists ( events with trigger / hit ) add events functions + // --------------------------------------------------------------------- + + SInt32 PrivFAddEvInListEvWithTrig ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt ); + SInt32 PrivFAddEvInListEvWithHit ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt, SInt8 HitOnAllPlanes, SInt8 SingleHitOnEachPlane ); + + protected: + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Process one frame = one event of plane specified by Id (0..5) + + SInt32 ProFProcessPlane ( SInt32 DbdEvNo, SInt8 Id, FSBB0__TZsFFrameRaw* PtSrc ); + + + + public: + + // -------------------------------------------------------------------------- + // Flag to select one Acq off-line processing / full RUN off-line processing + // -------------------------------------------------------------------------- + // Will be done via a method later + // 06/08/2009 + // -------------------------------------------------------------------------- + + SInt8 PubAcqOffLineProcOrRunOffLineProc; + + // ------------------------------------------- + // Constructor & Destructor + // ------------------------------------------- + + FSBB0__TCTelMon (); + ~FSBB0__TCTelMon (); + + // ------------------------------------------------------------ + // Begin method => MUST be called before ANY other function ! + // ------------------------------------------------------------ + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 MaxBuffEvNb ); + + // ------------------------------------------- + // GUI handling methods + // ------------------------------------------- + + #ifndef ROOT_ROOT + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGetGuiPar (); + + #endif + + // ------------------------------------------- + // Run control methods + // ------------------------------------------- + // Allocate / free buffers + // ------------------------------------------- + + SInt32 PubFStartRun ( SInt8 MapsNb ); + SInt32 PubFStopRun (); + + // ------------------------------------------- + // Monitoring control methods + // ------------------------------------------- + + SInt32 PubFStartMon (); + SInt32 PubFStopMon (); + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Add events in on-line monitoring mode and call data processing methods ( protected ) + + SInt32 PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt32 EvNb, FSBB0__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + // Off-line processing of data + // WARNING : NOW - 26/07/2009 - IT'S ONLY data of LAST acquisition ( data provided by last call to PubFAddEvents ) + // => Uses as events number the one of last acq + // => Force mode to "Process one Acq" AND update GUI parameters + + SInt32 PubFProcessOffLineCurAcq (); + SInt32 PubFProcessOffLineCurAcq2 (); + + // Select frame to plot + + SInt32 PubFGotoFirstFrame (); + SInt32 PubFGotoPrevFrame (); + SInt32 PubFGotoNextFrame (); + SInt32 PubFGotoLastFrame (); + + // ------------------------------------------- + // Results print methods + // ------------------------------------------- + + // Print list of events with a trigger detected => print SStatus record + + SInt32 PubPrintListEvWithTrig ( SInt8 Verbose ); + + // Print list of events with at least one hit in one plane => print SStatus record + + SInt32 PubPrintListEvWithHit ( SInt8 Verbose ); + + // Print list of events with hit on ALL planes => print SStatus record + + SInt32 PubPrintListEvWithHitOnAllPlanes ( SInt8 Verbose ); + + // Print res run + + SInt32 PubAllocResRun (); + SInt32 PubFreeResRun (); + SInt32 PubPrintResRun (); + SInt32 PubSaveResRun ( char* FileName ); + + + SInt32 PubFIsEvInListEvWithHitOnAllPlanes ( SInt32 EvNo ); + SInt32 PubFIsEvLastOfListEvWithHitOnAllPlanes ( SInt32 EvNo ); + + SInt32 PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ); + + + // ------------------------------------------- + // Results plot methods + // ------------------------------------------- + + // There is NO plot method in class. + // + // Because a call of a plot function ( from plot lib ) in DAQ supervisor thread doesn't work + // - nothing is displayed ! + // - this may crash the application + // I don't know why and have no time to study and understand this bug. I have found a workarround + // by calling the plot function in an application timer. + // + // The class request plot by setting the flag ProRequestPlot to 1 + // plot is done by "plot timer" callback in application which + // reset the flag ProRequestPlot after plot. + + // The application "plot timer" must know : + // - when he must plot --> Test variable pointed by PubFGetPtPlotRq () + // - the matrix to plot : full / half scale --> Test variable pointed by PubFGetPtDispFullMatrix () + // - the data to plot --> Read via pointer given by PubFGetPtFullMatCol () / PubFGetPtHalfMatCol () + // + // Polling of plot request and access to data is NOT DONE via method calls because + // - calling class methods in timer while other methods may be called in DAQ supervisor thread MAY cause problems => No detailed understanding, no time ... + // - it will save execution time by avoiding function call + + SInt8* PubFGetPtDispFullMatrix (); + FSBB0__TMatDiscriColor* PubFGetPtFullMatCol (); + FSBB0__TMatDiscriColorHalfScale* PubFGetPtHalfMatCol (); + + +}; + + + +enum { +FSBB0_EMUL_HITS, FSBB0_EMUL_ALL_ZERO,FSBB0_EMUL_ALL_ONE, FSBB0_EMUL_CROSS, FSBB0_EMUL_BORDER +} FSBB0_EHitEmulType; + + + + + +#endif + + +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0.var b/include/pxi_daq_lib_v.2.1/fsbb0.var new file mode 100755 index 0000000..2b82a35 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0.var @@ -0,0 +1,36 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.var +Goal : Variables definition of fsbb library. + : It provides fsbb types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_VAR +#define FSBB0_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC FSBB0__TMatDiscriBit FSBB0__VGMatDiscriBitRef; +// 23/09/14 - MS +EXTERN VAR_STATIC FSBB0__TMatDiscriBit FSBB0__TESTBT_VGMatDiscriBitRef[6]; + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_110614.c b/include/pxi_daq_lib_v.2.1/fsbb0_110614.c new file mode 100755 index 0000000..3a15752 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_110614.c @@ -0,0 +1,7346 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.c +Goal : Functions of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_C +#define FSBB0_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// $ SInt32 FSBB0__FBegin ( SInt8 FileErrLogLvl, char* FileErrFile ) { + +// $ FSBB0__VGContext.FileErrLogLvl = FileErrLogLvl; +// $ strcpy ( FSBB0__VGContext.FileErrFile, FileErrFile ); + +// $ err_retok (( ERR_OUT, "" )); +// $} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// $SInt32 FSBB0__FEnd () { + + +// $ err_retok (( ERR_OUT, "" )); +// $} + + + +/* ------------------------------ */ +/* General functions for MAPS */ +/* ------------------------------ */ + + + +/******************************************************************************* +Prototype : SInt8 SUZE02_FHammingDecoder8_4(UInt8 CodedIn) + +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 10/07/2013 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + + SInt8 FSBB0_FHammingDecoder8_4(UInt8 CodedIn) + { + UInt8 VSyndrome; + UInt8 VParity; + SInt8 VResult; + UInt8 VTempResult; + UInt8 VError; + + VSyndrome = ((((CodedIn & 0x8)>>3)^((CodedIn & 0x10)>>4)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6))<<2 + + (((CodedIn & 0x2)>>1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6))<<1 + + ((CodedIn & 0x1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x10)>>4)^((CodedIn & 0x40)>>6))); + // Parity bit + + VParity = (CodedIn & 0x1)^((CodedIn & 0x2)>>1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x8)>>3)^((CodedIn & 0x10)>>4)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6); + VTempResult = CodedIn; + switch (VSyndrome ) + { + case 0 : { + // No Trans Error + // Nothing to do + break; + } + case 1 :{ + // Error on bit 0 + VTempResult ^= 0x1; + break; + } + case 2 : { + // Error on bit 1 + VTempResult ^= 0x2; + break; + } + case 3 : { + // Error on bit 2 + VTempResult ^= 0x4; + break; + } + case 4 : { + // Error on bit 3 + VTempResult ^= 0x8; + break; + } + case 5 : { + // Error on bit 4 + VTempResult ^= 0x10; + break; + } + case 6 : { + // Error on bit 5 + VTempResult ^= 0x20; + break; + } + default : { + // Error on bit 6 + VTempResult ^= 0x40; + break; + } + } /* end switch */ + // ------------------------------------------------------------- // + if (VSyndrome == 0){ + VError = 0; + } + else{ + if (VParity == ((CodedIn & 0x80)>>7)){ + VError = 5; + } + else{ + VError = 3; + } + } + VResult = ((VTempResult & 2)>>2) + ((VTempResult & 16)>>3) + ((VTempResult & 32)>>3) + ((VTempResult & 64)>>3); + err_trace (( ERR_OUT, "FSBB0_FHammingDecoder8_4, result :%X, Error code : %X",VResult,VError )); + + return (VResult); + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__MAPS__FRegDiscriCumulResetHit ( SInt32* PtDestCumul, SInt16 DiscriNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + PtDestCumul[Vi] = 0; + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__MAPS__FRegDiscriCumulAddHit ( SInt8* PtSrcDiscri, SInt32* PtDestCumul, SInt16 DiscriNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + + if ( PtSrcDiscri[Vi] == 1 ) { + ++PtDestCumul[Vi]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__MAPS__FRegDiscriCumulCalcPercent ( SInt32* PtSrcCumul, float* PtDestPercent, SInt16 DiscriNb, SInt16 EvNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + PtDestPercent[Vi] = 100* ((float) PtSrcCumul[Vi] / (float) EvNb); + } + + err_retok (( ERR_OUT, "" )); +} + + +// 25/02/2009 + +SInt32 FSBB0__MAPS__FRegDiscriCumulCountHits ( SInt32* PtSrcCumul, float* PtDestPercent, SInt16 DiscriNb, SInt16 EvNb ) { + + SInt16 Vi; + SInt32 VHiCnt; + + VHiCnt = 0; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + VHiCnt = VHiCnt + PtSrcCumul[Vi]; + PtDestPercent[Vi] = PtSrcCumul[Vi]; + } + + // err_retok (( ERR_OUT, "" )); + + return (VHiCnt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Set parameter FirstW16 or LastW16 to -1 to avoid data W16 printing +: +Level : +Date : 16/02/2009 +Rev : 17/06/2009 + : - Print Triger + +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0_FPrintZsFFrameRawHeader ( FSBB0__TZsFFrameRaw* Pt ) { + + UInt16 Vi; + + err_retnull ( Pt, (ERR_OUT,"Pt == NULL") ); + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "AsicNo = %4d [D]", Pt->SStatus.AsicNo )); + msg (( MSG_OUT, "AcqNo = %4d [D]", Pt->SStatus.AcqNo )); + msg (( MSG_OUT, "FrameNoInAcq = %4d [D]", Pt->SStatus.FrameNoInAcq )); + msg (( MSG_OUT, "FrameNoInRun = %4d [D]", Pt->SStatus.FrameNoInRun )); +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + msg (( MSG_OUT, "TrigSignalLine = %4d [D]", Pt->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE] )); + msg (( MSG_OUT, "TrigSignalClk = %4d [D]", Pt->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK] )); + msg (( MSG_OUT, "TrigLine = %4d [D]", Pt->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__LINE] )); + msg (( MSG_OUT, "TotTrigNb = %4d [D]", Pt->SStatus.ATrigRes[ASIC__FSBB0_TRIG_TOT_NB] )); +//#endif + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, "Header = %4x [H]", Pt->Header )); + msg (( MSG_OUT, "Trigger = %4x [h]", Pt->Trigger )); + msg (( MSG_OUT, "FrameCnt = %4d [D]", Pt->DataLengthRemFrCnt.F.FrameCnt )); + msg (( MSG_OUT, "CalcDataLength = %4d [D]", Pt->CalcDataLength )); + msg (( MSG_OUT, " - DataLength = %4d [D]", Pt->DataLengthRemFrCnt.F.DataLength )); + msg (( MSG_OUT, " - Rem = %4d [D]", Pt->DataLengthRemFrCnt.F.Rem )); + msg (( MSG_OUT, "Trailer = %4x [H]", Pt->Trailer )); + msg (( MSG_OUT, "=======================================" )); + + msg (( MSG_OUT, "" )); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Set parameter FirstW16 or LastW16 to -1 to avoid data W16 printing +: +Level : +Date : 09/12/2008 +Rev : 22/05/2014 - MS + : Applied the modifications from GC in fsrr_usr.typ and fsbb_usr.def +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0_FPrintZsFFrameRaw ( FSBB0__TZsFFrameRaw* Pt, SInt16 FirstW32, SInt16 LastW32 ) { + + UInt16 Vi; + + err_retnull ( Pt, (ERR_OUT,"Pt == NULL") ); + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "Header = %4x [H]", Pt->Header )); + msg (( MSG_OUT, "FrameCnt = %4x [H]", Pt->DataLengthRemFrCnt.F.FrameCnt )); + msg (( MSG_OUT, "CalcDataLength = %4d [D]", Pt->CalcDataLength )); + msg (( MSG_OUT, " - DataLength = %4d [D]", Pt->DataLengthRemFrCnt.F.DataLength )); + msg (( MSG_OUT, " - Rem = %4d [D]", Pt->DataLengthRemFrCnt.F.Rem )); + msg (( MSG_OUT, "Trailer = %4x [H]", Pt->Trailer )); + msg (( MSG_OUT, "=======================================" )); + + if ( (FirstW32 < 0) || (LastW32 < 0) || (LastW32 < FirstW32) ) { + err_retok (( ERR_OUT, "No W32 to print OR bad parameters ? FirstW32=%d - LastW32=%d", FirstW32, LastW32 )); + } + + for ( Vi=FirstW32; Vi <= LastW32; Vi++ ) { + msg (( MSG_OUT, "[W %4d] = %4x [H] - %4d [D]", Vi, Pt->ADataW32[Vi], Pt->ADataW32[Vi] )); + } + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* ------------------------------ */ +/* Specific functions for FSBB0 */ +/* ------------------------------ */ + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FRegDiscriConvBitToW32 ( SInt8* PtSrc, UInt32* PtDest, SInt16 DiscriW32Sz ) { + + + SInt32 ViDiscri; + SInt32 ViDestW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViDestW32=0; ViDestW32 < DiscriW32Sz; ViDestW32++ ) { + + PtDest[ViDestW32] = 0; + VMask = 1; + + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + + if ( PtSrc[ViDiscri] == 1 ) { + PtDest[ViDestW32] = PtDest[ViDestW32] + VMask; + } + + VMask = VMask << 1; + ++ViDiscri; + } + + } + + //err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FRegDiscriConvW32ToBit ( UInt32* PtSrc, SInt8* PtDest, SInt16 DiscriW32Sz ) { + + + SInt32 ViDiscri; + SInt32 ViSrcW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViSrcW32=0; ViSrcW32 < DiscriW32Sz; ViSrcW32++ ) { + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (PtSrc[ViSrcW32] & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + } + + return (0); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FRegDiscriConvW32ToBitAsW32 ( UInt32* PtSrc, SInt32* PtDest, SInt16 DiscriW32Sz ) { + + char VFuncName[] = "FSBB0__FRegDiscriConvW32ToBitAsW32"; + + SInt32 ViDiscri; + SInt32 ViSrcW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViSrcW32=0; ViSrcW32 < DiscriW32Sz; ViSrcW32++ ) { + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (PtSrc[ViSrcW32] & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + } + + return (0); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriConvW32ToBit ( FSBB0__TMatDiscriW32* PtSrc, FSBB0__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + FSBB0__FRegDiscriConvW32ToBit ( PtSrc->AALineW32[ViLine], PtDest->AALineCol[ViLine], FSBB0__REG_DISCRI_W32_SZ ); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 + : 20/05/2014 - MS : replaced 1152 by FSBB0__MAT_DISCRI_COL_NB in the line multiplicator +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriConvW32ToBitAsW32 ( FSBB0__TMatDiscriW32* PtSrc, SInt32* PtDest ) { + + char VFuncName[] = "FSBB0__FMatDiscriConvW32ToBitAsW32"; + + SInt32 ViLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + FSBB0__FRegDiscriConvW32ToBitAsW32 ( PtSrc->AALineW32[ViLine], &PtDest[ViLine * FSBB0__MAT_DISCRI_COL_NB], FSBB0__REG_DISCRI_W32_SZ ); + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FSubMatDiscriBitAsW32Copy ( SInt32* PtSrc, SInt32* PtDest, SInt8 Matrix ) { + + char VFuncName[] = "FSBB0__FSubMatDiscriBitAsW32Copy"; + + SInt32 ViLine; + SInt32 ViCol; + SInt32 ViPixSrc; + SInt32 ViPixDest; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + ViPixDest = 0; + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB / FSBB0__SUB_MAT_NB); ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + ViPixSrc = (ViLine * FSBB0__REG_DISCRI_BIT_SZ) + ViCol; + PtDest[ViPixDest] = PtSrc[ViPixSrc]; + ++ViPixDest; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriEmulHit ( FSBB0__TMatDiscriW32* PtDest, SInt16 HitPattern, SInt16 Hit0Line, SInt16 Hit0Col, SInt16 Hit1Line, SInt16 Hit1Col, SInt16 Hit2Line, SInt16 Hit2Col, SInt16 Hits0AllCol, SInt16 Hits1AllCol, SInt16 Hits2AllCol ) { + + SInt32 ViLine; + SInt32 ViCol; + FSBB0__TMatDiscriBit* PtDestBit; + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + // Reset all hits + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, start" )); + PtDestBit = (FSBB0__TMatDiscriBit*)malloc(sizeof (FSBB0__TMatDiscriBit)); + memset ( PtDestBit, 0, sizeof (FSBB0__TMatDiscriBit) ); + + switch (HitPattern){ + case FSBB0_EMUL_HITS:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_HITS" )); + + // Hit 0 + + if ( (Hit0Line >= 0) && (Hit0Col >= 0) ) { + PtDestBit->AALineCol[Hit0Line][Hit0Col] = 1; + } + + // Hit 1 + + if ( (Hit1Line >= 0) && (Hit1Col >= 0) ) { + PtDestBit->AALineCol[Hit1Line][Hit1Col] = 1; + } + + // Hit 2 + + if ( (Hit2Line >= 0) && (Hit2Col >= 0) ) { + PtDestBit->AALineCol[Hit2Line][Hit2Col] = 1; + } + + // Hits 0 on all lines of one col + + if ( Hits0AllCol >= 0 ) { + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + PtDestBit->AALineCol[ViLine][Hits0AllCol] = 1; + } + } + + // Hits 1 on all lines of one col + + if ( Hits1AllCol >= 0 ) { + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + PtDestBit->AALineCol[ViLine][Hits1AllCol] = 1; + } + } + + // Hits 2 on all lines of one col + + if ( Hits2AllCol >= 0 ) { + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + PtDestBit->AALineCol[ViLine][Hits2AllCol] = 1; + } + } + break; } + case FSBB0_EMUL_ALL_ZERO:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_ALL_ZERO" )); + // doing nothing because the matrix has been resetted + break;} + case FSBB0_EMUL_ALL_ONE:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_ALL_ONE" )); + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + for ( ViCol=0; ViCol < FSBB0__MAT_DISCRI_COL_NB; ViCol++ ) { + PtDestBit->AALineCol[ViLine][ViCol] = 1; + } + } + break;} + case FSBB0_EMUL_CROSS:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_CROSS" )); + ViCol = 0; + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + PtDestBit->AALineCol[ViLine][ViCol] = 1; + PtDestBit->AALineCol[ViLine][FSBB0__MAT_DISCRI_COL_NB - 1- ViCol] = 1; + ViCol++; + } + break;} + case FSBB0_EMUL_BORDER:{ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, case FSBB0_EMUL_BORDER" )); + // first line and last line + for ( ViCol=0; ViCol < FSBB0__MAT_DISCRI_COL_NB; ViCol++ ) { + PtDestBit->AALineCol[0][ViCol] = 1; + PtDestBit->AALineCol[FSBB0__MAT_DISCRI_USEFUL_LINES_NB - 1][ViCol] = 1; + } + // first col and last col + for ( ViLine=1; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB - 1; ViLine++ ) { + PtDestBit->AALineCol[ViLine][0] = 1; + PtDestBit->AALineCol[ViLine][FSBB0__MAT_DISCRI_COL_NB - 1] = 1; + ViCol++; + } + break;} + } /* end switch */ + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, Emulation done in bits" )); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + FSBB0__FRegDiscriConvBitToW32 ( PtDestBit->AALineCol[ViLine], PtDest->AALineW32[ViLine], FSBB0__REG_DISCRI_W32_SZ ); + } + + msg (( MSG_OUT, "FSBB0__FMatDiscriEmulHit, emulation bit converted to W32" )); + + free (PtDestBit); + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FRegDiscriResetHit ( SInt8* PtDest, SInt16 DiscriBitSz ) { + + SInt16 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // Reset row + + for ( ViCol=0; ViCol < DiscriBitSz; ViCol++ ) { + PtDest[ViCol] = 0; + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FRegDiscriPrintHit ( SInt8* PtSrc ) { + + SInt16 ViCol; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + + msg (( MSG_OUT, "*************************************" )); + msg (( MSG_OUT, "* Print coordinates pixels with hit *" )); + msg (( MSG_OUT, "*************************************" )); + + // Scan row => Print coordinates if hit + + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc[ViCol] == 1 ) { + msg (( MSG_OUT, "Hit => Col [%.4d]", ViCol )); + } + + } + + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FRegDiscriCompare ( SInt8* PtSrc, SInt8* PtRef, SInt8 PrintErrors ) { + + SInt16 ViCol; + SInt32 VErrCnt; + + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtRef, (ERR_OUT,"PtRef == NULL") ); + + // Scan row => Print if error + + VErrCnt = 0; + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc[ViCol] != PtRef[ViCol] ) { + + ++VErrCnt; + + if ( PrintErrors ) { + msg (( MSG_OUT, "Error => Col [%.4d] Read=%d - Must be=%d", ViCol, PtSrc[ViCol], PtRef[ViCol] )); + } + + } + + } + + + err_retval ( VErrCnt, ( ERR_OUT, "Compare done %d errors found !", VErrCnt ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriResetHit ( FSBB0__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + // Scan matrix => Reset hits + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 0; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FMatDiscriPrintHit ( char* CmtStrTitle, SInt8 CmtSInt8MapsId, FSBB0__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + msg (( MSG_OUT, "***************************************************************************" )); + msg (( MSG_OUT, "* Mi28 [%d] %s : Coordinates pixels with hit *", CmtSInt8MapsId, CmtStrTitle )); + msg (( MSG_OUT, "***************************************************************************" )); + + // Scan matrix => Print coordinates if hit + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtDest->AALineCol[ViLine][ViCol] == 1 ) { + msg (( MSG_OUT, "Hit => Line [%.4d] - Col [%.4d]", ViLine, ViCol )); + } + + } + + } + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FMatDiscriCumulResetHit ( FSBB0__TMatDiscriCumul* PtDest ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 0; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FMatDiscriCumulAddHit ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriCumul* PtDest ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + ++ PtDest->AALineCol[ViLine][ViCol]; + } + + } + + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FMatDiscriCumulCalcPercent ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 100 * ( (float) PtSrc->AALineCol[ViLine][ViCol] / (float) EvNb); + } + + } + + err_retok (( ERR_OUT, "" )); +} + +// 06/03/2009 +// Return mean % value of whole matrix +// 23/01/2013 +// - Calculates VMatPerCent on the whole matrix, before it was done on 1/4 matrix assuming +// that Ultimate was tested matrix by matrix = threshold set to 255 on the three matrices not tested + +float FSBB0__FExtMatDiscriCumulCalcPercent ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + float VPixPerCent; + float VSumPerCent; + float VMatPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + VSumPerCent = 0; + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + VPixPerCent = ( (float) PtSrc->AALineCol[ViLine][ViCol] / (float) EvNb); + PtDest->AALineCol[ViLine][ViCol] = 100 * VPixPerCent; + VSumPerCent = VSumPerCent + VPixPerCent; + } + + } + + // 23/01/2013 + + VMatPerCent = 100 * ( (float) VSumPerCent / (float) (FSBB0__MAT_DISCRI_COL_NB * FSBB0__MAT_DISCRI_USEFUL_LINES_NB) ); + + err_retval ( VMatPerCent, ( ERR_OUT, "Matrix %d [%]", VMatPerCent ) ); +} + + +// 25/02/2009 + +SInt32 FSBB0__FMatDiscriCumulCountHits ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + SInt32 VHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + VHitCnt = 0; + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + VHitCnt = VHitCnt + PtSrc->AALineCol[ViLine][ViCol]; + PtDest->AALineCol[ViLine][ViCol] = PtSrc->AALineCol[ViLine][ViCol]; + } + + } + + // err_retok (( ERR_OUT, "" )); + + // msg (( MSG_OUT, "VHitCnt = %d", VHitCnt )); + + return (VHitCnt); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriCopySubMatBit ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TSubMatDiscriBit* PtDest, SInt8 SubMatId ) { + + SInt16 ViLine; + SInt16 ViCol; + SInt16 VLineOffset; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + switch (SubMatId){ + case 0:{ + VLineOffset = 0; + break; } + case 1:{ + VLineOffset = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / FSBB0__SUB_MAT_NB; + break; } + default :{ + err_retfail ( -1, (ERR_OUT,"Unknown sub mat id = %d <> 0, 1", SubMatId) ); + break; } + + + }/* end switch */ + + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB/ FSBB0__SUB_MAT_NB); ViLine++ ) { + + + for ( ViCol=0; ViCol <= FSBB0__REG_DISCRI_BIT_SZ; ViCol++) { + + PtDest->AALineCol[ViLine ][ViCol] = PtSrc->AALineCol[ViLine + VLineOffset][ViCol]; + + } /* End for ViCol */ + + + } /* End for ViLine */ + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvBitToColState ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriColor* PtDest, FSBB0__TColor ColorStateZero, FSBB0__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatFullScaleConvCoinBitToColState ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriColor* PtDest, FSBB0__TColor ColorZeroHit, FSBB0__TColor* AColorOneHit, FSBB0__TColor ColorMultiHit, SInt8 RevertLineDirection ) { + + UInt16 VMatLineNb = FSBB0__MAT_DISCRI_USEFUL_LINES_NB; + UInt16 VMatColNb = FSBB0__REG_DISCRI_BIT_SZ; + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPixState; + FSBB0__TColor VPixColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + /* --------------------- */ + /* Revert line direction */ + /* --------------------- */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][VMatColNb - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* --------------------------- */ + /* Don't revert line direction */ + /* --------------------------- */ + + else { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCoinBitToColStateHalfScale ( FSBB0__TMatDiscriBitHalfScale* PtSrc, FSBB0__TMatDiscriColorHalfScale* PtDest, FSBB0__TColor ColorZeroHit, FSBB0__TColor* AColorOneHit, FSBB0__TColor ColorMultiHit, SInt8 RevertLineDirection ) { + + UInt16 VMatLineNb = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + UInt16 VMatColNb = FSBB0__REG_DISCRI_BIT_SZ / 2; + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPixState; + FSBB0__TColor VPixColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + /* --------------------- */ + /* Revert line direction */ + /* --------------------- */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][VMatColNb - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* --------------------------- */ + /* Don't revert line direction */ + /* --------------------------- */ + + else { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvBitToColStateHalfScale ( FSBB0__TMatDiscriBitHalfScale* PtSrc, FSBB0__TMatDiscriColorHalfScale* PtDest, FSBB0__TColor ColorStateZero, FSBB0__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + SInt32 VMaxCol; + SInt32 VMaxLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + VMaxCol = FSBB0__REG_DISCRI_BIT_SZ / 2; + VMaxLine = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMaxLine; ViLine++ ) { + + for ( ViCol=0; ViCol < VMaxCol; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][VMaxCol - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][VMaxCol - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < VMaxLine; ViLine++ ) { + + for ( ViCol=0; ViCol < VMaxCol; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriSubMatConvBitToColState ( FSBB0__TSubMatDiscriBit* PtSrc, FSBB0__TSubMatDiscriColor* PtDest, FSBB0__TColor ColorStateZero, FSBB0__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB / FSBB0__SUB_MAT_NB); ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ ) - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ ) - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB / FSBB0__SUB_MAT_NB); ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriCopySubMatPerCent ( FSBB0__TMatDiscriPerCent* PtSrc, FSBB0__TSubMatDiscriPerCent* PtDest, SInt8 SubMatId ) { + + SInt16 ViLine; + SInt16 ViCol; + SInt16 VLineOffset; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + switch ( SubMatId ) { + + case 0 : { + VLineOffset = 0; + break; } + + case 1 : { + VLineOffset = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / FSBB0__SUB_MAT_NB; + break; } + + + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown sub mat id = %d <> 0, 1", SubMatId) ); + break; } + + } /* End switch */ + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB/ FSBB0__SUB_MAT_NB); ViLine++ ) { + + for ( ViCol=0; ViCol <= FSBB0__REG_DISCRI_BIT_SZ; ViCol++) { + + PtDest->AALineCol[ViLine ][ViCol] = PtSrc->AALineCol[ViLine+ VLineOffset][ViCol]; + + } /* End for ViColSrc */ + + + } /* End for ViLine */ + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvPerCentToColVal ( FSBB0__TMatDiscriPerCent* PtSrc, FSBB0__TMatDiscriColor* PtDest, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCumulToColVal ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriColor* PtDest, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + FSBB0__TColor VHitStateColor; + FSBB0__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + if ( GrayOrBlueLevels == 0) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ) - 1 - ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCumulToColValHalfScale ( FSBB0__TMatDiscriCumulHalfScale* PtSrc, FSBB0__TMatDiscriColorHalfScale* PtDest, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection, SInt8 PrintLvl ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + FSBB0__TColor VHitStateColor; + FSBB0__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "==============================================" )); + err_error (( ERR_OUT, "= FSBB0__FDiscriMatConvCumulToColValHalfScale =" )); + err_error (( ERR_OUT, "==============================================" )); + } + + + if ( GrayOrBlueLevels == 0) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + err_error (( ERR_OUT, "Blue=%d - HitCnt=%d", GrayOrBlueLevels, PlotHitOrHitCnt )); + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ / 2) - 1 - ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FFFF00 + ( (255-VPixHitCnt) << 8 ); // Blue = 255 / Green = 255 / Red = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + err_error (( ERR_OUT, "==============================================" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCumulCoinOrToColVal ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriColor* PtDest, FSBB0__TColor* AColorOneHit, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + FSBB0__TColor VPixColor; + FSBB0__TColor VHitStateColor; + FSBB0__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( GrayOrBlueLevels == 0 ) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + PtDest->AALineCol[ViLine][FSBB0__REG_DISCRI_BIT_SZ - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriMatConvCumulCoinOrToColValHalfScale ( FSBB0__TMatDiscriCumulHalfScale* PtSrc, FSBB0__TMatDiscriColorHalfScale* PtDest, FSBB0__TColor* AColorOneHit, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection, SInt8 PrintLvl ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + FSBB0__TColor VPixColor; + FSBB0__TColor VHitStateColor; + FSBB0__TColor VHitColor; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "====================================================" )); + err_error (( ERR_OUT, "= FSBB0__FDiscriMatConvCumulCoinOrToColValHalfScale =" )); + err_error (( ERR_OUT, "====================================================" )); + } + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ / 2) - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + err_error (( ERR_OUT, "==============================================" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FPrintMatDiscriCumul ( FSBB0__TMatDiscriCumul* PtSrc ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + + err_error (( ERR_OUT, "===============================" )); + err_error (( ERR_OUT, "= Print FSBB0__TMatDiscriCumul =" )); + err_error (( ERR_OUT, "===============================" )); + + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] != 0 ) { + err_error (( ERR_OUT, "Hit cnt [L:%4d][C:%4d] = %4d", ViLine, ViCol, PtSrc->AALineCol[ViLine][ViCol] )); + } + + } + + } + + err_error (( ERR_OUT, "===============================" )); + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FPrintMatDiscriCumulHalfScale ( FSBB0__TMatDiscriCumulHalfScale* PtSrc ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + + err_error (( ERR_OUT, "========================================" )); + err_error (( ERR_OUT, "= Print FSBB0__TMatDiscriCumulHalfScale =" )); + err_error (( ERR_OUT, "========================================" )); + + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ / 2; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] != 0 ) { + err_error (( ERR_OUT, "Hit cnt [L:%4d][C:%4d] = %4d", ViLine, ViCol, PtSrc->AALineCol[ViLine][ViCol] )); + } + + } + + } + + err_error (( ERR_OUT, "========================================" )); + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FDiscriSubMatConvCumulToColVal ( FSBB0__TSubMatDiscriPerCent* PtSrc, FSBB0__TSubMatDiscriColor* PtDest, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB / FSBB0__SUB_MAT_NB); ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ ); ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ ) - 1 - ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][(FSBB0__REG_DISCRI_BIT_SZ ) - 1 - ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < (FSBB0__MAT_DISCRI_USEFUL_LINES_NB / FSBB0__SUB_MAT_NB); ViLine++ ) { + + for ( ViCol=0; ViCol < (FSBB0__REG_DISCRI_BIT_SZ ); ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][ViCol] = (VPerCent << 8) + (VPerCent << 16);; + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : convert 32 word of 8 bits to a word of 32 bits +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Mathieu GOFFE +E-mail : mathieu.goffe@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef FSBB0__MG_DEV + +SInt32 FSBB0__FnameDiscriConvBitToW32 ( UInt8* PtDest, UInt32 word ) { + + + SInt32 ViDiscri; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( word, (ERR_OUT,"word == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (word & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + msg (( MSG_OUT, "valeur du mot de 32 bit = %d", word )); + return (0); +} + +#else + +SInt32 FSBB0__FnameDiscriConvBitToW32 ( UInt8* PtDest, UInt32 word ) { + return (0); +} + +#endif + + + + + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 17/03/2009 +Doc date : 17/03/2009 +Rev : 04/05/2009 + : - Add a check of data length, if > 1140, force 1140, done to avoid bad + : data length due to transmission errors. + : + : 05/05/2009 + : - Add handling of odd number of W16 ( FSBB0 add one bad W16 in this case ) + : Not done at beginning because FSBB0 documentation was not clear enough + : ( bad translation of " impair " in even ! ) and it was not needed for + : tests done with emulated patterns. + : : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameRawToZsFFrame ( FSBB0__TZsFFrameRaw* Src, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) { + + SInt32 VRetW16Length; + SInt32 ViData; + UInt16 VDataW16LengthLow; + UInt16 VDataW16LengthHigh; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt16 ViSrcW16; + + FSBB0__TStatesLine VStatesLine; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + SInt16 VPrevLine; + + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Get useful data length + //VDataW16LengthLow = Src->DataLength & 0x0000FFFF; + //VDataW16LengthHigh = (Src->DataLength & 0xFFFF0000) >> 16; + VDataW16Length = ((Src->DataLengthRemFrCnt.F.DataLength) * 4) + Src->DataLengthRemFrCnt.F.Rem; + + VRetW16Length = VDataW16Length; + + if ( (PrintLvl == 5) || (PrintLvl == 6) || (PrintLvl == 7) ) { + msg (( MSG_OUT, "TOTAL frame length : %d W16", VDataW16Length )); + msg (( MSG_OUT, "" )); + } + + // Add a check of data length, if > FSBB0__ZS_FFRAME_RAW_MAX_W16, force 0 and continue processing ( no exit on error ) + + if ( VDataW16Length > FSBB0__ZS_FFRAME_RAW_MAX_W16 /* 1140 */ ) { + err_error (( ERR_OUT, "Bad data length get from FSBB0 = %d W16 => Force 0 W16", VDataW16Length )); + VDataW16Length = 0; + Src->CalcDataLength = 0; + // VRetW16Length = -1; + } + + // Copy information fields + + Dest->SStatus = Src->SStatus; + + Dest->Header = Src->Header; + Dest->FrameCnt = Src->DataLengthRemFrCnt.F.FrameCnt; + Dest->DataLength = Src->CalcDataLength; + Dest->Trailer = Src->Trailer; + //Dest->Zero = Src->Zero; + //Dest->Zero2 = Src->Zero2; +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + Dest->TrigSignalLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; + Dest->TrigSignalClk = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__LINE]; +//#endif + + // Process frame + + ViSrcW16 = 0; + ViStatesLine = 0; + VPrevLine = -1; + + if ( PrintLvl == 4 ) { + msg (( MSG_OUT, "Frame data length = %d [W16]", VDataW16Length )); + msg (( MSG_OUT, "" )); + } + + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, FSBB0 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Copy StatesLine field + // 22/05/14 - MS GCMODIF + VStatesLine.W32 = Src->ADataW32[ViSrcW16]; + Dest->AStatesRec[ViStatesLine].StatesLine = VStatesLine; + // VStatesNbPerLine = VStatesLine.F.StateNb; + + if ( (PrintLvl == 5) || (PrintLvl == 7) ) { + + msg (( MSG_OUT, "Line %4d - %d HitNbG0 - %d HitNbG1 ", VStatesLine.F.SLineAddr, VStatesLine.F.HitNbG0, VStatesLine.F.HitNbG1 )); + + /* Print to show missing handling of odd W16 nb + + if ( VStatesLine.F.LineAddr <= VPrevLine ) { + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ===============> ERROR odd W16 nb NOT HANDLED ! ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + } + + else { + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + VPrevLine = VStatesLine.F.LineAddr; + } + + */ + + } + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStates[ViState].W32 = Src->ADataW32[ViSrcW16]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "--> State %d : Col %4d - %2d pixels", ViState, Dest->AStatesRec[ViStatesLine].AStates[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStates[ViState].F.Code + 1 )); + ++ViSrcW16; + } + + ++ViStatesLine; + + + // Add on 25/03/2011 during test with random frame size + with all data = 0 + + if ( ViStatesLine >= FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "Max number of states reached = %d => Abort => Corrupted data !", FSBB0__ZS_FFRAME_MAX_STATES_REC )); + break; + } + + } // End while + + } // End if ( VDataW16Length != 0 ) + + Dest->StatesRecNb = ViStatesLine; + + if ( (PrintLvl == 5) || (PrintLvl == 6) || (PrintLvl == 7) ) { + msg (( MSG_OUT, "Conv : %d StatesLines", Dest->StatesRecNb )); + msg (( MSG_OUT, "" )); + } + + return (VRetW16Length); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 14/08/2009 +Doc date : +: +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameRawToZsFFrameHandleTrigger ( SInt8 MapsNb, SInt32 EvNo, SInt32 TotEvNb, FSBB0__TZsFFrameRaw* Src, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) { + + FSBB0__TZsFFrameRaw* VPtSrcEv; + SInt32 VTrigPosFromDaq; + SInt32 VTrigLine; + SInt8 VFirstEvent; + static FSBB0__TZsFFrame VASrcZsFFrameEv[2]; + SInt32 VLine; + SInt32 ViSrcStateRec; + SInt32 ViDestStateRec; + + // Check parameters + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Four events after this one are required => Abort if it's not the case + + if ( EvNo + 4 >= TotEvNb ) { + err_retfail ( -1, (ERR_OUT,"Processing stop on event %d => Less than 4 events after it !" ,EvNo) ); + } + + + // Trigger position ? +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VTrigPosFromDaq = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; +//#endif + + + if ( (VTrigPosFromDaq < 0) || (VTrigPosFromDaq > 575) ) { + err_retfail ( -1, (ERR_OUT,"Bad trigger pos from DAQ = %d <> [0..575] !", VTrigPosFromDaq) ); + } + + + // Set VPtEv on the first event to process + // - Pos < 572 => Pos correspond to current event + 1 ( next event ) + // - Pos >= 572 => Pos correspond to current event + 2 + +/* ORIGINAL => 1 plane + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 1; + } + + else { + VPtSrcEv = Src + 2; + } + +*/ + +/* 6 planes + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 7; + } + + else { + VPtSrcEv = Src + 8; + } + +*/ + + // N planes + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 1 + MapsNb; + } + + else { + VPtSrcEv = Src + 2 + MapsNb; + } + + + // Real trigger line = trigger position + 4 modulo 576 + + VTrigLine = (VTrigPosFromDaq + 4) % 576; + + // Debug print + + if ( PrintLvl == 1 ) { + // msg (( MSG_OUT, "=> Trig on Ev=%4d P=%4d L=%4d => Proc Ev=%4d - Ev=%4d", EvNo, VTrigPosFromDaq, VTrigLine, VPtSrcEv[0].SStatus.FrameNoInRun, VPtSrcEv[1].SStatus.FrameNoInRun )); + err_error (( ERR_OUT, "=> Trig on Ev=%4d - P=%4d - L=%4d => Proc Ev=%4d - Ev=%4d", EvNo, VTrigPosFromDaq, VTrigLine, VPtSrcEv[0].SStatus.FrameNoInRun, VPtSrcEv[1].SStatus.FrameNoInRun )); + } + + // Convert each event from ZsFFrameRaw to ZsFFrame + + FSBB0__FConvZsFFrameRawToZsFFrame ( VPtSrcEv , VASrcZsFFrameEv , 0 /* PrintLvl */ ); + FSBB0__FConvZsFFrameRawToZsFFrame ( VPtSrcEv + 1, VASrcZsFFrameEv + 1, 0 /* PrintLvl */ ); + + // ------------------------- + // Build destination event + // ------------------------- + + // Reset record + + memset ( Dest, 0, sizeof (FSBB0__TZsFFrame) ); + + // Copy information fields + + Dest->SStatus = Src->SStatus; + + Dest->Header = Src->Header; + Dest->FrameCnt = Src->DataLengthRemFrCnt.F.FrameCnt; + Dest->DataLength = Src->CalcDataLength; + Dest->Trailer = Src->Trailer; + //Dest->Zero = Src->Zero; + //Dest->Zero2 = Src->Zero2; +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + Dest->TrigSignalLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; + Dest->TrigSignalClk = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__LINE]; +//#endif + + // Extract lines + + ViDestStateRec = 0; + + // First event => Copy lines >= trigger pos to dest + + for ( ViSrcStateRec=0; ViSrcStateRec < VASrcZsFFrameEv->StatesRecNb; ViSrcStateRec++ ) { + + VLine = VASrcZsFFrameEv->AStatesRec[ViSrcStateRec].StatesLine.F.SLineAddr; + + if ( VLine >= VTrigLine ) { + Dest->AStatesRec[ViDestStateRec] = VASrcZsFFrameEv->AStatesRec[ViSrcStateRec]; + ++ViDestStateRec; + } + + } + + if ( VTrigLine == 0 ) { + Dest->StatesRecNb = ViDestStateRec; + return (0); + } + + // Second event => Copy lines < trigger pos to dest + + for ( ViSrcStateRec=0; ViSrcStateRec < VASrcZsFFrameEv[1].StatesRecNb; ViSrcStateRec++ ) { + + VLine = VASrcZsFFrameEv[1].AStatesRec[ViSrcStateRec].StatesLine.F.SLineAddr; + + if ( VLine < VTrigLine ) { + Dest->AStatesRec[ViDestStateRec] = VASrcZsFFrameEv[1].AStatesRec[ViSrcStateRec]; + ++ViDestStateRec; + } + + } + + // Update nb of StateRec + + Dest->StatesRecNb = ViDestStateRec; + + return (0); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 17/03/2009 +Rev : 22/07/2009 + : - Return number of hits found +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameToMatDiscriBit ( FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDest, SInt32* PtOvfCnt, SInt8 PrintLvl ) { + + UInt16 ViLine; + UInt16 VFirstCol; + UInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesRec; + SInt8 ViState; + UInt8 VStatesNb; + SInt32 VHitCnt; + SInt32 VOfvCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (FSBB0__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + // StatesRec loop + + VHitCnt = 0; + VOfvCnt = 0; + + if ( PtSrc->StatesRecNb > FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + err_error (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + PtSrc->StatesRecNb = FSBB0__ZS_FFRAME_MAX_STATES_REC; + } + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + if (( PtSrc->AStatesRec[ViStatesRec].StatesLine.F.HitNbG0 > 9 )||( PtSrc->AStatesRec[ViStatesRec].StatesLine.F.HitNbG1 > 9 )) { + ++VOfvCnt; + // err_error (( ERR_OUT, "Ovf ! Count=%d", VOfvCnt )); + } + // States in one StateRec loop + + // WARNING => Will slow down execution + + if ( VStatesNb > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNb, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC )); + VStatesNb = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC; + } + + // WARNING => Will slow down execution + + if ( ViLine >= FSBB0__MAT_DISCRI_LINES_NB) { + err_warning (( ERR_OUT, "ViLine=%d >= FSBB0__MAT_DISCRI_LINES_NB=%d => Force %d", ViLine, FSBB0__MAT_DISCRI_LINES_NB, FSBB0__MAT_DISCRI_LINES_NB - 1 )); + ViLine = FSBB0__MAT_DISCRI_LINES_NB - 1; + } + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // WARNING => Will slow down execution + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + + // WARNING => Will slow down execution + + if ( VLastCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "VLastCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VLastCol, FSBB0__REG_DISCRI_BIT_SZ )); + VLastCol = 0; + } + + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + if ( PtOvfCnt != NULL ) { + *PtOvfCnt = VOfvCnt; + } + + + // err_error (( ERR_OUT, "TRACE - VHitCnt=%d", VHitCnt )); // 13/02/2013 + + + return (VHitCnt); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : If UpdMatCumul = 0 +: - Don't update cumul matrix +: - BUT count hits => function return Hit nb +Level : +Date : 17/03/2009 +Rev : 22/07/2009 +: - Return number of hits found +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 OLD___FSBB0__FConvZsFFrameToMatDiscriBitAndCumul ( FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDest, SInt8 UpdMatCumul, FSBB0__TMatDiscriCumul* PtDestCum, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesRec; + SInt8 ViState; + SInt8 VStatesNb; + SInt32 VHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + if ( UpdMatCumul ) { + err_retnull ( PtDestCum, (ERR_OUT,"PtDestCum == NULL") ); + } + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (FSBB0__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "---------------------------------" )); + err_error (( ERR_OUT, " Print cumul" )); + err_error (( ERR_OUT, "---------------------------------" )); + } + + // StatesRec loop + + VHitCnt = 0; + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + PtDest->AALineCol[ViLine][ViCol] = 1; + + if ( UpdMatCumul ) { + ++ PtDestCum->AALineCol[ViLine][ViCol]; + + if ( PrintLvl ) { + err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, ViCol, PtDestCum->AALineCol[ViLine][ViCol] )); + } + + } + + ++VHitCnt; + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "-------------------------------" )); + } + + + + return (VHitCnt); +} + + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : - PtDestFrameBit -> Bit matrix of source frame + : - PtDestCoinBit -> Coin matrix of ONE frame of ALL selected planes + : - PtDestFrameCum -> Cumul matrix of ALL frames of CURRENT plane + : - PtDestCoinCum -> Cumul matrix of ALL frames of ALL selected planes + : +Globals : +Remark : This function is written in a strange way ... code duplication and + : something which looks like a " goto ". This is to avoid to have + : tests excuted in loop and therefore save execution time. + : + : + : +Level : +Date : 17/03/2009 +Rev : 22/07/2009 + : - Return number of hits found + : 25/07/2009 + : - Add Mode parameter => Handling of coincidence modes + : 02/08/2009 + : - Moved in class FSBB0__TCTelMon +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef ROOT_ROOT + +SInt32 FSBB0__TCTelMon::PrivFConvZsFFrameToMatDiscriBitAndCumul ( SInt32 DbgEvNo, SInt8 Mode, SInt8 PlaneNo, SInt8 PlaneSelForCoin, SInt8 EvNo, SInt8 EvSelForPlot, FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDestFrameBit, FSBB0__TMatDiscriBit* PtDestCoinBit, FSBB0__TMatDiscriCumul* PtDestFrameCum, FSBB0__TMatDiscriCumul* PtDestCoinCum, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesRec; + SInt8 ViState; + SInt8 VStatesNb; + SInt32 VHitCnt; + SInt8 VPlaneNoP1; + SInt8 VFlagRevertColDir; + SInt16 VDirRevCol; + SInt32 VEvNoInRun; + + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDestFrameBit, (ERR_OUT,"PtDestFrameBit == NULL") ); + err_retnull ( PtDestCoinBit , (ERR_OUT,"PtDestCoinBit == NULL") ); + err_retnull ( PtDestFrameCum, (ERR_OUT,"PtDestFrameCum == NULL") ); + err_retnull ( PtDestCoinCum , (ERR_OUT,"PtDestCoinCum == NULL") ); + + // Init intermediate variables + + // --------------------------------------------------------------- + // Revert or not X Dir ( columns ) depending of plane parameters + // --------------------------------------------------------------- + + VFlagRevertColDir = ProAPlanePar[PlaneNo].RevertXDir; + + VPlaneNoP1 = PlaneNo + 1; + + VEvNoInRun = PtSrc->SStatus.FrameNoInRun; + + // -------------------------------------------- + // Reset frame bit destination matrix + // -------------------------------------------- + + memset ( PtDestFrameBit, 0, sizeof (FSBB0__TMatDiscriBit) ); + + + VHitCnt = 0; + + while (1) { + + //--------------------------------------------------------------- + // Cumul all frames + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL ) { + + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++PtDestFrameCum->AALineCol[ViLine][VDirRevCol]; + + // err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, VDirRevCol, PtDestFrameCum->AALineCol[ViLine][VDirRevCol] )); + + ++VHitCnt; + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + + } // End MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL + + //--------------------------------------------------------------- + // Plot coincidence of selected planeS of ONE frame ( 6 colors ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS ) { + + if ( (PlaneSelForCoin == 1) && (EvNo == EvSelForPlot) ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++VHitCnt; + + while (1) { + + // If no hit from other plane => Set Plane Id + 1 (1..6) + + if ( PtDestCoinBit->AALineCol[ViLine][VDirRevCol] == 0 ) { + PtDestCoinBit->AALineCol[ViLine][VDirRevCol] = VPlaneNoP1; + break; + } + + // If already ONE hit from other plane => Set Base + hit count = 10 + 2 = 12 + + if ( PtDestCoinBit->AALineCol[ViLine][VDirRevCol] <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + PtDestCoinBit->AALineCol[ViLine][VDirRevCol] = 12; + break; + } + + // If already > ONE hit from other plane => Increment ( Rq : Hit count = value - 10 ) + + ++PtDestCoinBit->AALineCol[ViLine][VDirRevCol]; + break; + + } // End while (1) + + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + + //--------------------------------------------------------------- + // Plot coincidence cumul of selected planeS of all frames ( 1 color ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR ) { + + if ( PlaneSelForCoin ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++PtDestFrameCum->AALineCol[ViLine][VDirRevCol]; // Not useful => But keep processing of per plane cumul + // err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, VDirRevCol, PtDestFrameCum->AALineCol[ViLine][VDirRevCol] )); + ++VHitCnt; + ++PtDestCoinCum->AALineCol[ViLine][VDirRevCol]; + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + + //--------------------------------------------------------------- + // Plot coincidence cumul of selected planes of all frames ( 6 colors ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) { + + if ( PlaneSelForCoin ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++VHitCnt; + + // Res run update + + // err_error (( ERR_OUT, "ProcOnlyFrWithHitOnAllPlanes = %d", ProPar.ProcOnlyFrWithHitOnAllPlanes )); + + if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) && (PrivPtResRun != NULL) ) { + + if ( PrivPtResRun->EvNb < MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB) { + + SInt32 VBHitIndex = PrivPtResRun->ATracks[PrivPtResRun->EvNb].AHitsNbPerPlane[PlaneNo]; + + err_error (( ERR_OUT, "TRACE : Coin - Ev %4d - Fr %4d - Plane %d - StatesNb %d", DbgEvNo, PtSrc->FrameCnt, PlaneNo, VStatesNb )); + + if ( VBHitIndex < MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE ) { + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AAHits[PlaneNo][VBHitIndex].x = VDirRevCol; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AAHits[PlaneNo][VBHitIndex].y = ViLine; + ++VBHitIndex; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AHitsNbPerPlane[PlaneNo] = VBHitIndex; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].EvNoInRun = VEvNoInRun; + } + + + } + + else { + PrivPtResRun->Full = 1; + } + + } + + + // Res run update END + + while (1) { + + // If no hit from other plane => Set Plane Id + 1 (1..6) + + if ( (PtDestCoinCum->AALineCol[ViLine][VDirRevCol] == 0) || (PtDestCoinCum->AALineCol[ViLine][VDirRevCol] == VPlaneNoP1) ) { + PtDestCoinCum->AALineCol[ViLine][VDirRevCol] = VPlaneNoP1; + break; + } + + // If already ONE hit from other plane / other frame => Set Base + hit count = 10 + 2 = 12 + + if ( PtDestCoinCum->AALineCol[ViLine][VDirRevCol] <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + PtDestCoinCum->AALineCol[ViLine][VDirRevCol] = 12; + break; + } + + // If already > ONE hit from other plane / other frame => Increment ( Rq : Hit count = value - 10 ) + + ++PtDestCoinCum->AALineCol[ViLine][VDirRevCol]; + break; + + } // End while (1) + + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + + // If this is last plane selected for coincidence => Update Res run event counter + // Rq : If no plane is selected for coin => ProInf.LastPlaneSelForCoin == -1 therefore above condition is never true + + if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) && (PrivPtResRun != NULL) && (PlaneNo == ProInf.LastPlaneSelForCoin) ) { + ++PrivPtResRun->EvNb; + err_error (( ERR_OUT, "TRACE : Inc Res Run EvNb done => EvNb=%4d - EvNo=%4d - PlaneNo=%d", PrivPtResRun->EvNb, DbgEvNo, PlaneNo )); + } + + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + + + //--------------------------------------------------------------- + // Plot only frame + //--------------------------------------------------------------- + // MUST BE LAST ONE OF While (1) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; +#endif + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.SLineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... +#endif + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + + + if (EvNo == EvSelForPlot) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = FSBB0__MAT_DISCRI_COL_NB - 1 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + } + + ++VHitCnt; + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME + + + } // End while (1) + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "-------------------------------" )); + } + + + + return (VHitCnt); +} + + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 23/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvMatDiscriBitToMatDiscriBitHalfScale ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriBitHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = FSBB0__REG_DISCRI_BIT_SZ / 2; + VyDestMax = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] || PtSrc->AALineCol[V2yDest][V2xDestP1] || PtSrc->AALineCol[V2yDestP1][V2xDest] || PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 26/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvMatDiscriBitCoinToMatDiscriBitCoinHalfScale ( FSBB0__TMatDiscriBit* PtSrc, FSBB0__TMatDiscriBitHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + UInt8 VPixState0; + UInt8 VPixState1; + UInt8 VPixState2; + UInt8 VPixState3; + + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = FSBB0__REG_DISCRI_BIT_SZ / 2; + VyDestMax = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + VPixState0 = (PtSrc->AALineCol[V2yDest ][V2xDest ] != 0); + VPixState1 = (PtSrc->AALineCol[V2yDest ][V2xDestP1] != 0); + VPixState2 = (PtSrc->AALineCol[V2yDestP1][V2xDest ] != 0); + VPixState3 = (PtSrc->AALineCol[V2yDestP1][V2xDestP1] != 0); + + + while (1) { + + // If no pixel at 1 => set 0 + + if ( (VPixState0 | VPixState1 | VPixState2 | VPixState3) == 0 ) { + PtDest->AALineCol[VyDest][VxDest] = 0; + break; + } + + // If one pixel at 1 and ONLY one => Make or of values = or of PlaneID + 1 + + if ( (VPixState0 ^ VPixState1 ^ VPixState2 ^ VPixState3) == 1 ) { + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] | PtSrc->AALineCol[V2yDest][V2xDestP1] | PtSrc->AALineCol[V2yDestP1][V2xDest] | PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + break; + } + + // If more than one pixel at 1 => Base + Sum pixels states = 10 + Sum + + PtDest->AALineCol[VyDest][VxDest] = 10 + (VPixState0 + VPixState1 + VPixState2 + VPixState3); + break; + + } // End while (1) + + } // End for ( VxDest ... ) + + } // End for ( VyDest ... ) + + err_retok (( ERR_OUT, "" )); +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 23/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvMatDiscriCumToMatDiscriCumHalfScale ( FSBB0__TMatDiscriCumul* PtSrc, FSBB0__TMatDiscriCumulHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = FSBB0__REG_DISCRI_BIT_SZ / 2; + VyDestMax = FSBB0__MAT_DISCRI_USEFUL_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] + PtSrc->AALineCol[V2yDest][V2xDestP1] + PtSrc->AALineCol[V2yDestP1][V2xDest] + PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 30/04/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 FSBB0__FBuildMatDiscriW32FromLinePatReg ( FSBB0__TRegDiscriW32* PtLinePatReg0, FSBB0__TRegDiscriW32* PtLinePatReg1, FSBB0__TMatDiscriW32* PtDest ) { + + SInt16 ViLine; + + err_retnull ( PtLinePatReg0, (ERR_OUT,"PtLinePatReg0 == NULL !") ); + err_retnull ( PtLinePatReg1, (ERR_OUT,"PtLinePatReg1 == NULL !") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL !") ); + + ViLine= 0; + + do { + + memcpy ( PtDest->AALineW32[ViLine], PtLinePatReg0, FSBB0__REG_DISCRI_W32_SZ * 4 ); + ++ViLine; + memcpy ( PtDest->AALineW32[ViLine], PtLinePatReg1, FSBB0__REG_DISCRI_W32_SZ * 4 ); + ++ViLine; + + } while ( ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/05/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FCompareMatDiscriBit ( SInt16 LineNbToCompare, FSBB0__TMatDiscriBit* PtMat, FSBB0__TMatDiscriBit* PtMatRef, SInt8 PrintLvl, SInt8 PrintMimosaId, SInt32 PrintAcqId, SInt16 PrintFrameId ) { + + SInt32 ViLine; + SInt32 ViCol; + SInt8 VPixState; + SInt8 VRefPixState; + SInt32 VErrCnt; + + + if ( (LineNbToCompare <= 0) || (LineNbToCompare > FSBB0__MAT_DISCRI_USEFUL_LINES_NB) ) { + err_error (( ERR_OUT, "Bad line nb to compare = %d MUST be 1..%d", LineNbToCompare, FSBB0__MAT_DISCRI_USEFUL_LINES_NB )); + return (0); + } + + VErrCnt = 0; + + for ( ViLine=0; ViLine < LineNbToCompare; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ /* 580 for Test LP003 */; ViCol++ ) { + VPixState = PtMat->AALineCol[ViLine][ViCol]; + VRefPixState = PtMatRef->AALineCol[ViLine][ViCol]; + + if ( VPixState != VRefPixState ) { + ++VErrCnt; + if ( PrintLvl == 2 ) msg (( MSG_OUT, "Error => FSBB0[%d] Line %4d - Col %4d : Pixel = %d <> Expected = %d", PrintMimosaId, ViLine, ViCol, VPixState, VRefPixState )); + } + + } // End for ViCol + + } // End for ViLine + + if ( (PrintLvl >= 1) && (VErrCnt != 0) ) msg (( MSG_OUT, "For this event Acq[%3d] Frame [%6d] %d errors on Mimosa [%d]", PrintAcqId, PrintFrameId, VErrCnt, PrintMimosaId )); + + return ( VErrCnt ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TCDiscriFile :: FSBB0__TCDiscriFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) : FIL__TCBinFile ( ErrLogFile, EnableErrLog, ErrLogLvl ) { + + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFSetFileName ( char* DataFile ) { + + return ( FIL__TCBinFile :: PubFSetFileName (DataFile) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + return ( FIL__TCBinFile :: PubFSetFlushMode (FlushAfterWrite) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TCDiscriFile :: ~FSBB0__TCDiscriFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFConf ( char* DataFile, SInt8 WriteRead, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt32 VRet; + SInt32 VRWBMode; + SInt32 VMaxBlocSz; + SInt32 VBlocSz; + + switch ( WriteRead ) { + + case 0 : { + VRWBMode = FIL__TCBinFile_RWB_MODE_WRITE; + break; } + + case 1 : { + VRWBMode = FIL__TCBinFile_RWB_MODE_READ; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Bad WriteRead param = %d <> 0..1", WriteRead ) ); + break; } + + } + + VMaxBlocSz = VBlocSz = sizeof (FSBB0__TMatDiscriW32); + + VRet = FIL__TCBinFile::PubFConf ( DataFile, VRWBMode, VMaxBlocSz, VBlocSz, FlushAfterWrite, MeasTime ); + + // msg (( MSG_OUT, "PubFConf => FlushAfterWrite=%d", FlushAfterWrite )); + + return (VRet); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFGetFileSz () { + return ( FIL__TCBinFile::PubFGetFileSz () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFGetEvNb () { + return ( FIL__TCBinFile::PubFGetBlocNb () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFCreate () { + return ( FIL__TCBinFile::PubFCreate () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFOpen () { + return ( FIL__TCBinFile::PubFOpen () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFWriteEv ( FSBB0__TMatDiscriW32* PtSrcMat ) { + + SInt32 VRet; +// SInt32 VRet; // modif 2009_03_04 MG + + VRet = PubFSeqWrite ( (void*) PtSrcMat, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Write event failed !") ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFReadNextEv ( FSBB0__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( (void*) PtDestMat, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read event failed !") ); + err_retok (( ERR_OUT, "" )); + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TMatDiscriW32* FSBB0__TCDiscriFile :: PubFReadNextEv () { + + FSBB0__TMatDiscriW32* VPtEv; + + VPtEv = (FSBB0__TMatDiscriW32*) PubFSeqRead ( ProParBlocSz ); + + if ( VPtEv == NULL ) { + err_error (( ERR_OUT, "Read event failed !" )); + } + + err_retval ( VPtEv, ( ERR_OUT, "" ) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFGotoEv ( SInt32 EvNo ) { + + SInt32 VRet; + + VRet = PubFGotoBloc ( EvNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto event [%d] failed !", EvNo ) ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFReadEv ( SInt32 EvNo, FSBB0__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ) { + + SInt32 VRet; + + VRet = PubFBlocRead ( EvNo, PtDestMat, MaxDestSz ); + + err_retfail ( VRet, (ERR_OUT,"Read event [%d] failed !", EvNo ) ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TMatDiscriW32* FSBB0__TCDiscriFile :: PubFReadEv ( SInt32 EvNo ) { + + FSBB0__TMatDiscriW32* VPtEv; + + + VPtEv = (FSBB0__TMatDiscriW32*) PubFBlocRead ( EvNo ); + + if ( VPtEv == NULL ) { + err_error (( ERR_OUT, "Read event [%d] failed !", EvNo )); + } + + err_retval ( VPtEv, ( ERR_OUT, "" ) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFFlush () { + return ( FIL__TCBinFile::PubFFlush () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCDiscriFile :: PubFClose () { + return ( FIL__TCBinFile::PubFClose () ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FWriteZSRunCnf ( char* FileName, FSBB0__TZSRunCnf* PtSrc ) { + + SInt32 VRecSz; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (FSBB0__TZSRunCnf); + + err_retfail ( FIL_FWriteRecord ( FileName, PtSrc, VRecSz ), (ERR_OUT,"Write failed !") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FReadZSRunCnf ( char* FileName, FSBB0__TZSRunCnf* PtDest ) { + + SInt32 VRecSz; + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (FSBB0__TZSRunCnf); + + err_retfail ( FIL_FReadRecord ( FileName, PtDest, VRecSz ) , (ERR_OUT,"Read failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FPrintZSRunCnf ( FSBB0__TZSRunCnf* PtSrc ) { + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + msg (( MSG_OUT, "================================================" )); + msg (( MSG_OUT, "RunNo %6d", PtSrc->RunNo )); + msg (( MSG_OUT, "RunSave %6d", PtSrc->RunSave )); + msg (( MSG_OUT, "RunSaveMode %6d", PtSrc->RunSaveMode )); + msg (( MSG_OUT, "RunEvNb %6d", PtSrc->RunEvNb )); + msg (( MSG_OUT, "RunFileEvNb %6d", PtSrc->RunFileEvNb )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "StartDate %s", TIME__FDateS2Str ( PtSrc->StartDate, NULL, 0 ) )); + msg (( MSG_OUT, "StartTime %s", TIME__FTime2Str ( PtSrc->StartTime, NULL, 0 ) )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "AsicName %6d", PtSrc->AsicName )); + msg (( MSG_OUT, "AsicNb %6d", PtSrc->AsicNb )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "SwTrigEnabled %6d", PtSrc->SwTrigEnabled )); + msg (( MSG_OUT, "HwTrigModeSavedData %6d", PtSrc->HwTrigModeSavedData )); + msg (( MSG_OUT, "HwTrigPar[DPXI__HW_TRIG_PAR__OFFSET] %6d", PtSrc->HwTrigPar[DPXI__HW_TRIG_PAR__OFFSET] )); + msg (( MSG_OUT, "HwTrigPar[DPXI__HW_TRIG_PAR__WINDOW] %6d", PtSrc->HwTrigPar[DPXI__HW_TRIG_PAR__WINDOW] )); + msg (( MSG_OUT, "================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FWriteZSRunRes ( char* FileName, FSBB0__TZSRunRes* PtSrc ) { + + SInt32 VRecSz; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (FSBB0__TZSRunRes); + + err_retfail ( FIL_FWriteRecord ( FileName, PtSrc, VRecSz ), (ERR_OUT,"Write failed !") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FReadZSRunRes ( char* FileName, FSBB0__TZSRunRes* PtDest ) { + + SInt32 VRecSz; + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (FSBB0__TZSRunRes); + + err_retfail ( FIL_FReadRecord ( FileName, PtDest, VRecSz ) , (ERR_OUT,"Read failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FPrintZSRunRes ( FSBB0__TZSRunRes* PtSrc ) { + + SInt32 Vi; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + + msg (( MSG_OUT, "================================================" )); + msg (( MSG_OUT, "StopDate %s", TIME__FDateS2Str ( PtSrc->StopDate, NULL, 0 ) )); + msg (( MSG_OUT, "StopTime %s", TIME__FTime2Str ( PtSrc->StopTime, NULL, 0 ) )); + msg (( MSG_OUT, "EvNbTaken %6d", PtSrc->EvNbTaken )); + msg (( MSG_OUT, "RejAcqNb %6d", PtSrc->RejAcqNb )); + msg (( MSG_OUT, "================================================" )); + + for ( Vi=0; Vi < PtSrc->RejAcqNb; Vi++ ) { + msg (( MSG_OUT, "Acq [%6d] rejected !", PtSrc->ARejAcqList[Vi] )); + } + + msg (( MSG_OUT, "================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TCZsRunRW :: FSBB0__TCZsRunRW () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TCZsRunRW :: ~FSBB0__TCZsRunRW () { + + delete ProPtBinFile; + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : All fields BUT NOT + : - errors handling and log file + : - messages and event header print flags +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PrivFInitForNewRunLoading () { + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + + // Parameters from conf + + sprintf ( ProParRunDir, "" ); + ProParRunNo = 0; + ProParCurFSBB0No = 0; + ProParCurEvNo = 0; + + // Informations + + ProInfRunFSBB0Nb = 0; + ProInfRunEvNb = 0; + ProInfRunFileSz = 0; + ProInfRunEvNbPerFile = 0; + ProInfRunBlocNbPerFile = 0; + + // Variables for internal processing + + ProLastEvAccessDoneInOneFSBB0Mode = 1; + + ProCurBlocNoInRun = 0; + ProCurFileNo = 0; + ProCurBlocNoInFile = 0; + sprintf ( ProCurFileName, "" ); + + ProPtFFrameRaw = NULL; + + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + + // Conf done & errors log + // Parameters from constructor + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // Frame size + + ProInfZsFFrameRawSz = sizeof (FSBB0__TZsFFrameRaw); + + // Print ctrl fields + + ProParMeasTime = 0; + ProParPrintMsg = 0; + ProParPrintEvHeader = 0; + + + PrivFInitForNewRunLoading (); + + // Res + + // TCBinFile + + ProPtBinFile = new FIL__TCBinFile ( "x:\\log\\err_TCBinFile.txt", 0 /* EnableErrLog */, ERR_LOG_LVL_NONE ); + + err_retnull ( ProPtBinFile, (ERR_OUT,"Allocation of ProPtBinFile failed !!! => Abort") ); + + ProPtBinFile->PubFConf ( "", FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFSetMeasTime ( SInt8 Yes ) { + ProParMeasTime = Yes; + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFSetPrintMsg ( SInt8 Print ) { + ProParPrintMsg = Print; + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFSetPrintEvHeader ( SInt8 Print ) { + ProParPrintEvHeader = Print; + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetMeasTime () { + return (ProParMeasTime); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetPrintMsg () { + return ( ProParPrintMsg ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetPrintEvHeader () { + return ( ProParPrintEvHeader ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetFSBB0Nb () { + return ( ProInfRunFSBB0Nb ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetEvNb () { + return ( ProInfRunEvNb ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFGetEvNbPerFile () { + return ( ProInfRunEvNbPerFile ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Rev : 29/07/2009 + : - Two kinds of events handling : OneFSBB0 / AllFSBB0 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFLoadRun ( char* RunDir, UInt32 RunNo ) { + + SInt32 VRet; + + FSBB0__TCZsRunRW__CHK_INIT (); + + err_retnull ( RunDir, (ERR_OUT,"RunDir == NULL !") ); + + + // Set run dir and run no + + sprintf ( ProParRunDir, "%s", RunDir ); + + ProParRunNo = RunNo; + + // Load and print run conf + // Must be loaded here because fiels of VRunCnfFile are used later + + sprintf ( ProRunCnfFile, "%s\\run_%.4d_cnf.bin", ProParRunDir, ProParRunNo ); + + FSBB0__FReadZSRunCnf ( ProRunCnfFile, &ProRecZSRunCnf ); + FSBB0__FPrintZSRunCnf ( &ProRecZSRunCnf ); + + // Load and print run res + + sprintf ( ProRunResFile, "%s\\run_%.4d_res.bin", ProParRunDir, ProParRunNo ); + + FSBB0__FReadZSRunRes ( ProRunResFile, &ProRecZSRunRes ); + FSBB0__FPrintZSRunRes ( &ProRecZSRunRes ); + + // Update information fields + + ProInfRunFSBB0Nb = ProRecZSRunCnf.AsicNb; + ProInfRunEvNb = ProRecZSRunCnf.RunEvNb; + ProInfRunEvNbPerFile = ProRecZSRunCnf.RunFileEvNb; + + // ---------------------------------- + // WARNING - Upgrade on 29/07/2009 + // ---------------------------------- + // - Now class can provide two kinds of events pointer via PubFGotoEvOneFSBB0 / PubFGotoEvAllFSBB0 + // -> PubFGotoEvOneFSBB0 : Pointer to ONE plane of FSBB0 telescope + // -> PubFGotoEvAllFSBB0 : Pointer to ALL planes of FSBB0 telescope + // + // => ProInfRunBlocNbPerFile depend on which kind off event we want to access + // Therefore ProInfRunBlocNbPerFile is ovewritten in PubFGotoEvOneFSBB0 / PubFGotoEvAllFSBB0 + // By default it is set HERE for "PubFGotoEvOneFSBB0" kind of events + // + // The first call to ProPtBinFile->PubFConf done at the end of this function also configure + // buffer size for "PubFGotoEvOneFSBB0" kind of events. + + ProInfRunBlocNbPerFile = ProInfRunFSBB0Nb * ProInfRunEvNbPerFile; + + // Set flag to memorize last ev access mode + + ProLastEvAccessDoneInOneFSBB0Mode = 1; + + // Set cur event to first one, first FSBB0 + + ProParCurFSBB0No = 0; + ProParCurEvNo = 0; + + // Open file for first event + + ProCurBlocNoInRun = 0; + ProCurFileNo = 0; + ProCurBlocNoInFile = 0; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Load run try to open first file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + + // Try to open file + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + + + if ( VRet < 0 ) { + ProInfRunFileSz = 0; + err_retfail ( -1, (ERR_OUT,"Open file %s for event %d failed !", ProCurFileName, ProParCurEvNo ) ); + } + + ProInfRunFileSz = ProPtBinFile->PubFGetFileSz (); + + + err_retok (( ERR_OUT, "Open file %s done :-)", ProCurFileName )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TZsFFrameRaw* FSBB0__TCZsRunRW :: PubFGotoEvOneFSBB0 ( SInt8 FSBB0No, SInt32 EvNo ) { + + SInt32 VRet = 0; + SInt32 VNewFileNo; + + ProParCurFSBB0No = FSBB0No; + ProParCurEvNo = EvNo; + + // Calculate Nb of bloc per file ( Rq : value is different for PubFGotoEvAllFSBB0 ) + + ProInfRunBlocNbPerFile = ProInfRunFSBB0Nb * ProInfRunEvNbPerFile; + + // Calculate bloc no and file to access + + ProCurBlocNoInRun = ( ProParCurEvNo * ProInfRunFSBB0Nb ) + ProParCurFSBB0No; + VNewFileNo = ProCurBlocNoInRun / ProInfRunBlocNbPerFile; + ProCurBlocNoInFile = ProCurBlocNoInRun % ProInfRunBlocNbPerFile; + + // If last ev acces done in AllFSBB0 mode ( -> TCBin file MUST be reconfigured ) + // If event is not in current file + // => close current file & open new one + + if ( (ProLastEvAccessDoneInOneFSBB0Mode == 0) || (VNewFileNo != ProCurFileNo) ) { + + ProLastEvAccessDoneInOneFSBB0Mode = 1; + + // Close current file + + ProPtBinFile->PubFClose (); + + // Open new file + + ProCurFileNo = VNewFileNo; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d - FSBB0No=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProParCurFSBB0No, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "Try to open file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + err_retfailnull ( VRet, (ERR_OUT,"Open file %s failed !", ProCurFileName) ); + } + + else { + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d - FSBB0No=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProParCurFSBB0No, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + } + + // Try to read event + + ProPtFFrameRaw = (FSBB0__TZsFFrameRaw*) ProPtBinFile->PubFBlocRead ( ProCurBlocNoInFile ); + + if ( ProParPrintEvHeader ) { + FSBB0_FPrintZsFFrameRawHeader ( ProPtFFrameRaw ); + } + + return ( ProPtFFrameRaw ); +} + + + + +/******************************************************************************* +Prototype : +Goal : Retun pointeur to first plane of Telescope => size = Nb plane * ProInfZsFFrameRawSz +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 28/07/2009 +Doc date : 28/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +FSBB0__TZsFFrameRaw* FSBB0__TCZsRunRW :: PubFGotoEvAllFSBB0 ( SInt32 EvNo ) { + + SInt32 VRet = 0; + SInt32 VNewFileNo; + SInt32 VEventSz; + SInt32 Vi; + + + ProParCurEvNo = EvNo; + VEventSz = ProInfRunFSBB0Nb * ProInfZsFFrameRawSz; + + // Calculate Nb of bloc per file ( Rq : value is different for PubFGotoEvOneFSBB0 ) + + ProInfRunBlocNbPerFile = ProInfRunEvNbPerFile; + + // Calculate bloc no and file to access + + ProCurBlocNoInRun = ProParCurEvNo; // * ProInfRunFSBB0Nb; + VNewFileNo = ProCurBlocNoInRun / ProInfRunBlocNbPerFile; + ProCurBlocNoInFile = ProCurBlocNoInRun % ProInfRunBlocNbPerFile; + + // If last ev acces done in OneFSBB0 mode ( -> TCBin file MUST be reconfigured ) + // If event is not in current file + // => close current file & open new one + + if ( (ProLastEvAccessDoneInOneFSBB0Mode == 1) || (VNewFileNo != ProCurFileNo) ) { + + ProLastEvAccessDoneInOneFSBB0Mode = 0; + + // Close current file + + ProPtBinFile->PubFClose (); + + // Open new file + + ProCurFileNo = VNewFileNo; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "Try to open file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, VEventSz /* Max bloc sz */ , VEventSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + + err_retfailnull ( VRet, (ERR_OUT,"Open file %s failed !", ProCurFileName) ); + } + + else { + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + } + + // Try to read event + + ProPtFFrameRaw = (FSBB0__TZsFFrameRaw*) ProPtBinFile->PubFBlocRead ( ProCurBlocNoInFile ); + + if ( ProParPrintEvHeader ) { + + for ( Vi=0; Vi < ProInfRunFSBB0Nb; Vi++ ) { + FSBB0_FPrintZsFFrameRawHeader ( &ProPtFFrameRaw[Vi] ); + } + + } + + return ( ProPtFFrameRaw ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__TCZsRunRW :: PubFCloseRun () { + + ProPtBinFile->PubFClose (); + PrivFInitForNewRunLoading (); + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + + + + +// ************************************* +// ************************************* +// FSBB0__TCTelMon +// ************************************* +// ************************************* + + +#ifndef ROOT_ROOT + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PrivFInit () { + + SInt32 Vi; + + + // Plane & MAPS settings for FSBB0 + + ProPar.PlaneNb = 6; + + MAPS__TCDigTelMon_CHK_PLANE_NB (ProPar.PlaneNb); + + + ProPar.MapsName = ASIC__FSBB0; + ProPar.MapsNb = 6; + + // Planes conf + // - Id = Index of plane : seem's to be strange and redundant => can be useful later + // - plot color + // - revert or not X direction + + ProAPlanePar[0].MapsId = 0; + ProAPlanePar[0].PlotColor = FSBB0__TCTelMon__COL_PLANE_0; + ProAPlanePar[0].RevertXDir = 1; + + ProAPlanePar[1].MapsId = 1; + ProAPlanePar[1].PlotColor = FSBB0__TCTelMon__COL_PLANE_1; + ProAPlanePar[1].RevertXDir = 0; + + ProAPlanePar[2].MapsId = 2; + ProAPlanePar[2].PlotColor = FSBB0__TCTelMon__COL_PLANE_2; + ProAPlanePar[2].RevertXDir = 1; + + ProAPlanePar[3].MapsId = 3; + ProAPlanePar[3].PlotColor = FSBB0__TCTelMon__COL_PLANE_3; + ProAPlanePar[3].RevertXDir = 0; + + ProAPlanePar[4].MapsId = 4; + ProAPlanePar[4].PlotColor = FSBB0__TCTelMon__COL_PLANE_4; + ProAPlanePar[4].RevertXDir = 1; + + ProAPlanePar[5].MapsId = 5; + ProAPlanePar[5].PlotColor = FSBB0__TCTelMon__COL_PLANE_5; + ProAPlanePar[5].RevertXDir = 0; + + + for ( Vi=0; Vi < MAPS__TCDigTelMon_MAX_PLANE_NB; Vi++ ) { + PrivAPlanePlotColor[Vi] = ProAPlanePar[Vi].PlotColor; + } + + + + + // Frames record reset + + memset ( &PrivZsFFrame , 0, sizeof (FSBB0__TZsFFrame) ); + + memset ( &PrivMatDiscriCoin , 0, sizeof (FSBB0__TMatDiscriBit) ); + memset ( &PrivMatDiscriCoinCum , 0, sizeof (FSBB0__TMatDiscriCumul) ); + memset ( &PrivMatDispColor , 0, sizeof (FSBB0__TMatDiscriColor) ); + + memset ( &PrivMatDiscriBitHalfScale, 0, sizeof (FSBB0__TMatDiscriBitHalfScale) ); + memset ( &PrivMatDiscriCumHalfScale, 0, sizeof (FSBB0__TMatDiscriCumulHalfScale) ); + memset ( &PrivMatDispColorHalfScale, 0, sizeof (FSBB0__TMatDiscriColorHalfScale) ); + + + // Events list allocation & reset + + PriEnListEvWitHitUpdate = 1; + PriEnListEvWithTrigUpdate = 1; + + // Allocation & reset + + for ( Vi=0; Vi < FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB; Vi++ ) { + + PrivAAListEvWithTrig[Vi] = (ASIC__TFrameStatus*) malloc ( FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + err_retnull ( PrivAAListEvWithTrig[Vi], (ERR_OUT,"Allocation of trigger list elt=%d failed !", Vi) ); + + memset ( PrivAAListEvWithTrig[Vi], 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + + + PrivAAListEvWithHit[Vi] = (ASIC__TFrameStatus*) malloc ( FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + err_retnull ( PrivAAListEvWithHit[Vi], (ERR_OUT,"Allocation of hit list elt=%d failed !", Vi) ); + + memset ( PrivAAListEvWithHit[Vi], 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + + } + + PrivAListEvWithHitAllPlanes = (FSBB0__TCTelMon_TEltListEvWithHitAllPlanes*) malloc ( FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (FSBB0__TCTelMon_TEltListEvWithHitAllPlanes) ); + + err_retnull ( PrivAListEvWithHitAllPlanes, (ERR_OUT,"Allocation of hit all planes failed !") ); + + memset ( PrivAListEvWithHitAllPlanes, 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (FSBB0__TCTelMon_TEltListEvWithHitAllPlanes) ); + + + // Reset + + PrivListEvWithTrigIndex = 0; + PrivListEvWithTrigFull = 0; + + PrivListEvWithHitIndex = 0; + PrivListEvWithHitFull = 0; + + PrivListEvWithHitAllPlanesIndex = 0; + PrivListEvWithHitAllPlanesFull = 0; + + // Variables reset + + PrivPtAcqData = NULL; + PrivAcqEvNb = 0; + + PrivPtResRun = NULL; + + PubAcqOffLineProcOrRunOffLineProc = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Rev : 31/07/2009 + : - Add multi planes handling +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PrivFAddEvInListEvWithTrig ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt ) { + + err_retnull ( PtFrStatus, (ERR_OUT,"PtFrStatus == NULL") ); + + if ( PriEnListEvWithTrigUpdate == 0 ) { + return (0); + } + + if ( PrivListEvWithTrigIndex < FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB ) { + PtFrStatus->HitCnt = HitCnt; + PrivAAListEvWithTrig[PlaneNo][PrivListEvWithTrigIndex] = *PtFrStatus; + ++PrivListEvWithTrigIndex; + } + + else { + PrivListEvWithTrigFull = 1; + err_retfail (-1, (ERR_OUT,"List full %d elt", PrivListEvWithTrigIndex ) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : This function MUST always be called one time / ev with PlaneNo = FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL + : because list index is ONLY updated when PlaneNo = FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL + : +Date : 26/07/2009 +Rev : 31/07/2009 + : - Add multi planes handling +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PrivFAddEvInListEvWithHit ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt, SInt8 HitOnAllPlanes, SInt8 SingleHitOnEachPlane ) { + + err_retnull ( PtFrStatus, (ERR_OUT,"PtFrStatus == NULL") ); + + if ( PriEnListEvWitHitUpdate == 0 ) { + return (0); + } + + // Check PlaneNo + + if ( (PlaneNo < 0) || (PlaneNo > FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB) ) { + err_retfail ( -1, (ERR_OUT,"Bad Plane No = %d MUST be [0..%d]", PlaneNo, FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL ) ); + } + + // Update hit count field of FrStatus which already contains information about acq no, ev no, FSBB0 no etc ... + + PtFrStatus->HitCnt = HitCnt; + + // Copy FrStatus in plane array + + PrivAAListEvWithHit[PlaneNo][PrivListEvWithHitIndex] = *PtFrStatus; + + // Update list index ONLY if PlaneNo == FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL + + if ( PlaneNo == FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL ) { + + // Update hit on all planes list + + // Rq : Decision to add event in list or not is done in two steps ( two tests ) and not by a single test in order to save execution time + // -> First test ( HitOnAllPlanes == 1 ) cost less => Is there hits on all planes ? Yes / No ? + // -> Second test cost much and therefore is only done if first one has passed + + if ( HitOnAllPlanes == 1 ) { + + // Add or not event in list depending of list mode + // -> List events with hit(s) ( at least one per plane ) on all planes => Yes + // -> List events with single hit in each plane => Yes if SingleHitOnEachPlane parameter is set / otherwise No + + if ( (ProPar.ListHitAllPlanesMode == MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES ) || ( (ProPar.ListHitAllPlanesMode == MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE) && (SingleHitOnEachPlane == 1) ) ) { + + PrivAListEvWithHitAllPlanes[PrivListEvWithHitAllPlanesIndex].FrStatus = *PtFrStatus; + PrivAListEvWithHitAllPlanes[PrivListEvWithHitAllPlanesIndex].IndexInEvWithHitList = PrivListEvWithHitIndex; // Store ev with trig list index + + if ( PrivListEvWithHitAllPlanesIndex < FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB ) { + ++PrivListEvWithHitAllPlanesIndex; + } + + else { + PrivListEvWithHitAllPlanesFull = 1; + } + } + + + } // End if ( HitOnAllPlanes == 1 ) + + // Update PrivListEvWithHitIndex + + if ( PrivListEvWithHitIndex < FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB ) { + ++PrivListEvWithHitIndex; + } + + else { + PrivListEvWithHitFull = 1; + err_retfail (-1, (ERR_OUT,"List full %d elt", PrivListEvWithHitIndex ) ); + } + + + + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : Hit count +Remark : +Date : 22/07/2009 +Rev : 20/05/2010 + : - Add CumTotTrigNb & CumFrameTrigNb handling + : +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::ProFProcessPlane ( SInt32 DbgEvNo, SInt8 Id, FSBB0__TZsFFrameRaw* PtSrc ) { + + FSBB0__TMatDiscriBit* VPtFrMatDiscriBit; + FSBB0__TMatDiscriCumul* VPtFrMatCumTotHitCnt; + SInt32 VHitCnt; + SInt8 VUpdateMatCumul; + SInt8 VRequestPlot; + SInt8 VGoodFrame; + + // Check plane id + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + + VRequestPlot = 0; // Used to store plot request and move it at END of function AFTER ALL processings + + // Init pointers + + VPtFrMatDiscriBit = (FSBB0__TMatDiscriBit*) ProAPlaneRes[Id].PtMatDiscriBit; + VPtFrMatCumTotHitCnt = (FSBB0__TMatDiscriCumul*) ProAPlaneRes[Id].PtMatCumTotHitCnt; + + // If first event of analysis + // -> Reset all results of plane + + if ( ProInf.CurEvToProc == 0 ) { + ProAPlaneRes[Id].FrameNbWithTrig = 0; + ProAPlaneRes[Id].FramePCentWithTrig = 0; + ProAPlaneRes[Id].CumTotTrigNb = 0; + ProAPlaneRes[Id].CumFrameTrigNb = 0; + + ProAPlaneRes[Id].FrameNbWithHit = 0; + ProAPlaneRes[Id].FramePCentWithHit = 0; + ProAPlaneRes[Id].CumTotHitNb = 0; + ProAPlaneRes[Id].CumFrHitNb = 0; + FSBB0__FMatDiscriCumulResetHit ( VPtFrMatCumTotHitCnt ); + + msg (( MSG_OUT, "----------> ProFProcessPlane => Reset - Plane %d", Id )); + } + + VGoodFrame = 1; + + // Convert ZsFFrameRaw to ZsFFrame and store result in class tmp var PrivZsFFrame + + if ( ProPar.HandleTrigPos == 0 ) { + FSBB0__FConvZsFFrameRawToZsFFrame ( PtSrc, &PrivZsFFrame, 0 /* DbgPrintLvl */ ); + } + + // Trigger pos handling + + else { + if ( FSBB0__FConvZsFFrameRawToZsFFrameHandleTrigger ( ProPar.MapsNb, DbgEvNo, PrivAcqEvNb, PtSrc, &PrivZsFFrame, 1 /* DbgPrintLvl */ ) < 0 ) { +// msg (( MSG_OUT, "***********************************************************************************" )); +// msg (( MSG_OUT, "=> Event %4d has no trigger => Abort ! Plot may be false ! ( it's previous event ) ", DbgEvNo )); +// msg (( MSG_OUT, "**********************************************************************************" )); + +// return (0); + + VGoodFrame = 0; + } + } + + // Convert ZsFFrameRaw to Pixels matrix AND Process cumul AT THE SAME TIME + + VUpdateMatCumul = ProAPlanePar[Id].PlotCum || ProAPlanePar[Id].PlotCoin; + + // ****************************************************************************************************** + // WARNING !!! TODAY 25/07/2009 Update matrix cumul is ALWAYS done => flag VUpdateMatCumul IS NOT used + // => Use flag later AND check ! + // ****************************************************************************************************** + +if ( VGoodFrame == 1 ) { + + VHitCnt = PrivFConvZsFFrameToMatDiscriBitAndCumul ( + DbgEvNo, + ProPar.ProcMode /* Mode */, + Id /* PlaneNo */, + ProAPlanePar[Id].PlotCoin /* PlaneSelForCoin */, + ProInf.CurEvToProc /* EvNo */, + ProPar.GotoRawFrNo /* EvSelForPlot */, + &PrivZsFFrame /* PtSrc */, + VPtFrMatDiscriBit /* PtDestFrameBit */, // Plane pixel matrix as "bit = state" + &PrivMatDiscriCoin /* PtDestCoinBit */, // Common coincidence pixel matrix as "bit = state" + VPtFrMatCumTotHitCnt /* PtDestFrameCum */, // Plane pixel cumul matrix as "count" + &PrivMatDiscriCoinCum /* PtDestCoinCum */, // Common coincidence cumul matrix as "count" + 0 /* PrintLvl */ ); + + // Increment counter of frames with trigger + + if ( PrivZsFFrame.TrigSignalLine >= 0 ) { + ++ProAPlaneRes[Id].FrameNbWithTrig; + } + + // Increment counter of triggers +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + if ( PrivZsFFrame.SStatus.ATrigRes[ASIC__FSBB0_TRIG_TOT_NB] > 0 ) { + ProAPlaneRes[Id].CumTotTrigNb += PrivZsFFrame.SStatus.ATrigRes[ASIC__FSBB0_TRIG_TOT_NB]; + } +//#endif + + // Increment counter of frames with hits + + if ( VHitCnt > 0 ) { + ++ProAPlaneRes[Id].FrameNbWithHit; + ProAPlaneRes[Id].CumTotHitNb += VHitCnt; + } + + +} // End if ( VGoodFrame == 1 ) + + + // ------------------------------------------------ + // Plot frame + // ------------------------------------------------ + + if ( (ProAPlanePar[Id].PlotFrame ) && (ProPar.GotoRawFrNo >= 0) && (ProPar.GotoRawFrNo == ProInf.CurEvToProc) ) { + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatConvBitToColState ( VPtFrMatDiscriBit, &PrivMatDispColor, clWhite /* ColorStateZero */, ProAPlanePar[Id].PlotColor, 0 /* RevertLineDirection */ ); + } + + else { + FSBB0__FConvMatDiscriBitToMatDiscriBitHalfScale ( VPtFrMatDiscriBit, &PrivMatDiscriBitHalfScale ); + FSBB0__FDiscriMatConvBitToColStateHalfScale ( &PrivMatDiscriBitHalfScale, &PrivMatDispColorHalfScale, clWhite /* ColorStateZero */, ProAPlanePar[Id].PlotColor, 0 /* RevertLineDirection */ ); + + FSBB0_FPrintZsFFrameRawHeader ( PtSrc ); + FSBB0__FMatDiscriPrintHit ( "Plane", Id, VPtFrMatDiscriBit ); + + // err_error (( ERR_OUT, "---> ---> Plot frame request 1/2 matrix - Plane %d", Id )); + } + + VRequestPlot = 1; // PLot request will be done at end of function + + } // End if Plot frame + + + + // Copy to buffer if required + + if ( ProPar.StoreEvents == 1 ) { + + err_error (( ERR_OUT, "Copy of event to buffer NOT IMPLEMENTED" )); + + } // Enf if copy to buffer + + + // ================================================ + // Last event => calculate results & display + // ================================================ + + if ( (PrivStopProc == 1) || (ProInf.CurEvToProc >= (ProInf.LastEvToProc) ) ) { + + msg (( MSG_OUT, "----------> ProFProcessPlane => Last event => Calc" )); + + err_error (( ERR_OUT, "----------> ProFProcessPlane => Last event => Calc" )); + + ProAPlaneRes[Id].FramePCentWithTrig = ( (float) ProAPlaneRes[Id].FrameNbWithTrig / (float) ProInf.EvNbToProc ) * 100; + + ProAPlaneRes[Id].FramePCentWithHit = ( (float) ProAPlaneRes[Id].FrameNbWithHit / (float) ProInf.EvNbToProc ) * 100; + + if ( ProAPlaneRes[Id].FrameNbWithTrig != 0 ) { + ProAPlaneRes[Id].CumFrameTrigNb = (float) ProAPlaneRes[Id].CumTotTrigNb / (float) ProAPlaneRes[Id].FrameNbWithTrig; + } + + else { + ProAPlaneRes[Id].CumFrameTrigNb = 0; + } + + + if ( ProAPlaneRes[Id].FrameNbWithHit != 0 ) { + ProAPlaneRes[Id].CumFrHitNb = ( (float) ProAPlaneRes[Id].CumTotHitNb / (float) ProAPlaneRes[Id].FrameNbWithHit ); + } + + else { + ProAPlaneRes[Id].CumFrHitNb = 0; + } + + + PubFPrintPlaneRes (Id); + + while (1) { + + // ------------------------------------------------ + // Plot cumul + // ------------------------------------------------ + + if ( ProAPlanePar[Id].PlotCum ) { + + // FSBB0__FPrintMatDiscriCumul ( VPtFrMatCumTotHitCnt ); + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatConvCumulToColVal ( VPtFrMatCumTotHitCnt, &PrivMatDispColor, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + err_error (( ERR_OUT, "---> Plot cumul request FULL matrix - Plane %d", Id )); + } + + else { + FSBB0__FConvMatDiscriCumToMatDiscriCumHalfScale ( VPtFrMatCumTotHitCnt, &PrivMatDiscriCumHalfScale ); + + // FSBB0__FPrintMatDiscriCumulHalfScale ( &PrivMatDiscriCumHalfScale ); + + FSBB0__FDiscriMatConvCumulToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + err_error (( ERR_OUT, "---> Plot cumul request 1/2 matrix - Plane %d", Id )); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCum) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS) ) { + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatFullScaleConvCoinBitToColState ( &PrivMatDiscriCoin, &PrivMatDispColor, clWhite /* ColorZeroHit */, PrivAPlanePlotColor /* AColorOneHit */, clBlack /* ColorMultiHit */, 0 /* RevertLineDirection */ ); + } + + else { + FSBB0__FConvMatDiscriBitCoinToMatDiscriBitCoinHalfScale ( &PrivMatDiscriCoin, &PrivMatDiscriBitHalfScale ); + FSBB0__FDiscriMatConvCoinBitToColStateHalfScale ( &PrivMatDiscriBitHalfScale, &PrivMatDispColorHalfScale, clWhite /* ColorZeroHit */, PrivAPlanePlotColor /* AColorOneHit */, clBlack /* ColorMultiHit */, 0 /* RevertLineDirection */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR) ) { + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatConvCumulToColVal ( &PrivMatDiscriCoinCum, &PrivMatDispColor, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + } + + else { + FSBB0__FConvMatDiscriCumToMatDiscriCumHalfScale ( &PrivMatDiscriCoinCum, &PrivMatDiscriCumHalfScale ); + FSBB0__FDiscriMatConvCumulToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) ) { + + if ( ProPar.DispFullMatrix ) { + FSBB0__FDiscriMatConvCumulCoinOrToColVal ( &PrivMatDiscriCoinCum, &PrivMatDispColor, PrivAPlanePlotColor /* AColorOneHit */, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + } + + else { + FSBB0__FConvMatDiscriCumToMatDiscriCumHalfScale ( &PrivMatDiscriCoinCum, &PrivMatDiscriCumHalfScale ); + FSBB0__FDiscriMatConvCumulCoinOrToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, PrivAPlanePlotColor /* AColorOneHit */, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) + + + break; + } // End while (1) + + + } // End if Last event + + + // ------------------ + // Plot request + // ------------------ + + if ( VRequestPlot ) { + + if ( ProRequestPlot == 0 ) { + ProRequestPlot = 1; + } + + } + + + return (VHitCnt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +FSBB0__TCTelMon::FSBB0__TCTelMon () : MAPS__TCDigTelMon () { + + err_error (( ERR_OUT, "TRACE - ProPar.PlaneNb=%d", ProPar.PlaneNb )); + + PrivFInit (); + + err_error (( ERR_OUT, "TRACE - ProPar.PlaneNb=%d", ProPar.PlaneNb )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +FSBB0__TCTelMon::~FSBB0__TCTelMon () { + + SInt32 Vi; + + // Free + + for ( Vi=0; Vi < FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB; Vi++ ) { + free ( PrivAAListEvWithTrig[Vi] ); + free ( PrivAAListEvWithHit[Vi] ); + } + + free ( PrivAListEvWithHitAllPlanes ); + + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 MaxBuffEvNb ) { + + if ( MaxBuffEvNb > MAPS__TCDigTelMon_MAX_EV_NB ) { + err_retfail ( -1, (ERR_OUT,"MaxBuffEvNb=%d > MAPS__TCDigTelMon_MAX_EV_NB=%d", MaxBuffEvNb, MAPS__TCDigTelMon_MAX_EV_NB ) ); + } + + ProPar.MaxBuffEvNb = MaxBuffEvNb; + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFConnectGui () { + + MAPS__TCDigTelMon::PubFConnectGui (); + + PubPt_ALbPlane[0]->Font->Color = FSBB0__TCTelMon__COL_PLANE_0; + PubPt_ALbPlane[1]->Font->Color = FSBB0__TCTelMon__COL_PLANE_1; + PubPt_ALbPlane[2]->Font->Color = FSBB0__TCTelMon__COL_PLANE_2; + PubPt_ALbPlane[3]->Font->Color = FSBB0__TCTelMon__COL_PLANE_3; + PubPt_ALbPlane[4]->Font->Color = FSBB0__TCTelMon__COL_PLANE_4; + PubPt_ALbPlane[5]->Font->Color = FSBB0__TCTelMon__COL_PLANE_5; + + PubPt_GrpTelMon->Color = clSilver; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGetGuiPar () { + + // -------------------------- + // Get parameters from GUI + // -------------------------- + + MAPS__TCDigTelMon::PubFGetGuiPar (); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 FSBB0__TCTelMon::PubFStartRun ( SInt8 MapsNb) { + + SInt8 ViPlane; + SInt32 ViEv; + void* VPtMat; + + + // --------------------- + // Run in progress + // --------------------- + + ProInf.RunInProgress = 1; + + // --------------------- + // Set MAPS nb + // --------------------- + + ProPar.MapsNb = MapsNb; + + // --------------------- + // Reset Ev No to process + // --------------------- + + ProInf.CurEvToProc = 0; + + // --------------------- + // Allocate memory + // --------------------- + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + // Intermediate buffers + + ProAPlaneRes[ViPlane].PtMatDiscriBit = malloc ( sizeof (FSBB0__TMatDiscriBit) ); + err_retnull ( ProAPlaneRes[ViPlane].PtMatDiscriBit, (ERR_OUT,"Allocation of PtMatDiscriBit plane [%d] failed !", ViPlane) ); + + ProAPlaneRes[ViPlane].PtMatCumTotHitCnt = malloc ( sizeof (FSBB0__TMatDiscriCumul)); + err_retnull ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt, (ERR_OUT,"Allocation of PtMatCumTotHitCnt plane [%d] failed !", ViPlane) ); + + // Events + + if ( ProPar.StoreEvents == 1 ) { + + for ( ViEv=0; ViEv < ProPar.MaxBuffEvNb; ViEv++ ) { + VPtMat = malloc ( sizeof (FSBB0__TMatDiscriBit) ); + + if ( VPtMat = NULL) { + err_retfail ( -1, (ERR_OUT,"Allocation of plane[%d] event[%d] failed !",ViPlane, ViEv) ); + } + + ProAPlaneData[ViPlane].AEvPt[ViEv] = VPtMat; + + } // End for ViEv + + } // End if StoreEvents + + } // End for + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFStopRun () { + + SInt8 ViPlane; + SInt32 ViEv; + + // --------------------- + // Run stopped + // --------------------- + + ProInf.RunInProgress = 0; + + // --------------------- + // DeAllocate memory + // --------------------- + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + // Intermediate buffers + + if ( ProAPlaneRes[ViPlane].PtMatDiscriBit != NULL ) free ( ProAPlaneRes[ViPlane].PtMatDiscriBit ); + if ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt != NULL ) free ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt ); + + // Events + + for ( ViEv=0; ViEv < MAPS__TCDigTelMon_MAX_EV_NB; ViEv++ ) { + if ( ProAPlaneData[ViPlane].AEvPt != NULL ) { + free ( ProAPlaneData[ViPlane].AEvPt ); + } + } + + } // End for + + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFStartMon () { + + ProPar.MonEnabled = 1; + + PubFSetGuiPar (); + + PubPt_GrpTelMon->Color = clBtnFace; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFStopMon () { + + ProPar.MonEnabled = 0; + + PubFSetGuiPar (); + + PubPt_GrpTelMon->Color = clSilver; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ) { + + ProPar.ProcOnlyFrWithHitOnAllPlanes = Yes; + PriEnListEvWitHitUpdate = !Yes; + PriEnListEvWithTrigUpdate = !Yes; + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 - 06/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt32 EvNb, FSBB0__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ) { + + SInt8 ViPlane; + SInt32 ViFramePlane0ofEvent; + SInt32 ViFrame; + SInt32 ViEvInAcq; + SInt32 VTrigSigLine; + SInt32 VEvHitCnt; + SInt32 VPlaneHitCnt; + SInt8 VFlgHitOnAllPlane; + SInt8 VFlgSingleHitOnEachPlane; + SInt32 VLocalCpySz; + ASIC__TFrameStatus* VPtEvStatus; + static UInt32 VTimeBeg; + static UInt32 VTimeEnd; + + SInt8 ViDbgMaps; + UInt16 VDbgTrigNb; + UInt16 VADbgTrigVal[3]; + UInt16 VADbgTrigLine[3]; + UInt16 VADbgTrigClock[3]; + + err_error (( ERR_OUT, "MapsName=%d - MapsNb=%d - EvNb=%d", MapsName, MapsNb, EvNb )); + err_error (( ERR_OUT, "" )); + + for ( ViDbgMaps=0; ViDbgMaps < MapsNb; ViDbgMaps++ ) { +#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VDbgTrigNb = (PtSrc[ViDbgMaps].Zero & 0xFFFF0000) >> 16; + VADbgTrigVal[0] = (PtSrc[ViDbgMaps].Zero & 0x0000FFFF); + VADbgTrigVal[1] = (PtSrc[ViDbgMaps].Zero2 & 0xFFFF0000) >> 16; + VADbgTrigVal[2] = (PtSrc[ViDbgMaps].Zero2 & 0x0000FFFF); +#endif + + VADbgTrigLine[0] = VADbgTrigVal[0] / 16; + VADbgTrigLine[1] = VADbgTrigVal[1] / 16; + VADbgTrigLine[2] = VADbgTrigVal[2] / 16; + + VADbgTrigClock[0] = VADbgTrigVal[0] % 16; + VADbgTrigClock[1] = VADbgTrigVal[1] % 16; + VADbgTrigClock[2] = VADbgTrigVal[2] % 16; + + err_error (( ERR_OUT, "=======================================================================================" )); + err_error (( ERR_OUT, "ViDbgMaps=%d : AsicNo=%d - AcqNo=%d - Header=%x", ViDbgMaps, PtSrc[ViDbgMaps].SStatus.AsicNo, PtSrc[ViDbgMaps].SStatus.AcqNo, PtSrc[ViDbgMaps].Header )); +// err_error (( ERR_OUT, "--> Trailer=%x", PtSrc[ViDbgMaps].Trailer )); +// err_error (( ERR_OUT, "--> Zero H=%d - Zero L=%d", (PtSrc[ViDbgMaps].Zero & 0xFFFF0000) >> 16, (PtSrc[ViDbgMaps].Zero & 0x0000FFFF) )); +// err_error (( ERR_OUT, "--> Zero2 H=%d - Zero2 L=%d", (PtSrc[ViDbgMaps].Zero2 & 0xFFFF0000) >> 16, (PtSrc[ViDbgMaps].Zero2 & 0x0000FFFF) )); + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "--> Trig Nb = %d", VDbgTrigNb )); + err_error (( ERR_OUT, "--> Trig [0] : Line %4d - clock %4d", VADbgTrigLine[0], VADbgTrigClock[0] )); + err_error (( ERR_OUT, "--> Trig [1] : Line %4d - clock %4d", VADbgTrigLine[1], VADbgTrigClock[1] )); + err_error (( ERR_OUT, "--> Trig [2] : Line %4d - clock %4d", VADbgTrigLine[2], VADbgTrigClock[2] )); + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + err_error (( ERR_OUT, "Info Trigger : Line %4d - clock %4d", PtSrc[ViDbgMaps].SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], PtSrc[ViDbgMaps].SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK] )); +//#endif + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); + + } + + err_error (( ERR_OUT, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" )); + + if ( (ProPar.MonEnabled == 0) && (OffLineCall == 0) ) { + return (0); + } + + // Check parameters + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc = NULL") ); + + if ( MapsName != ProPar.MapsName ) { + err_retfail ( -1, (ERR_OUT,"Bad MapsName=%d <> ProPar.MapsName=%d", MapsName, ProPar.MapsName ) ); + } + + if ( MapsNb != ProPar.MapsNb ) { + err_retfail ( -1, (ERR_OUT,"Bad MapsNb=%d <> ProPar.MapsNb=%d", MapsNb, ProPar.MapsNb ) ); + } + + // make a copy of Acq event nb, for off-line processing call of this function + + PrivAcqEvNb = EvNb; + + // Make a local copy if required + + if ( MakeLocalCpy ) { + + if ( PrivPtAcqData != NULL ) { + free ( PrivPtAcqData ); + } + + VLocalCpySz = MapsNb * EvNb * sizeof (FSBB0__TZsFFrameRaw); + + PrivPtAcqData = (FSBB0__TZsFFrameRaw*) malloc ( VLocalCpySz ); + + if ( PrivPtAcqData == NULL ) { + err_error (( ERR_OUT, "Allocation of buffer for local copy of %d bytes ... failed !", VLocalCpySz )); + } + + else { + memcpy ( PrivPtAcqData, PtSrc, VLocalCpySz ); + msg (( MSG_OUT, "Allocation of buffer AND local copy of %d Kbytes done :-)", VLocalCpySz / 1024 )); + err_error (( ERR_OUT, "Allocation of buffer for local copy of %d Kbytes done :-)", VLocalCpySz / 1024 )); + } + + } + + // Read GUI parameters + + PubFGetGuiPar (); + + + // Update processing mode flags + + PrivListEvWithHitAllPlanesCurProcMode = ProPar.ListHitAllPlanesMode; + + // ---------------------------------------- + // If beginning of processing + // ---------------------------------------- + + + if ( ProInf.CurEvToProc == 0 ) { + + PrivStopProc = 0; + + VTimeBeg = GetTickCount (); // Get time of beginning of processing + + msg (( MSG_OUT, "----------> PubFAddEvents => Reset all results" )); + + // Reset all coin destination matrices ( common for all planes ) + + memset ( &PrivMatDiscriCoin , 0, sizeof (FSBB0__TMatDiscriBit) ); + memset ( &PrivMatDiscriCoinCum, 0, sizeof (FSBB0__TMatDiscriCumul) ); + + // Reset list & list index & full flag + // + // -> Must be done HERE + // -> MUST NOT be done at end of this function when ProInf.EvNbToProc is reached + // because user will want to plot theses results at end of processing + + if ( PriEnListEvWithTrigUpdate == 1 ) { + + for ( ViPlane=0; ViPlane < FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB; ViPlane++ ) { + memset ( PrivAAListEvWithTrig[ViPlane], 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + } + + PrivListEvWithTrigIndex = 0; + PrivListEvWithTrigFull = 0; + } // End if ( PriEnListUpdate == 1 ) + + if ( PriEnListEvWitHitUpdate == 1 ) { + + for ( ViPlane=0; ViPlane < FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB; ViPlane++ ) { + memset ( PrivAAListEvWithHit[ViPlane], 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + } + + memset ( PrivAListEvWithHitAllPlanes, 0, FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (FSBB0__TCTelMon_TEltListEvWithHitAllPlanes) ); + + PrivListEvWithHitIndex = 0; + PrivListEvWithHitFull = 0; + + PrivListEvWithHitAllPlanesIndex = 0; + PrivListEvWithHitAllPlanesFull = 0; + + } // End if ( PriEnListUpdate == 1 ) + + + } + + // Results set + + ProRes.AcqFrNb = EvNb; + + // Processing mode selection + // - One acq => number of events received by server + // - Events number from GUI => can be less or more than one Acq + + if ( ProPar.ProcOneAcq ) { + ProInf.EvNbToProc = EvNb; + } + + else { + ProInf.EvNbToProc = ProPar.ProcEvNb; + } + + ProInf.LastEvToProc = ProInf.EvNbToProc - 1; + + msg (( MSG_OUT, "PubFAddEvents => MapsName=%d - MapsNb=%d - EvNb=%d (DAQ) - ProcOneAcq=%d - EvNbToProc=%d", MapsName, MapsNb, EvNb, ProPar.ProcOneAcq, ProInf.EvNbToProc )); + + // Process events + + + for ( ViEvInAcq=0; ViEvInAcq < EvNb; ViEvInAcq++ ) { + + if ( ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) { + PrivStopProc = PubFIsEvLastOfListEvWithHitOnAllPlanes ( ViEvInAcq ); + } + + else { + PrivStopProc = 0; + } + + + VFlgHitOnAllPlane = 1; + VFlgSingleHitOnEachPlane = 1; + + if ( ProInf.CurEvToProc < ProInf.EvNbToProc ) { + + if ( ViEvInAcq % 100 == 0 ) { + FDecInt2Edit ( ViEvInAcq, PubPt_DispCurProcFr ); + Application->ProcessMessages (); + } + + ViFramePlane0ofEvent = MapsNb * ViEvInAcq; + VTrigSigLine = PtSrc[ViFramePlane0ofEvent].SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; + VPtEvStatus = &PtSrc[ViFramePlane0ofEvent].SStatus; + + // If Process all frames OR Process frame with trigger AND there is a Trigger on this frame + + // if ( (ProPar.ProcOnlyFrWithTrig == 0) || (VTrigSigLine >= 0) ) { + // if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 0) || (PubFIsEvInListEvWithHitOnAllPlanes (ViEvInAcq) == 1) ) { + + if ( ((ProPar.ProcOnlyFrWithTrig == 0) || (VTrigSigLine >= 0)) && ((ProPar.ProcOnlyFrWithHitOnAllPlanes == 0) || (PubFIsEvInListEvWithHitOnAllPlanes (ViEvInAcq) == 1)) ) { + + // Reset event hits counter + + VEvHitCnt = 0; + + // Loop on all selected planes + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + if ( ProAPlanePar[ViPlane].Process == 1 ) { + + ViFrame = ViFramePlane0ofEvent + ViPlane; + VPlaneHitCnt = ProFProcessPlane ( ViEvInAcq, ViPlane, &PtSrc[ViFrame] ); + VEvHitCnt += VPlaneHitCnt; + + if ( VPlaneHitCnt != 1 ) { + VFlgSingleHitOnEachPlane = 0; + } + + if ( VPlaneHitCnt > 0 ) { + PrivFAddEvInListEvWithHit ( ViPlane, VPtEvStatus, VPlaneHitCnt, 0 /* HitOnAllPlanes */, 0 /* SingleHitOnEachPlane */ ); + } + + else { + VFlgHitOnAllPlane = 0; // Reset flag in at least one plane is without hit + } + + } + } + + // If trigger ( -1 => no trigger ) => store in list + + if ( VTrigSigLine >= 0 ) { + PrivFAddEvInListEvWithTrig ( FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL, VPtEvStatus, VEvHitCnt ); + } + + // If hits => store in list + + if ( VEvHitCnt > 0 ) { + PrivFAddEvInListEvWithHit ( FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL, VPtEvStatus, VEvHitCnt, VFlgHitOnAllPlane, VFlgSingleHitOnEachPlane ); + } + + // Results + + ProRes.ProFrNo = ProInf.CurEvToProc; + + ++ProInf.CurEvToProc; + + } + + + } + + else { + break; // End of processing => We can reach ProInf.EvNbToProc while all events of current Acq are not needed for processing + } + + } // End for + + // If end of processing => Reset event index + + if ( ProInf.CurEvToProc >= ProInf.EvNbToProc ) { + + msg (( MSG_OUT, "----------> PubFAddEvents => Print results" )); + + ProInf.CurEvToProc = 0; + + // Get time of end of processing + + VTimeEnd = GetTickCount (); + ProRes.ProTimeMs = VTimeEnd - VTimeBeg; + + // Display results + + PubFSetGuiRes (); + + // Stop monitoring if required + + if ( ProPar.StopAtEndOfProc ) { + PubFStopMon (); + } + + } + + // Display status + + PubFSetGuiStatus (); + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFProcessOffLineCurAcq () { + + + // Stop on-line monitoring + + PubFStopMon (); + + // Get GUI parameters => In order to get user choices + + PubFGetGuiPar (); + + // Force mode to "Process one Acq" AND update GUI fields + + ProPar.ProcOneAcq = 1; + + PubFSetGuiPar (); + + // Don't update list if processing of ONLY events with trigger + + if ( ProPar.ProcOnlyFrWithTrig == 1 ) { + PriEnListEvWithTrigUpdate = 0; + } + + else { + PriEnListEvWithTrigUpdate = 1; + } + + // Check buffer of current acq data + + err_retnull ( PrivPtAcqData, (ERR_OUT,"No data in buffer => PrivPtAcqData == NULL !") ); + + // ---------------------------------------------------------------------------------------------------------------------- + // Reset Ev No to process + // ---------------------------------------------------------------------------------------------------------------------- + // Because on some processing it may not be reset at end of processing, in case event nb to process has not been reached + // for example : processing of only events with trigger + // ---------------------------------------------------------------------------------------------------------------------- + // + // WARNING => IT MUST BE CHECKED if this init DONE HERE IS compatible WITH ALL sw operating modes !!! + // => It may CAUSE BUGS in other operating modes !!! + // + // 15/08/09 + // ---------------------------------------------------------------------------------------------------------------------- + + ProInf.CurEvToProc = 0; + + + // Execute PubFAddEvents (...) in off-line mode + + PubFAddEvents ( ProPar.MapsName, ProPar.MapsNb, PrivAcqEvNb, PrivPtAcqData/* PtSrc */, 0 /* MakeLocalCpy */, 1 /* OffLineCall */ ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFProcessOffLineCurAcq2 () { + + // Stop on-line monitoring + + PubFStopMon (); + + // Force mode to "Process one Acq" AND update GUI fields + + ProPar.ProcOneAcq = 1; + + // Execute PubFAddEvents (...) in off-line mode + + PubFAddEvents ( ProPar.MapsName, ProPar.MapsNb, PrivAcqEvNb, PrivPtAcqData/* PtSrc */, 0 /* MakeLocalCpy */, 1 /* OffLineCall */ ); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGotoFirstFrame () { + + ProPar.GotoRawFrNo = 0; + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGotoPrevFrame () { + + if ( ProPar.GotoRawFrNo > 0 ) { + --ProPar.GotoRawFrNo; + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGotoNextFrame () { + + if ( ProPar.GotoRawFrNo < PrivAcqEvNb ) { + ++ProPar.GotoRawFrNo; + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFGotoLastFrame () { + + if ( PrivAcqEvNb > 0 ) { + ProPar.GotoRawFrNo = PrivAcqEvNb-1; + } + + else { + ProPar.GotoRawFrNo = -1; // No frame available, < 0 tested when we try to access data + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubPrintListEvWithTrig ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPt; + + + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "- Print events with trigger -" )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithTrigIndex, PrivListEvWithTrigFull )); + msg (( MSG_OUT, "-----------------------------" )); + + VPt = PrivAAListEvWithTrig[FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL]; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithTrigIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithTrigIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - TSigLine=%4d - HitCnt=%4d", Vi, VPt->FrameNoInRun, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubPrintListEvWithHit ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPtPlane0; + ASIC__TFrameStatus* VPtPlane1; + ASIC__TFrameStatus* VPt; + + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "- Print events with hit -" )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithHitIndex, PrivListEvWithHitFull )); + msg (( MSG_OUT, "-----------------------------" )); + + + VPtPlane0 = PrivAAListEvWithHit[0]; + VPtPlane1 = PrivAAListEvWithHit[1]; + VPt = PrivAAListEvWithHit[FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL]; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithHitIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt[C]=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + ++VPtPlane0; + ++VPtPlane1; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithHitIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - TSigLine=%4d - HitCnt [0]=%4d / [1]=%4d / [C]=%4d", Vi, VPt->FrameNoInRun, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPtPlane0->HitCnt, VPtPlane1->HitCnt, VPt->HitCnt )); + ++VPt; + ++VPtPlane0; + ++VPtPlane1; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubPrintListEvWithHitOnAllPlanes ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPtP0; + ASIC__TFrameStatus* VPtP1; + ASIC__TFrameStatus* VPt; + FSBB0__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + if ( ProPar.ListHitAllPlanesMode != PrivListEvWithHitAllPlanesCurProcMode ) { + msg (( MSG_OUT, "----------------------------------------------------------" )); + msg (( MSG_OUT, "- Please process data before with button -" )); + msg (( MSG_OUT, "----------------------------------------------------------" )); + err_retok (( ERR_OUT, "" )); + } + + + msg (( MSG_OUT, "--------------------------------------" )); + + + switch ( ProPar.ListHitAllPlanesMode ) { + + case MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES : { + msg (( MSG_OUT, "- Print events with hit on ALL planes -" )); + break; } + + case MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE : { + msg (( MSG_OUT, "- Print events with single hit on EACH plane -" )); + break; } + + default : { + msg (( MSG_OUT, "- Error => Unknown list mode = %d -", ProPar.ListHitAllPlanesMode )); + break; } + + } + + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithHitAllPlanesIndex, PrivListEvWithHitAllPlanesFull )); + msg (( MSG_OUT, "------------------------------------------------------" )); + + + VPtRec = PrivAListEvWithHitAllPlanes; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + VPt = &VPtRec->FrStatus; + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt[C]=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPtRec; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + VPt = &VPtRec->FrStatus; + + if ( (VPtRec->IndexInEvWithHitList >=0) && (VPtRec->IndexInEvWithHitList < PrivListEvWithHitIndex) ) { + VPtP0 = &PrivAAListEvWithHit[0][VPtRec->IndexInEvWithHitList]; + VPtP1 = &PrivAAListEvWithHit[1][VPtRec->IndexInEvWithHitList]; + msg (( MSG_OUT, "[%4d] : EvInAcq=%4d - TSigLine=%4d - HitCnt [0]=%4d / [1]=%4d / [C]=%4d", Vi, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPtP0->HitCnt, VPtP1->HitCnt, VPt->HitCnt )); + } + + else { + msg (( MSG_OUT, "[%4d] : EvInAcq=%4d - TSigLine=%4d - HitCnt [0]=! / [1]=! / [C]=%4d", Vi, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE], VPt->HitCnt )); + } + + ++VPtRec; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubAllocResRun () { + + // Res run alloc / free handling + + if ( PrivPtResRun != NULL ) { + free ( PrivPtResRun ); + } + + + PrivPtResRun = (FSBB0__TCTelMon_TResRun*) malloc ( sizeof (FSBB0__TCTelMon_TResRun) ); + + if ( PrivPtResRun == NULL ) { + err_error (( ERR_OUT, "Allocation of result run failed !" )); + } + + else { + + memset ( PrivPtResRun, 0, sizeof (FSBB0__TCTelMon_TResRun) ); + + PrivPtResRun->EvNb = 0; + PrivPtResRun->PlaneNb = 2; + } + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 06/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFreeResRun () { + + if ( PrivPtResRun != NULL ) { + free ( PrivPtResRun ); + } + + + PrivPtResRun = NULL; + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubPrintResRun () { + + SInt32 ViEv; + SInt32 ViHit; + FSBB0__TCTelMon_TTrack* VPt; + + if ( PrivPtResRun == NULL ) { + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "- ERROR => Res run is NOT allocated - " )); + msg (( MSG_OUT, "-------------------------------------" )); + err_retfail ( -1, (ERR_OUT,"PrivPtResRun == NULL") ); + } + + msg (( MSG_OUT, "--------------------------------------" )); + msg (( MSG_OUT, "- Result run -" )); + msg (( MSG_OUT, "--------------------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivPtResRun->EvNb, PrivPtResRun->Full )); + msg (( MSG_OUT, "--------------------------------------" )); + + + for ( ViEv=0; ViEv < PrivPtResRun->EvNb; ViEv++) { + + VPt = &PrivPtResRun->ATracks[ViEv]; + + if ( VPt->AHitsNbPerPlane[0] != VPt->AHitsNbPerPlane[1] ) { + msg (( MSG_OUT, "WARNING : Hit nb P0 = %d <> Hit nb P1 = %d => Use P0 for print", VPt->AHitsNbPerPlane[0], VPt->AHitsNbPerPlane[1] )); + } + + msg (( MSG_OUT, "=================================================================" )); + + for ( ViHit=0; ViHit < VPt->AHitsNbPerPlane[0]; ViHit++) { + msg (( MSG_OUT, "Ev %4d - EvInRun %4d - Hit %4d : P0 [x=%4d, y=%4d] - P1[x=%4d, y=%4d]", ViEv, VPt->EvNoInRun, ViHit, VPt->AAHits[0][ViHit].x, VPt->AAHits[0][ViHit].y, VPt->AAHits[1][ViHit].x, VPt->AAHits[1][ViHit].y )); + } + + } + + + msg (( MSG_OUT, "-----------------------------" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubSaveResRun ( char* FileName ) { + + SInt32 VTotResRecordSz; + + if ( PrivPtResRun == NULL ) { + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "- ERROR => Res run is NOT allocated - " )); + msg (( MSG_OUT, "-------------------------------------" )); + err_retfail ( -1, (ERR_OUT,"PrivPtResRun == NULL") ); + } + + FIL__TCBinFile VResFile ( "x:\\log\\err_TCBinFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_WARNINGS_ERRORS ); + + err_retnull ( FileName, (ERR_OUT,"FileName == NULL") ); + + VTotResRecordSz = sizeof (FSBB0__TCTelMon_TResRun); + + VResFile.PubFConf ( FileName, 0 /* WriteRead => 0=Write 1=Read */ , VTotResRecordSz /* MaxBlocSz */, VTotResRecordSz /* BlocSz */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VResFile.PubFCreate (); + VResFile.PubFSeqWrite ( PrivPtResRun, VTotResRecordSz ); + + VResFile.PubFClose (); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFIsEvInListEvWithHitOnAllPlanes ( SInt32 EvNo ) { + + SInt8 VFound; + SInt32 Vi; + FSBB0__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + VPtRec = PrivAListEvWithHitAllPlanes; + + VFound = 0; + + // Acq processing + + if ( PubAcqOffLineProcOrRunOffLineProc == 0 ) { + + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + if ( EvNo == VPtRec->FrStatus.FrameNoInRun ) { + err_error (( ERR_OUT, "TRACE : EltNo %4d - EvNo %4d - FrNoInAcq %4d => Hit on all planes", Vi, VPtRec->FrStatus.FrameNoInRun, VPtRec->FrStatus.FrameNoInAcq )); + VFound = 1; + break; + } + ++VPtRec; + } + + } + + // Run processing via N Acq processing + + else { + + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + if ( EvNo == VPtRec->FrStatus.FrameNoInAcq ) { + err_error (( ERR_OUT, "TRACE : EltNo %4d - EvNo %4d - FrNoInAcq %4d => Hit on all planes", Vi, VPtRec->FrStatus.FrameNoInRun, VPtRec->FrStatus.FrameNoInAcq )); + VFound = 1; + break; + } + ++VPtRec; + } + + } + + + return (VFound); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__TCTelMon::PubFIsEvLastOfListEvWithHitOnAllPlanes ( SInt32 EvNo ) { + + SInt32 Vi; + FSBB0__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + VPtRec = PrivAListEvWithHitAllPlanes; + + if ( EvNo == VPtRec[PrivListEvWithHitAllPlanesIndex - 1].FrStatus.FrameNoInRun ) { + return (1); + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt8* FSBB0__TCTelMon::PubFGetPtDispFullMatrix () { + return ( &ProPar.DispFullMatrix ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +FSBB0__TMatDiscriColor* FSBB0__TCTelMon::PubFGetPtFullMatCol () { + return ( &PrivMatDispColor ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +FSBB0__TMatDiscriColorHalfScale* FSBB0__TCTelMon::PubFGetPtHalfMatCol () { + return ( &PrivMatDispColorHalfScale ); +} + +#endif + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_110614.def b/include/pxi_daq_lib_v.2.1/fsbb0_110614.def new file mode 100755 index 0000000..21f4558 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_110614.def @@ -0,0 +1,204 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_DEF +#define FSBB0_DEF + +#define FSBB0__APP_IGNORE_GC_MOD_220514 + + + +#ifdef FSBB0__APP_DLL_TEST_ULT1 + #include "fsbb0_test_ult1.def" +#else + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define FSBB0__REG_DISCRI_BIT_SZ 416 // Ult1 = 960 // Mi26 = 1152 +#define FSBB0__REG_DISCRI_W32_SZ 13 // Ult1 = 30 // Mi26 = 36 + + + + + // Size in CLK unit of the frame which contains the readout of ONE line + #define FSBB0__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 832 // Single line = nop scanning mode + #define FSBB0__DISCRI_RO_SCAN_FRAME_CLK_NB 836 // Scanning mode + + + + + +// This register is not implemented on Ultimate +// +// #define FSBB0__REG_AFTER_ZS_BIT_SZ 160 +// #define FSBB0__REG_AFTER_ZS_W32_SZ 5 + +#define FSBB0__REG_AFTER_MUX_BIT_SZ 160 // Mi26 = 160 +#define FSBB0__REG_AFTER_MUX_W32_SZ 5 // Mi26 = 5 + +#define FSBB0__MAT_DISCRI_COL_NB 416 // 23/01/2013 +#define FSBB0__MAT_DISCRI_LINES_NB 424 // +#define FSBB0__MAT_DISCRI_USEFUL_LINES_NB 416 // 23/01/2013 - Without the two markers lines + + +#define FSBB0__ZS_FFRAME_MODE0_1X80MHZ 0 +#define FSBB0__ZS_FFRAME_MODE1_2X80MHZ 1 +#define FSBB0__ZS_FFRAME_MODE2_1X160MHZ 2 +#define FSBB0__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 13312 // 832 W16 // Ult1 = 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 13312 // 832 W16 // Ult1 = 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 13312 //26624 // 1772 W16 // Ult1 = 29696 // 1856 W16 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 13312 //26624 // 1772 W16 // Ult1 = 29696 // 1856 W16 + + + +// #define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +/* +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 416 // Ult1 = 928 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 416 // Ult1 = 928 // Mi26 = 576 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 832 // Ult1 = 1856 // Mi26 = 576 + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 208// Ult1 = 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 208// Ult1 = 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 416// Ult1 = 928 // Mi26 = 144 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 416// Ult1 = 928 // Mi26 = 288*/ + + +// Id to select FSBB0 register + +#define FSBB0__REG_DISCRI 0 +// #define FSBB0__REG_AFTER_ZS 1 -> Not implemented on Ultimate +//#define FSBB0__REG_AFTER_MUX 1 -> not implemented on fsbb +#define FSBB0__REG_DISCRI_SCAN 1 + +#define FSBB0__REG_DISCRI_SCAN__SRC_CLK_160MHZ 2 // 23/06/2010 + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define FSBB0__REG_BIAS_NB 19 + +// $ #define FSBB0__REG_BIAS_ICLPDISC 0 +// $ #define FSBB0__REG_BIAS_IPWRSW 1 +// $ #define FSBB0__REG_BIAS_IBUF 2 +// $ #define FSBB0__REG_BIAS_ID1PWRS 3 +// $ #define FSBB0__REG_BIAS_ID2PWRS 4 +// $ #define FSBB0__REG_BIAS_ILVDSTX 5 +// $ #define FSBB0__REG_BIAS_ILVDSRX 6 +// $ #define FSBB0__REG_BIAS_IVTST1 7 +// $ #define FSBB0__REG_BIAS_IVTST2 8 +// $ #define FSBB0__REG_BIAS_IANABUF 9 +// $ #define FSBB0__REG_BIAS_IVDREF1D 10 +// $ #define FSBB0__REG_BIAS_IVDREF1C 11 +// $ #define FSBB0__REG_BIAS_IVDREF1B 12 +// $ #define FSBB0__REG_BIAS_IVDREF1A 13 +// $ #define FSBB0__REG_BIAS_IVDREF2 14 +// $ #define FSBB0__REG_BIAS_IDIS1 15 +// $ #define FSBB0__REG_BIAS_IDIS2 16 +// $ #define FSBB0__REG_BIAS_IPXI 17 +// $ #define FSBB0__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define FSBB0__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define FSBB0__DIS_MEAS_STEP_PAR_FIRST 0 +#define FSBB0__DIS_MEAS_STEP_PAR_LAST (FSBB0__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define FSBB0__DIS_TEST_MAX_STEP_NB 50 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define FSBB0__NB_MAX_FSBB0_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define FSBB0__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define FSBB0__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define FSBB0__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// FSBB0__TCTelMon +// -------------------- + +#define FSBB0__COLOR_BROWN 0x000066CC +#define FSBB0__COLOR_ORANGE 0x0000A5FF +#define FSBB0__COLOR_YELLOW 0x0000FFFF +#define FSBB0__COLOR_GREEN 0x0000FF00 +#define FSBB0__COLOR_BLUE 0x00FF0000 +#define FSBB0__COLOR_VIOLET 0x00990066 + +#define FSBB0__TCTelMon__COL_PLANE_0 (TColor) FSBB0__COLOR_ORANGE +#define FSBB0__TCTelMon__COL_PLANE_1 (TColor) FSBB0__COLOR_BLUE +#define FSBB0__TCTelMon__COL_PLANE_2 (TColor) FSBB0__COLOR_BROWN +#define FSBB0__TCTelMon__COL_PLANE_3 (TColor) FSBB0__COLOR_YELLOW +#define FSBB0__TCTelMon__COL_PLANE_4 (TColor) FSBB0__COLOR_GREEN +#define FSBB0__TCTelMon__COL_PLANE_5 (TColor) FSBB0__COLOR_VIOLET + + +#define FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + +#endif + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_convert_frm.c b/include/pxi_daq_lib_v.2.1/fsbb0_convert_frm.c new file mode 100755 index 0000000..365a9bb --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_convert_frm.c @@ -0,0 +1,774 @@ + + +/******************************************************************************* +Prototype : SInt8 SUZE02_FHammingDecoder8_4(UInt8 CodedIn) + +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 10/07/2013 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + + UInt8 FSBB0_FHammingDecoder8_4(UInt8 CodedIn) + { + UInt8 VResult; + + // 27/06/2014 - MS replaced the hamming code ( which doesn't seem to be working for FSBB) by the converting the code received according to the mail from GD + // have to investigate when there will be some spare time........ + + switch (CodedIn){ + case 0:{ + VResult = 0; + break; + } + case 0x87:{ + VResult = 1; + break; + } + case 0x99:{ + VResult = 2; + break; + } + case 0x1e:{ + VResult = 3; + break; + } + case 0xaa:{ + VResult = 4; + break; + } + case 0x2d:{ + VResult = 5; + break; + } + case 0x33:{ + VResult = 6; + break; + } + case 0xb4:{ + VResult = 7; + break; + } + case 0x4b:{ + VResult = 8; + break; + } + case 0xcc:{ + VResult = 9; + break; + } + case 0xd2:{ + VResult = 0xa; + break; + } + case 0x55:{ + VResult = 0xb; + break; + } + case 0xe1:{ + VResult = 0xc; + break; + } + case 0x66:{ + VResult = 0xd; + break; + } + case 0x78:{ + VResult = 0xe; + break; + } + case 0xff:{ + VResult = 0xf; + break; + } + + }/* end switch G0 */ + + + +/* UInt8 VSyndrome; + UInt8 VParity; + UInt8 VTempResult; + UInt8 VError; + + VSyndrome = ((((CodedIn & 0x8)>>3)^((CodedIn & 0x10)>>4)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6))<<2 + + (((CodedIn & 0x2)>>1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6))<<1 + + ((CodedIn & 0x1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x10)>>4)^((CodedIn & 0x40)>>6))); + // Parity bit + + VParity = (CodedIn & 0x1)^((CodedIn & 0x2)>>1)^((CodedIn & 0x4)>>2)^((CodedIn & 0x8)>>3)^((CodedIn & 0x10)>>4)^((CodedIn & 0x20)>>5)^((CodedIn & 0x40)>>6); + VTempResult = CodedIn; + switch (VSyndrome ) + { + case 0 : { + // No Trans Error + // Nothing to do + break; + } + case 1 :{ + // Error on bit 0 + VTempResult ^= 0x1; + break; + } + case 2 : { + // Error on bit 1 + VTempResult ^= 0x2; + break; + } + case 3 : { + // Error on bit 2 + VTempResult ^= 0x4; + break; + } + case 4 : { + // Error on bit 3 + VTempResult ^= 0x8; + break; + } + case 5 : { + // Error on bit 4 + VTempResult ^= 0x10; + break; + } + case 6 : { + // Error on bit 5 + VTempResult ^= 0x20; + break; + } + default : { + // Error on bit 6 + VTempResult ^= 0x40; + break; + } + }*/ /* end switch */ + // ------------------------------------------------------------- // +/* if (VSyndrome == 0){ + VError = 0; + } + else{ + if (VParity == ((CodedIn & 0x80)>>7)){ + VError = 5; + } + else{ + VError = 3; + } + } + VResult = ((VTempResult & 2)>>2) + ((VTempResult & 16)>>3) + ((VTempResult & 32)>>3) + ((VTempResult & 64)>>3); + err_trace (( ERR_OUT, "FSBB0_FHammingDecoder8_4, result :%X, Error code : %X",VResult,VError ));*/ + + return (VResult); + +} /* End FSBB0_FHammingDecoder8_4 */ + + + + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 17/03/2009 +Doc date : 17/03/2009 +Rev : 04/05/2009 + : - Add a check of data length, if > 1140, force 1140, done to avoid bad + : data length due to transmission errors. + : + : 05/05/2009 + : - Add handling of odd number of W16 ( FSBB0 add one bad W16 in this case ) + : Not done at beginning because FSBB0 documentation was not clear enough + : ( bad translation of " impair " in even ! ) and it was not needed for + : tests done with emulated patterns. + : : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameRawToZsFFrame ( FSBB0__TZsFFrameRaw* Src, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) { + + SInt32 VRetW30Length; + SInt32 ViData; + UInt16 VDataW30Length; + UInt16 VLastW30; + SInt16 ViSrcW30; + + FSBB0__TStatesLine VStatesLine; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbG0; + SInt8 VStatesNbG1; + SInt16 VPrevLine; + SInt8 VG0Overflow; + SInt8 VG1Overflow; + + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Get useful data length + VDataW30Length = Src->UsefulDataLengthW30; + + VRetW30Length = VDataW30Length; + + if ( (PrintLvl == 5) || (PrintLvl == 6) || (PrintLvl == 7)/*||(PrintLvl == 8)*/ ) { + msg (( MSG_OUT, "TOTAL frame length : %d W30", VDataW30Length )); + msg (( MSG_OUT, "" )); + } + + // Add a check of data length, if > FSBB0__ZS_FFRAME_RAW_MAX_W30, force 0 and continue processing ( no exit on error ) + + if ( VDataW30Length > FSBB0__ZS_FFRAME_RAW_MAX_W32 /* 1140 */ ) { + err_error (( ERR_OUT, "Bad data length get from FSBB0 = %d W30 => Force 0 W30", VDataW30Length )); + VDataW30Length = 0; + Src->UsefulDataLengthW30 = 0; + VRetW30Length = -1; + } + + // Copy information fields + + Dest->SStatus = Src->SStatus; + + Dest->Header = Src->Header; + Dest->FrameCnt = Src->DataLengthRemFrCnt.F.FrameCnt; + Dest->DataLength = Src->UsefulDataLengthW30; + Dest->Trailer = Src->Trailer; +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + Dest->TrigSignalLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; + Dest->TrigSignalClk = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__LINE]; +//#endif + + // Process frame + + ViSrcW30 = 0; + ViStatesLine = 0; + VPrevLine = -1; + + if ( PrintLvl == 4 ) { + msg (( MSG_OUT, "Frame data length = %d [W30]", VDataW30Length )); + msg (( MSG_OUT, "" )); + } + +//#ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + + if ( VDataW30Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W30 nb handling ! + // + // It can seem strange that this can be done by processing one W30 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W30 number is odd, FSBB0 add one more bad W30 to get an even W30 number. + // This bad W30 will be seen as a StatesLine field followed by NO state because it is the last W30. + // Therefore if at the beginning of the while loop there is only one W30 to process, this W30 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W30 at the beginning of loop is the index of last W30 this W30 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W30 number, after processing of last + // state of last line the index of W30 equal W30 number, therefore is > of index of last W30, and + // we don't enter the loop. + + //VLastW30 = VDataW30Length - 1; + + while ( ViSrcW30 < VDataW30Length ) { // Odd W30 nb handling => Don't process last W30 + + // Copy StatesLine field + VStatesLine.W32 = Src->ADataW32[ViSrcW30]; + Dest->AStatesRec[ViStatesLine].StatesLine = VStatesLine; + VG0Overflow = 0; + VG1Overflow = 0; + + VStatesNbG0 = FSBB0_FHammingDecoder8_4(VStatesLine.F.HitNbG0); + VStatesNbG1 = FSBB0_FHammingDecoder8_4(VStatesLine.F.HitNbG1); + //msg (( MSG_OUT, " ViStatesLine :%d :VStatesLine.F.HitNbG0 : %X - VStatesNbG0 : %x - VStatesLine.F.HitNbG1 : %X - VStatesNbG1 : %x ", ViStatesLine, VStatesLine.F.HitNbG0,VStatesNbG0,VStatesLine.F.HitNbG1,VStatesNbG1 )); + + Dest->AStatesRec[ViStatesLine].NbWinG0 = VStatesNbG0; + Dest->AStatesRec[ViStatesLine].NbWinG1 = VStatesNbG1; + Dest->AStatesRec[ViStatesLine].NbWinTot = VStatesNbG0 + VStatesNbG1; + + if (VStatesNbG0 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ){ + VG0Overflow =VStatesNbG0; + VStatesNbG0 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + } + if (VStatesNbG1 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ){ + VG1Overflow =VStatesNbG1; + VStatesNbG1 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + } + // VStatesNbPerLine = VStatesLine.F.StateNb; + + + if ( (PrintLvl == 5) || (PrintLvl == 7) ) { + msg (( MSG_OUT, " ViStatesLine :%d :VStatesLine.W32 : %X - NbWinG0 : %d - NbWinG1 : %d ", ViStatesLine, VStatesLine.W32,Dest->AStatesRec[ViStatesLine].NbWinG0,Dest->AStatesRec[ViStatesLine].NbWinG1 )); + + //msg (( MSG_OUT, "NbWinG0 : %4d - NbWinG1 : %d - NbWinTot : %d ", Dest->AStatesRec[ViStatesLine].NbWinG0, Dest->AStatesRec[ViStatesLine].NbWinG1,Dest->AStatesRec[ViStatesLine].NbWinTot )); + + msg (( MSG_OUT, "Line %4d - %d HitNbG0 (Ovf:%d) - %d HitNbG1 (Ovf:%d)", VStatesLine.F.SLineAddr, VStatesNbG0, VG0Overflow,VStatesNbG1,VG1Overflow )); + + /* Print to show missing handling of odd W30 nb + + if ( VStatesLine.F.LineAddr <= VPrevLine ) { + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ===============> ERROR odd W30 nb NOT HANDLED ! ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + } + + else { + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + VPrevLine = VStatesLine.F.LineAddr; + } + + */ + + } + + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + + // Copy states G1 + if (VStatesNbG1 > 0){ + for ( ViState=0; ViState < VStatesNbG1; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].W32 = Src->ADataW32[ViSrcW30]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "-->G1: State %d : Delta : %d - Col %4d - %X pixels", ViState, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Delta , Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code )); + if ( (PrintLvl == 8)&&(((Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code)& 0xFFFFF) == 0)&&(ViSrcW30 < VDataW30Length) ) { + msg (( MSG_OUT, " G1 : Frame :%d ,Word : %d of %d, SLineAddr :%d : Window word : %X - Code = 0, %d state out of %d ", Dest->FrameCnt, ViSrcW30,VDataW30Length, VStatesLine.F.SLineAddr, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].W32,ViState ,VStatesNbG0 )); + } + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + } + } + // Copy states G0 + + if (VStatesNbG0 > 0){ + for ( ViState=0; ViState < VStatesNbG0; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].W32 = Src->ADataW32[ViSrcW30]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "-->G0: State %d : Delta : %d - Col %4d - %X pixels", ViState, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Delta , Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code )); + if ( (PrintLvl == 8)&&(((Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code)& 0xFFFFF) == 0)&&(ViSrcW30 < VDataW30Length) ) { + msg (( MSG_OUT, " G0 : Frame :%d ,Word : %d out of %d, SLineAddr :%d : Window word : %X - Code = 0, %d state out of %d ", Dest->FrameCnt, ViSrcW30,VDataW30Length, VStatesLine.F.SLineAddr, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].W32,ViState ,VStatesNbG0 )); + } + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + } + } + + ++ViStatesLine; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + + // Add on 25/03/2011 during test with random frame size + with all data = 0 + + if ( ViStatesLine >= FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "Max number of states reached = %d => Abort => Corrupted data !", FSBB0__ZS_FFRAME_MAX_STATES_REC )); + break; + } + + } // End while + + } // End if ( VDataW30Length != 0 ) + + Dest->StatesRecNb = ViStatesLine; + +//#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + if ( (PrintLvl == 5)/* || (PrintLvl == 6)*/|| (PrintLvl == 7) /*|| (PrintLvl == 8)*/ ) { + msg (( MSG_OUT, "Conv : %d StatesLines", Dest->StatesRecNb )); + msg (( MSG_OUT, "" )); + } + + return (VRetW30Length); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 14/08/2009 +Doc date : +: +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameRawToZsFFrameHandleTrigger ( SInt8 MapsNb, SInt32 EvNo, SInt32 TotEvNb, FSBB0__TZsFFrameRaw* Src, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) { + + FSBB0__TZsFFrameRaw* VPtSrcEv; + SInt32 VTrigPosFromDaq; + SInt32 VTrigLine; + SInt8 VFirstEvent; + static FSBB0__TZsFFrame VASrcZsFFrameEv[2]; + SInt32 VLine; + SInt32 ViSrcStateRec; + SInt32 ViDestStateRec; + + // Check parameters + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Four events after this one are required => Abort if it's not the case + + if ( EvNo + 4 >= TotEvNb ) { + err_retfail ( -1, (ERR_OUT,"Processing stop on event %d => Less than 4 events after it !" ,EvNo) ); + } + + + // Trigger position ? +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + VTrigPosFromDaq = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; +//#endif + + + if ( (VTrigPosFromDaq < 0) || (VTrigPosFromDaq > 575) ) { + err_retfail ( -1, (ERR_OUT,"Bad trigger pos from DAQ = %d <> [0..575] !", VTrigPosFromDaq) ); + } + + + // Set VPtEv on the first event to process + // - Pos < 572 => Pos correspond to current event + 1 ( next event ) + // - Pos >= 572 => Pos correspond to current event + 2 + +/* ORIGINAL => 1 plane + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 1; + } + + else { + VPtSrcEv = Src + 2; + } + +*/ + +/* 6 planes + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 7; + } + + else { + VPtSrcEv = Src + 8; + } + +*/ + + // N planes + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 1 + MapsNb; + } + + else { + VPtSrcEv = Src + 2 + MapsNb; + } + + + // Real trigger line = trigger position + 4 modulo 576 + + VTrigLine = (VTrigPosFromDaq + 4) % 576; + + // Debug print + + if ( PrintLvl == 1 ) { + // msg (( MSG_OUT, "=> Trig on Ev=%4d P=%4d L=%4d => Proc Ev=%4d - Ev=%4d", EvNo, VTrigPosFromDaq, VTrigLine, VPtSrcEv[0].SStatus.FrameNoInRun, VPtSrcEv[1].SStatus.FrameNoInRun )); + err_error (( ERR_OUT, "=> Trig on Ev=%4d - P=%4d - L=%4d => Proc Ev=%4d - Ev=%4d", EvNo, VTrigPosFromDaq, VTrigLine, VPtSrcEv[0].SStatus.FrameNoInRun, VPtSrcEv[1].SStatus.FrameNoInRun )); + } + + // Convert each event from ZsFFrameRaw to ZsFFrame + + FSBB0__FConvZsFFrameRawToZsFFrame ( VPtSrcEv , VASrcZsFFrameEv , 0 /* PrintLvl */ ); + FSBB0__FConvZsFFrameRawToZsFFrame ( VPtSrcEv + 1, VASrcZsFFrameEv + 1, 0 /* PrintLvl */ ); + + // ------------------------- + // Build destination event + // ------------------------- + + // Reset record + + memset ( Dest, 0, sizeof (FSBB0__TZsFFrame) ); + + // Copy information fields + + Dest->SStatus = Src->SStatus; + + Dest->Header = Src->Header; + Dest->FrameCnt = Src->DataLengthRemFrCnt.F.FrameCnt; + Dest->DataLength = Src->UsefulDataLengthW30; + Dest->Trailer = Src->Trailer; + //Dest->Zero = Src->Zero; + //Dest->Zero2 = Src->Zero2; +//#ifndef FSBB0__APP_IGNORE_GC_MOD_220514 + Dest->TrigSignalLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_LINE]; + Dest->TrigSignalClk = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Src->SStatus.ATrigRes[ASIC__FSBB0_TRIG_RES__LINE]; +//#endif + + // Extract lines + + ViDestStateRec = 0; + + // First event => Copy lines >= trigger pos to dest + + for ( ViSrcStateRec=0; ViSrcStateRec < VASrcZsFFrameEv->StatesRecNb; ViSrcStateRec++ ) { + + VLine = VASrcZsFFrameEv->AStatesRec[ViSrcStateRec].StatesLine.F.SLineAddr; + + if ( VLine >= VTrigLine ) { + Dest->AStatesRec[ViDestStateRec] = VASrcZsFFrameEv->AStatesRec[ViSrcStateRec]; + ++ViDestStateRec; + } + + } + + if ( VTrigLine == 0 ) { + Dest->StatesRecNb = ViDestStateRec; + return (0); + } + + // Second event => Copy lines < trigger pos to dest + + for ( ViSrcStateRec=0; ViSrcStateRec < VASrcZsFFrameEv[1].StatesRecNb; ViSrcStateRec++ ) { + + VLine = VASrcZsFFrameEv[1].AStatesRec[ViSrcStateRec].StatesLine.F.SLineAddr; + + if ( VLine < VTrigLine ) { + Dest->AStatesRec[ViDestStateRec] = VASrcZsFFrameEv[1].AStatesRec[ViSrcStateRec]; + ++ViDestStateRec; + } + + } + + // Update nb of StateRec + + Dest->StatesRecNb = ViDestStateRec; + + return (0); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 17/03/2009 +Rev : 22/07/2009 + : - Return number of hits found +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FSBB0__FConvZsFFrameToMatDiscriBit ( FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDest, SInt32* PtOvfCnt, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 ViFirstLine; + SInt16 ViTopLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesLine; + SInt16 ViState; + SInt16 VStatesNbG0; + SInt16 VStatesNbG1; + SInt32 VHitCnt; + SInt32 VOfvCnt; + SInt32 VMask; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (FSBB0__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + // StatesRec loop + + VHitCnt = 0; + VOfvCnt = 0; + + if ( PtSrc->StatesRecNb > FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + err_error (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + PtSrc->StatesRecNb = FSBB0__ZS_FFRAME_MAX_STATES_REC; + } + + +//#ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + if (PtSrc->StatesRecNb > 0){ + + for ( ViStatesLine=0; ViStatesLine < PtSrc->StatesRecNb; ViStatesLine++ ) { + + VStatesNbG0 = PtSrc->AStatesRec[ViStatesLine].NbWinG0; + VStatesNbG1 = PtSrc->AStatesRec[ViStatesLine].NbWinG1; + ViTopLine = ((PtSrc->AStatesRec[ViStatesLine].StatesLine.F.SLineAddr + 1) * 4) - 1 ; + + //msg (( MSG_OUT, " ViStatesLine :%d :ViTopLine : %d - VStatesNbG0 : %d - VStatesNbG1 : %d ", ViStatesLine, ViTopLine,VStatesNbG0,VStatesNbG1 )); + + + /*if (( PtSrc->AStatesRec[ViStatesLine].StatesLine.F.HitNbG0 > 9 )||( PtSrc->AStatesRec[ViStatesLine].StatesLine.F.HitNbG1 > 9 )) { + ++VOfvCnt; + // err_error (( ERR_OUT, "Ovf ! Count=%d", VOfvCnt )); + }*/ + // States in one StateRec loop + + // WARNING => Will slow down execution + + if ( VStatesNbG0 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNbG0, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP )); + VStatesNbG0 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + ++VOfvCnt; + } + if ( VStatesNbG1 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNbG1, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP )); + VStatesNbG1 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + ++VOfvCnt; + } + + // WARNING => Will slow down execution + + if ( ViTopLine >= FSBB0__MAT_DISCRI_LINES_NB) { + err_warning (( ERR_OUT, "ViTopLine=%d >= FSBB0__MAT_DISCRI_LINES_NB=%d => Force %d", ViTopLine, FSBB0__MAT_DISCRI_LINES_NB, FSBB0__MAT_DISCRI_LINES_NB - 1 )); + ViTopLine = FSBB0__MAT_DISCRI_LINES_NB - 1; + } + // Decode Hits for Group 1 + if ( VStatesNbG1 > 0 ){ + for ( ViState = 0; ViState < VStatesNbG1; ViState++ ) { + + VFirstCol = (PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.ColAddr) + 224; + // WARNING => Will slow down execution + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + + + // Hits in one State loop + ViFirstLine = ViTopLine - (PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Delta); + VMask = 0x80000; + for (ViLine = ViFirstLine; ViLine > (ViFirstLine - 4); ViLine-- ){ + if (ViLine < 0){ + break; + } + for ( ViCol = VFirstCol; ViCol > VFirstCol - 5; ViCol-- ) { + if (ViCol < 0){ + break; + } + if ( ((PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code) & VMask) != 0){ + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + // 01/08/2014 - MS : removed the printing of the decoding of the data words + /* + if (PrintLvl ==7){ + msg (( MSG_OUT, " G1 : ViStatesLine :%d :ViTopLine : %d : ViState:%d - Hit Line : %d - Col : %d , VMask :0x%X ", ViStatesLine, ViTopLine,ViState, ViLine,ViCol,VMask )); + }*/ + } + else{ + PtDest->AALineCol[ViLine][ViCol] = 0; + + } + VMask = VMask >> 1; + + } // End For ViCol + } // End For ViLine + + } // End States in one StateRec loop for G1 + } /* end decoding groups for G1 */ + + // Decode Hits for Group 0 + if ( VStatesNbG0 > 0 ){ + for ( ViState=0; ViState < VStatesNbG0; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.ColAddr ; + //VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + // WARNING => Will slow down execution + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + + // Hits in one State loop + ViFirstLine = ViTopLine - (PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Delta); + VMask = 0x80000; + for (ViLine = ViFirstLine; ViLine > ViFirstLine - 4; ViLine-- ){ + if (ViLine < 0){ + break; + } + for ( ViCol=VFirstCol; ViCol > VFirstCol - 5; ViCol-- ) { + if (ViCol < 0){ + break; + } + //msg (( MSG_OUT, " ViStatesLine :%d :ViLine : %d - ViCol : %d - PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code : %d ", ViStatesLine, ViLine,ViCol,PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code )); + if ( (PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code & VMask) != 0){ + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + // 01/08/2014 - MS : removed the printing of the decoding of the data words + /* + if (PrintLvl ==7){ + msg (( MSG_OUT, " G0 : ViStatesLine :%d :ViTopLine : %d : ViState:%d - Hit Line : %d - Col : %d , VMask :0x%x ", ViStatesLine, ViTopLine,ViState, ViLine,ViCol,VMask )); + }*/ + } + VMask = VMask >> 1; + + } // End For ViCol + } // End For ViLine + + } // End States in one StateRec loop for G0 + } /* end decoding groups for G0 */ + } // End StatesRec loop + } /* end if (PtSrc->StatesRecNb > 0)*/ + +//#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + if ( PtOvfCnt != NULL ) { + *PtOvfCnt = VOfvCnt; + } + + + // err_error (( ERR_OUT, "TRACE - VHitCnt=%d", VHitCnt )); // 13/02/2013 + + + return (VHitCnt); +} \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_test_ult1.def b/include/pxi_daq_lib_v.2.1/fsbb0_test_ult1.def new file mode 100755 index 0000000..4d7602b --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_test_ult1.def @@ -0,0 +1,214 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_TEST_ULT1_DEF +#define FSBB0_TEST_ULT1_DEF + + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define FSBB0__REG_DISCRI_BIT_SZ 960 +#define FSBB0__REG_DISCRI_W32_SZ 30 + + +#ifdef FSBB0__APP_DLL_TEST_WITH_PATTERN_GENERATOR + + // Size in CLK unit of the frame which contains the readout of ONE line + + #define FSBB0__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 1858 // Single line = nop scanning mode + #define FSBB0__DISCRI_RO_SCAN_FRAME_CLK_NB 1858 // Scanning mode + +#else + + // Size in CLK unit of the frame which contains the readout of ONE line + + #define FSBB0__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 1856 // Single line = nop scanning mode + #define FSBB0__DISCRI_RO_SCAN_FRAME_CLK_NB 1858 // Scanning mode + +#endif + + + + +// This register is not implemented on Ultimate +// +// #define FSBB0__REG_AFTER_ZS_BIT_SZ 160 +// #define FSBB0__REG_AFTER_ZS_W32_SZ 5 + +#define FSBB0__REG_AFTER_MUX_BIT_SZ 160 +#define FSBB0__REG_AFTER_MUX_W32_SZ 5 + +#define FSBB0__MAT_DISCRI_COL_NB 960 // 23/01/2013 +#define FSBB0__MAT_DISCRI_LINES_NB 930 +#define FSBB0__MAT_DISCRI_USEFUL_LINES_NB 928 // 23/01/2013 - Without the two markers lines + +#define FSBB0__ZS_FFRAME_RAW_MAX_W16 3700 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define FSBB0__ZS_FFRAME_RAW_MAX_W32 1850 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 +#define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 1856 // Total frame size ( sum of 2 links ) in W32 - Mi26 = 576 + +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define FSBB0__ZS_FFRAME_MAX_STATES_REC 928 // Mi26 = 576 - one per line + +#define FSBB0__ZS_FFRAME_MODE0_1X80MHZ 0 +#define FSBB0__ZS_FFRAME_MODE1_2X80MHZ 1 +#define FSBB0__ZS_FFRAME_MODE2_1X160MHZ 2 +#define FSBB0__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 29696 // 1856 W16 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 29696 // 1856 W16 + +// $ #define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 928 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 928 // Mi26 = 576 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 1856 // Mi26 = 576 +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 1856 // Mi26 = 576 => Moved in fsbb0_usr.def + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 928 // Mi26 = 144 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 928 // Mi26 = 288 + + +// Id to select FSBB0 register + +#define FSBB0__REG_DISCRI 0 +// #define FSBB0__REG_AFTER_ZS 1 -> Not implemented on Ultimate +#define FSBB0__REG_AFTER_MUX 1 +#define FSBB0__REG_DISCRI_SCAN 2 + +#define FSBB0__REG_DISCRI_SCAN__SRC_CLK_160MHZ 3 // 23/06/2010 + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + +// Submatrices number + +#define FSBB0__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define FSBB0__REG_BIAS_NB 19 + +// $ #define FSBB0__REG_BIAS_ICLPDISC 0 +// $ #define FSBB0__REG_BIAS_IPWRSW 1 +// $ #define FSBB0__REG_BIAS_IBUF 2 +// $ #define FSBB0__REG_BIAS_ID1PWRS 3 +// $ #define FSBB0__REG_BIAS_ID2PWRS 4 +// $ #define FSBB0__REG_BIAS_ILVDSTX 5 +// $ #define FSBB0__REG_BIAS_ILVDSRX 6 +// $ #define FSBB0__REG_BIAS_IVTST1 7 +// $ #define FSBB0__REG_BIAS_IVTST2 8 +// $ #define FSBB0__REG_BIAS_IANABUF 9 +// $ #define FSBB0__REG_BIAS_IVDREF1D 10 +// $ #define FSBB0__REG_BIAS_IVDREF1C 11 +// $ #define FSBB0__REG_BIAS_IVDREF1B 12 +// $ #define FSBB0__REG_BIAS_IVDREF1A 13 +// $ #define FSBB0__REG_BIAS_IVDREF2 14 +// $ #define FSBB0__REG_BIAS_IDIS1 15 +// $ #define FSBB0__REG_BIAS_IDIS2 16 +// $ #define FSBB0__REG_BIAS_IPXI 17 +// $ #define FSBB0__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define FSBB0__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define FSBB0__DIS_MEAS_STEP_PAR_FIRST 0 +#define FSBB0__DIS_MEAS_STEP_PAR_LAST (FSBB0__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define FSBB0__DIS_TEST_MAX_STEP_NB 50 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define FSBB0__NB_MAX_FSBB0_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define FSBB0__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define FSBB0__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define FSBB0__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// FSBB0__TCTelMon +// -------------------- + +#define FSBB0__COLOR_BROWN 0x000066CC +#define FSBB0__COLOR_ORANGE 0x0000A5FF +#define FSBB0__COLOR_YELLOW 0x0000FFFF +#define FSBB0__COLOR_GREEN 0x0000FF00 +#define FSBB0__COLOR_BLUE 0x00FF0000 +#define FSBB0__COLOR_VIOLET 0x00990066 + +#define FSBB0__TCTelMon__COL_PLANE_0 (TColor) FSBB0__COLOR_ORANGE +#define FSBB0__TCTelMon__COL_PLANE_1 (TColor) FSBB0__COLOR_BLUE +#define FSBB0__TCTelMon__COL_PLANE_2 (TColor) FSBB0__COLOR_BROWN +#define FSBB0__TCTelMon__COL_PLANE_3 (TColor) FSBB0__COLOR_YELLOW +#define FSBB0__TCTelMon__COL_PLANE_4 (TColor) FSBB0__COLOR_GREEN +#define FSBB0__TCTelMon__COL_PLANE_5 (TColor) FSBB0__COLOR_VIOLET + + +#define FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr.c b/include/pxi_daq_lib_v.2.1/fsbb0_usr.c new file mode 100755 index 0000000..256a299 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr.c @@ -0,0 +1,114 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.c +Goal : Functions of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_C +#define FSBB0_USR_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FBegin ( SInt8 FileErrLogLvl, char* FileErrFile ) { + + FSBB0__VGContext.FileErrLogLvl = FileErrLogLvl; + strcpy ( FSBB0__VGContext.FileErrFile, FileErrFile ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FSBB0__FEnd () { + + + err_retok (( ERR_OUT, "" )); +} + + + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr.def b/include/pxi_daq_lib_v.2.1/fsbb0_usr.def new file mode 100755 index 0000000..17b868f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr.def @@ -0,0 +1,210 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_DEF +#define FSBB0_USR_DEF + +#ifdef FSBB0__APP_DLL_TEST_ULT1 + #include "fsbb0_usr_test_ult1.def" +#else + + +/* ================= */ +/* Macro example */ +/* ================= */ + + + + +// 27/05/2014 - GC : Rename cst & update values +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 892 //ult = 1856 // Mi26 = 576 +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1784 //ult=3712 // +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 886 // Add on 11/05/2011 - value per link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1772 // Add on 11/05/2011 - value per link + +// ----------------------------------------------------------------------------- +// Frame total size & data part size (per link) FSBB0 in mode 1 link @ 160 MHz +// ----------------------------------------------------------------------------- + +// 27/08/2014 - GC : Update cst values : +// +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 443 => BAD value +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 886 => BAD value +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ 1772 => BAD value +// +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 886 // FSBB0 = 886 W16 / frame / link including ... +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ 1772 // FSBB0 = 1772 W8 / frame / link including ... + +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 440 // FSBB0 = 440 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 880 // FSBB0 = 880 W16 / frame / link including ... +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ 1760 // FSBB0 = 1760 W8 / frame / link including ... + + + +// 27/08/2014 - GC : Update cst values : +// +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W32_SZ 436 => OK +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 878 => BAD value +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1756 => BAD value +// +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 878 // FSBB0 = 878 = Number of W16 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1756 // FSBB0 = 1756 = Number of W8 in data part / frame / link + +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W32_SZ 436 // FSBB0 = 436 = Number of W30 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 872 // FSBB0 = 436 * 2 = Number of W16 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1744 // FSBB0 = 436 * 4 = Number of W8 in data part / frame / link + +// 20/09/2014 - GC : New update of cst value because MAW W30 nb in data part is 433 and not 436 +// => More explanation in mail "... FSBB .. Question No 12" 20/09/2014 +// + + #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W32_SZ 433 // FSBB0 = 433 = Number of W30 in data part / frame / link + #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 866 // FSBB0 = 433 * 2 = Number of W16 in data part / frame / link + #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1732 // FSBB0 = 433 * 4 = Number of W8 in data part / frame / link + + + +// ----------------------------------------------------------------------------- +// Frame total size & data part size (per link) FSBB0 in mode 2 links @ 160 MHz +// ----------------------------------------------------------------------------- +// The value are the same as for 1 link mode ... if there is no erros in doc +// that's why I prefer to keep two sets of constants +// ----------------------------------------------------------------------------- + +// 27/08/2014 - GC : Update cst values : +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 443 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 886 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1772 => BAD value +// +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 => BAD value +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 886 // FSBB0 = 886 W16 / frame / link including ... +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1772 // FSBB0 = 1772 W8 / frame / link including ... + +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 // FSBB0 = 439 = Number of W30 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 // FSBB0 = 878 = Number of W16 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 // FSBB0 = 1756 = Number of W8 in data part / frame / link + + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 440 // FSBB0 = 440 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 880 // FSBB0 = 880 W16 / frame / link including ... +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1760 // FSBB0 = 1760 W8 / frame / link including ... + + + +// 27/08/2014 - GC : Update cst values : +// +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 => OK +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 => BAD value +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 // FSBB0 = 878 = Number of W16 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 // FSBB0 = 1756 = Number of W8 in data part / frame / link + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 // FSBB0 = 436 = Number of W30 in data part / frame / link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 872 // FSBB0 = 436 * 2 = Number of W16 in data part / frame / link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1744 // FSBB0 = 436 * 4 = Number of W8 in data part / frame / link + +// Before 27/08/2014 - GC => Update cst values on 27/08/2014 +// +// FSBB0 will be used with only one link for beam test +// 22/05/2014 - GC : Redefine cst values +// 27/05/2014 - GC : Cst removed in fsbb0_usr.def, they were in the two files before ... with different values ... +// +// #define FSBB0__ZS_FFRAME_RAW_MAX_W8 1756 // FSBB0 = 1756 = Maximum data part number of W8 / frame / link +// #define FSBB0__ZS_FFRAME_RAW_MAX_W16 878 // FSBB0 = 878 = Maximum data part number of W16 / frame / link +// #define FSBB0__ZS_FFRAME_RAW_MAX_W32 439 // FSBB0 = 439 = Maximum data part number of W30 / frame / link +// #define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer + +// 27/08/2014 - GC : New cts values + +#define FSBB0__ZS_FFRAME_RAW_MAX_W8 1744 // FSBB0 = 1744 = Maximum data part number of W8 / frame / link +#define FSBB0__ZS_FFRAME_RAW_MAX_W16 872 // FSBB0 = 872 = Maximum data part number of W16 / frame / link +#define FSBB0__ZS_FFRAME_RAW_MAX_W32 436 // FSBB0 = 436 = Maximum data part number of W30 / frame / link +#define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 440 // FSBB0 = 440 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer + + +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 18 // 28/05/14 - GC : 9 on G + 9 on G1 +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP 9 // 05/06/14 - GC : Max 9 Windows on each group G0, G1 +#define FSBB0__ZS_FFRAME_MAX_STATES_REC 104 // 28/05/14 - GC : One per S-line => 416 lines / 4 = 104 S-lines + + + +// ----------------------------------------------------------------------------- +// Special constant for FSBB0 (Not needed on Mi26, Mi28) +// +// Due to FSBB0 integration time (41,6 us) and ro frequency (DDR @ 160 MHz) +// the total number of bits sent on each link is NOT a multiple of the maximum +// frame length in W30 (FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ), there are 112 bits more. +// This value is defined by the following constant +// ----------------------------------------------------------------------------- + +// 27/08/2014 - GC : Value used before 27/08/14, new value is 112, it's connected to others cst update on 27/08/14 +// +// #define FSBB0__ZS_HW_FRAME_PADDING_BITS_AT_END 22 // Padding bits at end of frame + +#define FSBB0__ZS_HW_FRAME_PADDING_BITS_AT_END 112 // Padding bits at end of frame + + +#define FSBB0__TEST_FILES_NAME_MAX_SZ 256 +#define FSBB0__TEST_MAX_NUMBER 40 + + + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + +// Submatrices number + +#define FSBB0__SUB_MAT_NB 2 + +// -------------------- +// Bias registers index +// -------------------- + +#define FSBB0__REG_BIAS_NB 15 + +#define FSBB0__REG_BIAS_ILVDSTX 0 +#define FSBB0__REG_BIAS_IDISCLP 1 +#define FSBB0__REG_BIAS_IBUFREF 2 +#define FSBB0__REG_BIAS_IVTST1 3 +#define FSBB0__REG_BIAS_IVTST2B 4 +#define FSBB0__REG_BIAS_IVTST2A 5 +#define FSBB0__REG_BIAS_IANABUF 6 +#define FSBB0__REG_BIAS_IVDREF1B 7 +#define FSBB0__REG_BIAS_IVDREF2B 8 +#define FSBB0__REG_BIAS_IVDREF1A 9 +#define FSBB0__REG_BIAS_IVDREF2A 10 +#define FSBB0__REG_BIAS_IDIS1 11 +#define FSBB0__REG_BIAS_IDIS2 12 +#define FSBB0__REG_BIAS_IPIX 13 +#define FSBB0__REG_BIAS_IPIXCLP 14 + + +#endif + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr.h b/include/pxi_daq_lib_v.2.1/fsbb0_usr.h new file mode 100755 index 0000000..a505219 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr.h @@ -0,0 +1,41 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.h +Goal : Functions prototypes of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* FSBB0_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + +FHEAD ( SInt32 FSBB0_FBegin ( SInt8 FileErrLogLvl, char* FileErrFile );) +FHEAD ( SInt32 FSBB0_FEnd ();) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef FSBB0_USR_H + #define FSBB0_USR_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr.typ b/include/pxi_daq_lib_v.2.1/fsbb0_usr.typ new file mode 100755 index 0000000..e4c9dac --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr.typ @@ -0,0 +1,414 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_TYP +#define FSBB0_USR_TYP + +/* ================================= */ +/* Lib context */ +/* Contain all global variables */ +/* --------------------------------- */ +/* Date : 24/11/2008 - GC */ +/* ================================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} FSBB0__TContext; + + +/* ================================= */ +/* Union to extract */ +/* Header 0,1 from header 30 bits */ +/* fro frame field */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 H0 : 15; // B00..B14 + UInt32 H1 : 15; // B15..B29 + UInt32 Nu : 2; // B30..B31 + } F; + +} FSBB0__THeader; + +/* ================================= */ +/* Union to extract */ +/* Trailer 0,1 from trailer 30 bits */ +/* fro frame field */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 T0 : 15; // B00..B14 + UInt32 T1 : 15; // B15..B29 + UInt32 Nu : 2; // B30..B31 + } F; + +} FSBB0__TTrailer; + + +/* ================================= */ +/* Union to extract */ +/* Trigger fields from 30 bits word */ +/* */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 Mode : 3; // B00..B02 + UInt32 NbLine : 8; // B03..B10 + UInt32 Nu : 21; // B11..B31 + } F; + +} FSBB0__TTriger; + + +/* ============================= */ +/* Union to extract */ +/* Data length, rem, frames cnt */ +/* fro frame field */ +/* ----------------------------- */ +/* Date : 22/05/2014 */ +/* ============================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 DataLength : 8; // B00..B07 + UInt32 Rem : 2; // B08..B09 + UInt32 FrameCnt : 20; // B10..B29 + } F; + +} FSBB0__TDataLengthRemFrCnt; + +/* ======================================================= */ +/* Frame provided by FSBB0 DAQ, it's independent of output */ +/* mode BUT data are not organized as in FSBB0__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by FSBB0__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 23/05/2014 - GC : Upd fields + THeader, TTRailer */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + FSBB0__THeader Header; // Header of FSBB0 frame + FSBB0__TTriger Trigger; // Trigger of FSBB0 frame - 22/05/14 GC + + FSBB0__TDataLengthRemFrCnt DataLengthRemFrCnt; // 22/05/14 GC + // Field from FSBB0 frame which contains + // - DataLength B00..B07 + // - Rem B08..B09 + // - FrCnt B10..B29 + + // UInt32 FrameCnt; // 22/05/14 GC => Replaced by DataLengthRemFrCnt + // Frame counter of FSBB0 frame + + +UInt8 TrigLine; + UInt8 TrigMode; + + // 22/05/14 GC => Replaced by CalcDataLength + // + // UInt32 DataLength; // Useful length in W32 unit of data contains in ADataW32 array + // Calculation to be defined + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + UInt8 FsbbFieldDataLength; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + UInt8 FsbbFieldRem; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + UInt32 UsefulDataLengthW30; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + UInt32 TotalDataLengthW30; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + SInt8 BugFieldDataLengthEqual0; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + + UInt32 CalcDataLength; // 22/05/14 GC - Replace fields "DataLength" but it has not the same meaning + // + // - "DataLength" (Mi26, 28) contains the fields data length from Mi26/28 frame + // - "CalcDataLength" = W32 nb in ADataW32 array calculated from DataLengthRemFrCnt + + + FSBB0__TTrailer Trailer; // Trailer of FSBB0 frame + +// 22/05/14 GC +// Set zeo fields in comments +// +// UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw +// UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + +// 22/05/14 GC +// U16 -> U32 because data are serialized on U30 words on FSBB +// +// UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + UInt32 ADataW32[FSBB0__ZS_FFRAME_RAW_MAX_W32]; // MUST BE AT END OF RECORD ! + + +} FSBB0__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 22/05/2014 - GC */ +/* =================================================== */ + +typedef union { + + UInt32 W32; + + struct { + + UInt32 HitNbG0 : 8; + UInt32 HitNbG1 : 8; + UInt32 SLineAddr : 9; + UInt32 NU : 7; + + } F; + +} FSBB0__TStatesLine; + +/* =================================================== */ +/* Hit window of Zero Sup frame, 2 views */ +/* - W32 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 22/05/2014 - GC */ +/* =================================================== */ + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Delta : 2; + UInt32 Code : 20; + UInt32 ColAddr : 8; + UInt32 NU : 2; + + } F; + +} FSBB0__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 05/06/2014 - GC : Update fields list to handle */ +/* easily groups G0, G1 */ +/* ======================================================= */ + +typedef struct { + + // Before 05/06/2014 - GC + // + // FSBB0__TStatesLine StatesLine; + // FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + + // Since 05/06/2014 - GC + + FSBB0__TStatesLine StatesLine; + FSBB0__TState AStatesG0[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP]; + FSBB0__TState AStatesG1[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP]; + + SInt8 NbWinTot; + SInt8 NbWinG0; + SInt8 NbWinG1; + +} FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +// typedef struct { +// +// FSBB0__TStatesLine StatesLine; +// FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; +// +// } FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by FSBB0, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 23/05/2014 - GC : Upd fields + THeader, TTRailer */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + FSBB0__THeader Header; + UInt32 FrameCnt; + FSBB0__TTriger Trigger; // Trigger of FSBB0 frame - 22/05/14 GC + + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a FSBB0 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + FSBB0__TZsFStatesRec AStatesRec[FSBB0__ZS_FFRAME_MAX_STATES_REC]; + + FSBB0__TTrailer Trailer; + + // 22/05/14 GC + // Set zero fields in comments + // + // UInt32 Zero; + // UInt32 Zero2; + +} FSBB0__TZsFFrame; // F in FFrame means Fixed size frame + + + +/* ======================================================= */ +/* Structure containing the pattern to be set via the JTAG */ +/* link to perform the automatic tests of the FSBB0 */ +/* structure */ +/* ------------------------------------------------------- */ +/* Date : 17/06/2014 */ +/* ------------------------------------------------------- */ + +typedef struct { + + SInt16 ConfigIndex; + SInt16 FileNumberMajor; + SInt16 FileNumberMinor; + UInt32 Pattern[8][13]; + SInt16 Zone11; + SInt16 Zone10; + SInt16 Zone01; + SInt16 Zone00; + + +} FSBB0__TTestPattern; // F in FFrame means Fixed size frame + + + + + +typedef struct { + + char ConfigFile[FSBB0__TEST_FILES_NAME_MAX_SZ]; + char ResultFileBit[FSBB0__TEST_FILES_NAME_MAX_SZ]; + char ResultFileW32[FSBB0__TEST_FILES_NAME_MAX_SZ]; + SInt16 FileNumberMajor; + SInt16 FileNumberMinor; + + +} FSBB0__TTestFiles; // F in FFrame means Fixed size frame + + + +/* ======================================================= */ +/* Structure containing the test parameters : */ +/* files name for all the tests to be done */ +/* structure */ +/* ------------------------------------------------------- */ +/* Date : 20/06/2014 */ +/* ------------------------------------------------------- */ + +typedef struct { + + FSBB0__TTestFiles Files[FSBB0__TEST_MAX_NUMBER]; + +} FSBB0__TTestParams; // F in FFrame means Fixed size frame + + + + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr.var b/include/pxi_daq_lib_v.2.1/fsbb0_usr.var new file mode 100755 index 0000000..e2370d4 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr.var @@ -0,0 +1,44 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.var +Goal : Variables definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_VAR +#define FSBB0_USR_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC FSBB0__TContext FSBB0__VGContext; +EXTERN VAR_STATIC FSBB0__TTestPattern FSBB0__VGTestPattern; +EXTERN VAR_STATIC FSBB0__TTestParams FSBB0__VGTestParams; +// 23/09/14 - MS +EXTERN VAR_STATIC FSBB0__TTestPattern FSBB0__TESTBT_VGTestPattern[6]; + + + + + + + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr_020614.typ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_020614.typ new file mode 100755 index 0000000..e914899 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_020614.typ @@ -0,0 +1,316 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_TYP +#define FSBB0_USR_TYP + +/* ================================= */ +/* Lib context */ +/* Contain all global variables */ +/* --------------------------------- */ +/* Date : 24/11/2008 - GC */ +/* ================================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} FSBB0__TContext; + + +/* ================================= */ +/* Union to extract */ +/* Header 0,1 from header 30 bits */ +/* fro frame field */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 H0 : 15; // B00..B14 + UInt32 H1 : 15; // B15..B29 + UInt32 Nu : 2; // B30..B31 + } F; + +} FSBB0__THeader; + +/* ================================= */ +/* Union to extract */ +/* Trailer 0,1 from trailer 30 bits */ +/* fro frame field */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 T0 : 15; // B00..B14 + UInt32 T1 : 15; // B15..B29 + UInt32 Nu : 2; // B30..B31 + } F; + +} FSBB0__TTrailer; + + +/* ================================= */ +/* Union to extract */ +/* Trigger fields from 30 bits word */ +/* */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 Mode : 3; // B00..B02 + UInt32 NbLine : 8; // B03..B10 + UInt32 Nu : 21; // B11..B31 + } F; + +} FSBB0__TTriger; + + +/* ============================= */ +/* Union to extract */ +/* Data length, rem, frames cnt */ +/* fro frame field */ +/* ----------------------------- */ +/* Date : 22/05/2014 */ +/* ============================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 DataLength : 8; // B00..B07 + UInt32 Rem : 2; // B08..B09 + UInt32 FrameCnt : 20; // B10..B29 + } F; + +} FSBB0__TDataLengthRemFrCnt; + +/* ======================================================= */ +/* Frame provided by FSBB0 DAQ, it's independent of output */ +/* mode BUT data are not organized as in FSBB0__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by FSBB0__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 23/05/2014 - GC : Upd fields + THeader, TTRailer */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + FSBB0__THeader Header; // Header of FSBB0 frame + FSBB0__TTriger Trigger; // Trigger of FSBB0 frame - 22/05/14 GC + + FSBB0__TDataLengthRemFrCnt DataLengthRemFrCnt; // 22/05/14 GC + // Field from FSBB0 frame which contains + // - DataLength B00..B07 + // - Rem B08..B09 + // - FrCnt B10..B29 + + // UInt32 FrameCnt; // 22/05/14 GC => Replaced by DataLengthRemFrCnt + // Frame counter of FSBB0 frame + + + UInt8 TrigLine; + UInt8 TrigMode; + + // 22/05/14 GC => Replaced by CalcDataLength + // + // UInt32 DataLength; // Useful length in W32 unit of data contains in ADataW32 array + // Calculation to be defined + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 CalcDataLength; // 22/05/14 GC - Replace fields "DataLength" but it has not the same meaning + // + // - "DataLength" (Mi26, 28) contains the fields data length from Mi26/28 frame + // - "CalcDataLength" = W32 nb in ADataW32 array calculated from DataLengthRemFrCnt + + FSBB0__TTrailer Trailer; // Trailer of FSBB0 frame + +// 22/05/14 GC +// Set zeo fields in comments +// +// UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw +// UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + +// 22/05/14 GC +// U16 -> U32 because data are serialized on U30 words on FSBB +// +// UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + UInt32 ADataW32[FSBB0__ZS_FFRAME_RAW_MAX_W32]; // MUST BE AT END OF RECORD ! + + +} FSBB0__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 22/05/2014 - GC */ +/* =================================================== */ + +typedef union { + + UInt16 W32; + + struct { + + UInt32 HitNbG0 : 8; + UInt32 HitNbG1 : 8; + UInt32 SLineAddr : 9; + UInt32 NU : 7; + + } F; + +} FSBB0__TStatesLine; + +/* =================================================== */ +/* Hit window of Zero Sup frame, 2 views */ +/* - W32 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 22/05/2014 - GC */ +/* =================================================== */ + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Delta : 2; + UInt32 Code : 20; + UInt32 ColAddr : 8; + UInt32 NU : 2; + + } F; + +} FSBB0__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + FSBB0__TStatesLine StatesLine; + FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by FSBB0, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 23/05/2014 - GC : Upd fields + THeader, TTRailer */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + FSBB0__THeader Header; + UInt32 FrameCnt; + FSBB0__TTriger Trigger; // Trigger of FSBB0 frame - 22/05/14 GC + + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a FSBB0 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + FSBB0__TZsFStatesRec AStatesRec[FSBB0__ZS_FFRAME_MAX_STATES_REC]; + + FSBB0__TTrailer Trailer; + + // 22/05/14 GC + // Set zero fields in comments + // + // UInt32 Zero; + // UInt32 Zero2; + +} FSBB0__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr_110614.def b/include/pxi_daq_lib_v.2.1/fsbb0_usr_110614.def new file mode 100755 index 0000000..2a75197 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_110614.def @@ -0,0 +1,144 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_DEF +#define FSBB0_USR_DEF + +#ifdef FSBB0__APP_DLL_TEST_ULT1 + #include "fsbb0_usr_test_ult1.def" +#else + + +/* ================= */ +/* Macro example */ +/* ================= */ + +// ----------------------------------------------------------------------------- +// Special constant for FSBB0 (Not needed on Mi26, Mi28) +// +// Due to FSBB0 integration time (41,6 us) and ro frequency (DDR @ 160 MHz) +// the total number of bits sent on each link is NOT a multiple of the maximum +// frame length in W30, there are 22 bits more. +// This value is defined by the following constant +// ----------------------------------------------------------------------------- + +#define FSBB0__ZS_HW_FRAME_PADDING_BITS_AT_END 22 // Padding bits at end of frame + + + +// 27/05/2014 - GC : Rename cst & update values +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 892 //ult = 1856 // Mi26 = 576 +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1784 //ult=3712 // +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 886 // Add on 11/05/2011 - value per link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1772 // Add on 11/05/2011 - value per link + +// ----------------------------------------------------------------------------- +// Frame total size & data part size (per link) FSBB0 in mode 1 link @ 160 MHz +// ----------------------------------------------------------------------------- + +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 886 // FSBB0 = 886 W16 / frame / link including ... +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ 1772 // FSBB0 = 1772 W8 / frame / link including ... + +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W32_SZ 436 // FSBB0 = 439 = Number of W30 in data part / frame / link +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 878 // FSBB0 = 878 = Number of W16 in data part / frame / link +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1756 // FSBB0 = 1756 = Number of W8 in data part / frame / link + +// ----------------------------------------------------------------------------- +// Frame total size & data part size (per link) FSBB0 in mode 2 links @ 160 MHz +// ----------------------------------------------------------------------------- +// The value are the same as for 1 link mode ... if there is no erros in doc +// that's why I prefer to keep two sets of constants +// ----------------------------------------------------------------------------- + + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 886 // FSBB0 = 886 W16 / frame / link including ... +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1772 // FSBB0 = 1772 W8 / frame / link including ... + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 // FSBB0 = 439 = Number of W30 in data part / frame / link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 // FSBB0 = 878 = Number of W16 in data part / frame / link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 // FSBB0 = 1756 = Number of W8 in data part / frame / link + + + +// FSBB0 will be used with only one link for beam test +// 22/05/2014 - GC : Redefine cst values +// 27/05/2014 - GC : Cst removed in fsbb0_usr.def, they were in the two files before ... with different values ... + +#define FSBB0__ZS_FFRAME_RAW_MAX_W8 1756 // FSBB0 = 1756 = Maximum data part number of W8 / frame / link +#define FSBB0__ZS_FFRAME_RAW_MAX_W16 878 // FSBB0 = 878 = Maximum data part number of W16 / frame / link +#define FSBB0__ZS_FFRAME_RAW_MAX_W32 439 // FSBB0 = 439 = Maximum data part number of W30 / frame / link +#define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer + + +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 18 // 28/05/14 - GC : 9 on G + 9 on G1 +#define FSBB0__ZS_FFRAME_MAX_STATES_REC 104 // 28/05/14 - GC : One per S-line => 416 lines / 4 = 104 S-lines + + + +// ----------------------------------------------------------------------------- +// Special constant for FSBB0 (Not needed on Mi26, Mi28) +// +// Due to FSBB0 integration time (41,6 us) and ro frequency (DDR @ 160 MHz) +// the total number of bits sent on each link is NOT a multiple of the maximum +// frame length in W30, there are 22 bits more. +// This value is defined by the following constant +// ----------------------------------------------------------------------------- + +#define FSBB0__ZS_HW_FRAME_PADDING_BITS_AT_END 22 // Padding bits at end of frame + + + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + +// Submatrices number + +#define FSBB0__SUB_MAT_NB 1 + +// -------------------- +// Bias registers index +// -------------------- + +#define FSBB0__REG_BIAS_NB 15 + +#define FSBB0__REG_BIAS_ILVDSTX 0 +#define FSBB0__REG_BIAS_IDISCLP 1 +#define FSBB0__REG_BIAS_IBUFREF 2 +#define FSBB0__REG_BIAS_IVTST1 3 +#define FSBB0__REG_BIAS_IVTST2B 4 +#define FSBB0__REG_BIAS_IVTST2A 5 +#define FSBB0__REG_BIAS_IANABUF 6 +#define FSBB0__REG_BIAS_IVDREF1B 7 +#define FSBB0__REG_BIAS_IVDREF2B 8 +#define FSBB0__REG_BIAS_IVDREF1A 9 +#define FSBB0__REG_BIAS_IVDREF2A 10 +#define FSBB0__REG_BIAS_IDIS1 11 +#define FSBB0__REG_BIAS_IDIS2 12 +#define FSBB0__REG_BIAS_IPIX 13 +#define FSBB0__REG_BIAS_IPIXCLP 14 + + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr_110614.typ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_110614.typ new file mode 100755 index 0000000..24e1287 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_110614.typ @@ -0,0 +1,316 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_TYP +#define FSBB0_USR_TYP + +/* ================================= */ +/* Lib context */ +/* Contain all global variables */ +/* --------------------------------- */ +/* Date : 24/11/2008 - GC */ +/* ================================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} FSBB0__TContext; + + +/* ================================= */ +/* Union to extract */ +/* Header 0,1 from header 30 bits */ +/* fro frame field */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 H0 : 15; // B00..B14 + UInt32 H1 : 15; // B15..B29 + UInt32 Nu : 2; // B30..B31 + } F; + +} FSBB0__THeader; + +/* ================================= */ +/* Union to extract */ +/* Trailer 0,1 from trailer 30 bits */ +/* fro frame field */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 T0 : 15; // B00..B14 + UInt32 T1 : 15; // B15..B29 + UInt32 Nu : 2; // B30..B31 + } F; + +} FSBB0__TTrailer; + + +/* ================================= */ +/* Union to extract */ +/* Trigger fields from 30 bits word */ +/* */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 Mode : 3; // B00..B02 + UInt32 NbLine : 8; // B03..B10 + UInt32 Nu : 21; // B11..B31 + } F; + +} FSBB0__TTriger; + + +/* ============================= */ +/* Union to extract */ +/* Data length, rem, frames cnt */ +/* fro frame field */ +/* ----------------------------- */ +/* Date : 22/05/2014 */ +/* ============================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 DataLength : 8; // B00..B07 + UInt32 Rem : 2; // B08..B09 + UInt32 FrameCnt : 20; // B10..B29 + } F; + +} FSBB0__TDataLengthRemFrCnt; + +/* ======================================================= */ +/* Frame provided by FSBB0 DAQ, it's independent of output */ +/* mode BUT data are not organized as in FSBB0__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by FSBB0__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 23/05/2014 - GC : Upd fields + THeader, TTRailer */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + FSBB0__THeader Header; // Header of FSBB0 frame + FSBB0__TTriger Trigger; // Trigger of FSBB0 frame - 22/05/14 GC + + FSBB0__TDataLengthRemFrCnt DataLengthRemFrCnt; // 22/05/14 GC + // Field from FSBB0 frame which contains + // - DataLength B00..B07 + // - Rem B08..B09 + // - FrCnt B10..B29 + + // UInt32 FrameCnt; // 22/05/14 GC => Replaced by DataLengthRemFrCnt + // Frame counter of FSBB0 frame + + + UInt8 TrigLine; + UInt8 TrigMode; + + // 22/05/14 GC => Replaced by CalcDataLength + // + // UInt32 DataLength; // Useful length in W32 unit of data contains in ADataW32 array + // Calculation to be defined + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 CalcDataLength; // 22/05/14 GC - Replace fields "DataLength" but it has not the same meaning + // + // - "DataLength" (Mi26, 28) contains the fields data length from Mi26/28 frame + // - "CalcDataLength" = W32 nb in ADataW32 array calculated from DataLengthRemFrCnt + + FSBB0__TTrailer Trailer; // Trailer of FSBB0 frame + +// 22/05/14 GC +// Set zeo fields in comments +// +// UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw +// UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + +// 22/05/14 GC +// U16 -> U32 because data are serialized on U30 words on FSBB +// +// UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + UInt32 ADataW32[FSBB0__ZS_FFRAME_RAW_MAX_W32]; // MUST BE AT END OF RECORD ! + + +} FSBB0__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 22/05/2014 - GC */ +/* =================================================== */ + +typedef union { + + UInt32 W32; + + struct { + + UInt32 HitNbG0 : 8; + UInt32 HitNbG1 : 8; + UInt32 SLineAddr : 9; + UInt32 NU : 7; + + } F; + +} FSBB0__TStatesLine; + +/* =================================================== */ +/* Hit window of Zero Sup frame, 2 views */ +/* - W32 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 22/05/2014 - GC */ +/* =================================================== */ + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Delta : 2; + UInt32 Code : 20; + UInt32 ColAddr : 8; + UInt32 NU : 2; + + } F; + +} FSBB0__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + FSBB0__TStatesLine StatesLine; + FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by FSBB0, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 23/05/2014 - GC : Upd fields + THeader, TTRailer */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + FSBB0__THeader Header; + UInt32 FrameCnt; + FSBB0__TTriger Trigger; // Trigger of FSBB0 frame - 22/05/14 GC + + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a FSBB0 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + FSBB0__TZsFStatesRec AStatesRec[FSBB0__ZS_FFRAME_MAX_STATES_REC]; + + FSBB0__TTrailer Trailer; + + // 22/05/14 GC + // Set zero fields in comments + // + // UInt32 Zero; + // UInt32 Zero2; + +} FSBB0__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr_220514.def b/include/pxi_daq_lib_v.2.1/fsbb0_usr_220514.def new file mode 100755 index 0000000..9ba23f3 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_220514.def @@ -0,0 +1,82 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_DEF +#define FSBB0_USR_DEF + +#ifdef FSBB0__APP_DLL_TEST_ULT1 + #include "fsbb0_usr_test_ult1.def" +#else + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 892 //ult = 1856 // Mi26 = 576 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1784 //ult=3712 // + + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 886 // Add on 11/05/2011 - value per link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1772 // Add on 11/05/2011 - value per link + +#define FSBB0__ZS_FFRAME_RAW_MAX_W8 3544 // ult1 =7400 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 +#define FSBB0__ZS_FFRAME_RAW_MAX_W16 1772 // ULT1 =3700 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define FSBB0__ZS_FFRAME_RAW_MAX_W32 886 // ULT1 =1850 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 + +#define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 892 // ult1 =1856 // Mi26 = 576 + + +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define FSBB0__ZS_FFRAME_MAX_STATES_REC 416 // ult =828 // Mi26 = 576 - one per line + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + +// Submatrices number + +#define FSBB0__SUB_MAT_NB 2 + +// -------------------- +// Bias registers index +// -------------------- + +#define FSBB0__REG_BIAS_NB 15 + +#define FSBB0__REG_BIAS_ILVDSTX 0 +#define FSBB0__REG_BIAS_IDISCLP 1 +#define FSBB0__REG_BIAS_IBUFREF 2 +#define FSBB0__REG_BIAS_IVTST1 3 +#define FSBB0__REG_BIAS_IVTST2B 4 +#define FSBB0__REG_BIAS_IVTST2A 5 +#define FSBB0__REG_BIAS_IANABUF 6 +#define FSBB0__REG_BIAS_IVDREF1B 7 +#define FSBB0__REG_BIAS_IVDREF2B 8 +#define FSBB0__REG_BIAS_IVDREF1A 9 +#define FSBB0__REG_BIAS_IVDREF2A 10 +#define FSBB0__REG_BIAS_IDIS1 11 +#define FSBB0__REG_BIAS_IDIS2 12 +#define FSBB0__REG_BIAS_IPIX 13 +#define FSBB0__REG_BIAS_IPIXCLP 14 + + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr_220514.typ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_220514.typ new file mode 100755 index 0000000..74a98a6 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_220514.typ @@ -0,0 +1,194 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_TYP +#define FSBB0_USR_TYP + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} FSBB0__TContext; + + +/* ======================================================= */ +/* Frame provided by FSBB0 DAQ, it's independent of output */ +/* mode BUT data are not organized as in FSBB0__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by FSBB0__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + UInt32 Header; // Header of Mimosa 26 frame + UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + UInt8 TrigLine; + UInt8 TrigMode; + UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 Trailer; // Trailer of Mimosa 26 frame + + UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} FSBB0__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} FSBB0__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} FSBB0__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + FSBB0__TStatesLine StatesLine; + FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by FSBB0, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a FSBB0 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + FSBB0__TZsFStatesRec AStatesRec[FSBB0__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} FSBB0__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/fsbb0_usr_test_ult1.def b/include/pxi_daq_lib_v.2.1/fsbb0_usr_test_ult1.def new file mode 100755 index 0000000..9d4c44b --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/fsbb0_usr_test_ult1.def @@ -0,0 +1,80 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_TEST_ULT1_DEF +#define FSBB0_USR_TEST_ULT1_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 1856 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 3712 // + + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 1850 // Add on 11/05/2011 - value per link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 3700 // Add on 11/05/2011 - value per link + +#define FSBB0__ZS_FFRAME_RAW_MAX_W8 7400 // Data part size ( sum of 2 links ) in W8 +#define FSBB0__ZS_FFRAME_RAW_MAX_W16 3700 // Data part size ( sum of 2 links ) in W16 +#define FSBB0__ZS_FFRAME_RAW_MAX_W32 1850 // Data part size ( sum of 2 links ) in W32 + +#define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 1856 // Mi26 = 576 + + +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 +#define FSBB0__ZS_FFRAME_MAX_STATES_REC 828 + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + +// Submatrices number + +#define FSBB0__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define FSBB0__REG_BIAS_NB 19 + +#define FSBB0__REG_BIAS_ICLPDISC 0 +#define FSBB0__REG_BIAS_IPWRSW 1 +#define FSBB0__REG_BIAS_IBUF 2 +#define FSBB0__REG_BIAS_ID1PWRS 3 +#define FSBB0__REG_BIAS_ID2PWRS 4 +#define FSBB0__REG_BIAS_ILVDSTX 5 +#define FSBB0__REG_BIAS_ILVDSRX 6 +#define FSBB0__REG_BIAS_IVTST1 7 +#define FSBB0__REG_BIAS_IVTST2 8 +#define FSBB0__REG_BIAS_IANABUF 9 +#define FSBB0__REG_BIAS_IVDREF1D 10 +#define FSBB0__REG_BIAS_IVDREF1C 11 +#define FSBB0__REG_BIAS_IVDREF1B 12 +#define FSBB0__REG_BIAS_IVDREF1A 13 +#define FSBB0__REG_BIAS_IVDREF2 14 +#define FSBB0__REG_BIAS_IDIS1 15 +#define FSBB0__REG_BIAS_IDIS2 16 +#define FSBB0__REG_BIAS_IPXI 17 +#define FSBB0__REG_BIAS_VPIXCLP 18 + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/globals.def b/include/pxi_daq_lib_v.2.1/globals.def new file mode 100755 index 0000000..0e2bdc4 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/globals.def @@ -0,0 +1,39 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_DEF +#define GLOBALS_DEF + +#ifndef CC_UNIX + #include "globals_root.def" +#endif + +#ifndef ROOT_ROOT + #define GLB_READ_CR { while ( getchar () != '\n' ); }; +#endif + + +#ifndef ROOT_ROOT + #define GLB_KEYB_CR { while ( getchar () != '\n' ); } +#endif + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/globals_root.def b/include/pxi_daq_lib_v.2.1/globals_root.def new file mode 100755 index 0000000..26466d2 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/globals_root.def @@ -0,0 +1,44 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_ROOT_DEF +#define GLOBALS_ROOT_DEF + +/* CONDITIONNAL COMPILATION */ + +#define GLB_GC_CASCADE +#define GLB_FIRST_REC_FORMAT + +/* MACROS */ + +#define GLB_FILE_PATH_SZ 256 +#define GLB_CMT_SZ 256 +#define GLB_HOST_NAME_SZ 50 + +#define GLB_SEQ 0 + +#define GLB_RMP_FILE_PATH "/common/rmp/RMP" +#define GLB_RMPS_FILE_PATH "/common/rmp/RUN" + + +#define GLB_DEF_BYTE_SEX 0x3615ABCD + + +// #define GLB_DESY_VME_A32_BASE 0xd0000000 /* By default it's LEPSI config base address 0xd0000000*/ + + + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/inter_app_com.c b/include/pxi_daq_lib_v.2.1/inter_app_com.c new file mode 100755 index 0000000..adb1396 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/inter_app_com.c @@ -0,0 +1,3991 @@ + +/******************************************************************************* +File : x:\lib\com\inter_app_com\inter_app_com.c +Goal : Functions of inter applications communication library. +Prj date : 05/12/2007 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef INTER_APP_COM_C +#define INTER_APP_COM_C + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 05/12/2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/12/2007 + : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FBegin ( SInt8 ErrLogLvl, char* ErrLogFilePath ) { + + IAC__TContext* PtCont = &IAC__VGContext; + + ERR_FBegin ( (ErrLogLvl != ERR_LOG_LVL_NONE ) /* Enable */, ErrLogFilePath ); + ERR_FSetFileLogLevel ( ErrLogLvl ); + ERR_FSetUserLogLevel ( ErrLogLvl ); + + memset ( &IAC__VGContext, 0, sizeof (IAC__VGContext) ); + + IAC__PRIV_FSockInit (); + + PtCont->Rmp.CmdComPcObjId = 0; + PtCont->Rmp.CmdComUcObjId = 1; + PtCont->Rmp.CmdGetCmdResLoopPeriod = 50; + PtCont->Rmp.CmdGetCmdResTryNb = 60; + + PtCont->Rmp.DataComPcObjId = 2; + PtCont->Rmp.DataComUcObjId = 3; + + CPC_FBegin ( PtCont->Rmp.CmdComPcObjId /* ObjId */, 0 /* ComMedia */, 0 /* ComId */, CPC_OBJ_CMD_BLK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, CPC_OBJ_CMD_RES_BLK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + CUC_FBegin ( PtCont->Rmp.CmdComUcObjId /* ObjId */, 0 /* ComMedia */, 0 /* ComId */, CPC_OBJ_CMD_RES_BLK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, CPC_OBJ_CMD_BLK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + + CPC_FBegin ( PtCont->Rmp.DataComPcObjId /* ObjId */, 0 /* ComMedia */, 1 /* ComId */, IAC__RMP_DATA_BLOCK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, IAC__RMP_DATA_BLOCK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + CUC_FBegin ( PtCont->Rmp.DataComUcObjId /* ObjId */, 0 /* ComMedia */, 1 /* ComId */, IAC__RMP_DATA_BLOCK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, IAC__RMP_DATA_BLOCK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + + err_retok (( ERR_OUT, "Lib compiled on %s at %s", __DATE__, __TIME__ )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/12/2007 + : 09/01/2008 + Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FEnd () { + + IAC__TContext* PtCont = &IAC__VGContext; + + CPC_FEnd ( PtCont->Rmp.CmdComPcObjId /* ObjId */ ); + CUC_FEnd ( PtCont->Rmp.CmdComUcObjId /* ObjId */ ); + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncRunStatusAnswer ( IAC__RMP_TFuncRunStatusAnswer PtFunc ) { + + IAC__VGContext.Rmp.FuncRunStatusAnswer = PtFunc; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncRunStatusAnswer2 ( IAC__RMP_TFuncRunStatusAnswer2 PtFunc ) { + + IAC__VGContext.Rmp.FuncRunStatusAnswer2 = PtFunc; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncAskEventAnswer ( IAC__RMP_TFuncAskEventAnswer PtFunc ) { + + IAC__VGContext.Rmp.FuncAskEventAnswer = PtFunc; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskRunStatus ( IAC__RMP_TRunStatusAnswer* PtStatus ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TRunStatusAnswer* VPtRes; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_RUN_STATUS, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TRunStatusAnswer ) /* CmdRetSz */, + "Run Status" /* CmdStr */, + NULL /* PtParam */, + 0 /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes /* & ((UInt8*) VPtRes) 14/01/08 */ ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtStatus != NULL ) { + *PtStatus = *VPtRes; + } + + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 11/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskRunStatus2 ( IAC__RMP_TRunStatusAnswer2* PtStatus ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TRunStatusAnswer2* VPtRes; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TRunStatusAnswer2 ) /* CmdRetSz */, + "Run Status 2" /* CmdStr */, + NULL /* PtParam */, + 0 /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtStatus != NULL ) { + *PtStatus = *VPtRes; + } + + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskEvent ( IAC__RMP_TAskEventAnswer* PtAns ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TAskEventAnswer* VPtRes; + static IAC__RMP_TAskEventPar VCmdPar; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + ++VCmdPar.EvNb; + VCmdPar.TestTag = 666; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_EVENT, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TAskEventAnswer ) /* CmdRetSz */, + "Ask event" /* CmdStr */, + (UInt8*) &VCmdPar /* PtParam */, + sizeof ( VCmdPar ) /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtAns != NULL ) { + *PtAns = *VPtRes; + } + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FDaqCmdInterpreter () { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VRetInterpreter; + char VStrStatus[GLB_CMT_SZ]; + COM_TCommand* VPtCmd; + + UInt8* VPtData; + IAC__RMP_TRunStatusAnswer VRunStatusAnswer; + IAC__RMP_TRunStatusAnswer2 VRunStatusAnswer2; + IAC__RMP_TAskEventAnswer VAskEventAnswer; + + + VRetInterpreter = CUC_FCmdInterpreter ( PtCont->Rmp.CmdComUcObjId, VStrStatus, &VPtCmd, &VPtData ); + + + switch ( VRetInterpreter ) { + + case -1 : { + err_retfail ( VRetInterpreter, (ERR_OUT,"Interpreter Error !") ); + break; } + + // Command + + case 1 : { + + err_trace (( ERR_OUT, "Cmd = %s", VPtCmd->StrCmd )); + + if ( VPtCmd->Type != IAC__CMD_TYPE__RMP ) { + err_trace (( ERR_OUT, "Not a RMP cmd !" )); + break; + } + + switch ( VPtCmd->SubType ) { + + + case IAC__CMD_STYPE__RMP__ASK_RUN_STATUS : { + + if ( IAC__VGContext.Rmp.FuncRunStatusAnswer != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_RUN_STATUS received - Response done" )); + + IAC__VGContext.Rmp.FuncRunStatusAnswer ( VPtCmd, &VRunStatusAnswer ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VRunStatusAnswer /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + case IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2 : { + + if ( IAC__VGContext.Rmp.FuncRunStatusAnswer2 != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2 received - Response done" )); + + IAC__VGContext.Rmp.FuncRunStatusAnswer2 ( VPtCmd, &VRunStatusAnswer2 ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VRunStatusAnswer2 /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + case IAC__CMD_STYPE__RMP__ASK_EVENT : { + + if ( IAC__VGContext.Rmp.FuncAskEventAnswer != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_EVENT received - Resonse done" )); + + IAC__VGContext.Rmp.FuncAskEventAnswer ( VPtCmd, &VAskEventAnswer ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VAskEventAnswer /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + default : { + err_error (( ERR_OUT, "Cmd SubType=%d unknown", VPtCmd->SubType )); + break; + } + + } + + + + + break; } + + // Data + + case 2 : { + err_trace (( ERR_OUT, "Data transaction" )); + + break; } + + } + + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSendEvent ( UInt8* PtEv, SInt32 Sz ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + + err_retnull ( PtEv, (ERR_OUT,"PtEv == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + VRet = CUC_FPutDatas ( IAC__VGContext.Rmp.DataComUcObjId /* ObjId */, 0 /* MultiExec */, PtEv, -1 /* BlkSz */, Sz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas (...) failed => Ret=%d", VRet ) ); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FReceiveEvent ( UInt8* PtEv, SInt32 MaxEvSz, SInt32* PtEvSz ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + UInt32 VEvSz; + + err_retnull ( PtEv , (ERR_OUT,"PtEv == NULL") ); + err_retnull ( PtEvSz, (ERR_OUT,"PtEvSz == NULL") ); + + if ( MaxEvSz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad MaxSz =%d <= 0", MaxEvSz) ); + } + + + VRet = CPC_FGetDatas ( IAC__VGContext.Rmp.DataComPcObjId /* ObjId */, 0 /* MultiExec */, PtEv, MaxEvSz, &VEvSz /* PtGetDataSz */ ); + + + switch ( VRet ) { + + case 0 : { + err_retfail ( -1, (ERR_OUT,"This case SHOULD NOT happne => CPC_FGetDatas called with MultiExec = 0 which returns 0 ! = only one block read !") ); + break; } + + case 1 : { + + *PtEvSz = VEvSz; + return (0); // Normal case + break; } + + case -1 : { + err_trace (( ERR_OUT, "Nothing to read" )); + return (-1); + break; } + + case -2 : { + err_retfail ( -1, (ERR_OUT,"Error reading data with CPC_FGetDatas (...) which return %d", VRet) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown error => CPC_FGetDatas (...) return %d", VRet) ); + break; + } + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FTestFillEvent ( UInt8* PtEv, SInt32 Sz ) { + + SInt32 Vi; + + err_retnull ( PtEv, (ERR_OUT,"PtEv == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + for ( Vi=0; Vi < Sz; Vi++ ) { + PtEv[Vi] = Vi; + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FTestCompareEvents ( UInt8* PtEvToCmp, UInt8* PtEvRef, SInt32 Sz ) { + + SInt32 VErrCnt; + SInt32 Vi; + + err_retnull ( PtEvRef , (ERR_OUT,"PtEvRef == NULL") ); + err_retnull ( PtEvToCmp, (ERR_OUT,"PtEvToCmp == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + VErrCnt = 0; + + for ( Vi=0; Vi < Sz; Vi++ ) { + + if ( PtEvToCmp[Vi] != PtEvRef[Vi]) { + err_error (( ERR_OUT, "Cmp error Mem[%6d] : Received=%d - Reference=%d", Vi, PtEvToCmp[Vi], PtEvRef[Vi] )); + ++VErrCnt; + } + + } + + + if ( VErrCnt >= 0 ) { + err_retval ( VErrCnt, ( ERR_OUT, "Event compare => %d errors !", VErrCnt ) ); + } + + else { + err_retok (( ERR_OUT, "" )); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +SInt32 IAC__RMP_FTestPrintMemStatusRec ( LPMEMORYSTATUS PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + err_error (( ERR_OUT, "------------ Mem Status ------------" )); + err_error (( ERR_OUT, "Percent of memory in use = %d", PtRec->dwMemoryLoad )); + err_error (( ERR_OUT, "Bytes of physical memory = %d", PtRec->dwTotalPhys )); + err_error (( ERR_OUT, "Free physical memory bytes = %d", PtRec->dwAvailPhys )); + err_error (( ERR_OUT, "Bytes of paging file = %d", PtRec->dwTotalPageFile )); + err_error (( ERR_OUT, "Free bytes of paging file = %d", PtRec->dwAvailPageFile )); + err_error (( ERR_OUT, "User bytes of address space = %d", PtRec->dwTotalVirtual )); + err_error (( ERR_OUT, "Free user bytes = %d", PtRec->dwAvailVirtual )); + err_error (( ERR_OUT, "------------------------------------" )); + + return (0); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +SInt32 IAC__RMP_FTestGetMemStatus ( SInt8 Print, LPMEMORYSTATUS PtRec, SInt32* PtStackAvailSz ) { + + MEMORYSTATUS VMemStatus; + SInt32 VStackAvailSz; + + + VMemStatus.dwLength = sizeof ( MEMORYSTATUS ); + + GlobalMemoryStatus ( &VMemStatus ); + + VStackAvailSz = stackavail (); + + if ( Print == 1 ) { + IAC__RMP_FTestPrintMemStatusRec ( &VMemStatus ); + err_error (( ERR_OUT, "----------------------------------" )); + err_error (( ERR_OUT, "Stack available = %d bytes", VStackAvailSz )); + err_error (( ERR_OUT, "----------------------------------" )); + } + + + if ( PtRec != NULL ) { + *PtRec = VMemStatus; + } + + if ( PtStackAvailSz != NULL ) { + *PtStackAvailSz = VStackAvailSz; + } + +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 04/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FPrepareMsg ( SInt8 Priority, SInt8 Type, SInt16 SubType, IAC__TWho* From, IAC__TWho* To ) { + + + + return (0); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +struct sockaddr IAC__PRIV_FTcpFormatAdress ( char * Host, u_short Port ) +{ + struct sockaddr_in addr; + struct sockaddr addrRet; + struct hostent FAR *lphost ; + u_long IP; + + + memset((char*)&addr, 0, sizeof(addr)); + + /* Soit on fournit une adresse IP, soit on fournit un nom */ + + if ((IP = inet_addr(Host)) == (u_long)INADDR_NONE) + { + if ((lphost = gethostbyname(Host))==NULL) + { + memset( (char * )&addrRet, 0, sizeof(addrRet) ); + return addrRet; + } + + addr.sin_family = lphost->h_addrtype; + + #ifdef _WIN16 /* A d�finir dans le projet WIN16 */ + _fmemcpy (&addr.sin_addr, lphost->h_addr, lphost->h_length); + #else /* WIN32, UNIX*/ + memcpy (&addr.sin_addr, lphost->h_addr, lphost->h_length); + #endif + + } + + else + { + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = IP; + } + + /* Port destination */ + + addr.sin_port = htons((u_short)Port ); + + memcpy( (char *)&addrRet, (char *)&addr, sizeof(addrRet) ); + + return addrRet; +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 31/01/2013 + : - Add parameter "Caller" for debug pb Mi28 NI6562 DAQ +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockSendShortMsg ( SInt32 ContextId, UInt8* PtMsg, UInt32 MsgSz, char* Caller ) { + + IAC__TSockSenderPort* VPtSocket; + SInt16 ViTry; + SInt16 ViMsgWord; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Caller=%s - Bad Id=%d", Caller, ContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + + /* ------------ */ + /* Check status */ + /* ------------ */ + + if ( VPtSocket->Started != 1 ) { + err_retfail ( -1, (ERR_OUT,"Caller=%s - Access [%d] not started => Can't send message", Caller, VPtSocket->Id ) ); + } + + /* --------------- */ + /* Check port mode */ + /* --------------- */ + + if ( VPtSocket->ParLongMsg == 1 ) { + err_retfail ( -1, (ERR_OUT,"Caller=%s - This port doesn't support short message ! ParLongMsg=%d", Caller, VPtSocket->ParLongMsg ) ); + } + + + /* ---------------------------- */ + /* Check message pointer & size */ + /* ---------------------------- */ + + err_retnull ( PtMsg, (ERR_OUT,"PtMsg == NULL !") ); + + /* Only for first version of text header => "SZ=" + + if ( ( MsgSz + IAC__SOCK_HEADER_TOT_SZ ) > IAC__SO_MAX_SHORT_MSG_SIZE ) { + err_retfail ( -1, (ERR_OUT,"Caller=%s - Message too long size=%d + IAC__SOCK_HEADER_TOT_SZ=%d > IAC__SO_MAX_SHORT_MSG_SIZE=%d", Caller, MsgSz, IAC__SOCK_HEADER_TOT_SZ, IAC__SO_MAX_SHORT_MSG_SIZE )); + } + + */ + + if ( ( MsgSz + (VPtSocket->CstHeaderSz) + (VPtSocket->CstTrailerSz) ) > IAC__SO_MAX_SHORT_MSG_SIZE ) { + err_retfail ( -1, (ERR_OUT,"Caller=%s - Message too long size + (Header & Trailer) =%d > IAC__SO_MAX_SHORT_MSG_SIZE=%d", Caller, MsgSz + (VPtSocket->CstHeaderSz) + (VPtSocket->CstTrailerSz), IAC__SO_MAX_SHORT_MSG_SIZE )); + } + + + VPtSocket->ParPtMsg = PtMsg; + VPtSocket->ParMsgSz = MsgSz; + + /* ------------------------------------ */ + /* Try to send message ParRetryNb times */ + /* ------------------------------------ */ + + for ( ViTry=0; ViTry < VPtSocket->ParRetryNb; ViTry++ ) { + + /* --------------- */ + /* Reset Status */ + /* --------------- */ + + VPtSocket->SendStatus = -1; + + /* -------------------- */ + /* Send event to thread */ + /* -------------------- */ + + if ( PulseEvent ( VPtSocket->EvNewMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Caller=%s - Event EvNewMsgHnd sent", Caller )); + } + + /* ------------------ */ + /* Wait thread answer */ + /* ------------------ */ + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"Caller=%s - Ack event not installed !", Caller ) ); + + // Time out => Retry + + if ( WaitForSingleObject ( VPtSocket->EvAckMsgHnd, VPtSocket->ParAckTimeOutMs ) == WAIT_TIMEOUT ) { + err_error (( ERR_OUT, "Caller=%s - No Ack [TO=%d ms]=> Exit on time out !! ViTry=%d - Msg : %s", Caller, VPtSocket->ParAckTimeOutMs, ViTry, PtMsg )); + continue; + } + + // Error => Retry + + if ( VPtSocket->SendStatus <= 0 ) { + err_error (( ERR_OUT, "Caller=%s - Send error - ViTry=%d - Msg : %s", Caller, ViTry, PtMsg )); + continue; + } + + // OK message sent, Ack received => break loop + + err_trace (( ERR_OUT, "Caller=%s - Ack received", Caller )); + break; + + + } /* End for */ + + // MS 10 01 2014 add printing of the msg + /*for (ViMsgWord = 0 ; ViMsgWord < MsgSz ; ViMsgWord++){ + err_warning (( ERR_OUT, "Word[%d] = %d ",ViMsgWord, PtMsg[ViMsgWord] )); + + }*/ + + return (VPtSocket->SendStatus); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 31/01/2013 + : - Add parameter "Caller" for debug pb Mi28 NI6562 DAQ +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockSendLongMsg ( SInt32 ContextId, UInt8* PtMsg, UInt32 MsgSz, char* Caller ) { + + IAC__TSockSenderPort* VPtSocket; + SInt16 ViTry; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Caller=%s - Bad Id=%d", Caller, ContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + + /* ------------ */ + /* Check status */ + /* ------------ */ + + if ( VPtSocket->Started != 1 ) { + err_retfail ( -1, (ERR_OUT,"Caller=%s - Access [%d] not started => Can't send message", Caller, VPtSocket->Id ) ); + } + + /* --------------- */ + /* Check port mode */ + /* --------------- */ + + if ( VPtSocket->ParLongMsg == 0 ) { + err_retfail ( -1, (ERR_OUT,"Caller=%s - This port doesn't support long message ! ParLongMsg=%d", Caller, VPtSocket->ParLongMsg ) ); + } + + /* ---------------------------- */ + /* Check message pointer & size */ + /* ---------------------------- */ + + err_retnull ( PtMsg, (ERR_OUT,"PtMsg == NULL !") ); + + if ( VPtSocket->ParMsgSz > IAC__SOCK_MAX_LONG_MSG_SZ ) { + err_retfail ( -1, (ERR_OUT,"Caller=%s - Message too long size=%d > IAC__SOCK_MAX_LONG_MSG_SZ=%d", Caller, MsgSz, IAC__SOCK_MAX_LONG_MSG_SZ )); + } + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + VPtSocket->ParPtMsg = PtMsg; + VPtSocket->ParMsgSz = MsgSz; + + err_trace (( ERR_OUT, "Caller=%s - LongMsgSz = %d", Caller, VPtSocket->ParMsgSz )); + + /* ------------------------------------ */ + /* Try to send message ParRetryNb times */ + /* ------------------------------------ */ + + for ( ViTry=0; ViTry < VPtSocket->ParRetryNb; ViTry++ ) { + + /* --------------- */ + /* Reset Status */ + /* --------------- */ + + VPtSocket->SendStatus = -1; + + /* -------------------- */ + /* Send event to thread */ + /* -------------------- */ + + if ( PulseEvent ( VPtSocket->EvNewMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Caller=%s - Event EvNewMsgHnd sent", Caller )); + } + + /* ------------------ */ + /* Wait thread answer */ + /* ------------------ */ + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"Caller=%s - Ack event not installed ! ", Caller ) ); + + // Time out => Retry + + if ( WaitForSingleObject ( VPtSocket->EvAckMsgHnd, VPtSocket->ParAckTimeOutMs ) == WAIT_TIMEOUT ) { + err_error (( ERR_OUT, "Caller=%s - No Ack => Exit on time out %d [ms] !!! ViTry=%d - Msg : %s", Caller, VPtSocket->ParAckTimeOutMs, ViTry, PtMsg )); + continue; + } + + // Error => Retry + + if ( VPtSocket->SendStatus <= 0 ) { + err_error (( ERR_OUT, "Caller=%s - Send error - ViTry=%d - Msg : %s", Caller, ViTry, PtMsg )); + continue; + } + + // OK message sent, Ack received => break loop + + err_trace (( ERR_OUT, "Caller=%s - Ack received", Caller )); + break; + + } /* End for */ + + + + return (VPtSocket->SendStatus); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 IAC__PRIV_FSockInit ( ) { + + WSADATA VStackInf; + + // Initialize winsock + + WSAStartup( MAKEWORD(2,0), &VStackInf ) ; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockGetSenderPortContext () { + + SInt32 Vi; + SInt32 VPortContextId; + + VPortContextId = -1; + + // Search a free port context record + + for ( Vi=0; Vi < IAC__SOCK_MAX_SENDER_PORT_NB; Vi++ ) { + + if ( IAC__VGContext.Sock.ASenderPort[Vi].Used == 0 ) { + IAC__VGContext.Sock.ASenderPort[Vi].Used = 1; + VPortContextId = Vi; + ++IAC__VGContext.Sock.SenderPortNb; + break; + } + + } + + // None found + + err_retfail ( VPortContextId, (ERR_OUT,"No free rec port context found => %d used", IAC__VGContext.Sock.SenderPortNb ) ); + + // Found + + err_retval ( VPortContextId, ( ERR_OUT, "Get reception port context Id=%d", VPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockGetReceiverPortContext () { + + SInt32 Vi; + SInt32 VPortContextId; + + VPortContextId = -1; + + // Search a free port context record + + for ( Vi=0; Vi < IAC__SOCK_MAX_REC_PORT_NB; Vi++ ) { + + if ( IAC__VGContext.Sock.AReceiverPort[Vi].Used == 0 ) { + IAC__VGContext.Sock.AReceiverPort[Vi].Used = 1; + VPortContextId = Vi; + ++IAC__VGContext.Sock.ReceiverPortNb; + break; + } + + } + + // None found + + err_retfail ( VPortContextId, (ERR_OUT,"No free rec port context found => %d used", IAC__VGContext.Sock.ReceiverPortNb ) ); + + // Found + + err_retval ( VPortContextId, ( ERR_OUT, "Get reception port context Id=%d", VPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockFreeSenderPortContext ( SInt32 ContextId ) { + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + /* -------- */ + /* Free */ + /* -------- */ + + IAC__VGContext.Sock.ASenderPort[ContextId].Used = 0; + + if ( IAC__VGContext.Sock.SenderPortNb > 0 ) { + --IAC__VGContext.Sock.SenderPortNb; + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockFreeReceiverPortContext ( SInt32 ContextId ) { + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + /* -------- */ + /* Free */ + /* -------- */ + + IAC__VGContext.Sock.AReceiverPort[ContextId].Used = 0; + + if ( IAC__VGContext.Sock.ReceiverPortNb > 0 ) { + --IAC__VGContext.Sock.ReceiverPortNb; + } + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FChkSenderContextId ( SInt32 ContextId ) { + + if ( (ContextId < 0) || (ContextId >= IAC__SOCK_MAX_SENDER_PORT_NB) ) { + err_retfail ( -1, (ERR_OUT,"Context Id=%d out of range[0..%d] !)", ContextId, IAC__SOCK_MAX_SENDER_PORT_NB-1) ); + } + + if ( IAC__VGContext.Sock.ASenderPort[ContextId].Used == 0 ) { + err_retfail ( -1, (ERR_OUT,"Context record Id=%d IS NOT used !", ContextId ) ); + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FChkReceiverContextId ( SInt32 ContextId ) { + + if ( (ContextId < 0) || (ContextId >= IAC__SOCK_MAX_REC_PORT_NB) ) { + err_retfail ( -1, (ERR_OUT,"Context Id=%d out of range[0..%d] !)", ContextId, IAC__SOCK_MAX_REC_PORT_NB-1) ); + } + + if ( IAC__VGContext.Sock.AReceiverPort[ContextId].Used == 0 ) { + err_retfail ( -1, (ERR_OUT,"Context record Id=%d IS NOT used !", ContextId ) ); + } + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header, add trailer + : 14/01/2009 + : - Detect lost of connection and try to reconnect by rebooting the sender + : with a IAC__FSockRebootSenderPort call. + : The goal is to allow receiver application to be stopped and restarted without + : broking permanently the communication channel, but not to recover all kind of errors. + : + Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockSendShortMsg ( SInt32 ContextId ) { + + SInt32 VRet; + IAC__TSockSenderPort* VPtSock; + UInt32 VTmpTotSz; + UInt32 VTotMsgSz; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + SInt32 VSockErrNo; + + + VRet = -1; + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + // Calculate message size + + VTotMsgSz = VPtSock->CstHeaderSz + VPtSock->ParMsgSz + VPtSock->CstTrailerSz; + + // Set size & CS in header + + VPtSock->MsgHeader.TotMsgSz = VTotMsgSz; + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VPtSock->MsgHeader.CheckSum = VPtSock->ParFuncCheckSum ( VPtSock->ParPtMsg, VPtSock->ParMsgSz ); + } + + else { + VPtSock->MsgHeader.CheckSum = 0; + } + + + + // Build messages + + memcpy ( VPtSock->PtBuffSendShortMsg , &(VPtSock->MsgHeader) , VPtSock->CstHeaderSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VPtSock->CstHeaderSz]) , VPtSock->ParPtMsg , VPtSock->ParMsgSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VTotMsgSz-(VPtSock->CstTrailerSz)]), &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz ); + + err_trace (( ERR_OUT, "Header.StartTag = %x [H]", VPtSock->MsgHeader.StartTag )); + err_trace (( ERR_OUT, "Header.TotSz = %d ", VPtSock->MsgHeader.TotMsgSz )); + err_trace (( ERR_OUT, "Header.CheckSum = %d ", VPtSock->MsgHeader.CheckSum )); + err_trace (( ERR_OUT, "Trailer.StopTag = %x [H]", VPtSock->MsgTrailer.StopTag )); + + // Send message + + VSzSent = send ( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VTotMsgSz, 0 ); + + /* BEFORE 14/01/09 + + if ( VSzSent == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"send () error %d - %s", VSockErrNo, strerror (VSockErrNo) )); + } + + */ + + + + if ( VSzSent == SOCKET_ERROR ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + // If connection reset => Try to connect and resend block + + if ( VSockErrNo == WSAECONNRESET ) { + + IAC__FSockRebootSenderPort ( ContextId ); + + // Try again to send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VTotMsgSz, 0 ); + + // Abort on send error + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + // Others error => Abort + + else { + err_retfail ( -1, (ERR_OUT,"send () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + err_trace (( ERR_OUT, "Message of %d Bytes sent", VSzSent )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + VSockErrNo = IAC__SOCKET_ERRNO; + VRet = -1; + err_error (( ERR_OUT, "Ack reception error %d - %s", VSockErrNo, strerror (VSockErrNo) )); + } + + VW32ServerAns = *((UInt32*) VPtSock->BuffRecAck); + + // Check Ack + + if ( VW32ServerAns != VTotMsgSz ) { + VRet = -1; + err_error (( ERR_OUT, "Server ack bad size %d - should be %d", VW32ServerAns, VTotMsgSz )); + } + + // OK : Message sent and Ack received + + VRet = VTotMsgSz; + + return (VRet); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header & trailer + : 14/01/2009 + : - Detect lost of connection and try to reconnect by rebooting the sender + : with a IAC__FSockRebootSenderPort call. + : The lost of connection test is only done at the beginning of a message ( on first + : block send ), if it occurs the middle, therefore message sending is aborted. + : This works like this because the goal is to allow receiver application to be + : stopped and restarted without broking permanently the communication channel, but + : not to recover all kind of errors. + : + : +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockSendLongMsg ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSock; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + + // UInt32 VTmpTotSz; + UInt32 VTotMsgSz; // Including header and trailer + + UInt32 VHeaderBlockDataSz; + UInt32 VHeaderBlockTotSz; + UInt32 VDataBlocksTotSz; + UInt32 VDataBlockSz; + UInt32 VLastBlockSz; + SInt32 VBlockNb; // Excluding first one and last one + SInt32 ViBlock; + SInt32 VPosNextBlockInSrcBuff; + SInt32 VTotSzSent; + SInt8 VMsgSingleBlock; + SInt32 VSockErrNo; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + // Evaluate blocks size + + + err_trace (( ERR_OUT, "ContextId=%d - ParMsgSz=%d", ContextId, VPtSock->ParMsgSz )); + + VTotSzSent = 0; + + // Evaluate blocks size + + // In case of single block message, header and trailer are added to message + + if ( VPtSock->ParMsgSz <= (IAC__SO_MAX_SHORT_MSG_SIZE - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz)) ) { + VMsgSingleBlock = 1; + VHeaderBlockDataSz = VPtSock->ParMsgSz; + VHeaderBlockTotSz = VHeaderBlockDataSz + (VPtSock->CstHeaderSz) + (VPtSock->CstTrailerSz); + VDataBlocksTotSz = 0; + VDataBlockSz = 0; + VBlockNb = 0; + VLastBlockSz = 0; // 0 => no icomplete block at the end + } + + // In case of multi block message, trailer is sent at the end by a specific call to send (...) + // Therefore trailer size must not be taken into account for blocks size and number calculation + + else { + VMsgSingleBlock = 0; + VHeaderBlockDataSz = IAC__SO_MAX_SHORT_MSG_SIZE - (VPtSock->CstHeaderSz); + VHeaderBlockTotSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VDataBlocksTotSz = VPtSock->ParMsgSz - VHeaderBlockDataSz; + VDataBlockSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VBlockNb = VDataBlocksTotSz / VDataBlockSz; + VLastBlockSz = VDataBlocksTotSz % VDataBlockSz; // 0 => no icomplete block at the end + } + + // Calculate message size + + VTotMsgSz = VPtSock->CstHeaderSz + VPtSock->ParMsgSz + VPtSock->CstTrailerSz; + + // Set size & CS in header + + VPtSock->MsgHeader.TotMsgSz = VTotMsgSz; + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VPtSock->MsgHeader.CheckSum = VPtSock->ParFuncCheckSum ( VPtSock->ParPtMsg, VPtSock->ParMsgSz ); + } + + else { + VPtSock->MsgHeader.CheckSum = 0; + } + + // Debug print + + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + err_trace (( ERR_OUT, "User message size = %d", VPtSock->ParMsgSz )); + err_trace (( ERR_OUT, "Total message size = %d", VTotMsgSz )); + err_trace (( ERR_OUT, "VHeaderBlockDataSz = %d", VHeaderBlockDataSz )); + err_trace (( ERR_OUT, "VHeaderBlockTotSz = %d", VHeaderBlockTotSz )); + err_trace (( ERR_OUT, "VDataBlocksTotSz = %d", VDataBlocksTotSz )); + err_trace (( ERR_OUT, "VDataBlockSz = %d", VDataBlockSz )); + err_trace (( ERR_OUT, "VBlockNb = %d", VBlockNb )); + err_trace (( ERR_OUT, "VLastBlockSz = %d", VLastBlockSz )); + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + + // Build header block + + memcpy ( VPtSock->PtBuffSendShortMsg , &(VPtSock->MsgHeader) , VPtSock->CstHeaderSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VPtSock->CstHeaderSz]) , VPtSock->ParPtMsg , VHeaderBlockDataSz ); + + // Copy trailer ONLY for single block message + + if ( VMsgSingleBlock == 1 ) { + memcpy ( &(VPtSock->PtBuffSendShortMsg[VTotMsgSz-(VPtSock->CstTrailerSz)]), &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz ); + } + + VPosNextBlockInSrcBuff = VHeaderBlockDataSz; + + // Send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + // If connection reset => Try to connect and resend block + + if ( VSockErrNo == WSAECONNRESET ) { + + IAC__FSockRebootSenderPort ( ContextId ); + + // Try again to send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + // Abort on send error + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + // Others error => Abort + + else { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + else { + err_trace (( ERR_OUT, "Header block of %d Bytes sent", VSzSent )); + } + + VTotSzSent += VSzSent; + + // Send complete blocks + + for ( ViBlock=0; ViBlock < VBlockNb; ViBlock++) { + + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VDataBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"send () error %d - Block[%d] => %s", VSockErrNo, ViBlock, strerror (VSockErrNo) )); + } + + // err_trace (( ERR_OUT, "Send block[%d] of %d bytes OK :-)", ViBlock, VSzSent )); + + VPosNextBlockInSrcBuff += VDataBlockSz; + VTotSzSent += VSzSent; + + // err_trace (( ERR_OUT, "Block[%d] of %d Bytes sent", ViBlock, VSzSent )); + + } + + // Send last block + + if ( VLastBlockSz > 0 ) { + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VLastBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"send () error %d - Last block => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + // Send trailer ONLY for multiple blocks message + + if ( VMsgSingleBlock == 0 ) { + VSzSent = send( VPtSock->Socket, (UInt8*) &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"send () error %d - Trailer => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + err_trace (( ERR_OUT, "Before waiting for host ACK" )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"Ack receive error %d - %s", VSockErrNo, strerror (VSockErrNo) )); + } + + VW32ServerAns = *((UInt32*) (VPtSock->BuffRecAck) ); + + // Check Ack + + if ( VW32ServerAns != VTotSzSent ) { + err_retfail ( -1, (ERR_OUT,"Server ack bad size %d - should be %d", VW32ServerAns, VTotSzSent )); + } + + err_trace (( ERR_OUT, "Message sent and Ack received" )); + + // OK : Message sent and Ack received + + return (VTotSzSent); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 +: - New header & trailer +: 14/01/2009 +: - Detect lost of connection and try to reconnect by rebooting the sender +: with a IAC__FSockRebootSenderPort call. +: The lost of connection test is only done at the beginning of a message ( on first +: block send ), if it occurs the middle, therefore message sending is aborted. +: This works like this because the goal is to allow receiver application to be +: stopped and restarted without broking permanently the communication channel, but +: not to recover all kind of errors. +: +: +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 DEBUG___IAC__PRIV_FSockSendLongMsg ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSock; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + + // UInt32 VTmpTotSz; + UInt32 VTotMsgSz; // Including header and trailer + + UInt32 VHeaderBlockDataSz; + UInt32 VHeaderBlockTotSz; + UInt32 VDataBlocksTotSz; + UInt32 VDataBlockSz; + UInt32 VLastBlockSz; + SInt32 VBlockNb; // Excluding first one and last one + SInt32 ViBlock; + SInt32 VPosNextBlockInSrcBuff; + SInt32 VTotSzSent; + SInt8 VMsgSingleBlock; + SInt32 VSockErrNo; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + // Evaluate blocks size + + + err_trace (( ERR_OUT, "ContextId=%d - ParMsgSz=%d", ContextId, VPtSock->ParMsgSz )); + + VTotSzSent = 0; + + // Evaluate blocks size + + // In case of single block message, header and trailer are added to message + + if ( VPtSock->ParMsgSz <= (IAC__SO_MAX_SHORT_MSG_SIZE - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz)) ) { + VMsgSingleBlock = 1; + VHeaderBlockDataSz = VPtSock->ParMsgSz; + VHeaderBlockTotSz = VHeaderBlockDataSz + (VPtSock->CstHeaderSz) + (VPtSock->CstTrailerSz); + VDataBlocksTotSz = 0; + VDataBlockSz = 0; + VBlockNb = 0; + VLastBlockSz = 0; // 0 => no icomplete block at the end + } + + // In case of multi block message, trailer is sent at the end by a specific call to send (...) + // Therefore trailer size must not be taken into account for blocks size and number calculation + + else { + VMsgSingleBlock = 0; + VHeaderBlockDataSz = IAC__SO_MAX_SHORT_MSG_SIZE - (VPtSock->CstHeaderSz); + VHeaderBlockTotSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VDataBlocksTotSz = VPtSock->ParMsgSz - VHeaderBlockDataSz; + VDataBlockSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VBlockNb = VDataBlocksTotSz / VDataBlockSz; + VLastBlockSz = VDataBlocksTotSz % VDataBlockSz; // 0 => no icomplete block at the end + } + + // Calculate message size + + VTotMsgSz = VPtSock->CstHeaderSz + VPtSock->ParMsgSz + VPtSock->CstTrailerSz; + + // Set size & CS in header + + VPtSock->MsgHeader.TotMsgSz = VTotMsgSz; + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VPtSock->MsgHeader.CheckSum = VPtSock->ParFuncCheckSum ( VPtSock->ParPtMsg, VPtSock->ParMsgSz ); + } + + else { + VPtSock->MsgHeader.CheckSum = 0; + } + + // Debug print + + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + err_trace (( ERR_OUT, "User message size = %d", VPtSock->ParMsgSz )); + err_trace (( ERR_OUT, "Total message size = %d", VTotMsgSz )); + err_trace (( ERR_OUT, "VHeaderBlockDataSz = %d", VHeaderBlockDataSz )); + err_trace (( ERR_OUT, "VHeaderBlockTotSz = %d", VHeaderBlockTotSz )); + err_trace (( ERR_OUT, "VDataBlocksTotSz = %d", VDataBlocksTotSz )); + err_trace (( ERR_OUT, "VDataBlockSz = %d", VDataBlockSz )); + err_trace (( ERR_OUT, "VBlockNb = %d", VBlockNb )); + err_trace (( ERR_OUT, "VLastBlockSz = %d", VLastBlockSz )); + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + + // Build header block + + memcpy ( VPtSock->PtBuffSendShortMsg , &(VPtSock->MsgHeader) , VPtSock->CstHeaderSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VPtSock->CstHeaderSz]) , VPtSock->ParPtMsg , VHeaderBlockDataSz ); + + // Copy trailer ONLY for single block message + + if ( VMsgSingleBlock == 1 ) { + memcpy ( &(VPtSock->PtBuffSendShortMsg[VTotMsgSz-(VPtSock->CstTrailerSz)]), &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz ); + } + + VPosNextBlockInSrcBuff = VHeaderBlockDataSz; + + // Send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + // If connection reset => Try to connect and resend block + + if ( VSockErrNo == WSAECONNRESET ) { + + IAC__FSockRebootSenderPort ( ContextId ); + + // Try again to send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + // Abort on send error + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + // Others error => Abort + + else { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + else { + err_trace (( ERR_OUT, "Header block of %d Bytes sent", VSzSent )); + } + + VTotSzSent += VSzSent; + + // Send complete blocks + + for ( ViBlock=0; ViBlock < VBlockNb; ViBlock++) { + + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VDataBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + + // If connection reset => Try to connect and resend block + + if ( VSockErrNo == WSAECONNRESET ) { + + IAC__FSockRebootSenderPort ( ContextId ); + + // Try again to send first block + + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VDataBlockSz, 0 ); + + // Abort on send error + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Block[%d] => %s", VSockErrNo, ViBlock, strerror (VSockErrNo) )); + } + } + + // Others error => Abort + + else { + err_retfail ( -1, (ERR_OUT,"send () error %d - Block[%d] => %s", VSockErrNo, ViBlock, strerror (VSockErrNo) )); + } + + } // End if ( VSockErrNo == WSAECONNRESET ) + + err_trace (( ERR_OUT, "Send block[%d] of %d bytes OK :-)", ViBlock, VSzSent )); + + VPosNextBlockInSrcBuff += VDataBlockSz; + VTotSzSent += VSzSent; + + err_trace (( ERR_OUT, "Block[%d] of %d Bytes sent", ViBlock, VSzSent )); + + } + + // Send last block + + if ( VLastBlockSz > 0 ) { + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VLastBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"send () error %d - Last block => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + // Send trailer ONLY for multiple blocks message + + if ( VMsgSingleBlock == 0 ) { + VSzSent = send( VPtSock->Socket, (UInt8*) &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"send () error %d - Trailer => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + err_trace (( ERR_OUT, "Before waiting for host ACK" )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"Ack receive error %d - %s", VSockErrNo, strerror (VSockErrNo) )); + } + + VW32ServerAns = *((UInt32*) (VPtSock->BuffRecAck) ); + + // Check Ack + + if ( VW32ServerAns != VTotSzSent ) { + err_retfail ( -1, (ERR_OUT,"Server ack bad size %d - should be %d", VW32ServerAns, VTotSzSent )); + } + + err_trace (( ERR_OUT, "Message sent and Ack received" )); + + // OK : Message sent and Ack received + + return (VTotSzSent); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 11/11/2008 + : - New header & trailer +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockInstallSenderPort ( char* DestHost, UInt32 DestPort, SInt8 LongMsg, UInt32 AckTimeOutMs, UInt8 RetryNb, IAC__TFSockFuncCheckSum FuncCheckSum ) { + + SInt32 VSenderPortContextId; + IAC__TSockSenderPort* VPtSocket; + SInt32 VSockErrNo; + + /* --------------------------------- */ + /* Find a free sender context record */ + /* --------------------------------- */ + + VSenderPortContextId = IAC__PRIV_FSockGetSenderPortContext (); + + err_retfail ( VSenderPortContextId, (ERR_OUT,"No free context record !") ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[VSenderPortContextId]); + VPtSocket->Id = VSenderPortContextId; + + /* --------------------- */ + /* Init constants fields */ + /* --------------------- */ + + VPtSocket->CstHeaderSz = sizeof (IAC__TSockMsgHeader ); + VPtSocket->CstTrailerSz = sizeof (IAC__TSockMsgTrailer); + + VPtSocket->MsgHeader.StartTag = IAC__SOCK_HEADER_START_TAG; + VPtSocket->MsgHeader.Zero = 0; + VPtSocket->MsgHeader.TotMsgSz = 0; // Unknown at this step + VPtSocket->MsgHeader.CheckSum = 0; // Unknown at this step + + VPtSocket->MsgTrailer.StopTag = IAC__SOCK_TRAILER_STOP_TAG; + VPtSocket->MsgTrailer.Zero = 0; + + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + strncpy ( VPtSocket->ParDestHost, DestHost, IAC__SOCK_MAX_STR_HOST_SZ - 1 ); + VPtSocket->ParDestPort = DestPort; + VPtSocket->ParLongMsg = LongMsg; + VPtSocket->ParAckTimeOutMs = AckTimeOutMs; + VPtSocket->ParRetryNb = RetryNb; + VPtSocket->ParPtMsg = NULL; + VPtSocket->ParFuncCheckSum = FuncCheckSum; + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->Socket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->Socket == INVALID_SOCKET ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short)0 ); + + if ( bind( VPtSocket->Socket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + // Transform the host/port into a struct sockaddr + + VPtSocket->DestAddr = IAC__PRIV_FTcpFormatAdress ( VPtSocket->ParDestHost, (u_short) (VPtSocket->ParDestPort) ); + + /* -------------- */ + /* Create events */ + /* -------------- */ + + VPtSocket->EvNewMsgHnd = CreateEvent ( + NULL /* LPSECURITY_ATTRIBUTES */, + FALSE /* Manual Reset */, + FALSE /* Initial State */, + NULL /* Name STring */ ); + + err_retnull ( VPtSocket->EvNewMsgHnd, (ERR_OUT,"CreateEvent EvNewMsgHnd failed ! - LastError=%d", GetLastError ()) ); + + VPtSocket->EvAckMsgHnd = CreateEvent ( + NULL /* LPSECURITY_ATTRIBUTES */, + FALSE /* Manual Reset */, + FALSE /* Initial State */, + NULL /* Name STring */ ); + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"CreateEvent EvAckMsgHnd failed ! - LastError=%d", GetLastError ()) ); + + + /* ------------- */ + /* Alloc buffers */ + /* ------------- */ + + VPtSocket->PtBuffSendShortMsg = (UInt8*) malloc ( IAC__SO_MAX_SHORT_MSG_SIZE ); + + err_retnull ( VPtSocket->PtBuffSendShortMsg, (ERR_OUT,"Allocation sender buffer of %d bytes failed !", IAC__SO_MAX_SHORT_MSG_SIZE) ); + + /* ------------- */ + /* Create thread */ + /* ------------- */ + + // It will be done in IAC__FSockStartSenderPort () + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSocket->Installed = 1; + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] installed", VPtSocket->Id )); + err_trace (( ERR_OUT, "Dest host = %s", VPtSocket->ParDestHost )); + err_trace (( ERR_OUT, "Dest port = %d", VPtSocket->ParDestPort )); + err_trace (( ERR_OUT, "Ack TO = %d", VPtSocket->ParAckTimeOutMs )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( VSenderPortContextId, ( ERR_OUT, "Emission port=%d installed - uses context record=%d", VPtSocket->ParDestPort, VSenderPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 14/01/2009 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockRebootSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSocket; + SInt32 VSockErrNo; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + /* ------------ */ + /* Check status */ + /* ------------ * + + if ( VPtSocket->Installed != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access not installed => Can't be started" ) ); + } + + + /* ------------ */ + /* Reset status */ + /* ------------ */ + + VPtSocket->Started = 0; + + + /* ------------ */ + /* Close Socket */ + /* ------------ */ + + closesocket ( VPtSocket->Socket ); + + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->Socket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->Socket == INVALID_SOCKET ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short)0 ); + + if ( bind( VPtSocket->Socket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + // Transform the host/port into a struct sockaddr + + VPtSocket->DestAddr = IAC__PRIV_FTcpFormatAdress ( VPtSocket->ParDestHost, (u_short) (VPtSocket->ParDestPort) ); + + // Connect + + while ( connect( VPtSocket->Socket, &(VPtSocket->DestAddr), sizeof(VPtSocket->DestAddr) ) == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_error (( ERR_OUT, "Connect () error %d => %s WILL RETRY in 100 ms", VSockErrNo, strerror (VSockErrNo) )); + Sleep ( 100 ); + } + + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Started = 1; + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] started", VPtSocket->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 13/01/2009 + : - Add closesocket call +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockUnInstallSenderPort ( SInt32 SenderPortContextId ) { + + IAC__TSockSenderPort* VPtSocket; + + err_retfail ( IAC__PRIV_FChkSenderContextId (SenderPortContextId), (ERR_OUT,"Bad Id=%d", SenderPortContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[SenderPortContextId]); + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSocket->Installed = 0; + + /* ------------- */ + /* Close events */ + /* ------------- */ + + if ( CloseHandle ( VPtSocket->EvNewMsgHnd ) == 0 ) { + err_error (( ERR_OUT, "CloseHandle ( VPtSocket->EvNewMsgHnd ) failed !" )); + } + + if ( CloseHandle ( VPtSocket->EvAckMsgHnd ) == 0 ) { + err_error (( ERR_OUT, "CloseHandle ( VPtSocket->EvAckMsgHnd ) failed !" )); + } + + /* ------------ */ + /* Close Socket */ + /* ------------ */ + + closesocket ( VPtSocket->Socket ); + + /* ------------ */ + /* Free buffers */ + /* ------------ */ + + if ( VPtSocket->PtBuffSendShortMsg != NULL ) { + free ( VPtSocket->PtBuffSendShortMsg ); + } + + else { + err_error (( ERR_OUT, "Try to free PtBuffSendShortMsg, but it's already NULL => ???" )); + } + + + /* --------------- */ + /* Release context */ + /* --------------- */ + + IAC__PRIV_FSockFreeSenderPortContext ( SenderPortContextId ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStartSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSocket; + + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + /* ------------ */ + /* Check status */ + /* ------------ */ + + if ( VPtSocket->Installed != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access not installed => Can't be started" ) ); + } + + /* --------------------- */ + /* Create & Start thread */ + /* --------------------- */ + + VPtSocket->ThreadHnd = CreateThread( NULL, NULL, IAC__PRIV_FSockSenderThreadFunc, (LPVOID) VPtSocket, NULL, &(VPtSocket->ThreadId) ); + + err_retnull ( VPtSocket->ThreadHnd, (ERR_OUT,"Thread creation failed !") ); + + + VPtSocket->ThreadFunc = IAC__PRIV_FSockSenderThreadFunc; + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Started = 1; + + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] started", VPtSocket->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStopSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread handle == NULL !") ); + + /* ---------------- */ + /* Terminate thread */ + /* ---------------- */ + + TerminateThread ( VPtSock->ThreadHnd, -1 /* Thread exit code */ ); + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 0; + + err_trace (( ERR_OUT, "TerminateThread sent - with exit code = -1" )); + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%] terminated", VPtSock->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Rev : 06/11/2008 + : - Add LongMsg Handling + : 10/11/2008 + : - Rewritten => No socket close after each message + : 11/11/2008 + : - New header & trailer +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockInstallReceiverPort ( UInt32 RecPort, SInt8 LongMsg, IAC__TFSockUsrHandleRecMsg FuncUsr, IAC__TFSockFuncCheckSum FuncCheckSum ) { + + SInt32 VRecPortContextId; + IAC__TSockReceiverPort* VPtSocket; + UInt8* VPtRecBuffer; + SInt32 VSockErrNo; + + /* --------------------------------- */ + /* Find a free sender context record */ + /* --------------------------------- */ + + VRecPortContextId = IAC__PRIV_FSockGetReceiverPortContext (); + + err_retfail ( VRecPortContextId, (ERR_OUT,"No free context record !") ); + + VPtSocket = &(IAC__VGContext.Sock.AReceiverPort[VRecPortContextId]); + VPtSocket->Id = VRecPortContextId; + + /* --------------------- */ + /* Init constants fields */ + /* --------------------- */ + + VPtSocket->CstHeaderSz = sizeof (IAC__TSockMsgHeader ); + VPtSocket->CstTrailerSz = sizeof (IAC__TSockMsgTrailer); + + VPtSocket->MsgHeader.StartTag = IAC__SOCK_HEADER_START_TAG; + VPtSocket->MsgHeader.Zero = 0; + VPtSocket->MsgHeader.TotMsgSz = 0; // Unknown at this step + VPtSocket->MsgHeader.CheckSum = 0; // Unknown at this step + + VPtSocket->MsgTrailer.StopTag = IAC__SOCK_TRAILER_STOP_TAG; + VPtSocket->MsgTrailer.Zero = 0; + + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + + VPtSocket->Id = VRecPortContextId; + VPtSocket->ParLongMsg = LongMsg; + VPtSocket->ParPort = RecPort; + VPtSocket->ParUsrFunc = FuncUsr; + VPtSocket->ParFuncCheckSum = FuncCheckSum; + + + /* ------------------------- */ + /* Allocate reception buffer */ + /* ------------------------- */ + + + if ( VPtSocket->ParLongMsg == 0 ) { + VPtSocket->MaxMsgSz = IAC__SO_MAX_SHORT_MSG_SIZE * 2; + } + + else { + VPtSocket->MaxMsgSz = IAC__SOCK_MAX_LONG_MSG_SZ; + } + + VPtRecBuffer = (UInt8*) malloc ( VPtSocket->MaxMsgSz ); + + err_retnull ( VPtRecBuffer, (ERR_OUT,"Malloc of %d bytes for rec buffer failed !", VPtSocket->MaxMsgSz) ); + + err_trace (( ERR_OUT, "Malloc of %d bytes for Receiver port[%d]", VPtSocket->MaxMsgSz, VRecPortContextId )); + + VPtSocket->PtMsg = VPtRecBuffer; + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->LSocket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->LSocket == INVALID_SOCKET ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short) VPtSocket->ParPort ); + + if ( bind( VPtSocket->LSocket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Installed = 1; + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Receiver port [%d] installed", VPtSocket->Id )); + err_trace (( ERR_OUT, "Port = %d", VPtSocket->ParPort )); + err_trace (( ERR_OUT, "Long msg = %d", VPtSocket->ParLongMsg )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( VRecPortContextId, ( ERR_OUT, "Reception port=%d installed - uses context record=%d", RecPort, VRecPortContextId ) ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 13/01/2009 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockRebootReceiverPort ( SInt32 ContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt32 VSockErrNo; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ------------ */ + /* Reset status */ + /* ------------ */ + + VPtSock->Installed = 0; + + /* ------------- */ + /* Close ASocket */ + /* ------------- */ + + closesocket ( VPtSock->ASocket ); + + /* ------------- */ + /* Close LSocket */ + /* ------------- */ + + closesocket ( VPtSock->LSocket ); + + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSock->LSocket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSock->LSocket == INVALID_SOCKET ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + // Bind + + VPtSock->LocAddr.sin_family = AF_INET ; + VPtSock->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSock->LocAddr.sin_port = htons ((unsigned short) VPtSock->ParPort ); + + if ( bind( VPtSock->LSocket, (struct sockaddr *)&(VPtSock->LocAddr), sizeof(VPtSock->LocAddr)) == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Installed = 1; + + + /* ---------------------- */ + /* Wait client connection */ + /* ---------------------- */ + + // Listen + + err_trace (( ERR_OUT, "Before listen" )); + + if ( listen( VPtSock->LSocket, 2) == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"listen () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + err_trace (( ERR_OUT, "Before accept" )); + + // Accept + + VPtSock->ASocket = accept ( VPtSock->LSocket, NULL, NULL ); + + if( VPtSock->ASocket == INVALID_SOCKET ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"accept () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Reboot of Receiver port [%d] done", VPtSock->Id )); + err_trace (( ERR_OUT, "Port = %d", VPtSock->ParPort )); + err_trace (( ERR_OUT, "Long msg = %d", VPtSock->ParLongMsg )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( ContextId, ( ERR_OUT, "Reception port Id=%d reboot", ContextId ) ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockUnInstallReceiverPort ( SInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (RecPortContextId), (ERR_OUT,"Bad Id=%d", RecPortContextId ) ); + VPtSock = &IAC__VGContext.Sock.AReceiverPort[RecPortContextId ]; + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSock->Installed = 0; + VPtSock->Started = 0; + + /* ------------- */ + /* Close LSocket */ + /* ------------- */ + + closesocket ( VPtSock->LSocket ); + + /* ------------- */ + /* Free buffer */ + /* ------------- */ + + if ( VPtSock->PtMsg != NULL ) { + free ( VPtSock->PtMsg ); + } + + VPtSock->MaxMsgSz = 0; + + IAC__PRIV_FSockFreeReceiverPortContext ( RecPortContextId ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStartReceiverPort ( SInt32 ContextId ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* --------------------- */ + /* Start thread function */ + /* --------------------- */ + + err_trace (( ERR_OUT, "Call CreateThread (...)" )); + + VPtSock->ThreadHnd = CreateThread( NULL, NULL, IAC__PRIV_FSockReceiverThreadFunc, (LPVOID) VPtSock, NULL, &(VPtSock->ThreadId) ); + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread creation failed !") ); + + VPtSock->ThreadFunc = IAC__PRIV_FSockReceiverThreadFunc; + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 1; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStopReceiverPort ( SInt32 ContextId ) { + + SInt8 VThreadKillOk; + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 0; + + /* -------------------- */ + /* Kill thread function */ + /* -------------------- */ + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread handle == NULL !") ); + + VThreadKillOk = TerminateThread ( VPtSock->ThreadHnd, -1 /* Thread exit code */ ); + + err_trace (( ERR_OUT, "TerminateThread sent - Return Ok ? = %d", VThreadKillOk )); + + /* ------------- */ + /* Close ASocket */ + /* ------------- */ + + closesocket ( VPtSock->ASocket ); + + err_retok (( ERR_OUT, "Receiver port Id=%d stopped", ContextId )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : For debugging only => Disable call to IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt + : in thread function +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockDbgReceiverPortDisableReception ( SInt32 ContextId, SInt8 DisableReception ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ------------- */ + /* Set parameter */ + /* ------------- */ + + VPtSock->DbgDisableReception = DisableReception; + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header, add trailer + : 13/01/2009 + : - Return -2 if recv failed on connection lost in order to infrom caller to + : " reboot " the receiver + : +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VRecSz; + SInt32 VAckSentSz; + IAC__TSockMsgHeader* VPtHeader; + IAC__TSockMsgTrailer* VPtTrailer; + SInt32 VUserDataSz; + SInt32 VCheckSum; + SInt32 VSockErrno; + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + + while (1) { + + + // Init status + + VPtSock->MsgReady = 0; + + // Read + + VRecSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[0]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "RecSz=%d", VRecSz )); + + if( VRecSz <= 0 ) { + + VSockErrno = IAC__SOCKET_ERRNO; + + err_error (( ERR_OUT, "VRecSz=%d - IAC__SOCKET_ERRNO=%d", VRecSz, VSockErrno )); + + /* --------------------------------------------------------------------------------- */ + /* If connection has been lost */ + /* => return -2 */ + /* => caller will detected this special error and will try to reboot the receiver */ + /* --------------------------------------------------------------------------------- */ + + if ( (VRecSz == 0) || (VSockErrno == WSAECONNRESET) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost ! VRecSz=%d - IAC__SOCKET_ERRNO=%d => %s", VRecSz, VSockErrno, strerror (VSockErrno) )); + } + + /* ------------------------------- */ + /* Normal error => Not recoverable */ + /* ------------------------------- */ + + else { + err_retfail ( -1, (ERR_OUT,"recv () error %d => %s", VSockErrno, strerror (VSockErrno) )); + } + + } + + // Check header & trailer & CS + + VPtHeader = (IAC__TSockMsgHeader*) VPtSock->PtMsg; + + if ( VPtHeader->StartTag != IAC__SOCK_HEADER_START_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad header start tag=%x [H] - Must be %x [H]", VPtHeader->StartTag, IAC__SOCK_HEADER_START_TAG ) ); + } + + if ( VPtHeader->TotMsgSz != VRecSz ) { + err_retfail ( -1, (ERR_OUT,"Header tot sz=%d <> Received sz=%d", VPtHeader->TotMsgSz, VRecSz ) ); + } + + VPtTrailer = (IAC__TSockMsgTrailer*) &(VPtSock->PtMsg[VRecSz-(VPtSock->CstTrailerSz)]); + + if ( VPtTrailer->StopTag != IAC__SOCK_TRAILER_STOP_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad trailer stop tag=%x [H] - Must be %x [H]", VPtTrailer->StopTag, IAC__SOCK_TRAILER_STOP_TAG ) ); + } + + VUserDataSz = VRecSz - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz); + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VCheckSum = VPtSock->ParFuncCheckSum ( &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + + if ( VCheckSum != VPtHeader->CheckSum ) { + err_retfail ( -1, (ERR_OUT,"Checksum error : Calculated=%d <> From Header=%d", VCheckSum, VPtHeader->CheckSum ) ); + } + + err_trace (( ERR_OUT, "Checksum OK = %d", VCheckSum )); + + } + + + // Set status + + VPtSock->MsgSz = VRecSz; + VPtSock->MsgReady = 1; + + // Call user function + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VPtSock->MsgSz, &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + } + + err_trace (( ERR_OUT, "Message received => %d bytes", VRecSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VRecSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + VSockErrno = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", VSockErrno, strerror (VSockErrno) )); + } + + break; /* Exit of while (1) at end of processing */ + + } /* End while (1) */ + + return (VRecSz); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header & trailer + : 13/01/2009 + : - Return -2 if recv failed on connection lost +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockLookForLongRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VMsgSzFromHeader; + SInt32 VCheckSumFromHeader; + SInt32 VAckSentSz; + SInt32 VRecBlocSz ; + SInt32 VTotRecSz ; + IAC__TSockMsgHeader* VPtMayBeHeader; + IAC__TSockMsgTrailer* VPtTrailer; + SInt32 VUserDataSz; + SInt32 VCheckSum; + SInt32 VSockErrNo; + + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + // Init status + + VPtSock->MsgReady = 0; + + VMsgReceptionRuning = 0; + VRecBlocSz = 0; + VTotRecSz = 0; + + + + while (1) { + + // Read + + VRecBlocSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[VTotRecSz]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "VRecBlocSz=%d", VRecBlocSz )); + + // If no data + +/* BEFORE 14/01/09 + + if( VRecBlocSz <= 0 ) { + + if ( (VRecBlocSz == 0) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost !") ); + } + + else { + VSockErrNo = IAC__SOCKET_ERRNO; + err_warning (( ERR_OUT, "recv () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + continue; + } + + } + +*/ + + if( VRecBlocSz <= 0 ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + /* --------------------------------------------------------------------------------- */ + /* If connection has been lost */ + /* => return -2 */ + /* => caller will detected this special error and will try to reboot the receiver */ + /* --------------------------------------------------------------------------------- */ + + if ( (VRecBlocSz == 0) || (VSockErrNo == WSAECONNRESET) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost ! VRecSz=%d - IAC__SOCKET_ERRNO=%d => %s", VRecBlocSz, VSockErrNo, strerror (VSockErrNo) )); + } + + /* ------------------------- */ + /* Normal warning => No data */ + /* ------------------------- */ + + else { + err_warning (( ERR_OUT, "recv () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + continue; + } + + } + + + + // If data + + // If it's message header + + /* ---------------------------------------------------------------------------------- */ + /* - WARNING - */ + /* ---------------------------------------------------------------------------------- */ + /* VPtMayBeHeader points to a valid header ONLY when current received block is header */ + /* On next blocks VPtMayBeHeader points to a something which IS NOT a header */ + /* Therefore if you need to access to header fields LATER you must do a copy of */ + /* these fields WHEN header is detected and use this copy NOT VPtMayBeHeader fields */ + /* ---------------------------------------------------------------------------------- */ + + VPtMayBeHeader = (IAC__TSockMsgHeader*) &(VPtSock->PtMsg[VTotRecSz]); + + if ( VPtMayBeHeader->StartTag == IAC__SOCK_HEADER_START_TAG ) { + + // Do a copy of useful header fields + + VMsgSzFromHeader = VPtMayBeHeader->TotMsgSz; + VCheckSumFromHeader = VPtMayBeHeader->CheckSum; + + VPtSock->MsgReady = 0; + + VMsgReceptionRuning = 1; + VTotRecSz = 0; + + err_trace (( ERR_OUT, "Message header tag = %x [H] - MsgSz=%d", VPtMayBeHeader->StartTag, VMsgSzFromHeader )); + err_trace (( ERR_OUT, "Message header received of %d bytes", VRecBlocSz )); + + VTotRecSz = VTotRecSz + VRecBlocSz; + } + + // If it's not message header + + else { + + // If it's not message header AND we are not in message recpetion phase => Message not for us + + if ( VMsgReceptionRuning == 0 ) { + err_retfail ( -1, (ERR_OUT,"Unknown message ! Not header / Not data part") ); + } + + // It's a data block => increment total size + + VTotRecSz = VTotRecSz + VRecBlocSz; + + err_trace (( ERR_OUT, "At this step tot received size of %d bytes", VTotRecSz )); + } + + // End of message reached + + if ( VTotRecSz >= VMsgSzFromHeader ) { + VMsgReceptionRuning = 0; + + // Check message size + + if ( VMsgSzFromHeader != VTotRecSz ) { + err_retfail ( -1, (ERR_OUT,"Header tot sz=%d <> Received sz=%d", VMsgSzFromHeader, VTotRecSz ) ); + } + + // Check trailer value + + VPtTrailer = (IAC__TSockMsgTrailer*) &(VPtSock->PtMsg[VTotRecSz-(VPtSock->CstTrailerSz)]); + + if ( VPtTrailer->StopTag != IAC__SOCK_TRAILER_STOP_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad trailer stop tag=%x [H] - Must be %x [H]", VPtTrailer->StopTag, IAC__SOCK_TRAILER_STOP_TAG ) ); + } + + // Calculate size of message user part + + VUserDataSz = VTotRecSz - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz); + + // Compare checksum + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VCheckSum = VPtSock->ParFuncCheckSum ( &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + + if ( VCheckSum != VCheckSumFromHeader ) { + err_retfail ( -1, (ERR_OUT,"Checksum error : Calculated=%d <> From Header=%d", VCheckSum, VCheckSumFromHeader ) ); + } + + err_trace (( ERR_OUT, "Checksum OK = %d", VCheckSum )); + + } + + // Good message received + + VPtSock->MsgSz = VTotRecSz; + VPtSock->MsgReady = 1; + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VTotRecSz, &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + } + + err_trace (( ERR_OUT, "Enf of message reception => %d bytes", VTotRecSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VTotRecSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + VMsgReceptionRuning = 0; + VRecBlocSz = 0; + VTotRecSz = 0; + + break; + } + + + } /* End while (1) */ + + + return (VTotRecSz); + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 13/01/2009 + : - Wait for a receicer if connect failed +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +DWORD WINAPI IAC__PRIV_FSockSenderThreadFunc ( LPVOID lpParam ) { + + IAC__TSockSenderPort* VPtSock = (IAC__TSockSenderPort*) lpParam; + SInt32 VSockErrNo; + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Thread execution of sender port [%d] started", VPtSock ->Id )); + err_trace (( ERR_OUT, "Dest host = %s", VPtSock ->ParDestHost )); + err_trace (( ERR_OUT, "Dest port = %d", VPtSock ->ParDestPort )); + err_trace (( ERR_OUT, "Ack TO = %d", VPtSock ->ParAckTimeOutMs )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + + err_error (( ERR_OUT, "----------------------------------------------------" )); + err_error (( ERR_OUT, "Thread execution of sender port [%d] started", VPtSock ->Id )); + err_error (( ERR_OUT, "Dest host = %s", VPtSock ->ParDestHost )); + err_error (( ERR_OUT, "Dest port = %d", VPtSock ->ParDestPort )); + err_error (( ERR_OUT, "Ack TO = %d", VPtSock ->ParAckTimeOutMs )); + err_error (( ERR_OUT, "----------------------------------------------------" )); + + + /* -------------------- */ + /* Connect to dest host */ + /* -------------------- */ + + err_warning (( ERR_OUT, "IAC__PRIV_FSockSenderThreadFunc Try to connect ..." )); + + // Blocking mode socket + + /* ----------------------------------------------- */ + /* Try to connect until a receiver is detected */ + /* if connection failed, it waits 100 ms and retry */ + /* ----------------------------------------------- */ + /* Before 13/01/09 it was a single call to connect */ + /* followed by retfail to abort in case of error */ + /* ----------------------------------------------- */ + + while ( connect( VPtSock->Socket, &(VPtSock->DestAddr), sizeof(VPtSock->DestAddr) ) == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_warning (( ERR_OUT, "Connect () error %d => %s WILL RETRY in 100 ms", VSockErrNo, strerror (VSockErrNo) )); + Sleep ( 100 ); + } + + err_warning (( ERR_OUT, "Sender [%d] connection to Host %s Port %d done :-)", VPtSock->Id, VPtSock->ParDestHost, VPtSock->ParDestPort )); + + /* --------------------- */ + /* Messages sending loop */ + /* --------------------- */ + + while (1) { + + // Wait event + + if ( VPtSock->EvNewMsgHnd != NULL ) { + WaitForSingleObject ( VPtSock->EvNewMsgHnd, INFINITE /* dwTimeout */ ); + } + + // Send message + + if ( VPtSock->ParLongMsg == 0 ) { + VPtSock->SendStatus = IAC__PRIV_FSockSendShortMsg ( VPtSock->Id ); + } + + else { + VPtSock->SendStatus = IAC__PRIV_FSockSendLongMsg ( VPtSock->Id ); + } + + + // Send Ack event + + if ( PulseEvent ( VPtSock->EvAckMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Event EvAckMsgHnd sent" )); + } + + + } /* End while (1) */ + + + + err_error (( ERR_OUT, "END of IAC__PRIV_FSockSenderThreadFunc" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Rev : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +DWORD WINAPI IAC__PRIV_FSockReceiverThreadFunc ( LPVOID lpParam ) { + + IAC__TSockReceiverPort* VPtSock = (IAC__TSockReceiverPort*) lpParam; + SInt32 VRet; + SInt32 VSockErrNo; + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Thread execution of receiver port [%d] started", VPtSock->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + + + err_error (( ERR_OUT, "----------------------------------------------------" )); + err_error (( ERR_OUT, "Thread execution of receiver port [%d] started", VPtSock->Id )); + err_error (( ERR_OUT, "----------------------------------------------------" )); + + + + /* ---------------------- */ + /* Wait client connection */ + /* ---------------------- */ + + // Listen + + err_trace (( ERR_OUT, "Before listen" )); + + if ( listen( VPtSock->LSocket, 2) == SOCKET_ERROR ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"listen () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + err_trace (( ERR_OUT, "Before accept" )); + + // Accept + + VPtSock->ASocket = accept ( VPtSock->LSocket, NULL, NULL ); + + if( VPtSock->ASocket == INVALID_SOCKET ) { + VSockErrNo = IAC__SOCKET_ERRNO; + err_retfail ( -1, (ERR_OUT,"accept () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + err_trace (( ERR_OUT, "Before loop" )); + + /* ---------------------- */ + /* Reception loop */ + /* ---------------------- */ + + while (1) { + + if ( VPtSock->DbgDisableReception == 1 ) { + err_error (( ERR_OUT, "Reception disabled !" )); + continue; + } + + if ( VPtSock->ParLongMsg == 0 ) { + VRet = IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( VPtSock->Id ); + } + + else { + VRet = IAC__PRIV_FSockLookForLongRecMsgOnPortAndProcessIt ( VPtSock->Id ); + } + + if ( VRet == -2 ) { + Sleep ( 100 ); + err_error (( ERR_OUT, "IAC__FSockRebootReceiverPort called !" )); + IAC__FSockRebootReceiverPort ( VPtSock->Id ); + } + + + } /* End while (1) */ + + + return (0); +} + + + + + +#endif + + + + + + + + + + + + diff --git a/include/pxi_daq_lib_v.2.1/inter_app_com.def b/include/pxi_daq_lib_v.2.1/inter_app_com.def new file mode 100755 index 0000000..9f9836a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/inter_app_com.def @@ -0,0 +1,95 @@ + + +/******************************************************************************* +File : x:\lib\com\inter_app_com\inter_app_com.def +Goal : Macros definition of inter applications communication library. +Prj date : 05/12/2007 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef INTER_APP_COM_DEF +#define INTER_APP_COM_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#ifdef ROOT_ROOT + #define SO_MAX_MSG_SIZE 8195 +#endif + + +#define IAC__CMD_TYPE__RMP 2 + +#define IAC__CMD_STYPE__RMP__ASK_RUN_STATUS 1 +#define IAC__CMD_STYPE__RMP__ASK_EVENT 2 +#define IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2 3 + + +#define IAC__RMP_MAX_EV_NB_REQUEST 10 + +#define IAC__RMP_DATA_BLOCK_SZ (1024 * 1024) + +/* ================= */ +/* Sockets */ +/* ================= */ + +#ifdef ROOT_ROOT + +#else + + #ifdef _WIN32 + #define IAC__SOCKET_ERRNO WSAGetLastError() + #define IAC__ERRNO GetLastError() + #else + #define IAC__SOCKET_ERRNO errno + #define IAC__ERRNO errno + #define closesocket close + #endif + + +#endif + + + +#define IAC__SOCK_HEADER_STR "SZ=" +#define IAC__SOCK_HEADER_STR_SZ 3 /* = IAC__SOCK_HEADER_STR characters number */ +#define IAC__SOCK_HEADER_TOT_SZ (IAC__SOCK_HEADER_STR_SZ + 5) /* = IAC__SOCK_HEADER_STR_SZ + 1 byte = 0 + 4 bytes used to store message size */ + +#define IAC__SOCK_HEADER_START_TAG 0x84541444 // "HEAD" +#define IAC__SOCK_TRAILER_STOP_TAG 0x451494C4 // "TAIL" + +#define IAC__SOCK_MAX_SENDER_PORT_NB 10 +#define IAC__SOCK_MAX_REC_PORT_NB 10 +#define IAC__SOCK_MAX_STR_HOST_SZ 255 +#define IAC__SOCK_ACK_SZ 4 + +#define IAC__SOCK_MAX_LONG_MSG_SZ (1024*1024*35) // 10 before 22/06/2009 + + +#define IAC__MSG_ID_STR "#IAC MESSAGE$" + +#define IAC__TWHO_MAX_NAME_SZ 255 +#define IAC__MSG_ID_STR_SZ 14 + + +#define IAC__SO_MAX_SHORT_MSG_SIZE (SO_MAX_MSG_SIZE - 100) + +/* ============== */ +/* */ +/* ============== */ + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/inter_app_com.h b/include/pxi_daq_lib_v.2.1/inter_app_com.h new file mode 100755 index 0000000..f6c7d21 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/inter_app_com.h @@ -0,0 +1,108 @@ + +/******************************************************************************* +File : x:\lib\com\inter_app_com\inter_app_com.h +Goal : Functions prototypes of inter applications communication library. +Prj date : 05/12/2007 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef INTER_APP_COM_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FBegin ( SInt8 ErrLogLvl, char* ErrLogFilePath );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FEnd ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FSetFuncRunStatusAnswer ( IAC__RMP_TFuncRunStatusAnswer PtFunc );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FSetFuncRunStatusAnswer2 ( IAC__RMP_TFuncRunStatusAnswer2 PtFunc );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FSetFuncAskEventAnswer ( IAC__RMP_TFuncAskEventAnswer PtFunc );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FCmdAskRunStatus ( IAC__RMP_TRunStatusAnswer* PtStatus );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FCmdAskRunStatus2 ( IAC__RMP_TRunStatusAnswer2* PtStatus );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FCmdAskEvent ( IAC__RMP_TAskEventAnswer* PtAns );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FDaqCmdInterpreter ();) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FSendEvent ( UInt8* PtEv, SInt32 Sz );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FReceiveEvent ( UInt8* PtEv, SInt32 MaxEvSz, SInt32* PtEvSz );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FTestFillEvent ( UInt8* PtEv, SInt32 Sz );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FTestCompareEvents ( UInt8* PtEvToCmp, UInt8* PtEvRef, SInt32 Sz );) + +#ifndef ROOT_ROOT + FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FTestPrintMemStatusRec ( LPMEMORYSTATUS PtRec );) + FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__RMP_FTestGetMemStatus ( SInt8 Print, LPMEMORYSTATUS PtRec, SInt32* PtStackAvailSz );) +#endif + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockInstallSenderPort ( char* DestHost, UInt32 DestPort, SInt8 LongMsg, UInt32 AckTimeOutMs, UInt8 RetryNb, IAC__TFSockFuncCheckSum FuncCheckSum );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockRebootSenderPort ( SInt32 ContextId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockUnInstallSenderPort ( SInt32 SendPortContextId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockStartSenderPort ( SInt32 ContextId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockStopSenderPort ( SInt32 ContextId );) + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockSendShortMsg ( SInt32 ContextId, UInt8* PtMsg, UInt32 MsgSz, char* Caller );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockSendLongMsg ( SInt32 ContextId, UInt8* PtMsg, UInt32 MsgSz, char* Caller );) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockInstallReceiverPort ( UInt32 RecPort, SInt8 LongMsg, IAC__TFSockUsrHandleRecMsg FuncUsr, IAC__TFSockFuncCheckSum FuncCheckSum );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockRebootReceiverPort ( SInt32 ContextId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockUnInstallReceiverPort ( SInt32 RecPortContextId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockStartReceiverPort ( SInt32 ContextId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockStopReceiverPort ( SInt32 ContextId );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 IAC__FSockDbgReceiverPortDisableReception ( SInt32 ContextId, SInt8 DisableReception );) + + + +// FHEAD ( SInt32 REF_FHello ();) + + +FHEAD ( SInt32 IAC__PRIV_FSockInit ();) +FHEAD ( struct sockaddr IAC__PRIV_FTcpFormatAdress ( char * Host, u_short Port );) + +FHEAD ( SInt32 IAC__PRIV_FSockGetSenderPortContext ();) +FHEAD ( SInt32 IAC__PRIV_FSockFreeSenderPortContext ( SInt32 ContextId );) +FHEAD ( SInt32 IAC__PRIV_FChkSenderContextId ( SInt32 ContextId );) + + +FHEAD ( SInt32 IAC__PRIV_FSockGetReceiverPortContext ();) +FHEAD ( SInt32 IAC__PRIV_FSockFreeReceiverPortContext ( SInt32 ContextId ) ;) +FHEAD ( SInt32 IAC__PRIV_FChkReceiverContextId ( SInt32 ContextId );) +FHEAD ( SInt32 IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId );) +FHEAD ( SInt32 IAC__PRIV_FSockLookForLongRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId );) + +#ifdef ROOT_ROOT + FHEAD ( void* IAC__PRIV_FSockReceiverThreadFunc ( void* lpParam );) +#else + FHEAD ( DWORD WINAPI IAC__PRIV_FSockReceiverThreadFunc ( LPVOID lpParam );) +#endif + + + FHEAD ( DWORD WINAPI IAC__PRIV_FSockSenderThreadFunc ( LPVOID lpParam );) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef INTER_APP_COM_H + #define INTER_APP_COM_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/inter_app_com.old1.c b/include/pxi_daq_lib_v.2.1/inter_app_com.old1.c new file mode 100755 index 0000000..2b1d432 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/inter_app_com.old1.c @@ -0,0 +1,4256 @@ + +/******************************************************************************* +File : x:\lib\com\inter_app_com\inter_app_com.c +Goal : Functions of inter applications communication library. +Prj date : 05/12/2007 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef INTER_APP_COM_C +#define INTER_APP_COM_C + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 05/12/2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/12/2007 + : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FBegin ( SInt8 ErrLogLvl, char* ErrLogFilePath ) { + + IAC__TContext* PtCont = &IAC__VGContext; + + ERR_FBegin ( (ErrLogLvl != ERR_LOG_LVL_NONE ) /* Enable */, ErrLogFilePath ); + ERR_FSetFileLogLevel ( ErrLogLvl ); + ERR_FSetUserLogLevel ( ErrLogLvl ); + + memset ( &IAC__VGContext, 0, sizeof (IAC__VGContext) ); + + IAC__PRIV_FSockInit (); + + PtCont->Rmp.CmdComPcObjId = 0; + PtCont->Rmp.CmdComUcObjId = 1; + PtCont->Rmp.CmdGetCmdResLoopPeriod = 50; + PtCont->Rmp.CmdGetCmdResTryNb = 60; + + PtCont->Rmp.DataComPcObjId = 2; + PtCont->Rmp.DataComUcObjId = 3; + + CPC_FBegin ( PtCont->Rmp.CmdComPcObjId /* ObjId */, 0 /* ComMedia */, 0 /* ComId */, CPC_OBJ_CMD_BLK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, CPC_OBJ_CMD_RES_BLK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + CUC_FBegin ( PtCont->Rmp.CmdComUcObjId /* ObjId */, 0 /* ComMedia */, 0 /* ComId */, CPC_OBJ_CMD_RES_BLK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, CPC_OBJ_CMD_BLK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + + CPC_FBegin ( PtCont->Rmp.DataComPcObjId /* ObjId */, 0 /* ComMedia */, 1 /* ComId */, IAC__RMP_DATA_BLOCK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, IAC__RMP_DATA_BLOCK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + CUC_FBegin ( PtCont->Rmp.DataComUcObjId /* ObjId */, 0 /* ComMedia */, 1 /* ComId */, IAC__RMP_DATA_BLOCK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, IAC__RMP_DATA_BLOCK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + + err_retok (( ERR_OUT, "Lib compiled on %s at %s", __DATE__, __TIME__ )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/12/2007 + : 09/01/2008 + Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FEnd () { + + IAC__TContext* PtCont = &IAC__VGContext; + + CPC_FEnd ( PtCont->Rmp.CmdComPcObjId /* ObjId */ ); + CUC_FEnd ( PtCont->Rmp.CmdComUcObjId /* ObjId */ ); + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncRunStatusAnswer ( IAC__RMP_TFuncRunStatusAnswer PtFunc ) { + + IAC__VGContext.Rmp.FuncRunStatusAnswer = PtFunc; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncRunStatusAnswer2 ( IAC__RMP_TFuncRunStatusAnswer2 PtFunc ) { + + IAC__VGContext.Rmp.FuncRunStatusAnswer2 = PtFunc; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncAskEventAnswer ( IAC__RMP_TFuncAskEventAnswer PtFunc ) { + + IAC__VGContext.Rmp.FuncAskEventAnswer = PtFunc; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskRunStatus ( IAC__RMP_TRunStatusAnswer* PtStatus ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TRunStatusAnswer* VPtRes; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_RUN_STATUS, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TRunStatusAnswer ) /* CmdRetSz */, + "Run Status" /* CmdStr */, + NULL /* PtParam */, + 0 /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes /* & ((UInt8*) VPtRes) 14/01/08 */ ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtStatus != NULL ) { + *PtStatus = *VPtRes; + } + + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 11/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskRunStatus2 ( IAC__RMP_TRunStatusAnswer2* PtStatus ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TRunStatusAnswer2* VPtRes; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TRunStatusAnswer2 ) /* CmdRetSz */, + "Run Status 2" /* CmdStr */, + NULL /* PtParam */, + 0 /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtStatus != NULL ) { + *PtStatus = *VPtRes; + } + + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskEvent ( IAC__RMP_TAskEventAnswer* PtAns ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TAskEventAnswer* VPtRes; + static IAC__RMP_TAskEventPar VCmdPar; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + ++VCmdPar.EvNb; + VCmdPar.TestTag = 666; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_EVENT, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TAskEventAnswer ) /* CmdRetSz */, + "Ask event" /* CmdStr */, + (UInt8*) &VCmdPar /* PtParam */, + sizeof ( VCmdPar ) /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtAns != NULL ) { + *PtAns = *VPtRes; + } + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FDaqCmdInterpreter () { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VRetInterpreter; + char VStrStatus[GLB_CMT_SZ]; + COM_TCommand* VPtCmd; + + UInt8* VPtData; + IAC__RMP_TRunStatusAnswer VRunStatusAnswer; + IAC__RMP_TRunStatusAnswer2 VRunStatusAnswer2; + IAC__RMP_TAskEventAnswer VAskEventAnswer; + + + VRetInterpreter = CUC_FCmdInterpreter ( PtCont->Rmp.CmdComUcObjId, VStrStatus, &VPtCmd, &VPtData ); + + + switch ( VRetInterpreter ) { + + case -1 : { + err_retfail ( VRetInterpreter, (ERR_OUT,"Interpreter Error !") ); + break; } + + // Command + + case 1 : { + + err_trace (( ERR_OUT, "Cmd = %s", VPtCmd->StrCmd )); + + if ( VPtCmd->Type != IAC__CMD_TYPE__RMP ) { + err_trace (( ERR_OUT, "Not a RMP cmd !" )); + break; + } + + switch ( VPtCmd->SubType ) { + + + case IAC__CMD_STYPE__RMP__ASK_RUN_STATUS : { + + if ( IAC__VGContext.Rmp.FuncRunStatusAnswer != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_RUN_STATUS received - Response done" )); + + IAC__VGContext.Rmp.FuncRunStatusAnswer ( VPtCmd, &VRunStatusAnswer ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VRunStatusAnswer /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + case IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2 : { + + if ( IAC__VGContext.Rmp.FuncRunStatusAnswer2 != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2 received - Response done" )); + + IAC__VGContext.Rmp.FuncRunStatusAnswer2 ( VPtCmd, &VRunStatusAnswer2 ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VRunStatusAnswer2 /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + case IAC__CMD_STYPE__RMP__ASK_EVENT : { + + if ( IAC__VGContext.Rmp.FuncAskEventAnswer != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_EVENT received - Resonse done" )); + + IAC__VGContext.Rmp.FuncAskEventAnswer ( VPtCmd, &VAskEventAnswer ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VAskEventAnswer /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + default : { + err_error (( ERR_OUT, "Cmd SubType=%d unknown", VPtCmd->SubType )); + break; + } + + } + + + + + break; } + + // Data + + case 2 : { + err_trace (( ERR_OUT, "Data transaction" )); + + break; } + + } + + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSendEvent ( UInt8* PtEv, SInt32 Sz ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + + err_retnull ( PtEv, (ERR_OUT,"PtEv == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + VRet = CUC_FPutDatas ( IAC__VGContext.Rmp.DataComUcObjId /* ObjId */, 0 /* MultiExec */, PtEv, -1 /* BlkSz */, Sz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas (...) failed => Ret=%d", VRet ) ); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FReceiveEvent ( UInt8* PtEv, SInt32 MaxEvSz, SInt32* PtEvSz ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + UInt32 VEvSz; + + err_retnull ( PtEv , (ERR_OUT,"PtEv == NULL") ); + err_retnull ( PtEvSz, (ERR_OUT,"PtEvSz == NULL") ); + + if ( MaxEvSz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad MaxSz =%d <= 0", MaxEvSz) ); + } + + + VRet = CPC_FGetDatas ( IAC__VGContext.Rmp.DataComPcObjId /* ObjId */, 0 /* MultiExec */, PtEv, MaxEvSz, &VEvSz /* PtGetDataSz */ ); + + + switch ( VRet ) { + + case 0 : { + err_retfail ( -1, (ERR_OUT,"This case SHOULD NOT happne => CPC_FGetDatas called with MultiExec = 0 which returns 0 ! = only one block read !") ); + break; } + + case 1 : { + + *PtEvSz = VEvSz; + return (0); // Normal case + break; } + + case -1 : { + err_trace (( ERR_OUT, "Nothing to read" )); + return (-1); + break; } + + case -2 : { + err_retfail ( -1, (ERR_OUT,"Error reading data with CPC_FGetDatas (...) which return %d", VRet) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown error => CPC_FGetDatas (...) return %d", VRet) ); + break; + } + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FTestFillEvent ( UInt8* PtEv, SInt32 Sz ) { + + SInt32 Vi; + + err_retnull ( PtEv, (ERR_OUT,"PtEv == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + for ( Vi=0; Vi < Sz; Vi++ ) { + PtEv[Vi] = Vi; + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FTestCompareEvents ( UInt8* PtEvToCmp, UInt8* PtEvRef, SInt32 Sz ) { + + SInt32 VErrCnt; + SInt32 Vi; + + err_retnull ( PtEvRef , (ERR_OUT,"PtEvRef == NULL") ); + err_retnull ( PtEvToCmp, (ERR_OUT,"PtEvToCmp == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + VErrCnt = 0; + + for ( Vi=0; Vi < Sz; Vi++ ) { + + if ( PtEvToCmp[Vi] != PtEvRef[Vi]) { + err_error (( ERR_OUT, "Cmp error Mem[%6d] : Received=%d - Reference=%d", Vi, PtEvToCmp[Vi], PtEvRef[Vi] )); + ++VErrCnt; + } + + } + + + if ( VErrCnt >= 0 ) { + err_retval ( VErrCnt, ( ERR_OUT, "Event compare => %d errors !", VErrCnt ) ); + } + + else { + err_retok (( ERR_OUT, "" )); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +SInt32 IAC__RMP_FTestPrintMemStatusRec ( LPMEMORYSTATUS PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + err_error (( ERR_OUT, "------------ Mem Status ------------" )); + err_error (( ERR_OUT, "Percent of memory in use = %d", PtRec->dwMemoryLoad )); + err_error (( ERR_OUT, "Bytes of physical memory = %d", PtRec->dwTotalPhys )); + err_error (( ERR_OUT, "Free physical memory bytes = %d", PtRec->dwAvailPhys )); + err_error (( ERR_OUT, "Bytes of paging file = %d", PtRec->dwTotalPageFile )); + err_error (( ERR_OUT, "Free bytes of paging file = %d", PtRec->dwAvailPageFile )); + err_error (( ERR_OUT, "User bytes of address space = %d", PtRec->dwTotalVirtual )); + err_error (( ERR_OUT, "Free user bytes = %d", PtRec->dwAvailVirtual )); + err_error (( ERR_OUT, "------------------------------------" )); + + return (0); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +SInt32 IAC__RMP_FTestGetMemStatus ( SInt8 Print, LPMEMORYSTATUS PtRec, SInt32* PtStackAvailSz ) { + + MEMORYSTATUS VMemStatus; + SInt32 VStackAvailSz; + + + VMemStatus.dwLength = sizeof ( MEMORYSTATUS ); + + GlobalMemoryStatus ( &VMemStatus ); + + VStackAvailSz = stackavail (); + + if ( Print == 1 ) { + IAC__RMP_FTestPrintMemStatusRec ( &VMemStatus ); + err_error (( ERR_OUT, "----------------------------------" )); + err_error (( ERR_OUT, "Stack available = %d bytes", VStackAvailSz )); + err_error (( ERR_OUT, "----------------------------------" )); + } + + + if ( PtRec != NULL ) { + *PtRec = VMemStatus; + } + + if ( PtStackAvailSz != NULL ) { + *PtStackAvailSz = VStackAvailSz; + } + +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 04/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FPrepareMsg ( SInt8 Priority, SInt8 Type, SInt16 SubType, IAC__TWho* From, IAC__TWho* To ) { + + + + return (0); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +struct sockaddr IAC__PRIV_FTcpFormatAdress ( char * Host, u_short Port ) +{ + struct sockaddr_in addr; + struct sockaddr addrRet; + struct hostent FAR *lphost ; + u_long IP; + + + memset((char*)&addr, 0, sizeof(addr)); + + /* Soit on fournit une adresse IP, soit on fournit un nom */ + + if ((IP = inet_addr(Host)) == (u_long)INADDR_NONE) + { + if ((lphost = gethostbyname(Host))==NULL) + { + memset( (char * )&addrRet, 0, sizeof(addrRet) ); + return addrRet; + } + + addr.sin_family = lphost->h_addrtype; + + #ifdef _WIN16 /* A d�finir dans le projet WIN16 */ + _fmemcpy (&addr.sin_addr, lphost->h_addr, lphost->h_length); + #else /* WIN32, UNIX*/ + memcpy (&addr.sin_addr, lphost->h_addr, lphost->h_length); + #endif + + } + + else + { + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = IP; + } + + /* Port destination */ + + addr.sin_port = htons((u_short)Port ); + + memcpy( (char *)&addrRet, (char *)&addr, sizeof(addrRet) ); + + return addrRet; +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockSendShortMsg ( SInt32 ContextId, UInt8* PtMsg, UInt32 MsgSz ) { + + IAC__TSockSenderPort* VPtSocket; + SInt16 ViTry; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + + /* ------------ */ + /* Check status */ + /* ------------ */ + + if ( VPtSocket->Started != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access [%d] not started => Can't send message", VPtSocket->Id ) ); + } + + /* --------------- */ + /* Check port mode */ + /* --------------- */ + + if ( VPtSocket->ParLongMsg == 1 ) { + err_retfail ( -1, (ERR_OUT,"This port doesn't support short message ! ParLongMsg=%d", VPtSocket->ParLongMsg ) ); + } + + + /* ---------------------------- */ + /* Check message pointer & size */ + /* ---------------------------- */ + + err_retnull ( PtMsg, (ERR_OUT,"PtMsg == NULL !") ); + + /* Only for first version of text header => "SZ=" + + if ( ( MsgSz + IAC__SOCK_HEADER_TOT_SZ ) > IAC__SO_MAX_SHORT_MSG_SIZE ) { + err_retfail ( -1, (ERR_OUT,"Message too long size=%d + IAC__SOCK_HEADER_TOT_SZ=%d > IAC__SO_MAX_SHORT_MSG_SIZE=%d", MsgSz, IAC__SOCK_HEADER_TOT_SZ, IAC__SO_MAX_SHORT_MSG_SIZE )); + } + + */ + + if ( ( MsgSz + (VPtSocket->CstHeaderSz) + (VPtSocket->CstTrailerSz) ) > IAC__SO_MAX_SHORT_MSG_SIZE ) { + err_retfail ( -1, (ERR_OUT,"Message too long size + (Header & Trailer) =%d > IAC__SO_MAX_SHORT_MSG_SIZE=%d", MsgSz + (VPtSocket->CstHeaderSz) + (VPtSocket->CstTrailerSz), IAC__SO_MAX_SHORT_MSG_SIZE )); + } + + + VPtSocket->ParPtMsg = PtMsg; + VPtSocket->ParMsgSz = MsgSz; + + /* ------------------------------------ */ + /* Try to send message ParRetryNb times */ + /* ------------------------------------ */ + + for ( ViTry=0; ViTry < VPtSocket->ParRetryNb; ViTry++ ) { + + /* --------------- */ + /* Reset Status */ + /* --------------- */ + + VPtSocket->SendStatus = -1; + + /* -------------------- */ + /* Send event to thread */ + /* -------------------- */ + + if ( PulseEvent ( VPtSocket->EvNewMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Event EvNewMsgHnd sent" )); + } + + /* ------------------ */ + /* Wait thread answer */ + /* ------------------ */ + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"Ack event not installed !" ) ); + + // Time out => Retry + + if ( WaitForSingleObject ( VPtSocket->EvAckMsgHnd, VPtSocket->ParAckTimeOutMs ) == WAIT_TIMEOUT ) { + err_error (( ERR_OUT, "No Ack => Exit on time out !! ViTry=%d - Msg : %s", ViTry, PtMsg )); + continue; + } + + // Error => Retry + + if ( VPtSocket->SendStatus <= 0 ) { + err_error (( ERR_OUT, "Send error - ViTry=%d - Msg : %s", ViTry, PtMsg )); + continue; + } + + // OK message sent, Ack received => break loop + + err_trace (( ERR_OUT, "Ack received" )); + break; + + + } /* End for */ + + return (VPtSocket->SendStatus); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockSendLongMsg ( SInt32 ContextId, UInt8* PtMsg, UInt32 MsgSz ) { + + IAC__TSockSenderPort* VPtSocket; + SInt16 ViTry; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + + /* ------------ */ + /* Check status */ + /* ------------ */ + + if ( VPtSocket->Started != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access [%d] not started => Can't send message", VPtSocket->Id ) ); + } + + /* --------------- */ + /* Check port mode */ + /* --------------- */ + + if ( VPtSocket->ParLongMsg == 0 ) { + err_retfail ( -1, (ERR_OUT,"This port doesn't support long message ! ParLongMsg=%d", VPtSocket->ParLongMsg ) ); + } + + /* ---------------------------- */ + /* Check message pointer & size */ + /* ---------------------------- */ + + err_retnull ( PtMsg, (ERR_OUT,"PtMsg == NULL !") ); + + if ( VPtSocket->ParMsgSz > IAC__SOCK_MAX_LONG_MSG_SZ ) { + err_retfail ( -1, (ERR_OUT,"Message too long size=%d > IAC__SOCK_MAX_LONG_MSG_SZ=%d", MsgSz, IAC__SOCK_MAX_LONG_MSG_SZ )); + } + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + VPtSocket->ParPtMsg = PtMsg; + VPtSocket->ParMsgSz = MsgSz; + + err_trace (( ERR_OUT, "LongMsgSz = %d", VPtSocket->ParMsgSz )); + + /* ------------------------------------ */ + /* Try to send message ParRetryNb times */ + /* ------------------------------------ */ + + for ( ViTry=0; ViTry < VPtSocket->ParRetryNb; ViTry++ ) { + + /* --------------- */ + /* Reset Status */ + /* --------------- */ + + VPtSocket->SendStatus = -1; + + /* -------------------- */ + /* Send event to thread */ + /* -------------------- */ + + if ( PulseEvent ( VPtSocket->EvNewMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Event EvNewMsgHnd sent" )); + } + + /* ------------------ */ + /* Wait thread answer */ + /* ------------------ */ + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"Ack event not installed !" ) ); + + // Time out => Retry + + if ( WaitForSingleObject ( VPtSocket->EvAckMsgHnd, VPtSocket->ParAckTimeOutMs ) == WAIT_TIMEOUT ) { + err_error (( ERR_OUT, "No Ack => Exit on time out !! ViTry=%d - Msg : %s", ViTry, PtMsg )); + continue; + } + + // Error => Retry + + if ( VPtSocket->SendStatus <= 0 ) { + err_error (( ERR_OUT, "Send error - ViTry=%d - Msg : %s", ViTry, PtMsg )); + continue; + } + + // OK message sent, Ack received => break loop + + err_trace (( ERR_OUT, "Ack received" )); + break; + + } /* End for */ + + + + return (VPtSocket->SendStatus); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 IAC__PRIV_FSockInit ( ) { + + WSADATA VStackInf; + + // Initialize winsock + + WSAStartup( MAKEWORD(2,0), &VStackInf ) ; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockGetSenderPortContext () { + + SInt32 Vi; + SInt32 VPortContextId; + + VPortContextId = -1; + + // Search a free port context record + + for ( Vi=0; Vi < IAC__SOCK_MAX_SENDER_PORT_NB; Vi++ ) { + + if ( IAC__VGContext.Sock.ASenderPort[Vi].Used == 0 ) { + IAC__VGContext.Sock.ASenderPort[Vi].Used = 1; + VPortContextId = Vi; + ++IAC__VGContext.Sock.SenderPortNb; + break; + } + + } + + // None found + + err_retfail ( VPortContextId, (ERR_OUT,"No free rec port context found => %d used", IAC__VGContext.Sock.SenderPortNb ) ); + + // Found + + err_retval ( VPortContextId, ( ERR_OUT, "Get reception port context Id=%d", VPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockGetReceiverPortContext () { + + SInt32 Vi; + SInt32 VPortContextId; + + VPortContextId = -1; + + // Search a free port context record + + for ( Vi=0; Vi < IAC__SOCK_MAX_REC_PORT_NB; Vi++ ) { + + if ( IAC__VGContext.Sock.AReceiverPort[Vi].Used == 0 ) { + IAC__VGContext.Sock.AReceiverPort[Vi].Used = 1; + VPortContextId = Vi; + ++IAC__VGContext.Sock.ReceiverPortNb; + break; + } + + } + + // None found + + err_retfail ( VPortContextId, (ERR_OUT,"No free rec port context found => %d used", IAC__VGContext.Sock.ReceiverPortNb ) ); + + // Found + + err_retval ( VPortContextId, ( ERR_OUT, "Get reception port context Id=%d", VPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockFreeSenderPortContext ( SInt32 ContextId ) { + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + /* -------- */ + /* Free */ + /* -------- */ + + IAC__VGContext.Sock.ASenderPort[ContextId].Used = 0; + + if ( IAC__VGContext.Sock.SenderPortNb > 0 ) { + --IAC__VGContext.Sock.SenderPortNb; + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockFreeReceiverPortContext ( SInt32 ContextId ) { + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + /* -------- */ + /* Free */ + /* -------- */ + + IAC__VGContext.Sock.AReceiverPort[ContextId].Used = 0; + + if ( IAC__VGContext.Sock.ReceiverPortNb > 0 ) { + --IAC__VGContext.Sock.ReceiverPortNb; + } + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FChkSenderContextId ( SInt32 ContextId ) { + + if ( (ContextId < 0) || (ContextId >= IAC__SOCK_MAX_SENDER_PORT_NB) ) { + err_retfail ( -1, (ERR_OUT,"Context Id=%d out of range[0..%d] !)", ContextId, IAC__SOCK_MAX_SENDER_PORT_NB-1) ); + } + + if ( IAC__VGContext.Sock.ASenderPort[ContextId].Used == 0 ) { + err_retfail ( -1, (ERR_OUT,"Context record Id=%d IS NOT used !", ContextId ) ); + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FChkReceiverContextId ( SInt32 ContextId ) { + + if ( (ContextId < 0) || (ContextId >= IAC__SOCK_MAX_REC_PORT_NB) ) { + err_retfail ( -1, (ERR_OUT,"Context Id=%d out of range[0..%d] !)", ContextId, IAC__SOCK_MAX_REC_PORT_NB-1) ); + } + + if ( IAC__VGContext.Sock.AReceiverPort[ContextId].Used == 0 ) { + err_retfail ( -1, (ERR_OUT,"Context record Id=%d IS NOT used !", ContextId ) ); + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 OLD___IAC__PRIV_FSockSendShortMsg ( SInt32 ContextId ) { + + SInt32 VRet; + IAC__TSockSenderPort* VPtSock; + UInt32 VTmpTotSz; + UInt32 VTotMsgSz; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + + + + VRet = -1; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + + // Build message + + VTotMsgSz = VPtSock->ParMsgSz + IAC__SOCK_HEADER_TOT_SZ; + + memcpy ( VPtSock->PtBuffSendShortMsg, IAC__SOCK_HEADER_STR , IAC__SOCK_HEADER_STR_SZ - 1 ); // Copy string + VPtSock->PtBuffSendShortMsg[IAC__SOCK_HEADER_STR_SZ] = 0; // Set 0 at end of string + memcpy ( &(VPtSock->PtBuffSendShortMsg[IAC__SOCK_HEADER_STR_SZ+1]), &VTotMsgSz, 4 ); // Copy TOTAL message size (W32) + memcpy ( &(VPtSock->PtBuffSendShortMsg[IAC__SOCK_HEADER_TOT_SZ]) , VPtSock->ParPtMsg, VPtSock->ParMsgSz ); // Copy user message + + memcpy ( &VTmpTotSz, &(VPtSock->PtBuffSendShortMsg[IAC__SOCK_HEADER_STR_SZ+1]), 4 ); + + err_trace (( ERR_OUT, "IAC__SOCK_HEADER_STR_SZ+1 = %d", IAC__SOCK_HEADER_STR_SZ+1 )); + err_trace (( ERR_OUT, "IAC__SOCK_HEADER_TOT_SZ = %d", IAC__SOCK_HEADER_TOT_SZ )); + err_trace (( ERR_OUT, "VTotMsgSz = %d", VTotMsgSz )); + err_trace (( ERR_OUT, "Message header = %s", VPtSock->PtBuffSendShortMsg )); + err_trace (( ERR_OUT, "- Message size = %d", VTmpTotSz )); + err_trace (( ERR_OUT, "Message = %s", &(VPtSock->PtBuffSendShortMsg[IAC__SOCK_HEADER_TOT_SZ]) )); + + + // Send message + + VSzSent = send ( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VTotMsgSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Message of %d Bytes sent", VSzSent )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + VRet = -1; + err_error (( ERR_OUT, "Ack reception error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VW32ServerAns = *((UInt32*) VPtSock->BuffRecAck); + + // Check Ack + + if ( VW32ServerAns != VTotMsgSz ) { + VRet = -1; + err_error (( ERR_OUT, "Server ack bad size %d - should be %d", VW32ServerAns, VTotMsgSz )); + } + + // OK : Message sent and Ack received + + VRet = VTotMsgSz; + + return (VRet); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header, add trailer + : 14/01/2009 + : - Detect lost of connection and try to reconnect by rebooting the sender + : with a IAC__FSockRebootSenderPort call. + : The goal is to allow receiver application to be stopped and restarted without + : broking permanently the communication channel, but not to recover all kind of errors. + : + Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockSendShortMsg ( SInt32 ContextId ) { + + SInt32 VRet; + IAC__TSockSenderPort* VPtSock; + UInt32 VTmpTotSz; + UInt32 VTotMsgSz; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + SInt32 VSockErrNo; + + + VRet = -1; + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + // Calculate message size + + VTotMsgSz = VPtSock->CstHeaderSz + VPtSock->ParMsgSz + VPtSock->CstTrailerSz; + + // Set size & CS in header + + VPtSock->MsgHeader.TotMsgSz = VTotMsgSz; + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VPtSock->MsgHeader.CheckSum = VPtSock->ParFuncCheckSum ( VPtSock->ParPtMsg, VPtSock->ParMsgSz ); + } + + else { + VPtSock->MsgHeader.CheckSum = 0; + } + + + + // Build messages + + memcpy ( VPtSock->PtBuffSendShortMsg , &(VPtSock->MsgHeader) , VPtSock->CstHeaderSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VPtSock->CstHeaderSz]) , VPtSock->ParPtMsg , VPtSock->ParMsgSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VTotMsgSz-(VPtSock->CstTrailerSz)]), &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz ); + + err_trace (( ERR_OUT, "Header.StartTag = %x [H]", VPtSock->MsgHeader.StartTag )); + err_trace (( ERR_OUT, "Header.TotSz = %d ", VPtSock->MsgHeader.TotMsgSz )); + err_trace (( ERR_OUT, "Header.CheckSum = %d ", VPtSock->MsgHeader.CheckSum )); + err_trace (( ERR_OUT, "Trailer.StopTag = %x [H]", VPtSock->MsgTrailer.StopTag )); + + // Send message + + VSzSent = send ( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VTotMsgSz, 0 ); + + /* BEFORE 14/01/09 + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + */ + + + + if ( VSzSent == SOCKET_ERROR ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + // If connection reset => Try to connect and resend block + + if ( VSockErrNo == WSAECONNRESET ) { + + IAC__FSockRebootSenderPort ( ContextId ); + + // Try again to send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VTotMsgSz, 0 ); + + // Abort on send error + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + // Others error => Abort + + else { + err_retfail ( -1, (ERR_OUT,"send () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + + + err_trace (( ERR_OUT, "Message of %d Bytes sent", VSzSent )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + VRet = -1; + err_error (( ERR_OUT, "Ack reception error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VW32ServerAns = *((UInt32*) VPtSock->BuffRecAck); + + // Check Ack + + if ( VW32ServerAns != VTotMsgSz ) { + VRet = -1; + err_error (( ERR_OUT, "Server ack bad size %d - should be %d", VW32ServerAns, VTotMsgSz )); + } + + // OK : Message sent and Ack received + + VRet = VTotMsgSz; + + return (VRet); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 OLD___IAC__PRIV_FSockSendLongMsg ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSock; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + + UInt32 VTmpTotSz; + + UInt32 VHeaderBlockDataSz; + UInt32 VHeaderBlockTotSz; + UInt32 VDataBlocksTotSz; + UInt32 VDataBlockSz; + UInt32 VLastBlockSz; + SInt32 VBlockNb; // Excluding first one and last one + SInt32 ViBlock; + SInt32 VPosNextBlockInSrcBuff; + SInt32 VTotSzSent; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + // Evaluate blocks size + + + err_trace (( ERR_OUT, "ContextId=%d - ParMsgSz=%d", ContextId, VPtSock->ParMsgSz )); + + VTotSzSent = 0; + + // Evaluate blocks size + + if ( VPtSock->ParMsgSz <= (IAC__SO_MAX_SHORT_MSG_SIZE - IAC__SOCK_HEADER_TOT_SZ) ) { + VHeaderBlockDataSz = VPtSock->ParMsgSz; + VHeaderBlockTotSz = VHeaderBlockDataSz + IAC__SOCK_HEADER_TOT_SZ; + VDataBlocksTotSz = 0; + VDataBlockSz = 0; + VBlockNb = 0; + VLastBlockSz = 0; // 0 => no icomplete block at the end + } + + else { + VHeaderBlockDataSz = IAC__SO_MAX_SHORT_MSG_SIZE - IAC__SOCK_HEADER_TOT_SZ; + VHeaderBlockTotSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VDataBlocksTotSz = VPtSock->ParMsgSz - VHeaderBlockDataSz; + VDataBlockSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VBlockNb = VDataBlocksTotSz / VDataBlockSz; + VLastBlockSz = VDataBlocksTotSz % VDataBlockSz; // 0 => no icomplete block at the end + } + + // Debug print + + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + err_trace (( ERR_OUT, "VHeaderBlockDataSz = %d", VHeaderBlockDataSz )); + err_trace (( ERR_OUT, "VHeaderBlockTotSz = %d", VHeaderBlockTotSz )); + err_trace (( ERR_OUT, "VDataBlocksTotSz = %d", VDataBlocksTotSz )); + err_trace (( ERR_OUT, "VDataBlockSz = %d", VDataBlockSz )); + err_trace (( ERR_OUT, "VBlockNb = %d", VBlockNb )); + err_trace (( ERR_OUT, "VLastBlockSz = %d", VLastBlockSz )); + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + + + // Build header block + + memcpy ( VPtSock->PtBuffSendShortMsg, IAC__SOCK_HEADER_STR , IAC__SOCK_HEADER_STR_SZ - 1 ); // Copy header string + VPtSock->PtBuffSendShortMsg[IAC__SOCK_HEADER_STR_SZ] = 0; // Set 0 at end of string + memcpy ( &(VPtSock->PtBuffSendShortMsg[IAC__SOCK_HEADER_STR_SZ+1]), &(VPtSock->ParMsgSz), 4 ); // Copy TOTAL message size (W32) + memcpy ( &(VPtSock->PtBuffSendShortMsg[IAC__SOCK_HEADER_TOT_SZ]) , VPtSock->ParPtMsg, VHeaderBlockDataSz ); // Copy message + + VPosNextBlockInSrcBuff = VHeaderBlockDataSz; + + err_trace (( ERR_OUT, "Message size written in header=%d", VPtSock->ParMsgSz )); + + // Send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + else { + err_trace (( ERR_OUT, "Header block of %d Bytes sent", VSzSent )); + } + + VTotSzSent += VSzSent; + + // Send complete blocks + + for ( ViBlock=0; ViBlock < VBlockNb; ViBlock++) { + + VSzSent = send( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VDataBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Block[%d] => %s", IAC__SOCKET_ERRNO, ViBlock, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Send block[%d] of %d bytes OK :-)", ViBlock, VSzSent )); + + VPosNextBlockInSrcBuff += VDataBlockSz; + VTotSzSent += VSzSent; + + err_trace (( ERR_OUT, "Block[%d] of %d Bytes sent", ViBlock, VSzSent )); + + } + + // Send last block + + if ( VLastBlockSz > 0 ) { + VSzSent = send( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VLastBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Last block => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + err_trace (( ERR_OUT, "Before wainting for host ACK" )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Ack receive error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VW32ServerAns = *((UInt32*) (VPtSock->BuffRecAck) ); + + // Check Ack + + if ( VW32ServerAns != VTotSzSent ) { + err_retfail ( -1, (ERR_OUT,"Server ack bad size %d - should be %d", VW32ServerAns, VTotSzSent )); + } + + err_trace (( ERR_OUT, "Message sent and Ack received" )); + + // OK : Message sent and Ack received + + return (VTotSzSent); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header & trailer + : 14/01/2009 + : - Detect lost of connection and try to reconnect by rebooting the sender + : with a IAC__FSockRebootSenderPort call. + : The lost of connection test is only done at the beginning of a message ( on first + : block send ), if it occurs the middle, therefore message sending is aborted. + : This works like this because the goal is to allow receiver application to be + : stopped and restarted without broking permanently the communication channel, but + : not to recover all kind of errors. + : + : +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockSendLongMsg ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSock; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + + // UInt32 VTmpTotSz; + UInt32 VTotMsgSz; // Including header and trailer + + UInt32 VHeaderBlockDataSz; + UInt32 VHeaderBlockTotSz; + UInt32 VDataBlocksTotSz; + UInt32 VDataBlockSz; + UInt32 VLastBlockSz; + SInt32 VBlockNb; // Excluding first one and last one + SInt32 ViBlock; + SInt32 VPosNextBlockInSrcBuff; + SInt32 VTotSzSent; + SInt8 VMsgSingleBlock; + SInt32 VSockErrNo; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + // Evaluate blocks size + + + err_trace (( ERR_OUT, "ContextId=%d - ParMsgSz=%d", ContextId, VPtSock->ParMsgSz )); + + VTotSzSent = 0; + + // Evaluate blocks size + + // In case of single block message, header and trailer are added to message + + if ( VPtSock->ParMsgSz <= (IAC__SO_MAX_SHORT_MSG_SIZE - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz)) ) { + VMsgSingleBlock = 1; + VHeaderBlockDataSz = VPtSock->ParMsgSz; + VHeaderBlockTotSz = VHeaderBlockDataSz + (VPtSock->CstHeaderSz) + (VPtSock->CstTrailerSz); + VDataBlocksTotSz = 0; + VDataBlockSz = 0; + VBlockNb = 0; + VLastBlockSz = 0; // 0 => no icomplete block at the end + } + + // In case of multi block message, trailer is sent at the end by a specific call to send (...) + // Therefore trailer size must not be taken into account for blocks size and number calculation + + else { + VMsgSingleBlock = 0; + VHeaderBlockDataSz = IAC__SO_MAX_SHORT_MSG_SIZE - (VPtSock->CstHeaderSz); + VHeaderBlockTotSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VDataBlocksTotSz = VPtSock->ParMsgSz - VHeaderBlockDataSz; + VDataBlockSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VBlockNb = VDataBlocksTotSz / VDataBlockSz; + VLastBlockSz = VDataBlocksTotSz % VDataBlockSz; // 0 => no icomplete block at the end + } + + // Calculate message size + + VTotMsgSz = VPtSock->CstHeaderSz + VPtSock->ParMsgSz + VPtSock->CstTrailerSz; + + // Set size & CS in header + + VPtSock->MsgHeader.TotMsgSz = VTotMsgSz; + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VPtSock->MsgHeader.CheckSum = VPtSock->ParFuncCheckSum ( VPtSock->ParPtMsg, VPtSock->ParMsgSz ); + } + + else { + VPtSock->MsgHeader.CheckSum = 0; + } + + // Debug print + + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + err_trace (( ERR_OUT, "User message size = %d", VPtSock->ParMsgSz )); + err_trace (( ERR_OUT, "Total message size = %d", VTotMsgSz )); + err_trace (( ERR_OUT, "VHeaderBlockDataSz = %d", VHeaderBlockDataSz )); + err_trace (( ERR_OUT, "VHeaderBlockTotSz = %d", VHeaderBlockTotSz )); + err_trace (( ERR_OUT, "VDataBlocksTotSz = %d", VDataBlocksTotSz )); + err_trace (( ERR_OUT, "VDataBlockSz = %d", VDataBlockSz )); + err_trace (( ERR_OUT, "VBlockNb = %d", VBlockNb )); + err_trace (( ERR_OUT, "VLastBlockSz = %d", VLastBlockSz )); + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + + // Build header block + + memcpy ( VPtSock->PtBuffSendShortMsg , &(VPtSock->MsgHeader) , VPtSock->CstHeaderSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VPtSock->CstHeaderSz]) , VPtSock->ParPtMsg , VHeaderBlockDataSz ); + + // Copy trailer ONLY for single block message + + if ( VMsgSingleBlock == 1 ) { + memcpy ( &(VPtSock->PtBuffSendShortMsg[VTotMsgSz-(VPtSock->CstTrailerSz)]), &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz ); + } + + VPosNextBlockInSrcBuff = VHeaderBlockDataSz; + + // Send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + // If connection reset => Try to connect and resend block + + if ( VSockErrNo == WSAECONNRESET ) { + + IAC__FSockRebootSenderPort ( ContextId ); + + // Try again to send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + // Abort on send error + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + // Others error => Abort + + else { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + else { + err_trace (( ERR_OUT, "Header block of %d Bytes sent", VSzSent )); + } + + VTotSzSent += VSzSent; + + // Send complete blocks + + for ( ViBlock=0; ViBlock < VBlockNb; ViBlock++) { + + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VDataBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Block[%d] => %s", IAC__SOCKET_ERRNO, ViBlock, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Send block[%d] of %d bytes OK :-)", ViBlock, VSzSent )); + + VPosNextBlockInSrcBuff += VDataBlockSz; + VTotSzSent += VSzSent; + + err_trace (( ERR_OUT, "Block[%d] of %d Bytes sent", ViBlock, VSzSent )); + + } + + // Send last block + + if ( VLastBlockSz > 0 ) { + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VLastBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Last block => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + // Send trailer ONLY for multiple blocks message + + if ( VMsgSingleBlock == 0 ) { + VSzSent = send( VPtSock->Socket, (UInt8*) &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Trailer => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + err_trace (( ERR_OUT, "Before waiting for host ACK" )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Ack receive error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VW32ServerAns = *((UInt32*) (VPtSock->BuffRecAck) ); + + // Check Ack + + if ( VW32ServerAns != VTotSzSent ) { + err_retfail ( -1, (ERR_OUT,"Server ack bad size %d - should be %d", VW32ServerAns, VTotSzSent )); + } + + err_trace (( ERR_OUT, "Message sent and Ack received" )); + + // OK : Message sent and Ack received + + return (VTotSzSent); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 11/11/2008 + : - New header & trailer +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockInstallSenderPort ( char* DestHost, UInt32 DestPort, SInt8 LongMsg, UInt32 AckTimeOutMs, UInt8 RetryNb, IAC__TFSockFuncCheckSum FuncCheckSum ) { + + SInt32 VSenderPortContextId; + IAC__TSockSenderPort* VPtSocket; + + /* --------------------------------- */ + /* Find a free sender context record */ + /* --------------------------------- */ + + VSenderPortContextId = IAC__PRIV_FSockGetSenderPortContext (); + + err_retfail ( VSenderPortContextId, (ERR_OUT,"No free context record !") ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[VSenderPortContextId]); + VPtSocket->Id = VSenderPortContextId; + + /* --------------------- */ + /* Init constants fields */ + /* --------------------- */ + + VPtSocket->CstHeaderSz = sizeof (IAC__TSockMsgHeader ); + VPtSocket->CstTrailerSz = sizeof (IAC__TSockMsgTrailer); + + VPtSocket->MsgHeader.StartTag = IAC__SOCK_HEADER_START_TAG; + VPtSocket->MsgHeader.Zero = 0; + VPtSocket->MsgHeader.TotMsgSz = 0; // Unknown at this step + VPtSocket->MsgHeader.CheckSum = 0; // Unknown at this step + + VPtSocket->MsgTrailer.StopTag = IAC__SOCK_TRAILER_STOP_TAG; + VPtSocket->MsgTrailer.Zero = 0; + + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + strncpy ( VPtSocket->ParDestHost, DestHost, IAC__SOCK_MAX_STR_HOST_SZ - 1 ); + VPtSocket->ParDestPort = DestPort; + VPtSocket->ParLongMsg = LongMsg; + VPtSocket->ParAckTimeOutMs = AckTimeOutMs; + VPtSocket->ParRetryNb = RetryNb; + VPtSocket->ParPtMsg = NULL; + VPtSocket->ParFuncCheckSum = FuncCheckSum; + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->Socket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->Socket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short)0 ); + + if ( bind( VPtSocket->Socket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Transform the host/port into a struct sockaddr + + VPtSocket->DestAddr = IAC__PRIV_FTcpFormatAdress ( VPtSocket->ParDestHost, (u_short) (VPtSocket->ParDestPort) ); + + /* -------------- */ + /* Create events */ + /* -------------- */ + + VPtSocket->EvNewMsgHnd = CreateEvent ( + NULL /* LPSECURITY_ATTRIBUTES */, + FALSE /* Manual Reset */, + FALSE /* Initial State */, + NULL /* Name STring */ ); + + err_retnull ( VPtSocket->EvNewMsgHnd, (ERR_OUT,"CreateEvent EvNewMsgHnd failed ! - LastError=%d", GetLastError ()) ); + + VPtSocket->EvAckMsgHnd = CreateEvent ( + NULL /* LPSECURITY_ATTRIBUTES */, + FALSE /* Manual Reset */, + FALSE /* Initial State */, + NULL /* Name STring */ ); + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"CreateEvent EvAckMsgHnd failed ! - LastError=%d", GetLastError ()) ); + + + /* ------------- */ + /* Alloc buffers */ + /* ------------- */ + + VPtSocket->PtBuffSendShortMsg = (UInt8*) malloc ( IAC__SO_MAX_SHORT_MSG_SIZE ); + + err_retnull ( VPtSocket->PtBuffSendShortMsg, (ERR_OUT,"Allocation sender buffer of %d bytes failed !", IAC__SO_MAX_SHORT_MSG_SIZE) ); + + /* ------------- */ + /* Create thread */ + /* ------------- */ + + // It will be done in IAC__FSockStartSenderPort () + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSocket->Installed = 1; + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] installed", VPtSocket->Id )); + err_trace (( ERR_OUT, "Dest host = %s", VPtSocket->ParDestHost )); + err_trace (( ERR_OUT, "Dest port = %d", VPtSocket->ParDestPort )); + err_trace (( ERR_OUT, "Ack TO = %d", VPtSocket->ParAckTimeOutMs )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( VSenderPortContextId, ( ERR_OUT, "Emission port=%d installed - uses context record=%d", VPtSocket->ParDestPort, VSenderPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 14/01/2009 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockRebootSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSocket; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + /* ------------ */ + /* Check status */ + /* ------------ * + + if ( VPtSocket->Installed != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access not installed => Can't be started" ) ); + } + + + /* ------------ */ + /* Reset status */ + /* ------------ */ + + VPtSocket->Started = 0; + + + /* ------------ */ + /* Close Socket */ + /* ------------ */ + + closesocket ( VPtSocket->Socket ); + + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->Socket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->Socket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short)0 ); + + if ( bind( VPtSocket->Socket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Transform the host/port into a struct sockaddr + + VPtSocket->DestAddr = IAC__PRIV_FTcpFormatAdress ( VPtSocket->ParDestHost, (u_short) (VPtSocket->ParDestPort) ); + + // Connect + + while ( connect( VPtSocket->Socket, &(VPtSocket->DestAddr), sizeof(VPtSocket->DestAddr) ) == SOCKET_ERROR ) { + err_error (( ERR_OUT, "Connect () error %d => %s WILL RETRY in 100 ms", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + Sleep ( 100 ); + } + + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Started = 1; + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] started", VPtSocket->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 13/01/2009 + : - Add closesocket call +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockUnInstallSenderPort ( SInt32 SenderPortContextId ) { + + IAC__TSockSenderPort* VPtSocket; + + err_retfail ( IAC__PRIV_FChkSenderContextId (SenderPortContextId), (ERR_OUT,"Bad Id=%d", SenderPortContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[SenderPortContextId]); + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSocket->Installed = 0; + + /* ------------- */ + /* Close events */ + /* ------------- */ + + if ( CloseHandle ( VPtSocket->EvNewMsgHnd ) == 0 ) { + err_error (( ERR_OUT, "CloseHandle ( VPtSocket->EvNewMsgHnd ) failed !" )); + } + + if ( CloseHandle ( VPtSocket->EvAckMsgHnd ) == 0 ) { + err_error (( ERR_OUT, "CloseHandle ( VPtSocket->EvAckMsgHnd ) failed !" )); + } + + /* ------------ */ + /* Close Socket */ + /* ------------ */ + + closesocket ( VPtSocket->Socket ); + + /* ------------ */ + /* Free buffers */ + /* ------------ */ + + if ( VPtSocket->PtBuffSendShortMsg != NULL ) { + free ( VPtSocket->PtBuffSendShortMsg ); + } + + else { + err_error (( ERR_OUT, "Try to free PtBuffSendShortMsg, but it's already NULL => ???" )); + } + + + /* --------------- */ + /* Release context */ + /* --------------- */ + + IAC__PRIV_FSockFreeSenderPortContext ( SenderPortContextId ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStartSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSocket; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + /* ------------ */ + /* Check status */ + /* ------------ * + + if ( VPtSocket->Installed != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access not installed => Can't be started" ) ); + } + + /* --------------------- */ + /* Create & Start thread */ + /* --------------------- */ + + VPtSocket->ThreadHnd = CreateThread( NULL, NULL, IAC__PRIV_FSockSenderThreadFunc, (LPVOID) VPtSocket, NULL, &(VPtSocket->ThreadId) ); + + err_retnull ( VPtSocket->ThreadHnd, (ERR_OUT,"Thread creation failed !") ); + + VPtSocket->ThreadFunc = IAC__PRIV_FSockSenderThreadFunc; + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Started = 1; + + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] started", VPtSocket->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStopSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread handle == NULL !") ); + + /* ---------------- */ + /* Terminate thread */ + /* ---------------- */ + + TerminateThread ( VPtSock->ThreadHnd, -1 /* Thread exit code */ ); + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 0; + + err_trace (( ERR_OUT, "TerminateThread sent - with exit code = -1" )); + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%] terminated", VPtSock->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Rev : 06/11/2008 + : - Add LongMsg Handling + : 10/11/2008 + : - Rewritten => No socket close after each message + : 11/11/2008 + : - New header & trailer +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockInstallReceiverPort ( UInt32 RecPort, SInt8 LongMsg, IAC__TFSockUsrHandleRecMsg FuncUsr, IAC__TFSockFuncCheckSum FuncCheckSum ) { + + SInt32 VRecPortContextId; + IAC__TSockReceiverPort* VPtSocket; + UInt8* VPtRecBuffer; + + /* --------------------------------- */ + /* Find a free sender context record */ + /* --------------------------------- */ + + VRecPortContextId = IAC__PRIV_FSockGetReceiverPortContext (); + + err_retfail ( VRecPortContextId, (ERR_OUT,"No free context record !") ); + + VPtSocket = &(IAC__VGContext.Sock.AReceiverPort[VRecPortContextId]); + VPtSocket->Id = VRecPortContextId; + + /* --------------------- */ + /* Init constants fields */ + /* --------------------- */ + + VPtSocket->CstHeaderSz = sizeof (IAC__TSockMsgHeader ); + VPtSocket->CstTrailerSz = sizeof (IAC__TSockMsgTrailer); + + VPtSocket->MsgHeader.StartTag = IAC__SOCK_HEADER_START_TAG; + VPtSocket->MsgHeader.Zero = 0; + VPtSocket->MsgHeader.TotMsgSz = 0; // Unknown at this step + VPtSocket->MsgHeader.CheckSum = 0; // Unknown at this step + + VPtSocket->MsgTrailer.StopTag = IAC__SOCK_TRAILER_STOP_TAG; + VPtSocket->MsgTrailer.Zero = 0; + + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + + VPtSocket->Id = VRecPortContextId; + VPtSocket->ParLongMsg = LongMsg; + VPtSocket->ParPort = RecPort; + VPtSocket->ParUsrFunc = FuncUsr; + VPtSocket->ParFuncCheckSum = FuncCheckSum; + + + /* ------------------------- */ + /* Allocate reception buffer */ + /* ------------------------- */ + + + if ( VPtSocket->ParLongMsg == 0 ) { + VPtSocket->MaxMsgSz = IAC__SO_MAX_SHORT_MSG_SIZE * 2; + } + + else { + VPtSocket->MaxMsgSz = IAC__SOCK_MAX_LONG_MSG_SZ; + } + + VPtRecBuffer = (UInt8*) malloc ( VPtSocket->MaxMsgSz ); + + err_retnull ( VPtRecBuffer, (ERR_OUT,"Malloc of %d bytes for rec buffer failed !", VPtSocket->MaxMsgSz) ); + + err_trace (( ERR_OUT, "Malloc of %d bytes for Receiver port[%d]", VPtSocket->MaxMsgSz, VRecPortContextId )); + + VPtSocket->PtMsg = VPtRecBuffer; + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->LSocket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->LSocket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short) VPtSocket->ParPort ); + + if ( bind( VPtSocket->LSocket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Installed = 1; + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Receiver port [%d] installed", VPtSocket->Id )); + err_trace (( ERR_OUT, "Port = %d", VPtSocket->ParPort )); + err_trace (( ERR_OUT, "Long msg = %d", VPtSocket->ParLongMsg )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( VRecPortContextId, ( ERR_OUT, "Reception port=%d installed - uses context record=%d", RecPort, VRecPortContextId ) ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 13/01/2009 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockRebootReceiverPort ( SInt32 ContextId ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ------------ */ + /* Reset status */ + /* ------------ */ + + VPtSock->Installed = 0; + + /* ------------- */ + /* Close ASocket */ + /* ------------- */ + + closesocket ( VPtSock->ASocket ); + + /* ------------- */ + /* Close LSocket */ + /* ------------- */ + + closesocket ( VPtSock->LSocket ); + + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSock->LSocket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSock->LSocket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Bind + + VPtSock->LocAddr.sin_family = AF_INET ; + VPtSock->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSock->LocAddr.sin_port = htons ((unsigned short) VPtSock->ParPort ); + + if ( bind( VPtSock->LSocket, (struct sockaddr *)&(VPtSock->LocAddr), sizeof(VPtSock->LocAddr)) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Installed = 1; + + + /* ---------------------- */ + /* Wait client connection */ + /* ---------------------- */ + + // Listen + + err_trace (( ERR_OUT, "Before listen" )); + + if ( listen( VPtSock->LSocket, 2) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"listen () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Before accept" )); + + // Accept + + VPtSock->ASocket = accept ( VPtSock->LSocket, NULL, NULL ); + + if( VPtSock->ASocket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"accept () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Reboot of Receiver port [%d] done", VPtSock->Id )); + err_trace (( ERR_OUT, "Port = %d", VPtSock->ParPort )); + err_trace (( ERR_OUT, "Long msg = %d", VPtSock->ParLongMsg )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( ContextId, ( ERR_OUT, "Reception port Id=%d reboot", ContextId ) ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockUnInstallReceiverPort ( SInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (RecPortContextId), (ERR_OUT,"Bad Id=%d", RecPortContextId ) ); + VPtSock = &IAC__VGContext.Sock.AReceiverPort[RecPortContextId ]; + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSock->Installed = 0; + VPtSock->Started = 0; + + /* ------------- */ + /* Close LSocket */ + /* ------------- */ + + closesocket ( VPtSock->LSocket ); + + /* ------------- */ + /* Free buffer */ + /* ------------- */ + + if ( VPtSock->PtMsg != NULL ) { + free ( VPtSock->PtMsg ); + } + + VPtSock->MaxMsgSz = 0; + + IAC__PRIV_FSockFreeReceiverPortContext ( RecPortContextId ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStartReceiverPort ( SInt32 ContextId ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* --------------------- */ + /* Start thread function */ + /* --------------------- */ + + err_trace (( ERR_OUT, "Call CreateThread (...)" )); + + VPtSock->ThreadHnd = CreateThread( NULL, NULL, IAC__PRIV_FSockReceiverThreadFunc, (LPVOID) VPtSock, NULL, &(VPtSock->ThreadId) ); + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread creation failed !") ); + + VPtSock->ThreadFunc = IAC__PRIV_FSockReceiverThreadFunc; + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 1; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStopReceiverPort ( SInt32 ContextId ) { + + SInt8 VThreadKillOk; + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 0; + + /* -------------------- */ + /* Kill thread function */ + /* -------------------- */ + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread handle == NULL !") ); + + VThreadKillOk = TerminateThread ( VPtSock->ThreadHnd, -1 /* Thread exit code */ ); + + err_trace (( ERR_OUT, "TerminateThread sent - Return Ok ? = %d", VThreadKillOk )); + + /* ------------- */ + /* Close ASocket */ + /* ------------- */ + + closesocket ( VPtSock->ASocket ); + + err_retok (( ERR_OUT, "Receiver port Id=%d stopped", ContextId )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : For debugging only => Disable call to IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt + : in thread function +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockDbgReceiverPortDisableReception ( SInt32 ContextId, SInt8 DisableReception ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ------------- */ + /* Set parameter */ + /* ------------- */ + + VPtSock->DbgDisableReception = DisableReception; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 OLD1___IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VMsgSz; + SInt32 VAckSentSz; + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + // Init status + + VPtSock->MsgReady = 0; + + // Read + + VMsgSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[0]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "MsgSz=%d", VMsgSz )); + + if( VMsgSz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"recv () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Set status + + VPtSock->MsgSz = VMsgSz; + VPtSock->MsgReady = 1; + + // Call user function + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VPtSock->MsgSz, &(VPtSock->PtMsg[IAC__SOCK_HEADER_TOT_SZ]), VPtSock->MsgSz - IAC__SOCK_HEADER_TOT_SZ ); + } + + err_trace (( ERR_OUT, "Message received => %d bytes", VMsgSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VMsgSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + + return (VMsgSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header, add trailer +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 OLD2___IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VRecSz; + SInt32 VAckSentSz; + IAC__TSockMsgHeader* VPtHeader; + IAC__TSockMsgTrailer* VPtTrailer; + SInt32 VUserDataSz; + SInt32 VCheckSum; + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + // Init status + + VPtSock->MsgReady = 0; + + // Read + + VRecSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[0]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "RecSz=%d", VRecSz )); + + if( VRecSz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"recv () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Check header & trailer & CS + + VPtHeader = (IAC__TSockMsgHeader*) VPtSock->PtMsg; + + if ( VPtHeader->StartTag != IAC__SOCK_HEADER_START_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad header start tag=%x [H] - Must be %x [H]", VPtHeader->StartTag, IAC__SOCK_HEADER_START_TAG ) ); + } + + if ( VPtHeader->TotMsgSz != VRecSz ) { + err_retfail ( -1, (ERR_OUT,"Header tot sz=%d <> Received sz=%d", VPtHeader->TotMsgSz, VRecSz ) ); + } + + VPtTrailer = (IAC__TSockMsgTrailer*) &(VPtSock->PtMsg[VRecSz-(VPtSock->CstTrailerSz)]); + + if ( VPtTrailer->StopTag != IAC__SOCK_TRAILER_STOP_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad trailer stop tag=%x [H] - Must be %x [H]", VPtTrailer->StopTag, IAC__SOCK_TRAILER_STOP_TAG ) ); + } + + VUserDataSz = VRecSz - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz); + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VCheckSum = VPtSock->ParFuncCheckSum ( &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + + if ( VCheckSum != VPtHeader->CheckSum ) { + err_retfail ( -1, (ERR_OUT,"Checksum error : Calculated=%d <> From Header=%d", VCheckSum, VPtHeader->CheckSum ) ); + } + + err_trace (( ERR_OUT, "Checksum OK = %d", VCheckSum )); + + } + + + // Set status + + VPtSock->MsgSz = VRecSz; + VPtSock->MsgReady = 1; + + // Call user function + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VPtSock->MsgSz, &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + } + + err_trace (( ERR_OUT, "Message received => %d bytes", VRecSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VRecSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + + return (VRecSz); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header, add trailer + : 13/01/2009 + : - Return -2 if recv failed on connection lost in order to infrom caller to + : " reboot " the receiver + : +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VRecSz; + SInt32 VAckSentSz; + IAC__TSockMsgHeader* VPtHeader; + IAC__TSockMsgTrailer* VPtTrailer; + SInt32 VUserDataSz; + SInt32 VCheckSum; + SInt32 VSockErrno; + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + + while (1) { + + + // Init status + + VPtSock->MsgReady = 0; + + // Read + + VRecSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[0]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "RecSz=%d", VRecSz )); + + if( VRecSz <= 0 ) { + + VSockErrno = IAC__SOCKET_ERRNO; + + err_error (( ERR_OUT, "VRecSz=%d - IAC__SOCKET_ERRNO=%d", VRecSz, VSockErrno )); + + /* --------------------------------------------------------------------------------- */ + /* If connection has been lost */ + /* => return -2 */ + /* => caller will detected this special error and will try to reboot the receiver */ + /* --------------------------------------------------------------------------------- */ + + if ( (VRecSz == 0) || (VSockErrno == WSAECONNRESET) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost ! VRecSz=%d - IAC__SOCKET_ERRNO=%d => %s", VRecSz, VSockErrno, strerror (VSockErrno) )); + } + + /* ------------------------------- */ + /* Normal error => Not recoverable */ + /* ------------------------------- */ + + else { + err_retfail ( -1, (ERR_OUT,"recv () error %d => %s", VSockErrno, strerror (VSockErrno) )); + } + + } + + // Check header & trailer & CS + + VPtHeader = (IAC__TSockMsgHeader*) VPtSock->PtMsg; + + if ( VPtHeader->StartTag != IAC__SOCK_HEADER_START_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad header start tag=%x [H] - Must be %x [H]", VPtHeader->StartTag, IAC__SOCK_HEADER_START_TAG ) ); + } + + if ( VPtHeader->TotMsgSz != VRecSz ) { + err_retfail ( -1, (ERR_OUT,"Header tot sz=%d <> Received sz=%d", VPtHeader->TotMsgSz, VRecSz ) ); + } + + VPtTrailer = (IAC__TSockMsgTrailer*) &(VPtSock->PtMsg[VRecSz-(VPtSock->CstTrailerSz)]); + + if ( VPtTrailer->StopTag != IAC__SOCK_TRAILER_STOP_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad trailer stop tag=%x [H] - Must be %x [H]", VPtTrailer->StopTag, IAC__SOCK_TRAILER_STOP_TAG ) ); + } + + VUserDataSz = VRecSz - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz); + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VCheckSum = VPtSock->ParFuncCheckSum ( &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + + if ( VCheckSum != VPtHeader->CheckSum ) { + err_retfail ( -1, (ERR_OUT,"Checksum error : Calculated=%d <> From Header=%d", VCheckSum, VPtHeader->CheckSum ) ); + } + + err_trace (( ERR_OUT, "Checksum OK = %d", VCheckSum )); + + } + + + // Set status + + VPtSock->MsgSz = VRecSz; + VPtSock->MsgReady = 1; + + // Call user function + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VPtSock->MsgSz, &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + } + + err_trace (( ERR_OUT, "Message received => %d bytes", VRecSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VRecSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + break; /* Exit of while (1) at end of processing */ + + } /* End while (1) */ + + return (VRecSz); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 OLD1___IAC__PRIV_FSockLookForLongRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VMsgSz; + SInt32 VAckSentSz; + SInt32 VRecBlocSz ; + SInt32 VTotRecSz ; + + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + // Init status + + VPtSock->MsgReady = 0; + + VMsgReceptionRuning = 0; + VRecBlocSz = 0; + VTotRecSz = 0; + + + + while (1) { + + // Read + + VRecBlocSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[VTotRecSz]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "VRecBlocSz=%d", VRecBlocSz )); + + // If no data + + if( VRecBlocSz <= 0 ) { + err_warning (( ERR_OUT, "recv () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + continue; + } + + // If data + + // If it's message header + + if ( strncmp ( &(VPtSock->PtMsg[VTotRecSz]), IAC__SOCK_HEADER_STR, IAC__SOCK_HEADER_STR_SZ-1 ) == 0 ) { + + memcpy ( &VMsgSz, &(VPtSock->PtMsg[IAC__SOCK_HEADER_STR_SZ+1]), 4 ); + + VPtSock->MsgReady = 0; + + VMsgReceptionRuning = 1; + VTotRecSz = 0; + + err_trace (( ERR_OUT, "Message header = %s - MsgSz=%d", VPtSock->PtMsg, VMsgSz )); + err_trace (( ERR_OUT, "Message header received of %d bytes", VRecBlocSz )); + + VTotRecSz = VTotRecSz + VRecBlocSz; + } + + // If it's not message header + + else { + + // If it's not message header AND we are not in message recpetion phase => Message not for us + + if ( VMsgReceptionRuning == 0 ) { + err_retfail ( -1, (ERR_OUT,"Unknown message ! Not header / Not data part") ); + } + + // It's a data block => increment total size + + VTotRecSz = VTotRecSz + VRecBlocSz; + + err_trace (( ERR_OUT, "At this step tot received size of %d bytes", VTotRecSz )); + } + + // End of message reached + + if ( VTotRecSz >= VMsgSz ) { + VMsgReceptionRuning = 0; + + VPtSock->MsgSz = VTotRecSz; + VPtSock->MsgReady = 1; + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VTotRecSz, &(VPtSock->PtMsg[IAC__SOCK_HEADER_TOT_SZ]), VTotRecSz - IAC__SOCK_HEADER_TOT_SZ ); + } + + err_trace (( ERR_OUT, "Enf of message reception => %d bytes", VTotRecSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VTotRecSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VMsgReceptionRuning = 0; + VRecBlocSz = 0; + VTotRecSz = 0; + + break; + } + + + } /* End while (1) */ + + + return (VTotRecSz); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header & trailer + : 13/01/2009 + : - Return -2 if recv failed on connection lost +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockLookForLongRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VMsgSzFromHeader; + SInt32 VCheckSumFromHeader; + SInt32 VAckSentSz; + SInt32 VRecBlocSz ; + SInt32 VTotRecSz ; + IAC__TSockMsgHeader* VPtMayBeHeader; + IAC__TSockMsgTrailer* VPtTrailer; + SInt32 VUserDataSz; + SInt32 VCheckSum; + SInt32 VSockErrNo; + + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + // Init status + + VPtSock->MsgReady = 0; + + VMsgReceptionRuning = 0; + VRecBlocSz = 0; + VTotRecSz = 0; + + + + while (1) { + + // Read + + VRecBlocSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[VTotRecSz]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "VRecBlocSz=%d", VRecBlocSz )); + + // If no data + +/* BEFORE 14/01/09 + + if( VRecBlocSz <= 0 ) { + + if ( (VRecBlocSz == 0) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost !") ); + } + + else { + err_warning (( ERR_OUT, "recv () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + continue; + } + + } + +*/ + + if( VRecBlocSz <= 0 ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + err_error (( ERR_OUT, "VRecSz=%d - IAC__SOCKET_ERRNO=%d", VRecBlocSz, VSockErrNo )); + + /* --------------------------------------------------------------------------------- */ + /* If connection has been lost */ + /* => return -2 */ + /* => caller will detected this special error and will try to reboot the receiver */ + /* --------------------------------------------------------------------------------- */ + + if ( (VRecBlocSz == 0) || (VSockErrNo == WSAECONNRESET) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost ! VRecSz=%d - IAC__SOCKET_ERRNO=%d => %s", VRecBlocSz, VSockErrNo, strerror (VSockErrNo) )); + } + + /* ------------------------- */ + /* Normal warning => No data */ + /* ------------------------- */ + + else { + err_warning (( ERR_OUT, "recv () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + continue; + } + + } + + + + // If data + + // If it's message header + + /* ---------------------------------------------------------------------------------- */ + /* - WARNING - */ + /* ---------------------------------------------------------------------------------- */ + /* VPtMayBeHeader points to a valid header ONLY when current received block is header */ + /* On next blocks VPtMayBeHeader points to a something which IS NOT a header */ + /* Therefore if you need to access to header fields LATER you must do a copy of */ + /* these fields WHEN header is detected and use this copy NOT VPtMayBeHeader fields */ + /* ---------------------------------------------------------------------------------- */ + + VPtMayBeHeader = (IAC__TSockMsgHeader*) &(VPtSock->PtMsg[VTotRecSz]); + + if ( VPtMayBeHeader->StartTag == IAC__SOCK_HEADER_START_TAG ) { + + // Do a copy of useful header fields + + VMsgSzFromHeader = VPtMayBeHeader->TotMsgSz; + VCheckSumFromHeader = VPtMayBeHeader->CheckSum; + + VPtSock->MsgReady = 0; + + VMsgReceptionRuning = 1; + VTotRecSz = 0; + + err_trace (( ERR_OUT, "Message header tag = %x [H] - MsgSz=%d", VPtMayBeHeader->StartTag, VMsgSzFromHeader )); + err_trace (( ERR_OUT, "Message header received of %d bytes", VRecBlocSz )); + + VTotRecSz = VTotRecSz + VRecBlocSz; + } + + // If it's not message header + + else { + + // If it's not message header AND we are not in message recpetion phase => Message not for us + + if ( VMsgReceptionRuning == 0 ) { + err_retfail ( -1, (ERR_OUT,"Unknown message ! Not header / Not data part") ); + } + + // It's a data block => increment total size + + VTotRecSz = VTotRecSz + VRecBlocSz; + + err_trace (( ERR_OUT, "At this step tot received size of %d bytes", VTotRecSz )); + } + + // End of message reached + + if ( VTotRecSz >= VMsgSzFromHeader ) { + VMsgReceptionRuning = 0; + + // Check message size + + if ( VMsgSzFromHeader != VTotRecSz ) { + err_retfail ( -1, (ERR_OUT,"Header tot sz=%d <> Received sz=%d", VMsgSzFromHeader, VTotRecSz ) ); + } + + // Check trailer value + + VPtTrailer = (IAC__TSockMsgTrailer*) &(VPtSock->PtMsg[VTotRecSz-(VPtSock->CstTrailerSz)]); + + if ( VPtTrailer->StopTag != IAC__SOCK_TRAILER_STOP_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad trailer stop tag=%x [H] - Must be %x [H]", VPtTrailer->StopTag, IAC__SOCK_TRAILER_STOP_TAG ) ); + } + + // Calculate size of message user part + + VUserDataSz = VTotRecSz - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz); + + // Compare checksum + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VCheckSum = VPtSock->ParFuncCheckSum ( &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + + if ( VCheckSum != VCheckSumFromHeader ) { + err_retfail ( -1, (ERR_OUT,"Checksum error : Calculated=%d <> From Header=%d", VCheckSum, VCheckSumFromHeader ) ); + } + + err_trace (( ERR_OUT, "Checksum OK = %d", VCheckSum )); + + } + + // Good message received + + VPtSock->MsgSz = VTotRecSz; + VPtSock->MsgReady = 1; + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VTotRecSz, &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + } + + err_trace (( ERR_OUT, "Enf of message reception => %d bytes", VTotRecSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VTotRecSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VMsgReceptionRuning = 0; + VRecBlocSz = 0; + VTotRecSz = 0; + + break; + } + + + } /* End while (1) */ + + + return (VTotRecSz); + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 13/01/2009 + : - Wait for a receicer if connect failed +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +DWORD WINAPI IAC__PRIV_FSockSenderThreadFunc ( LPVOID lpParam ) { + + IAC__TSockSenderPort* VPtSock = (IAC__TSockSenderPort*) lpParam; + + + err_error (( ERR_OUT, "BEGINNING of IAC__PRIV_FSockSenderThreadFunc" )); + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Thread execution of sender port [%d] started", VPtSock ->Id )); + err_trace (( ERR_OUT, "Dest host = %s", VPtSock ->ParDestHost )); + err_trace (( ERR_OUT, "Dest port = %d", VPtSock ->ParDestPort )); + err_trace (( ERR_OUT, "Ack TO = %d", VPtSock ->ParAckTimeOutMs )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + + /* -------------------- */ + /* Connect to dest host */ + /* -------------------- */ + + err_warning (( ERR_OUT, "IAC__PRIV_FSockSenderThreadFunc Try to connect ..." )); + + // Blocking mode socket + + /* ----------------------------------------------- */ + /* Try to connect until a receiver is detected */ + /* if connection failed, it waits 100 ms and retry */ + /* ----------------------------------------------- */ + /* Before 13/01/09 it was a single call to connect */ + /* followed by retfail to abort in case of error */ + /* ----------------------------------------------- */ + + while ( connect( VPtSock->Socket, &(VPtSock->DestAddr), sizeof(VPtSock->DestAddr) ) == SOCKET_ERROR ) { + err_error (( ERR_OUT, "Connect () error %d => %s WILL RETRY in 100 ms", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + Sleep ( 100 ); + } + + err_warning (( ERR_OUT, "Sender [%d] connection to Host %s Port %d done :-)", VPtSock->Id, VPtSock->ParDestHost, VPtSock->ParDestPort )); + + /* --------------------- */ + /* Messages sending loop */ + /* --------------------- */ + + while (1) { + + // Wait event + + if ( VPtSock->EvNewMsgHnd != NULL ) { + WaitForSingleObject ( VPtSock->EvNewMsgHnd, INFINITE /* dwTimeout */ ); + } + + // Send message + + if ( VPtSock->ParLongMsg == 0 ) { + VPtSock->SendStatus = IAC__PRIV_FSockSendShortMsg ( VPtSock->Id ); + } + + else { + VPtSock->SendStatus = IAC__PRIV_FSockSendLongMsg ( VPtSock->Id ); + } + + + // Send Ack event + + if ( PulseEvent ( VPtSock->EvAckMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Event EvAckMsgHnd sent" )); + } + + + } /* End while (1) */ + + + + err_error (( ERR_OUT, "END of IAC__PRIV_FSockSenderThreadFunc" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Rev : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +DWORD WINAPI IAC__PRIV_FSockReceiverThreadFunc ( LPVOID lpParam ) { + + IAC__TSockReceiverPort* VPtSock = (IAC__TSockReceiverPort*) lpParam; + SInt32 VRet; + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Thread execution of receiver port [%d] started", VPtSock->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + + /* ---------------------- */ + /* Wait client connection */ + /* ---------------------- */ + + // Listen + + err_trace (( ERR_OUT, "Before listen" )); + + if ( listen( VPtSock->LSocket, 2) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"listen () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Before accept" )); + + // Accept + + VPtSock->ASocket = accept ( VPtSock->LSocket, NULL, NULL ); + + if( VPtSock->ASocket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"accept () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Before loop" )); + + /* ---------------------- */ + /* Reception loop */ + /* ---------------------- */ + + while (1) { + + if ( VPtSock->DbgDisableReception == 1 ) { + continue; + } + + if ( VPtSock->ParLongMsg == 0 ) { + VRet = IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( VPtSock->Id ); + } + + else { + VRet = IAC__PRIV_FSockLookForLongRecMsgOnPortAndProcessIt ( VPtSock->Id ); + } + + if ( VRet == -2 ) { + Sleep ( 100 ); + err_error (( ERR_OUT, "IAC__FSockRebootReceiverPort called !" )); + IAC__FSockRebootReceiverPort ( VPtSock->Id ); + } + + + } /* End while (1) */ + + + return (0); +} + + + + + +#endif + + + + + + + + + + + + diff --git a/include/pxi_daq_lib_v.2.1/inter_app_com.old2.c b/include/pxi_daq_lib_v.2.1/inter_app_com.old2.c new file mode 100755 index 0000000..d933ba6 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/inter_app_com.old2.c @@ -0,0 +1,3648 @@ + +/******************************************************************************* +File : x:\lib\com\inter_app_com\inter_app_com.c +Goal : Functions of inter applications communication library. +Prj date : 05/12/2007 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef INTER_APP_COM_C +#define INTER_APP_COM_C + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 05/12/2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/12/2007 + : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FBegin ( SInt8 ErrLogLvl, char* ErrLogFilePath ) { + + IAC__TContext* PtCont = &IAC__VGContext; + + ERR_FBegin ( (ErrLogLvl != ERR_LOG_LVL_NONE ) /* Enable */, ErrLogFilePath ); + ERR_FSetFileLogLevel ( ErrLogLvl ); + ERR_FSetUserLogLevel ( ErrLogLvl ); + + memset ( &IAC__VGContext, 0, sizeof (IAC__VGContext) ); + + IAC__PRIV_FSockInit (); + + PtCont->Rmp.CmdComPcObjId = 0; + PtCont->Rmp.CmdComUcObjId = 1; + PtCont->Rmp.CmdGetCmdResLoopPeriod = 50; + PtCont->Rmp.CmdGetCmdResTryNb = 60; + + PtCont->Rmp.DataComPcObjId = 2; + PtCont->Rmp.DataComUcObjId = 3; + + CPC_FBegin ( PtCont->Rmp.CmdComPcObjId /* ObjId */, 0 /* ComMedia */, 0 /* ComId */, CPC_OBJ_CMD_BLK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, CPC_OBJ_CMD_RES_BLK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + CUC_FBegin ( PtCont->Rmp.CmdComUcObjId /* ObjId */, 0 /* ComMedia */, 0 /* ComId */, CPC_OBJ_CMD_RES_BLK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, CPC_OBJ_CMD_BLK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + + CPC_FBegin ( PtCont->Rmp.DataComPcObjId /* ObjId */, 0 /* ComMedia */, 1 /* ComId */, IAC__RMP_DATA_BLOCK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, IAC__RMP_DATA_BLOCK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + CUC_FBegin ( PtCont->Rmp.DataComUcObjId /* ObjId */, 0 /* ComMedia */, 1 /* ComId */, IAC__RMP_DATA_BLOCK_SZ /* SendBuffSz */, PIP_FFileSend /* PtSendFunc */, IAC__RMP_DATA_BLOCK_SZ /* RecBuffSz */, PIP_FFileGet /* PtGetFunc */ ); + + err_retok (( ERR_OUT, "Lib compiled on %s at %s", __DATE__, __TIME__ )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/12/2007 + : 09/01/2008 + Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FEnd () { + + IAC__TContext* PtCont = &IAC__VGContext; + + CPC_FEnd ( PtCont->Rmp.CmdComPcObjId /* ObjId */ ); + CUC_FEnd ( PtCont->Rmp.CmdComUcObjId /* ObjId */ ); + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncRunStatusAnswer ( IAC__RMP_TFuncRunStatusAnswer PtFunc ) { + + IAC__VGContext.Rmp.FuncRunStatusAnswer = PtFunc; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncRunStatusAnswer2 ( IAC__RMP_TFuncRunStatusAnswer2 PtFunc ) { + + IAC__VGContext.Rmp.FuncRunStatusAnswer2 = PtFunc; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSetFuncAskEventAnswer ( IAC__RMP_TFuncAskEventAnswer PtFunc ) { + + IAC__VGContext.Rmp.FuncAskEventAnswer = PtFunc; + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskRunStatus ( IAC__RMP_TRunStatusAnswer* PtStatus ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TRunStatusAnswer* VPtRes; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_RUN_STATUS, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TRunStatusAnswer ) /* CmdRetSz */, + "Run Status" /* CmdStr */, + NULL /* PtParam */, + 0 /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes /* & ((UInt8*) VPtRes) 14/01/08 */ ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtStatus != NULL ) { + *PtStatus = *VPtRes; + } + + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 11/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskRunStatus2 ( IAC__RMP_TRunStatusAnswer2* PtStatus ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TRunStatusAnswer2* VPtRes; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TRunStatusAnswer2 ) /* CmdRetSz */, + "Run Status 2" /* CmdStr */, + NULL /* PtParam */, + 0 /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtStatus != NULL ) { + *PtStatus = *VPtRes; + } + + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FCmdAskEvent ( IAC__RMP_TAskEventAnswer* PtAns ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VCmdIndex; + IAC__RMP_TAskEventAnswer* VPtRes; + static IAC__RMP_TAskEventPar VCmdPar; + CPC_TContext* VPt; + SInt8 ViCmdResTry; + + VPt = &CPC_VGContext[PtCont->Rmp.CmdComPcObjId]; + + ++VCmdPar.EvNb; + VCmdPar.TestTag = 666; + + VCmdIndex = CPC_FSendCmd ( PtCont->Rmp.CmdComPcObjId, + IAC__CMD_TYPE__RMP, + IAC__CMD_STYPE__RMP__ASK_EVENT, + COM_CMD_RET_MODE_WAIT /* CmdRetMode */, + sizeof ( IAC__RMP_TAskEventAnswer ) /* CmdRetSz */, + "Ask event" /* CmdStr */, + (UInt8*) &VCmdPar /* PtParam */, + sizeof ( VCmdPar ) /* ParamSz */ ); + + + err_retfail ( VCmdIndex, (ERR_OUT,"FSendCmd fail => return %d", VCmdIndex) ); + + for ( ViCmdResTry=0; ViCmdResTry < PtCont->Rmp.CmdGetCmdResTryNb; ViCmdResTry++ ) { + + VRet = CPC_FGetCmdRes ( PtCont->Rmp.CmdComPcObjId, VCmdIndex, (UInt8**) &VPtRes ); + + if ( VRet >= 0 ) { + break; + } + + #ifdef ROOT_ROOT + gSystem->Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #else + Sleep ( PtCont->Rmp.CmdGetCmdResLoopPeriod ); + #endif + + } + + if ( VRet < 0 ) { + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + err_retfail ( -1, (ERR_OUT,"FGetCmdResfail => return %d after %d try each %d ms", VRet, PtCont->Rmp.CmdGetCmdResTryNb, PtCont->Rmp.CmdGetCmdResLoopPeriod ) ); + } + + err_warning (( ERR_OUT, "TRACE => Anser get after %d polling cyles of each %d ms ", ViCmdResTry, PtCont->Rmp.CmdGetCmdResLoopPeriod )); + + + if ( PtAns != NULL ) { + *PtAns = *VPtRes; + } + + free ( VPtRes ); + + CPC_PRIV_FFreeCmd ( PtCont->Rmp.CmdComPcObjId, VCmdIndex ); + + err_retok (( ERR_OUT, "" )); + + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FDaqCmdInterpreter () { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + SInt32 VRetInterpreter; + char VStrStatus[GLB_CMT_SZ]; + COM_TCommand* VPtCmd; + + UInt8* VPtData; + IAC__RMP_TRunStatusAnswer VRunStatusAnswer; + IAC__RMP_TRunStatusAnswer2 VRunStatusAnswer2; + IAC__RMP_TAskEventAnswer VAskEventAnswer; + + + VRetInterpreter = CUC_FCmdInterpreter ( PtCont->Rmp.CmdComUcObjId, VStrStatus, &VPtCmd, &VPtData ); + + + switch ( VRetInterpreter ) { + + case -1 : { + err_retfail ( VRetInterpreter, (ERR_OUT,"Interpreter Error !") ); + break; } + + // Command + + case 1 : { + + err_trace (( ERR_OUT, "Cmd = %s", VPtCmd->StrCmd )); + + if ( VPtCmd->Type != IAC__CMD_TYPE__RMP ) { + err_trace (( ERR_OUT, "Not a RMP cmd !" )); + break; + } + + switch ( VPtCmd->SubType ) { + + + case IAC__CMD_STYPE__RMP__ASK_RUN_STATUS : { + + if ( IAC__VGContext.Rmp.FuncRunStatusAnswer != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_RUN_STATUS received - Response done" )); + + IAC__VGContext.Rmp.FuncRunStatusAnswer ( VPtCmd, &VRunStatusAnswer ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VRunStatusAnswer /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + case IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2 : { + + if ( IAC__VGContext.Rmp.FuncRunStatusAnswer2 != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_RUN_STATUS_2 received - Response done" )); + + IAC__VGContext.Rmp.FuncRunStatusAnswer2 ( VPtCmd, &VRunStatusAnswer2 ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VRunStatusAnswer2 /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + case IAC__CMD_STYPE__RMP__ASK_EVENT : { + + if ( IAC__VGContext.Rmp.FuncAskEventAnswer != NULL ) { + + err_trace (( ERR_OUT, "Cmd IAC__CMD_STYPE__RMP__ASK_EVENT received - Resonse done" )); + + IAC__VGContext.Rmp.FuncAskEventAnswer ( VPtCmd, &VAskEventAnswer ); + + VRet = CUC_FPutDatas ( PtCont->Rmp.CmdComUcObjId, 0 /* MultiExec */, (UInt8*) &VAskEventAnswer /* PtSrc */, CPC_OBJ_CMD_RES_BLK_SZ /* BlkSz */, VPtCmd->RetSz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas failed !") ); + } + + break; } + + + default : { + err_error (( ERR_OUT, "Cmd SubType=%d unknown", VPtCmd->SubType )); + break; + } + + } + + + + + break; } + + // Data + + case 2 : { + err_trace (( ERR_OUT, "Data transaction" )); + + break; } + + } + + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FSendEvent ( UInt8* PtEv, SInt32 Sz ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + + err_retnull ( PtEv, (ERR_OUT,"PtEv == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + VRet = CUC_FPutDatas ( IAC__VGContext.Rmp.DataComUcObjId /* ObjId */, 0 /* MultiExec */, PtEv, -1 /* BlkSz */, Sz /* TotSz */ ); + + err_retfail ( VRet, (ERR_OUT,"CUC_FPutDatas (...) failed => Ret=%d", VRet ) ); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FReceiveEvent ( UInt8* PtEv, SInt32 MaxEvSz, SInt32* PtEvSz ) { + + IAC__TContext* PtCont = &IAC__VGContext; + SInt32 VRet; + UInt32 VEvSz; + + err_retnull ( PtEv , (ERR_OUT,"PtEv == NULL") ); + err_retnull ( PtEvSz, (ERR_OUT,"PtEvSz == NULL") ); + + if ( MaxEvSz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad MaxSz =%d <= 0", MaxEvSz) ); + } + + + VRet = CPC_FGetDatas ( IAC__VGContext.Rmp.DataComPcObjId /* ObjId */, 0 /* MultiExec */, PtEv, MaxEvSz, &VEvSz /* PtGetDataSz */ ); + + + switch ( VRet ) { + + case 0 : { + err_retfail ( -1, (ERR_OUT,"This case SHOULD NOT happne => CPC_FGetDatas called with MultiExec = 0 which returns 0 ! = only one block read !") ); + break; } + + case 1 : { + + *PtEvSz = VEvSz; + return (0); // Normal case + break; } + + case -1 : { + err_trace (( ERR_OUT, "Nothing to read" )); + return (-1); + break; } + + case -2 : { + err_retfail ( -1, (ERR_OUT,"Error reading data with CPC_FGetDatas (...) which return %d", VRet) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown error => CPC_FGetDatas (...) return %d", VRet) ); + break; + } + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FTestFillEvent ( UInt8* PtEv, SInt32 Sz ) { + + SInt32 Vi; + + err_retnull ( PtEv, (ERR_OUT,"PtEv == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + for ( Vi=0; Vi < Sz; Vi++ ) { + PtEv[Vi] = Vi; + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__RMP_FTestCompareEvents ( UInt8* PtEvToCmp, UInt8* PtEvRef, SInt32 Sz ) { + + SInt32 VErrCnt; + SInt32 Vi; + + err_retnull ( PtEvRef , (ERR_OUT,"PtEvRef == NULL") ); + err_retnull ( PtEvToCmp, (ERR_OUT,"PtEvToCmp == NULL") ); + + if ( Sz <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad Sz =%d <= 0", Sz) ); + } + + VErrCnt = 0; + + for ( Vi=0; Vi < Sz; Vi++ ) { + + if ( PtEvToCmp[Vi] != PtEvRef[Vi]) { + err_error (( ERR_OUT, "Cmp error Mem[%6d] : Received=%d - Reference=%d", Vi, PtEvToCmp[Vi], PtEvRef[Vi] )); + ++VErrCnt; + } + + } + + + if ( VErrCnt >= 0 ) { + err_retval ( VErrCnt, ( ERR_OUT, "Event compare => %d errors !", VErrCnt ) ); + } + + else { + err_retok (( ERR_OUT, "" )); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +SInt32 IAC__RMP_FTestPrintMemStatusRec ( LPMEMORYSTATUS PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL") ); + + err_error (( ERR_OUT, "------------ Mem Status ------------" )); + err_error (( ERR_OUT, "Percent of memory in use = %d", PtRec->dwMemoryLoad )); + err_error (( ERR_OUT, "Bytes of physical memory = %d", PtRec->dwTotalPhys )); + err_error (( ERR_OUT, "Free physical memory bytes = %d", PtRec->dwAvailPhys )); + err_error (( ERR_OUT, "Bytes of paging file = %d", PtRec->dwTotalPageFile )); + err_error (( ERR_OUT, "Free bytes of paging file = %d", PtRec->dwAvailPageFile )); + err_error (( ERR_OUT, "User bytes of address space = %d", PtRec->dwTotalVirtual )); + err_error (( ERR_OUT, "Free user bytes = %d", PtRec->dwAvailVirtual )); + err_error (( ERR_OUT, "------------------------------------" )); + + return (0); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 12/01/2008 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +SInt32 IAC__RMP_FTestGetMemStatus ( SInt8 Print, LPMEMORYSTATUS PtRec, SInt32* PtStackAvailSz ) { + + MEMORYSTATUS VMemStatus; + SInt32 VStackAvailSz; + + + VMemStatus.dwLength = sizeof ( MEMORYSTATUS ); + + GlobalMemoryStatus ( &VMemStatus ); + + VStackAvailSz = stackavail (); + + if ( Print == 1 ) { + IAC__RMP_FTestPrintMemStatusRec ( &VMemStatus ); + err_error (( ERR_OUT, "----------------------------------" )); + err_error (( ERR_OUT, "Stack available = %d bytes", VStackAvailSz )); + err_error (( ERR_OUT, "----------------------------------" )); + } + + + if ( PtRec != NULL ) { + *PtRec = VMemStatus; + } + + if ( PtStackAvailSz != NULL ) { + *PtStackAvailSz = VStackAvailSz; + } + +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 04/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FPrepareMsg ( SInt8 Priority, SInt8 Type, SInt16 SubType, IAC__TWho* From, IAC__TWho* To ) { + + + + return (0); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +struct sockaddr IAC__PRIV_FTcpFormatAdress ( char * Host, u_short Port ) +{ + struct sockaddr_in addr; + struct sockaddr addrRet; + struct hostent FAR *lphost ; + u_long IP; + + + memset((char*)&addr, 0, sizeof(addr)); + + /* Soit on fournit une adresse IP, soit on fournit un nom */ + + if ((IP = inet_addr(Host)) == (u_long)INADDR_NONE) + { + if ((lphost = gethostbyname(Host))==NULL) + { + memset( (char * )&addrRet, 0, sizeof(addrRet) ); + return addrRet; + } + + addr.sin_family = lphost->h_addrtype; + + #ifdef _WIN16 /* A d�finir dans le projet WIN16 */ + _fmemcpy (&addr.sin_addr, lphost->h_addr, lphost->h_length); + #else /* WIN32, UNIX*/ + memcpy (&addr.sin_addr, lphost->h_addr, lphost->h_length); + #endif + + } + + else + { + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = IP; + } + + /* Port destination */ + + addr.sin_port = htons((u_short)Port ); + + memcpy( (char *)&addrRet, (char *)&addr, sizeof(addrRet) ); + + return addrRet; +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockSendShortMsg ( SInt32 ContextId, UInt8* PtMsg, UInt32 MsgSz ) { + + IAC__TSockSenderPort* VPtSocket; + SInt16 ViTry; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + + /* ------------ */ + /* Check status */ + /* ------------ */ + + if ( VPtSocket->Started != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access [%d] not started => Can't send message", VPtSocket->Id ) ); + } + + /* --------------- */ + /* Check port mode */ + /* --------------- */ + + if ( VPtSocket->ParLongMsg == 1 ) { + err_retfail ( -1, (ERR_OUT,"This port doesn't support short message ! ParLongMsg=%d", VPtSocket->ParLongMsg ) ); + } + + + /* ---------------------------- */ + /* Check message pointer & size */ + /* ---------------------------- */ + + err_retnull ( PtMsg, (ERR_OUT,"PtMsg == NULL !") ); + + /* Only for first version of text header => "SZ=" + + if ( ( MsgSz + IAC__SOCK_HEADER_TOT_SZ ) > IAC__SO_MAX_SHORT_MSG_SIZE ) { + err_retfail ( -1, (ERR_OUT,"Message too long size=%d + IAC__SOCK_HEADER_TOT_SZ=%d > IAC__SO_MAX_SHORT_MSG_SIZE=%d", MsgSz, IAC__SOCK_HEADER_TOT_SZ, IAC__SO_MAX_SHORT_MSG_SIZE )); + } + + */ + + if ( ( MsgSz + (VPtSocket->CstHeaderSz) + (VPtSocket->CstTrailerSz) ) > IAC__SO_MAX_SHORT_MSG_SIZE ) { + err_retfail ( -1, (ERR_OUT,"Message too long size + (Header & Trailer) =%d > IAC__SO_MAX_SHORT_MSG_SIZE=%d", MsgSz + (VPtSocket->CstHeaderSz) + (VPtSocket->CstTrailerSz), IAC__SO_MAX_SHORT_MSG_SIZE )); + } + + + VPtSocket->ParPtMsg = PtMsg; + VPtSocket->ParMsgSz = MsgSz; + + /* ------------------------------------ */ + /* Try to send message ParRetryNb times */ + /* ------------------------------------ */ + + for ( ViTry=0; ViTry < VPtSocket->ParRetryNb; ViTry++ ) { + + /* --------------- */ + /* Reset Status */ + /* --------------- */ + + VPtSocket->SendStatus = -1; + + /* -------------------- */ + /* Send event to thread */ + /* -------------------- */ + + if ( PulseEvent ( VPtSocket->EvNewMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Event EvNewMsgHnd sent" )); + } + + /* ------------------ */ + /* Wait thread answer */ + /* ------------------ */ + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"Ack event not installed !" ) ); + + // Time out => Retry + + if ( WaitForSingleObject ( VPtSocket->EvAckMsgHnd, VPtSocket->ParAckTimeOutMs ) == WAIT_TIMEOUT ) { + err_error (( ERR_OUT, "No Ack => Exit on time out !! ViTry=%d - Msg : %s", ViTry, PtMsg )); + continue; + } + + // Error => Retry + + if ( VPtSocket->SendStatus <= 0 ) { + err_error (( ERR_OUT, "Send error - ViTry=%d - Msg : %s", ViTry, PtMsg )); + continue; + } + + // OK message sent, Ack received => break loop + + err_trace (( ERR_OUT, "Ack received" )); + break; + + + } /* End for */ + + return (VPtSocket->SendStatus); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockSendLongMsg ( SInt32 ContextId, UInt8* PtMsg, UInt32 MsgSz ) { + + IAC__TSockSenderPort* VPtSocket; + SInt16 ViTry; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + + /* ------------ */ + /* Check status */ + /* ------------ */ + + if ( VPtSocket->Started != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access [%d] not started => Can't send message", VPtSocket->Id ) ); + } + + /* --------------- */ + /* Check port mode */ + /* --------------- */ + + if ( VPtSocket->ParLongMsg == 0 ) { + err_retfail ( -1, (ERR_OUT,"This port doesn't support long message ! ParLongMsg=%d", VPtSocket->ParLongMsg ) ); + } + + /* ---------------------------- */ + /* Check message pointer & size */ + /* ---------------------------- */ + + err_retnull ( PtMsg, (ERR_OUT,"PtMsg == NULL !") ); + + if ( VPtSocket->ParMsgSz > IAC__SOCK_MAX_LONG_MSG_SZ ) { + err_retfail ( -1, (ERR_OUT,"Message too long size=%d > IAC__SOCK_MAX_LONG_MSG_SZ=%d", MsgSz, IAC__SOCK_MAX_LONG_MSG_SZ )); + } + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + VPtSocket->ParPtMsg = PtMsg; + VPtSocket->ParMsgSz = MsgSz; + + err_trace (( ERR_OUT, "LongMsgSz = %d", VPtSocket->ParMsgSz )); + + /* ------------------------------------ */ + /* Try to send message ParRetryNb times */ + /* ------------------------------------ */ + + for ( ViTry=0; ViTry < VPtSocket->ParRetryNb; ViTry++ ) { + + /* --------------- */ + /* Reset Status */ + /* --------------- */ + + VPtSocket->SendStatus = -1; + + /* -------------------- */ + /* Send event to thread */ + /* -------------------- */ + + if ( PulseEvent ( VPtSocket->EvNewMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Event EvNewMsgHnd sent" )); + } + + /* ------------------ */ + /* Wait thread answer */ + /* ------------------ */ + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"Ack event not installed !" ) ); + + // Time out => Retry + + if ( WaitForSingleObject ( VPtSocket->EvAckMsgHnd, VPtSocket->ParAckTimeOutMs ) == WAIT_TIMEOUT ) { + err_error (( ERR_OUT, "No Ack => Exit on time out !! ViTry=%d - Msg : %s", ViTry, PtMsg )); + continue; + } + + // Error => Retry + + if ( VPtSocket->SendStatus <= 0 ) { + err_error (( ERR_OUT, "Send error - ViTry=%d - Msg : %s", ViTry, PtMsg )); + continue; + } + + // OK message sent, Ack received => break loop + + err_trace (( ERR_OUT, "Ack received" )); + break; + + } /* End for */ + + + + return (VPtSocket->SendStatus); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 IAC__PRIV_FSockInit ( ) { + + WSADATA VStackInf; + + // Initialize winsock + + WSAStartup( MAKEWORD(2,0), &VStackInf ) ; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockGetSenderPortContext () { + + SInt32 Vi; + SInt32 VPortContextId; + + VPortContextId = -1; + + // Search a free port context record + + for ( Vi=0; Vi < IAC__SOCK_MAX_SENDER_PORT_NB; Vi++ ) { + + if ( IAC__VGContext.Sock.ASenderPort[Vi].Used == 0 ) { + IAC__VGContext.Sock.ASenderPort[Vi].Used = 1; + VPortContextId = Vi; + ++IAC__VGContext.Sock.SenderPortNb; + break; + } + + } + + // None found + + err_retfail ( VPortContextId, (ERR_OUT,"No free rec port context found => %d used", IAC__VGContext.Sock.SenderPortNb ) ); + + // Found + + err_retval ( VPortContextId, ( ERR_OUT, "Get reception port context Id=%d", VPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockGetReceiverPortContext () { + + SInt32 Vi; + SInt32 VPortContextId; + + VPortContextId = -1; + + // Search a free port context record + + for ( Vi=0; Vi < IAC__SOCK_MAX_REC_PORT_NB; Vi++ ) { + + if ( IAC__VGContext.Sock.AReceiverPort[Vi].Used == 0 ) { + IAC__VGContext.Sock.AReceiverPort[Vi].Used = 1; + VPortContextId = Vi; + ++IAC__VGContext.Sock.ReceiverPortNb; + break; + } + + } + + // None found + + err_retfail ( VPortContextId, (ERR_OUT,"No free rec port context found => %d used", IAC__VGContext.Sock.ReceiverPortNb ) ); + + // Found + + err_retval ( VPortContextId, ( ERR_OUT, "Get reception port context Id=%d", VPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockFreeSenderPortContext ( SInt32 ContextId ) { + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + /* -------- */ + /* Free */ + /* -------- */ + + IAC__VGContext.Sock.ASenderPort[ContextId].Used = 0; + + if ( IAC__VGContext.Sock.SenderPortNb > 0 ) { + --IAC__VGContext.Sock.SenderPortNb; + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockFreeReceiverPortContext ( SInt32 ContextId ) { + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + /* -------- */ + /* Free */ + /* -------- */ + + IAC__VGContext.Sock.AReceiverPort[ContextId].Used = 0; + + if ( IAC__VGContext.Sock.ReceiverPortNb > 0 ) { + --IAC__VGContext.Sock.ReceiverPortNb; + } + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FChkSenderContextId ( SInt32 ContextId ) { + + if ( (ContextId < 0) || (ContextId >= IAC__SOCK_MAX_SENDER_PORT_NB) ) { + err_retfail ( -1, (ERR_OUT,"Context Id=%d out of range[0..%d] !)", ContextId, IAC__SOCK_MAX_SENDER_PORT_NB-1) ); + } + + if ( IAC__VGContext.Sock.ASenderPort[ContextId].Used == 0 ) { + err_retfail ( -1, (ERR_OUT,"Context record Id=%d IS NOT used !", ContextId ) ); + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FChkReceiverContextId ( SInt32 ContextId ) { + + if ( (ContextId < 0) || (ContextId >= IAC__SOCK_MAX_REC_PORT_NB) ) { + err_retfail ( -1, (ERR_OUT,"Context Id=%d out of range[0..%d] !)", ContextId, IAC__SOCK_MAX_REC_PORT_NB-1) ); + } + + if ( IAC__VGContext.Sock.AReceiverPort[ContextId].Used == 0 ) { + err_retfail ( -1, (ERR_OUT,"Context record Id=%d IS NOT used !", ContextId ) ); + } + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header, add trailer + : 14/01/2009 + : - Detect lost of connection and try to reconnect by rebooting the sender + : with a IAC__FSockRebootSenderPort call. + : The goal is to allow receiver application to be stopped and restarted without + : broking permanently the communication channel, but not to recover all kind of errors. + : + Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockSendShortMsg ( SInt32 ContextId ) { + + SInt32 VRet; + IAC__TSockSenderPort* VPtSock; + UInt32 VTmpTotSz; + UInt32 VTotMsgSz; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + SInt32 VSockErrNo; + + + VRet = -1; + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + // Calculate message size + + VTotMsgSz = VPtSock->CstHeaderSz + VPtSock->ParMsgSz + VPtSock->CstTrailerSz; + + // Set size & CS in header + + VPtSock->MsgHeader.TotMsgSz = VTotMsgSz; + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VPtSock->MsgHeader.CheckSum = VPtSock->ParFuncCheckSum ( VPtSock->ParPtMsg, VPtSock->ParMsgSz ); + } + + else { + VPtSock->MsgHeader.CheckSum = 0; + } + + + + // Build messages + + memcpy ( VPtSock->PtBuffSendShortMsg , &(VPtSock->MsgHeader) , VPtSock->CstHeaderSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VPtSock->CstHeaderSz]) , VPtSock->ParPtMsg , VPtSock->ParMsgSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VTotMsgSz-(VPtSock->CstTrailerSz)]), &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz ); + + err_trace (( ERR_OUT, "Header.StartTag = %x [H]", VPtSock->MsgHeader.StartTag )); + err_trace (( ERR_OUT, "Header.TotSz = %d ", VPtSock->MsgHeader.TotMsgSz )); + err_trace (( ERR_OUT, "Header.CheckSum = %d ", VPtSock->MsgHeader.CheckSum )); + err_trace (( ERR_OUT, "Trailer.StopTag = %x [H]", VPtSock->MsgTrailer.StopTag )); + + // Send message + + VSzSent = send ( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VTotMsgSz, 0 ); + + /* BEFORE 14/01/09 + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + */ + + + + if ( VSzSent == SOCKET_ERROR ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + // If connection reset => Try to connect and resend block + + if ( VSockErrNo == WSAECONNRESET ) { + + IAC__FSockRebootSenderPort ( ContextId ); + + // Try again to send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VTotMsgSz, 0 ); + + // Abort on send error + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + // Others error => Abort + + else { + err_retfail ( -1, (ERR_OUT,"send () error %d => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + + + err_trace (( ERR_OUT, "Message of %d Bytes sent", VSzSent )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + VRet = -1; + err_error (( ERR_OUT, "Ack reception error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VW32ServerAns = *((UInt32*) VPtSock->BuffRecAck); + + // Check Ack + + if ( VW32ServerAns != VTotMsgSz ) { + VRet = -1; + err_error (( ERR_OUT, "Server ack bad size %d - should be %d", VW32ServerAns, VTotMsgSz )); + } + + // OK : Message sent and Ack received + + VRet = VTotMsgSz; + + return (VRet); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header & trailer + : 14/01/2009 + : - Detect lost of connection and try to reconnect by rebooting the sender + : with a IAC__FSockRebootSenderPort call. + : The lost of connection test is only done at the beginning of a message ( on first + : block send ), if it occurs the middle, therefore message sending is aborted. + : This works like this because the goal is to allow receiver application to be + : stopped and restarted without broking permanently the communication channel, but + : not to recover all kind of errors. + : + : +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockSendLongMsg ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSock; + SInt32 VSzSent; + SInt32 VSzRec; + SInt32 VW32ServerAns; + + // UInt32 VTmpTotSz; + UInt32 VTotMsgSz; // Including header and trailer + + UInt32 VHeaderBlockDataSz; + UInt32 VHeaderBlockTotSz; + UInt32 VDataBlocksTotSz; + UInt32 VDataBlockSz; + UInt32 VLastBlockSz; + SInt32 VBlockNb; // Excluding first one and last one + SInt32 ViBlock; + SInt32 VPosNextBlockInSrcBuff; + SInt32 VTotSzSent; + SInt8 VMsgSingleBlock; + SInt32 VSockErrNo; + + + /* -------- */ + /* Check Id */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &(IAC__VGContext.Sock.ASenderPort[ContextId]); + + /* ------------ */ + /* Send message */ + /* ------------ */ + + // Evaluate blocks size + + + err_trace (( ERR_OUT, "ContextId=%d - ParMsgSz=%d", ContextId, VPtSock->ParMsgSz )); + + VTotSzSent = 0; + + // Evaluate blocks size + + // In case of single block message, header and trailer are added to message + + if ( VPtSock->ParMsgSz <= (IAC__SO_MAX_SHORT_MSG_SIZE - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz)) ) { + VMsgSingleBlock = 1; + VHeaderBlockDataSz = VPtSock->ParMsgSz; + VHeaderBlockTotSz = VHeaderBlockDataSz + (VPtSock->CstHeaderSz) + (VPtSock->CstTrailerSz); + VDataBlocksTotSz = 0; + VDataBlockSz = 0; + VBlockNb = 0; + VLastBlockSz = 0; // 0 => no icomplete block at the end + } + + // In case of multi block message, trailer is sent at the end by a specific call to send (...) + // Therefore trailer size must not be taken into account for blocks size and number calculation + + else { + VMsgSingleBlock = 0; + VHeaderBlockDataSz = IAC__SO_MAX_SHORT_MSG_SIZE - (VPtSock->CstHeaderSz); + VHeaderBlockTotSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VDataBlocksTotSz = VPtSock->ParMsgSz - VHeaderBlockDataSz; + VDataBlockSz = IAC__SO_MAX_SHORT_MSG_SIZE; + VBlockNb = VDataBlocksTotSz / VDataBlockSz; + VLastBlockSz = VDataBlocksTotSz % VDataBlockSz; // 0 => no icomplete block at the end + } + + // Calculate message size + + VTotMsgSz = VPtSock->CstHeaderSz + VPtSock->ParMsgSz + VPtSock->CstTrailerSz; + + // Set size & CS in header + + VPtSock->MsgHeader.TotMsgSz = VTotMsgSz; + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VPtSock->MsgHeader.CheckSum = VPtSock->ParFuncCheckSum ( VPtSock->ParPtMsg, VPtSock->ParMsgSz ); + } + + else { + VPtSock->MsgHeader.CheckSum = 0; + } + + // Debug print + + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + err_trace (( ERR_OUT, "User message size = %d", VPtSock->ParMsgSz )); + err_trace (( ERR_OUT, "Total message size = %d", VTotMsgSz )); + err_trace (( ERR_OUT, "VHeaderBlockDataSz = %d", VHeaderBlockDataSz )); + err_trace (( ERR_OUT, "VHeaderBlockTotSz = %d", VHeaderBlockTotSz )); + err_trace (( ERR_OUT, "VDataBlocksTotSz = %d", VDataBlocksTotSz )); + err_trace (( ERR_OUT, "VDataBlockSz = %d", VDataBlockSz )); + err_trace (( ERR_OUT, "VBlockNb = %d", VBlockNb )); + err_trace (( ERR_OUT, "VLastBlockSz = %d", VLastBlockSz )); + err_trace (( ERR_OUT, "-----------------------------------------------------" )); + + // Build header block + + memcpy ( VPtSock->PtBuffSendShortMsg , &(VPtSock->MsgHeader) , VPtSock->CstHeaderSz ); + memcpy ( &(VPtSock->PtBuffSendShortMsg[VPtSock->CstHeaderSz]) , VPtSock->ParPtMsg , VHeaderBlockDataSz ); + + // Copy trailer ONLY for single block message + + if ( VMsgSingleBlock == 1 ) { + memcpy ( &(VPtSock->PtBuffSendShortMsg[VTotMsgSz-(VPtSock->CstTrailerSz)]), &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz ); + } + + VPosNextBlockInSrcBuff = VHeaderBlockDataSz; + + // Send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + // If connection reset => Try to connect and resend block + + if ( VSockErrNo == WSAECONNRESET ) { + + IAC__FSockRebootSenderPort ( ContextId ); + + // Try again to send first block + + VSzSent = send( VPtSock->Socket, (char*) VPtSock->PtBuffSendShortMsg, VHeaderBlockTotSz, 0 ); + + // Abort on send error + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + // Others error => Abort + + else { + err_retfail ( -1, (ERR_OUT,"send () error %d - Header => %s", VSockErrNo, strerror (VSockErrNo) )); + } + + } + + else { + err_trace (( ERR_OUT, "Header block of %d Bytes sent", VSzSent )); + } + + VTotSzSent += VSzSent; + + // Send complete blocks + + for ( ViBlock=0; ViBlock < VBlockNb; ViBlock++) { + + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VDataBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Block[%d] => %s", IAC__SOCKET_ERRNO, ViBlock, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Send block[%d] of %d bytes OK :-)", ViBlock, VSzSent )); + + VPosNextBlockInSrcBuff += VDataBlockSz; + VTotSzSent += VSzSent; + + err_trace (( ERR_OUT, "Block[%d] of %d Bytes sent", ViBlock, VSzSent )); + + } + + // Send last block + + if ( VLastBlockSz > 0 ) { + VSzSent = send ( VPtSock->Socket, &(VPtSock->ParPtMsg[VPosNextBlockInSrcBuff]), VLastBlockSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Last block => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + // Send trailer ONLY for multiple blocks message + + if ( VMsgSingleBlock == 0 ) { + VSzSent = send( VPtSock->Socket, (UInt8*) &(VPtSock->MsgTrailer), VPtSock->CstTrailerSz, 0 ); + + if ( VSzSent == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () error %d - Trailer => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Send last block of %d bytes OK :-)", VSzSent )); + + VTotSzSent += VSzSent; + } + + err_trace (( ERR_OUT, "Before waiting for host ACK" )); + + // Listen to Ack from destination host + + memset ( VPtSock->BuffRecAck, 0, IAC__SOCK_ACK_SZ ); + + VSzRec = recv ( VPtSock->Socket, VPtSock->BuffRecAck, IAC__SOCK_ACK_SZ, 0 ); + + // Ack reception error + + if ( VSzRec <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Ack receive error %d - %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VW32ServerAns = *((UInt32*) (VPtSock->BuffRecAck) ); + + // Check Ack + + if ( VW32ServerAns != VTotSzSent ) { + err_retfail ( -1, (ERR_OUT,"Server ack bad size %d - should be %d", VW32ServerAns, VTotSzSent )); + } + + err_trace (( ERR_OUT, "Message sent and Ack received" )); + + // OK : Message sent and Ack received + + return (VTotSzSent); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 11/11/2008 + : - New header & trailer +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockInstallSenderPort ( char* DestHost, UInt32 DestPort, SInt8 LongMsg, UInt32 AckTimeOutMs, UInt8 RetryNb, IAC__TFSockFuncCheckSum FuncCheckSum ) { + + SInt32 VSenderPortContextId; + IAC__TSockSenderPort* VPtSocket; + + /* --------------------------------- */ + /* Find a free sender context record */ + /* --------------------------------- */ + + VSenderPortContextId = IAC__PRIV_FSockGetSenderPortContext (); + + err_retfail ( VSenderPortContextId, (ERR_OUT,"No free context record !") ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[VSenderPortContextId]); + VPtSocket->Id = VSenderPortContextId; + + /* --------------------- */ + /* Init constants fields */ + /* --------------------- */ + + VPtSocket->CstHeaderSz = sizeof (IAC__TSockMsgHeader ); + VPtSocket->CstTrailerSz = sizeof (IAC__TSockMsgTrailer); + + VPtSocket->MsgHeader.StartTag = IAC__SOCK_HEADER_START_TAG; + VPtSocket->MsgHeader.Zero = 0; + VPtSocket->MsgHeader.TotMsgSz = 0; // Unknown at this step + VPtSocket->MsgHeader.CheckSum = 0; // Unknown at this step + + VPtSocket->MsgTrailer.StopTag = IAC__SOCK_TRAILER_STOP_TAG; + VPtSocket->MsgTrailer.Zero = 0; + + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + strncpy ( VPtSocket->ParDestHost, DestHost, IAC__SOCK_MAX_STR_HOST_SZ - 1 ); + VPtSocket->ParDestPort = DestPort; + VPtSocket->ParLongMsg = LongMsg; + VPtSocket->ParAckTimeOutMs = AckTimeOutMs; + VPtSocket->ParRetryNb = RetryNb; + VPtSocket->ParPtMsg = NULL; + VPtSocket->ParFuncCheckSum = FuncCheckSum; + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->Socket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->Socket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short)0 ); + + if ( bind( VPtSocket->Socket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Transform the host/port into a struct sockaddr + + VPtSocket->DestAddr = IAC__PRIV_FTcpFormatAdress ( VPtSocket->ParDestHost, (u_short) (VPtSocket->ParDestPort) ); + + /* -------------- */ + /* Create events */ + /* -------------- */ + + VPtSocket->EvNewMsgHnd = CreateEvent ( + NULL /* LPSECURITY_ATTRIBUTES */, + FALSE /* Manual Reset */, + FALSE /* Initial State */, + NULL /* Name STring */ ); + + err_retnull ( VPtSocket->EvNewMsgHnd, (ERR_OUT,"CreateEvent EvNewMsgHnd failed ! - LastError=%d", GetLastError ()) ); + + VPtSocket->EvAckMsgHnd = CreateEvent ( + NULL /* LPSECURITY_ATTRIBUTES */, + FALSE /* Manual Reset */, + FALSE /* Initial State */, + NULL /* Name STring */ ); + + err_retnull ( VPtSocket->EvAckMsgHnd, (ERR_OUT,"CreateEvent EvAckMsgHnd failed ! - LastError=%d", GetLastError ()) ); + + + /* ------------- */ + /* Alloc buffers */ + /* ------------- */ + + VPtSocket->PtBuffSendShortMsg = (UInt8*) malloc ( IAC__SO_MAX_SHORT_MSG_SIZE ); + + err_retnull ( VPtSocket->PtBuffSendShortMsg, (ERR_OUT,"Allocation sender buffer of %d bytes failed !", IAC__SO_MAX_SHORT_MSG_SIZE) ); + + /* ------------- */ + /* Create thread */ + /* ------------- */ + + // It will be done in IAC__FSockStartSenderPort () + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSocket->Installed = 1; + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] installed", VPtSocket->Id )); + err_trace (( ERR_OUT, "Dest host = %s", VPtSocket->ParDestHost )); + err_trace (( ERR_OUT, "Dest port = %d", VPtSocket->ParDestPort )); + err_trace (( ERR_OUT, "Ack TO = %d", VPtSocket->ParAckTimeOutMs )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( VSenderPortContextId, ( ERR_OUT, "Emission port=%d installed - uses context record=%d", VPtSocket->ParDestPort, VSenderPortContextId ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 14/01/2009 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockRebootSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSocket; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + /* ------------ */ + /* Check status */ + /* ------------ * + + if ( VPtSocket->Installed != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access not installed => Can't be started" ) ); + } + + + /* ------------ */ + /* Reset status */ + /* ------------ */ + + VPtSocket->Started = 0; + + + /* ------------ */ + /* Close Socket */ + /* ------------ */ + + closesocket ( VPtSocket->Socket ); + + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->Socket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->Socket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short)0 ); + + if ( bind( VPtSocket->Socket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Transform the host/port into a struct sockaddr + + VPtSocket->DestAddr = IAC__PRIV_FTcpFormatAdress ( VPtSocket->ParDestHost, (u_short) (VPtSocket->ParDestPort) ); + + // Connect + + while ( connect( VPtSocket->Socket, &(VPtSocket->DestAddr), sizeof(VPtSocket->DestAddr) ) == SOCKET_ERROR ) { + err_error (( ERR_OUT, "Connect () error %d => %s WILL RETRY in 100 ms", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + Sleep ( 100 ); + } + + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Started = 1; + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] started", VPtSocket->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 13/01/2009 + : - Add closesocket call +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockUnInstallSenderPort ( SInt32 SenderPortContextId ) { + + IAC__TSockSenderPort* VPtSocket; + + err_retfail ( IAC__PRIV_FChkSenderContextId (SenderPortContextId), (ERR_OUT,"Bad Id=%d", SenderPortContextId ) ); + + VPtSocket = &(IAC__VGContext.Sock.ASenderPort[SenderPortContextId]); + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSocket->Installed = 0; + + /* ------------- */ + /* Close events */ + /* ------------- */ + + if ( CloseHandle ( VPtSocket->EvNewMsgHnd ) == 0 ) { + err_error (( ERR_OUT, "CloseHandle ( VPtSocket->EvNewMsgHnd ) failed !" )); + } + + if ( CloseHandle ( VPtSocket->EvAckMsgHnd ) == 0 ) { + err_error (( ERR_OUT, "CloseHandle ( VPtSocket->EvAckMsgHnd ) failed !" )); + } + + /* ------------ */ + /* Close Socket */ + /* ------------ */ + + closesocket ( VPtSocket->Socket ); + + /* ------------ */ + /* Free buffers */ + /* ------------ */ + + if ( VPtSocket->PtBuffSendShortMsg != NULL ) { + free ( VPtSocket->PtBuffSendShortMsg ); + } + + else { + err_error (( ERR_OUT, "Try to free PtBuffSendShortMsg, but it's already NULL => ???" )); + } + + + /* --------------- */ + /* Release context */ + /* --------------- */ + + IAC__PRIV_FSockFreeSenderPortContext ( SenderPortContextId ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStartSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSocket; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSocket = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + /* ------------ */ + /* Check status */ + /* ------------ * + + if ( VPtSocket->Installed != 1 ) { + err_retfail ( -1, (ERR_OUT,"Access not installed => Can't be started" ) ); + } + + /* --------------------- */ + /* Create & Start thread */ + /* --------------------- */ + + VPtSocket->ThreadHnd = CreateThread( NULL, NULL, IAC__PRIV_FSockSenderThreadFunc, (LPVOID) VPtSocket, NULL, &(VPtSocket->ThreadId) ); + + err_retnull ( VPtSocket->ThreadHnd, (ERR_OUT,"Thread creation failed !") ); + + VPtSocket->ThreadFunc = IAC__PRIV_FSockSenderThreadFunc; + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Started = 1; + + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%d] started", VPtSocket->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStopSenderPort ( SInt32 ContextId ) { + + IAC__TSockSenderPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkSenderContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.ASenderPort[ContextId]; + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread handle == NULL !") ); + + /* ---------------- */ + /* Terminate thread */ + /* ---------------- */ + + TerminateThread ( VPtSock->ThreadHnd, -1 /* Thread exit code */ ); + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 0; + + err_trace (( ERR_OUT, "TerminateThread sent - with exit code = -1" )); + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Sender port [%] terminated", VPtSock->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + return (0); + +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Rev : 06/11/2008 + : - Add LongMsg Handling + : 10/11/2008 + : - Rewritten => No socket close after each message + : 11/11/2008 + : - New header & trailer +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockInstallReceiverPort ( UInt32 RecPort, SInt8 LongMsg, IAC__TFSockUsrHandleRecMsg FuncUsr, IAC__TFSockFuncCheckSum FuncCheckSum ) { + + SInt32 VRecPortContextId; + IAC__TSockReceiverPort* VPtSocket; + UInt8* VPtRecBuffer; + + /* --------------------------------- */ + /* Find a free sender context record */ + /* --------------------------------- */ + + VRecPortContextId = IAC__PRIV_FSockGetReceiverPortContext (); + + err_retfail ( VRecPortContextId, (ERR_OUT,"No free context record !") ); + + VPtSocket = &(IAC__VGContext.Sock.AReceiverPort[VRecPortContextId]); + VPtSocket->Id = VRecPortContextId; + + /* --------------------- */ + /* Init constants fields */ + /* --------------------- */ + + VPtSocket->CstHeaderSz = sizeof (IAC__TSockMsgHeader ); + VPtSocket->CstTrailerSz = sizeof (IAC__TSockMsgTrailer); + + VPtSocket->MsgHeader.StartTag = IAC__SOCK_HEADER_START_TAG; + VPtSocket->MsgHeader.Zero = 0; + VPtSocket->MsgHeader.TotMsgSz = 0; // Unknown at this step + VPtSocket->MsgHeader.CheckSum = 0; // Unknown at this step + + VPtSocket->MsgTrailer.StopTag = IAC__SOCK_TRAILER_STOP_TAG; + VPtSocket->MsgTrailer.Zero = 0; + + + /* --------------- */ + /* Init parameters */ + /* --------------- */ + + + VPtSocket->Id = VRecPortContextId; + VPtSocket->ParLongMsg = LongMsg; + VPtSocket->ParPort = RecPort; + VPtSocket->ParUsrFunc = FuncUsr; + VPtSocket->ParFuncCheckSum = FuncCheckSum; + + + /* ------------------------- */ + /* Allocate reception buffer */ + /* ------------------------- */ + + + if ( VPtSocket->ParLongMsg == 0 ) { + VPtSocket->MaxMsgSz = IAC__SO_MAX_SHORT_MSG_SIZE * 2; + } + + else { + VPtSocket->MaxMsgSz = IAC__SOCK_MAX_LONG_MSG_SZ; + } + + VPtRecBuffer = (UInt8*) malloc ( VPtSocket->MaxMsgSz ); + + err_retnull ( VPtRecBuffer, (ERR_OUT,"Malloc of %d bytes for rec buffer failed !", VPtSocket->MaxMsgSz) ); + + err_trace (( ERR_OUT, "Malloc of %d bytes for Receiver port[%d]", VPtSocket->MaxMsgSz, VRecPortContextId )); + + VPtSocket->PtMsg = VPtRecBuffer; + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSocket->LSocket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSocket->LSocket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Bind + + VPtSocket->LocAddr.sin_family = AF_INET ; + VPtSocket->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSocket->LocAddr.sin_port = htons ((unsigned short) VPtSocket->ParPort ); + + if ( bind( VPtSocket->LSocket, (struct sockaddr *)&(VPtSocket->LocAddr), sizeof(VPtSocket->LocAddr)) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSocket->Installed = 1; + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Receiver port [%d] installed", VPtSocket->Id )); + err_trace (( ERR_OUT, "Port = %d", VPtSocket->ParPort )); + err_trace (( ERR_OUT, "Long msg = %d", VPtSocket->ParLongMsg )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( VRecPortContextId, ( ERR_OUT, "Reception port=%d installed - uses context record=%d", RecPort, VRecPortContextId ) ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : The Index of Rec port context record +: +Globals : +: +Remark : +: +Level : +Date : 13/01/2009 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockRebootReceiverPort ( SInt32 ContextId ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ------------ */ + /* Reset status */ + /* ------------ */ + + VPtSock->Installed = 0; + + /* ------------- */ + /* Close ASocket */ + /* ------------- */ + + closesocket ( VPtSock->ASocket ); + + /* ------------- */ + /* Close LSocket */ + /* ------------- */ + + closesocket ( VPtSock->LSocket ); + + + /* --------------- */ + /* Create socket */ + /* --------------- */ + + // Create + + VPtSock->LSocket = socket ( PF_INET, SOCK_STREAM, 0 ); + + if ( VPtSock->LSocket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"socket () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + // Bind + + VPtSock->LocAddr.sin_family = AF_INET ; + VPtSock->LocAddr.sin_addr.s_addr = htonl (INADDR_ANY); + VPtSock->LocAddr.sin_port = htons ((unsigned short) VPtSock->ParPort ); + + if ( bind( VPtSock->LSocket, (struct sockaddr *)&(VPtSock->LocAddr), sizeof(VPtSock->LocAddr)) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"bind () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Installed = 1; + + + /* ---------------------- */ + /* Wait client connection */ + /* ---------------------- */ + + // Listen + + err_trace (( ERR_OUT, "Before listen" )); + + if ( listen( VPtSock->LSocket, 2) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"listen () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Before accept" )); + + // Accept + + VPtSock->ASocket = accept ( VPtSock->LSocket, NULL, NULL ); + + if( VPtSock->ASocket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"accept () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Reboot of Receiver port [%d] done", VPtSock->Id )); + err_trace (( ERR_OUT, "Port = %d", VPtSock->ParPort )); + err_trace (( ERR_OUT, "Long msg = %d", VPtSock->ParLongMsg )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + err_retval ( ContextId, ( ERR_OUT, "Reception port Id=%d reboot", ContextId ) ); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__FSockUnInstallReceiverPort ( SInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (RecPortContextId), (ERR_OUT,"Bad Id=%d", RecPortContextId ) ); + VPtSock = &IAC__VGContext.Sock.AReceiverPort[RecPortContextId ]; + + /* ------------- */ + /* Set status */ + /* ------------- */ + + VPtSock->Installed = 0; + VPtSock->Started = 0; + + /* ------------- */ + /* Close LSocket */ + /* ------------- */ + + closesocket ( VPtSock->LSocket ); + + /* ------------- */ + /* Free buffer */ + /* ------------- */ + + if ( VPtSock->PtMsg != NULL ) { + free ( VPtSock->PtMsg ); + } + + VPtSock->MaxMsgSz = 0; + + IAC__PRIV_FSockFreeReceiverPortContext ( RecPortContextId ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStartReceiverPort ( SInt32 ContextId ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* --------------------- */ + /* Start thread function */ + /* --------------------- */ + + err_trace (( ERR_OUT, "Call CreateThread (...)" )); + + VPtSock->ThreadHnd = CreateThread( NULL, NULL, IAC__PRIV_FSockReceiverThreadFunc, (LPVOID) VPtSock, NULL, &(VPtSock->ThreadId) ); + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread creation failed !") ); + + VPtSock->ThreadFunc = IAC__PRIV_FSockReceiverThreadFunc; + + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 1; + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockStopReceiverPort ( SInt32 ContextId ) { + + SInt8 VThreadKillOk; + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ---------- */ + /* Set status */ + /* ---------- */ + + VPtSock->Started = 0; + + /* -------------------- */ + /* Kill thread function */ + /* -------------------- */ + + err_retnull ( VPtSock->ThreadHnd, (ERR_OUT,"Thread handle == NULL !") ); + + VThreadKillOk = TerminateThread ( VPtSock->ThreadHnd, -1 /* Thread exit code */ ); + + err_trace (( ERR_OUT, "TerminateThread sent - Return Ok ? = %d", VThreadKillOk )); + + /* ------------- */ + /* Close ASocket */ + /* ------------- */ + + closesocket ( VPtSock->ASocket ); + + err_retok (( ERR_OUT, "Receiver port Id=%d stopped", ContextId )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : For debugging only => Disable call to IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt + : in thread function +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/01/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__FSockDbgReceiverPortDisableReception ( SInt32 ContextId, SInt8 DisableReception ) { + + IAC__TSockReceiverPort* VPtSock; + + /* -------- */ + /* Check ID */ + /* -------- */ + + err_retfail ( IAC__PRIV_FChkReceiverContextId (ContextId), (ERR_OUT,"Bad Id=%d", ContextId ) ); + + VPtSock = &IAC__VGContext.Sock.AReceiverPort[ContextId]; + + /* ------------- */ + /* Set parameter */ + /* ------------- */ + + VPtSock->DbgDisableReception = DisableReception; + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header, add trailer + : 13/01/2009 + : - Return -2 if recv failed on connection lost in order to infrom caller to + : " reboot " the receiver + : +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VRecSz; + SInt32 VAckSentSz; + IAC__TSockMsgHeader* VPtHeader; + IAC__TSockMsgTrailer* VPtTrailer; + SInt32 VUserDataSz; + SInt32 VCheckSum; + SInt32 VSockErrno; + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + + while (1) { + + + // Init status + + VPtSock->MsgReady = 0; + + // Read + + VRecSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[0]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "RecSz=%d", VRecSz )); + + if( VRecSz <= 0 ) { + + VSockErrno = IAC__SOCKET_ERRNO; + + err_error (( ERR_OUT, "VRecSz=%d - IAC__SOCKET_ERRNO=%d", VRecSz, VSockErrno )); + + /* --------------------------------------------------------------------------------- */ + /* If connection has been lost */ + /* => return -2 */ + /* => caller will detected this special error and will try to reboot the receiver */ + /* --------------------------------------------------------------------------------- */ + + if ( (VRecSz == 0) || (VSockErrno == WSAECONNRESET) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost ! VRecSz=%d - IAC__SOCKET_ERRNO=%d => %s", VRecSz, VSockErrno, strerror (VSockErrno) )); + } + + /* ------------------------------- */ + /* Normal error => Not recoverable */ + /* ------------------------------- */ + + else { + err_retfail ( -1, (ERR_OUT,"recv () error %d => %s", VSockErrno, strerror (VSockErrno) )); + } + + } + + // Check header & trailer & CS + + VPtHeader = (IAC__TSockMsgHeader*) VPtSock->PtMsg; + + if ( VPtHeader->StartTag != IAC__SOCK_HEADER_START_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad header start tag=%x [H] - Must be %x [H]", VPtHeader->StartTag, IAC__SOCK_HEADER_START_TAG ) ); + } + + if ( VPtHeader->TotMsgSz != VRecSz ) { + err_retfail ( -1, (ERR_OUT,"Header tot sz=%d <> Received sz=%d", VPtHeader->TotMsgSz, VRecSz ) ); + } + + VPtTrailer = (IAC__TSockMsgTrailer*) &(VPtSock->PtMsg[VRecSz-(VPtSock->CstTrailerSz)]); + + if ( VPtTrailer->StopTag != IAC__SOCK_TRAILER_STOP_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad trailer stop tag=%x [H] - Must be %x [H]", VPtTrailer->StopTag, IAC__SOCK_TRAILER_STOP_TAG ) ); + } + + VUserDataSz = VRecSz - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz); + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VCheckSum = VPtSock->ParFuncCheckSum ( &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + + if ( VCheckSum != VPtHeader->CheckSum ) { + err_retfail ( -1, (ERR_OUT,"Checksum error : Calculated=%d <> From Header=%d", VCheckSum, VPtHeader->CheckSum ) ); + } + + err_trace (( ERR_OUT, "Checksum OK = %d", VCheckSum )); + + } + + + // Set status + + VPtSock->MsgSz = VRecSz; + VPtSock->MsgReady = 1; + + // Call user function + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VPtSock->MsgSz, &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + } + + err_trace (( ERR_OUT, "Message received => %d bytes", VRecSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VRecSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + break; /* Exit of while (1) at end of processing */ + + } /* End while (1) */ + + return (VRecSz); +} + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/11/2008 +Rev : 11/11/2008 + : - New header & trailer + : 13/01/2009 + : - Return -2 if recv failed on connection lost +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 IAC__PRIV_FSockLookForLongRecMsgOnPortAndProcessIt ( UInt32 RecPortContextId ) { + + IAC__TSockReceiverPort* VPtSock; + SInt8 VMsgReceptionRuning; + SInt32 VMsgSzFromHeader; + SInt32 VCheckSumFromHeader; + SInt32 VAckSentSz; + SInt32 VRecBlocSz ; + SInt32 VTotRecSz ; + IAC__TSockMsgHeader* VPtMayBeHeader; + IAC__TSockMsgTrailer* VPtTrailer; + SInt32 VUserDataSz; + SInt32 VCheckSum; + SInt32 VSockErrNo; + + + + VPtSock = &(IAC__VGContext.Sock.AReceiverPort[RecPortContextId]); + + // Init status + + VPtSock->MsgReady = 0; + + VMsgReceptionRuning = 0; + VRecBlocSz = 0; + VTotRecSz = 0; + + + + while (1) { + + // Read + + VRecBlocSz = recv ( VPtSock->ASocket, &(VPtSock->PtMsg[VTotRecSz]), VPtSock->MaxMsgSz, 0 ); + + err_trace (( ERR_OUT, "VRecBlocSz=%d", VRecBlocSz )); + + // If no data + +/* BEFORE 14/01/09 + + if( VRecBlocSz <= 0 ) { + + if ( (VRecBlocSz == 0) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost !") ); + } + + else { + err_warning (( ERR_OUT, "recv () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + continue; + } + + } + +*/ + + if( VRecBlocSz <= 0 ) { + + VSockErrNo = IAC__SOCKET_ERRNO; + + err_error (( ERR_OUT, "VRecSz=%d - IAC__SOCKET_ERRNO=%d", VRecBlocSz, VSockErrNo )); + + /* --------------------------------------------------------------------------------- */ + /* If connection has been lost */ + /* => return -2 */ + /* => caller will detected this special error and will try to reboot the receiver */ + /* --------------------------------------------------------------------------------- */ + + if ( (VRecBlocSz == 0) || (VSockErrNo == WSAECONNRESET) ) { + err_retfail ( -2, (ERR_OUT,"Connection lost ! VRecSz=%d - IAC__SOCKET_ERRNO=%d => %s", VRecBlocSz, VSockErrNo, strerror (VSockErrNo) )); + } + + /* ------------------------- */ + /* Normal warning => No data */ + /* ------------------------- */ + + else { + err_warning (( ERR_OUT, "recv () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + continue; + } + + } + + + + // If data + + // If it's message header + + /* ---------------------------------------------------------------------------------- */ + /* - WARNING - */ + /* ---------------------------------------------------------------------------------- */ + /* VPtMayBeHeader points to a valid header ONLY when current received block is header */ + /* On next blocks VPtMayBeHeader points to a something which IS NOT a header */ + /* Therefore if you need to access to header fields LATER you must do a copy of */ + /* these fields WHEN header is detected and use this copy NOT VPtMayBeHeader fields */ + /* ---------------------------------------------------------------------------------- */ + + VPtMayBeHeader = (IAC__TSockMsgHeader*) &(VPtSock->PtMsg[VTotRecSz]); + + if ( VPtMayBeHeader->StartTag == IAC__SOCK_HEADER_START_TAG ) { + + // Do a copy of useful header fields + + VMsgSzFromHeader = VPtMayBeHeader->TotMsgSz; + VCheckSumFromHeader = VPtMayBeHeader->CheckSum; + + VPtSock->MsgReady = 0; + + VMsgReceptionRuning = 1; + VTotRecSz = 0; + + err_trace (( ERR_OUT, "Message header tag = %x [H] - MsgSz=%d", VPtMayBeHeader->StartTag, VMsgSzFromHeader )); + err_trace (( ERR_OUT, "Message header received of %d bytes", VRecBlocSz )); + + VTotRecSz = VTotRecSz + VRecBlocSz; + } + + // If it's not message header + + else { + + // If it's not message header AND we are not in message recpetion phase => Message not for us + + if ( VMsgReceptionRuning == 0 ) { + err_retfail ( -1, (ERR_OUT,"Unknown message ! Not header / Not data part") ); + } + + // It's a data block => increment total size + + VTotRecSz = VTotRecSz + VRecBlocSz; + + err_trace (( ERR_OUT, "At this step tot received size of %d bytes", VTotRecSz )); + } + + // End of message reached + + if ( VTotRecSz >= VMsgSzFromHeader ) { + VMsgReceptionRuning = 0; + + // Check message size + + if ( VMsgSzFromHeader != VTotRecSz ) { + err_retfail ( -1, (ERR_OUT,"Header tot sz=%d <> Received sz=%d", VMsgSzFromHeader, VTotRecSz ) ); + } + + // Check trailer value + + VPtTrailer = (IAC__TSockMsgTrailer*) &(VPtSock->PtMsg[VTotRecSz-(VPtSock->CstTrailerSz)]); + + if ( VPtTrailer->StopTag != IAC__SOCK_TRAILER_STOP_TAG ) { + err_retfail ( -1, (ERR_OUT,"Bad trailer stop tag=%x [H] - Must be %x [H]", VPtTrailer->StopTag, IAC__SOCK_TRAILER_STOP_TAG ) ); + } + + // Calculate size of message user part + + VUserDataSz = VTotRecSz - (VPtSock->CstHeaderSz) - (VPtSock->CstTrailerSz); + + // Compare checksum + + if ( VPtSock->ParFuncCheckSum != NULL ) { + VCheckSum = VPtSock->ParFuncCheckSum ( &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + + if ( VCheckSum != VCheckSumFromHeader ) { + err_retfail ( -1, (ERR_OUT,"Checksum error : Calculated=%d <> From Header=%d", VCheckSum, VCheckSumFromHeader ) ); + } + + err_trace (( ERR_OUT, "Checksum OK = %d", VCheckSum )); + + } + + // Good message received + + VPtSock->MsgSz = VTotRecSz; + VPtSock->MsgReady = 1; + + if ( VPtSock->ParUsrFunc != NULL ) { + VPtSock->ParUsrFunc ( VPtSock->PtMsg, VTotRecSz, &(VPtSock->PtMsg[VPtSock->CstHeaderSz]), VUserDataSz ); + } + + err_trace (( ERR_OUT, "Enf of message reception => %d bytes", VTotRecSz )); + + // Send back size of message + + VAckSentSz = send ( VPtSock->ASocket, (SInt8*) &VTotRecSz, 4, 0 ); + + if( VAckSentSz == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"send () Ack error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + VMsgReceptionRuning = 0; + VRecBlocSz = 0; + VTotRecSz = 0; + + break; + } + + + } /* End while (1) */ + + + return (VTotRecSz); + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/11/2008 +Rev : 13/01/2009 + : - Wait for a receicer if connect failed +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +DWORD WINAPI IAC__PRIV_FSockSenderThreadFunc ( LPVOID lpParam ) { + + IAC__TSockSenderPort* VPtSock = (IAC__TSockSenderPort*) lpParam; + + + err_error (( ERR_OUT, "BEGINNING of IAC__PRIV_FSockSenderThreadFunc" )); + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Thread execution of sender port [%d] started", VPtSock ->Id )); + err_trace (( ERR_OUT, "Dest host = %s", VPtSock ->ParDestHost )); + err_trace (( ERR_OUT, "Dest port = %d", VPtSock ->ParDestPort )); + err_trace (( ERR_OUT, "Ack TO = %d", VPtSock ->ParAckTimeOutMs )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + + /* -------------------- */ + /* Connect to dest host */ + /* -------------------- */ + + err_warning (( ERR_OUT, "IAC__PRIV_FSockSenderThreadFunc Try to connect ..." )); + + // Blocking mode socket + + /* ----------------------------------------------- */ + /* Try to connect until a receiver is detected */ + /* if connection failed, it waits 100 ms and retry */ + /* ----------------------------------------------- */ + /* Before 13/01/09 it was a single call to connect */ + /* followed by retfail to abort in case of error */ + /* ----------------------------------------------- */ + + while ( connect( VPtSock->Socket, &(VPtSock->DestAddr), sizeof(VPtSock->DestAddr) ) == SOCKET_ERROR ) { + err_error (( ERR_OUT, "Connect () error %d => %s WILL RETRY in 100 ms", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + Sleep ( 100 ); + } + + err_warning (( ERR_OUT, "Sender [%d] connection to Host %s Port %d done :-)", VPtSock->Id, VPtSock->ParDestHost, VPtSock->ParDestPort )); + + /* --------------------- */ + /* Messages sending loop */ + /* --------------------- */ + + while (1) { + + // Wait event + + if ( VPtSock->EvNewMsgHnd != NULL ) { + WaitForSingleObject ( VPtSock->EvNewMsgHnd, INFINITE /* dwTimeout */ ); + } + + // Send message + + if ( VPtSock->ParLongMsg == 0 ) { + VPtSock->SendStatus = IAC__PRIV_FSockSendShortMsg ( VPtSock->Id ); + } + + else { + VPtSock->SendStatus = IAC__PRIV_FSockSendLongMsg ( VPtSock->Id ); + } + + + // Send Ack event + + if ( PulseEvent ( VPtSock->EvAckMsgHnd ) == TRUE ) { + err_trace (( ERR_OUT, "Event EvAckMsgHnd sent" )); + } + + + } /* End while (1) */ + + + + err_error (( ERR_OUT, "END of IAC__PRIV_FSockSenderThreadFunc" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 05/01/2008 +Rev : 10/11/2008 +Doc date : //2008 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +DWORD WINAPI IAC__PRIV_FSockReceiverThreadFunc ( LPVOID lpParam ) { + + IAC__TSockReceiverPort* VPtSock = (IAC__TSockReceiverPort*) lpParam; + SInt32 VRet; + + + /* ------------- */ + /* Debug print */ + /* ------------- */ + + err_trace (( ERR_OUT, "----------------------------------------------------" )); + err_trace (( ERR_OUT, "Thread execution of receiver port [%d] started", VPtSock->Id )); + err_trace (( ERR_OUT, "----------------------------------------------------" )); + + + /* ---------------------- */ + /* Wait client connection */ + /* ---------------------- */ + + // Listen + + err_trace (( ERR_OUT, "Before listen" )); + + if ( listen( VPtSock->LSocket, 2) == SOCKET_ERROR ) { + err_retfail ( -1, (ERR_OUT,"listen () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Before accept" )); + + // Accept + + VPtSock->ASocket = accept ( VPtSock->LSocket, NULL, NULL ); + + if( VPtSock->ASocket == INVALID_SOCKET ) { + err_retfail ( -1, (ERR_OUT,"accept () error %d => %s", IAC__SOCKET_ERRNO, strerror (IAC__SOCKET_ERRNO) )); + } + + err_trace (( ERR_OUT, "Before loop" )); + + /* ---------------------- */ + /* Reception loop */ + /* ---------------------- */ + + while (1) { + + if ( VPtSock->DbgDisableReception == 1 ) { + continue; + } + + if ( VPtSock->ParLongMsg == 0 ) { + VRet = IAC__PRIV_FSockLookForShortRecMsgOnPortAndProcessIt ( VPtSock->Id ); + } + + else { + VRet = IAC__PRIV_FSockLookForLongRecMsgOnPortAndProcessIt ( VPtSock->Id ); + } + + if ( VRet == -2 ) { + Sleep ( 100 ); + err_error (( ERR_OUT, "IAC__FSockRebootReceiverPort called !" )); + IAC__FSockRebootReceiverPort ( VPtSock->Id ); + } + + + } /* End while (1) */ + + + return (0); +} + + + + + +#endif + + + + + + + + + + + + diff --git a/include/pxi_daq_lib_v.2.1/inter_app_com.typ b/include/pxi_daq_lib_v.2.1/inter_app_com.typ new file mode 100755 index 0000000..9cc364b --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/inter_app_com.typ @@ -0,0 +1,336 @@ + +/******************************************************************************* +File : x:\lib\com\inter_app_com\inter_app_com.typ +Goal : Types definition of inter applications communication library. +Prj date : 05/12/2007 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef INTER_APP_COM_TYP +#define INTER_APP_COM_TYP + + + +/* ============== */ +/* */ +/* ============== */ + +// ------------------------------------------------------- +// Commands RMP +// ------------------------------------------------------- + +// Ask run status + +typedef struct { + + SInt32 ParRunNo; + SInt32 ParEventNb; + char ParRunDir[GLB_FILE_PATH_SZ]; + + SInt8 ResRunning; + SInt32 ResCurEvNb; + +} + +#ifdef ROOT_SCRIPT + RS__IAC__RMP_TRunStatusAnswer; +#else + IAC__RMP_TRunStatusAnswer; +#endif + + +typedef SInt32 (*IAC__RMP_TFuncRunStatusAnswer ) ( COM_TCommand* PtCmd, IAC__RMP_TRunStatusAnswer* PtAns ); + + +// Ask run status 2 + +typedef struct { + + SInt32 ParRunNo; + SInt32 ParEventNb; + char ParRunDir[GLB_FILE_PATH_SZ]; + + SInt8 ResRunning; + SInt32 ResCurEvNb; + + char ResPadding[157]; + +} IAC__RMP_TRunStatusAnswer2; + + +typedef SInt32 (*IAC__RMP_TFuncRunStatusAnswer2 ) ( COM_TCommand* PtCmd, IAC__RMP_TRunStatusAnswer2* PtAns ); + + + +// Ask event + + +typedef struct { + + SInt32 EvNb; + SInt32 TestTag; + +} IAC__RMP_TAskEventPar; + +typedef struct { + + SInt32 CmdEvNbRequested; + + SInt32 ResEvNbAvailable; + SInt32 AResEvSz [IAC__RMP_MAX_EV_NB_REQUEST]; + SInt32 AResEvOffset[IAC__RMP_MAX_EV_NB_REQUEST]; + +} + +#ifdef ROOT_SCRIPT + RS__IAC__RMP_TAskEventAnswer; +#else + IAC__RMP_TAskEventAnswer; +#endif + +typedef SInt32 (*IAC__RMP_TFuncAskEventAnswer ) ( COM_TCommand* PtCmd, IAC__RMP_TAskEventAnswer* PtAns ); + + +// ------------------------------------------------------- +// Socket handling +// ------------------------------------------------------- + + +#ifdef ROOT_ROOT + + typedef void* (*IAC__TFSockReceiverThread) ( void* lpParam ); + +#else + + typedef DWORD WINAPI (*IAC__TFSockReceiverThread) ( LPVOID lpParam ); + typedef DWORD WINAPI (*IAC__TFSockSenderThread) ( LPVOID lpParam ); + +#endif + + +// typedef DWORD WINAPI (*IAC__TFSockSenderThread) ( LPVOID lpParam ); // moved on 26/01/09 + +typedef SInt32 (*IAC__TFSockUsrHandleRecMsg) (UInt8* PtMsg, UInt32 MsgSz, UInt8* PtUsrData, UInt32 UsrDataSz ); + +typedef SInt32 (*IAC__TFSockFuncCheckSum) ( UInt8* PtData, UInt32 DataSz ); + +typedef struct { + + UInt32 StartTag; + UInt8 Zero; + UInt32 TotMsgSz; + UInt32 CheckSum; + +} IAC__TSockMsgHeader; + + +typedef struct { + + UInt32 StopTag; + UInt8 Zero; + +} IAC__TSockMsgTrailer; + + + +#ifndef ROOT_ROOT + +typedef struct { + + UInt8 Id; + UInt8 Used; + UInt8 Installed; + UInt8 Started; + + UInt16 CstHeaderSz; + UInt16 CstTrailerSz; + + IAC__TSockMsgHeader MsgHeader; + IAC__TSockMsgTrailer MsgTrailer; + + char ParDestHost[IAC__SOCK_MAX_STR_HOST_SZ]; + UInt32 ParDestPort; + UInt8 ParLongMsg; + UInt32 ParAckTimeOutMs; + UInt8 ParRetryNb; + UInt8* ParPtMsg; + UInt32 ParMsgSz; + IAC__TFSockFuncCheckSum ParFuncCheckSum; + + UInt8* PtBuffSendShortMsg; + UInt8 BuffRecAck[IAC__SOCK_ACK_SZ]; + + + IAC__TFSockSenderThread ThreadFunc; + + SOCKET Socket; + struct sockaddr_in LocAddr; + struct sockaddr DestAddr; + + + + HANDLE ThreadHnd; + DWORD ThreadId; + HANDLE EvNewMsgHnd; // New message to send + HANDLE EvAckMsgHnd; // Acknowledge received from message receiver + + SInt32 SendStatus; + +} IAC__TSockSenderPort; + + +typedef struct { + + UInt8 Id; + UInt8 Used; + UInt8 Installed; + UInt8 Started; + + UInt8 MsgReady; + + UInt16 CstHeaderSz; + UInt16 CstTrailerSz; + + IAC__TSockMsgHeader MsgHeader; + IAC__TSockMsgTrailer MsgTrailer; + + + UInt32 ParPort; + SInt8 ParLongMsg; // 0 short message - 1 long message + IAC__TFSockUsrHandleRecMsg ParUsrFunc; + IAC__TFSockFuncCheckSum ParFuncCheckSum; + + SOCKET LSocket; // Listen socket + SOCKET ASocket; // Accept socket + struct sockaddr_in LocAddr; + + + IAC__TFSockReceiverThread ThreadFunc; + HANDLE ThreadHnd; + DWORD ThreadId; + + UInt8* PtMsg; + UInt32 MaxMsgSz; + UInt32 MsgSz; + + + SInt32 DbgDisableReception; + + // Fields to removr later + + UInt8 Run; // ??? + SOCKET Socket; // ??? + SOCKET Accept; // ??? + +} IAC__TSockReceiverPort; + + +typedef struct { + + SInt8 InitDone; + + SInt32 SenderPortNb; + IAC__TSockSenderPort ASenderPort[IAC__SOCK_MAX_SENDER_PORT_NB]; + + SInt32 ReceiverPortNb; + IAC__TSockReceiverPort AReceiverPort[IAC__SOCK_MAX_REC_PORT_NB]; + +} IAC__TSockContext; + +#endif + +// ------------------------------------------------------- +// IAC__TWho => Record which identifies sender / receiver +// ------------------------------------------------------- + +typedef struct { + + char PcName[IAC__TWHO_MAX_NAME_SZ]; + char ApplicationName[IAC__TWHO_MAX_NAME_SZ]; + SInt16 ApplicationInstance; + char ApplicationCommonDir[GLB_FILE_PATH_SZ]; + +} IAC__TWho; + + +// ------------------------------------------------------- +// IAC_TMsgHeader => Message header +// ------------------------------------------------------- + +typedef struct { + + char MsgIdStr[IAC__MSG_ID_STR_SZ]; + SInt32 MsgTotSz; + SInt32 MsgDataSz; + + SInt8 Priority; + SInt8 Type; + SInt16 SubType; + + IAC__TWho From; + IAC__TWho To; + +} IAC_TMsgHeader; + +// ------------------------------------------------------- +// IAC__TMsg => Message +// ------------------------------------------------------- + +typedef struct { + + IAC_TMsgHeader Header; + UInt8 Data; + +} IAC__TMsg; + + +// ------------------------------------------------------- +// IAC__TRmpContext => RMP +// ------------------------------------------------------- + +typedef struct { + + SInt8 CmdComPcObjId; + SInt8 CmdComUcObjId; + + UInt16 CmdGetCmdResLoopPeriod; + SInt32 CmdGetCmdResTryNb; + + SInt8 DataComPcObjId; + SInt8 DataComUcObjId; + + IAC__RMP_TFuncRunStatusAnswer FuncRunStatusAnswer; + IAC__RMP_TFuncRunStatusAnswer2 FuncRunStatusAnswer2; + IAC__RMP_TFuncAskEventAnswer FuncAskEventAnswer; + +} IAC__TRmpContext; + +// ------------------------------------------------------- +// IAC__TContext => Lib context +// ------------------------------------------------------- + +typedef struct { + + SInt8 InitDone; + + IAC__TRmpContext Rmp; + + #ifndef ROOT_ROOT + IAC__TSockContext Sock; + #endif + +} IAC__TContext; + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/inter_app_com.var b/include/pxi_daq_lib_v.2.1/inter_app_com.var new file mode 100755 index 0000000..999cb7d --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/inter_app_com.var @@ -0,0 +1,36 @@ + +/******************************************************************************* +File : x:\lib\com\inter_app_com\inter_app_com.var +Goal : Variables definition of inter applications communication library. +Prj date : 05/12/2007 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef INTER_APP_COM_VAR +#define INTER_APP_COM_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN VAR_STATIC SInt8 IAC__VGMyVar VAR_INIT(0); + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC IAC__TContext IAC__VGContext; + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/maps.c b/include/pxi_daq_lib_v.2.1/maps.c new file mode 100755 index 0000000..6a496a3 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/maps.c @@ -0,0 +1,1241 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.c +Goal : Functions of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_C +#define MAPS_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef ROOT_ROOT + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Rev : 20/05/2010 + : - Set PubPt_ADispCumFrTrigNb items to NULL because they willnot be available + : on previous GUI version => they will be updated by PubFSetGuiRes ONLY if <> NULL. + : +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 MAPS__TCDigTelMon::PrivFInit () { + + SInt8 Vi; + + // Reset all parameters and results fields + + memset ( &ProPar , 0, sizeof (MAPS__TDigTelPar) ); + memset ( &ProInf , 0, sizeof (MAPS__TDigTelInf) ); + memset ( ProAPlanePar , 0, MAPS__TCDigTelMon_MAX_PLANE_NB * sizeof (MAPS__TDigTelPlanePar) ); + memset ( ProAPlaneData, 0, MAPS__TCDigTelMon_MAX_PLANE_NB * sizeof (MAPS__TDigTelPlaneData) ); + memset ( ProAPlaneRes , 0, MAPS__TCDigTelMon_MAX_PLANE_NB * sizeof (MAPS__TDigTelPlaneRes) ); + + // Set default values for flags + + PrivGuiConnected = -1; + PrivSetGuiParDontRead = 0; + ProRequestPlot = 0; + + // Set default values for GUI parameters + + ProPar.ProcOneAcq = 1; + ProPar.ProcEvNb = 100; + + + for ( Vi=0; Vi < MAPS__TCDigTelMon_MAX_PLANE_NB; Vi++ ) { + ProAPlaneInf[Vi].PrevProcState = -1; + + PubPt_ADispCumFrTrigNb[Vi] = NULL; + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PrivChkPlaneId ( SInt8 Id ) { + + if ( (Id < 0 ) ||(Id >= MAPS__TCDigTelMon_MAX_PLANE_NB) ) { + return (-1); + } + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 05/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PrivFSetGuiLabelsDispFrNbWithTrigOrFrNbWithHit () { + + // Display frame nb with trigger + + if ( ProPar.DispFrNbWithTrigOrFrNbWithHit == 0 ) { + PubPt_LbFrNbWithTrigOrHit->Caption = "Frames nb with trig"; + PubPt_LbFrPCentWithTrigOrHit->Caption = "Frames % with trig"; + } + + // Display frame nb with hit + + else { + PubPt_LbFrNbWithTrigOrHit->Caption = "Frames nb with hit"; + PubPt_LbFrPCentWithTrigOrHit->Caption = "Frames % with hit"; + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +MAPS__TCDigTelMon::MAPS__TCDigTelMon () { + + err_error (( ERR_OUT, "TRACE" )); + + PrivFInit (); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +MAPS__TCDigTelMon::~MAPS__TCDigTelMon () { +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + + + err_retok (( ERR_OUT, "" )); +} + +// GUI BEGIN + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFConnectGui () { + + SInt8 Vi; + + PrivGuiConnected = 1; + + // Set default paramters values + + PubFSetGuiPar (); + + // Disable all planes processing + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++) { + PubFGuiEnablePlane (Vi, 0); + } + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFGuiEnablePlane ( SInt8 Id, SInt8 Enable ) { + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + PubPt_ARbPlotCum[Id]->Enabled = (bool) Enable; + PubPt_AChkPlotCoin[Id]->Enabled = (bool) Enable; + PubPt_ARdPlotFr[Id]->Enabled = (bool) Enable; + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFSetGuiPar () { + + SInt8 Vi; + + err_retfail ( PrivGuiConnected, (ERR_OUT,"GUI not connected !") ); + + PrivSetGuiParDontRead = 1; + + PubPt_ChkEnableMonitor->Checked = (bool) ProPar.MonEnabled; + + + FDecInt2Edit ( ProPar.ProcEvNb, PubPt_EdFrNbToProc ); + FDecInt2Edit ( ProPar.GotoRawFrNo, PubPt_EdGotoFr ); + + PubPt_ChkProcOneAcq->Checked = (bool) ProPar.ProcOneAcq; + PubPt_ChkProcOnlyFrWithTrig->Checked = (bool) ProPar.ProcOnlyFrWithTrig; + + PubPt_CbListHitAllPlanesMode->ItemIndex = ProPar.ListHitAllPlanesMode; + + PubPt_ChkTrigPosHanling->Checked = (bool) ProPar.HandleTrigPos; + PubPt_ChkStopAtEndOfProc->Checked = (bool) ProPar.StopAtEndOfProc; + PubPt_ChkStoreFr->Checked = (bool) ProPar.StoreEvents; + PubPt_ChkDispFrNbWithTrigOrFrNbWithHit->Checked = (bool) ProPar.DispFrNbWithTrigOrFrNbWithHit; + + PubPt_ChkDispFullMatrix->Checked = (bool) ProPar.DispFullMatrix; + PubPt_ChkCumPlotGrayOrBlueLevels->Checked = (bool) ProPar.CumPlotGrayOrBlueLevels; + PubPt_ChkCumPlotHitOrHitCnt->Checked = (bool) ProPar.CumPlotHitOrHitCnt; + + PubPt_CbProcMode->ItemIndex = ProPar.ProcMode; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + PubPt_AChkProc[Vi]->Checked = (bool) ProAPlanePar[Vi].Process; + PubPt_AChkRevertXDir[Vi]->Checked = (bool) ProAPlanePar[Vi].RevertXDir; + PubPt_ARbPlotCum[Vi]->Checked = (bool) ProAPlanePar[Vi].PlotCum; + PubPt_AChkPlotCoin[Vi]->Checked = (bool) ProAPlanePar[Vi].PlotCoin; + PubPt_ARdPlotFr[Vi]->Checked = (bool) ProAPlanePar[Vi].PlotFrame; + } + + + PrivFSetGuiLabelsDispFrNbWithTrigOrFrNbWithHit (); + + PrivSetGuiParDontRead = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFSetGuiParGotoFr () { + + SInt8 Vi; + + + err_retfail ( PrivGuiConnected, (ERR_OUT,"GUI not connected !") ); + + PrivSetGuiParDontRead = 1; + + FDecInt2Edit ( ProPar.GotoRawFrNo, PubPt_EdGotoFr ); + + PrivSetGuiParDontRead = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFGetGuiPar () { + + SInt8 Vi; + + err_retfail ( PrivGuiConnected, (ERR_OUT,"GUI not connected !") ); + + if ( PrivSetGuiParDontRead ) { + return (0); + } + + + ProPar.MonEnabled = (SInt8) PubPt_ChkEnableMonitor->Checked; + + ProPar.ProcOnlyFrWithTrig = (SInt8) PubPt_ChkProcOnlyFrWithTrig->Checked; + + if ( ProPar.ProcOnlyFrWithTrig == 1 ) { + PrivSetGuiParDontRead = 1; + + ProPar.ProcOneAcq = 0; + PubPt_ChkProcOneAcq->Checked = false; + PubPt_ChkProcOneAcq->Enabled = false; + + PrivSetGuiParDontRead = 0; + } + + else { + PubPt_ChkProcOneAcq->Enabled = True; + ProPar.ProcOneAcq = (SInt8) PubPt_ChkProcOneAcq->Checked; + } + + ProPar.ListHitAllPlanesMode = PubPt_CbListHitAllPlanesMode->ItemIndex; + + ProPar.ProcEvNb = FEdit2DecInt ( PubPt_EdFrNbToProc ); + ProPar.GotoRawFrNo = FEdit2DecInt ( PubPt_EdGotoFr ); + + ProPar.HandleTrigPos = (SInt8) PubPt_ChkTrigPosHanling->Checked; + ProPar.StopAtEndOfProc = (SInt8) PubPt_ChkStopAtEndOfProc->Checked; + ProPar.StoreEvents = (SInt8) PubPt_ChkStoreFr->Checked; + ProPar.DispFullMatrix = (SInt8) PubPt_ChkDispFullMatrix->Checked; + + ProPar.DispFrNbWithTrigOrFrNbWithHit = (SInt8) PubPt_ChkDispFrNbWithTrigOrFrNbWithHit->Checked; + + + ProPar.ProcMode = (SInt8) PubPt_CbProcMode->ItemIndex; + + ProPar.CumPlotGrayOrBlueLevels = (SInt8) PubPt_ChkCumPlotGrayOrBlueLevels->Checked; + ProPar.CumPlotHitOrHitCnt = (SInt8) PubPt_ChkCumPlotHitOrHitCnt->Checked; + + + ProInf.LastPlaneSelForCoin = -1; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + + ProAPlanePar[Vi].Process = (SInt8) PubPt_AChkProc[Vi]->Checked; + ProAPlanePar[Vi].RevertXDir = (SInt8) PubPt_AChkRevertXDir[Vi]->Checked; + + PubFGuiEnablePlane (Vi, ProAPlanePar[Vi].Process ); + + ProAPlanePar[Vi].PlotCum = (SInt8) PubPt_ARbPlotCum[Vi]->Checked; + ProAPlanePar[Vi].PlotCoin = (SInt8) PubPt_AChkPlotCoin[Vi]->Checked; + ProAPlanePar[Vi].PlotFrame = (SInt8) PubPt_ARdPlotFr[Vi]->Checked; + + if ( ProAPlanePar[Vi].PlotCoin == 1 ) { + ProInf.LastPlaneSelForCoin = Vi; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 05/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFOnGuiParDispModeChangeFrNbWithTrigOrFrNbWithHit () { + + err_retfail ( PrivGuiConnected, (ERR_OUT,"GUI not connected !") ); + + if ( PrivSetGuiParDontRead ) { + return (0); + } + + // Get display mode parameter + + ProPar.DispFrNbWithTrigOrFrNbWithHit = (SInt8) PubPt_ChkDispFrNbWithTrigOrFrNbWithHit->Checked; + + // Update labels on fields Trig / Hit frame nb and % + + PrivFSetGuiLabelsDispFrNbWithTrigOrFrNbWithHit (); + + // Update results of fields Trig / Hit frame nb and % + + PubFSetGuiRes (); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 MAPS__TCDigTelMon::PubFSetGuiStatus () { + + SInt8 Vi; + + err_retfail ( PrivGuiConnected, (ERR_OUT,"GUI not connected !") ); + + FDecInt2Edit( ProRes.AcqFrNb , PubPt_DispAcqFrNb ); + FDecInt2Edit( ProRes.ProFrNo , PubPt_DispProFrNo ); + FDecInt2Edit( ProRes.ProTimeMs, PubPt_DispProcTimeMs ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Rev : 20/05/2010 + : - Add PubPt_ADispCumFrTrigNb update +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 MAPS__TCDigTelMon::PubFSetGuiRes () { + + SInt8 Vi; + + err_retfail ( PrivGuiConnected, (ERR_OUT,"GUI not connected !") ); + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + + // Display frame nb and % with trigger + + if ( ProPar.DispFrNbWithTrigOrFrNbWithHit == 0 ) { + FDecInt2Edit( ProAPlaneRes[Vi].FrameNbWithTrig , PubPt_ADispFrNbWithTrigOrHit[Vi] ); + FFloat2Edit ( ProAPlaneRes[Vi].FramePCentWithTrig , PubPt_ADispFrPCentWithTrigOrHit[Vi] ); + } + + // Display frame nb and % with hit(s) + + else { + FDecInt2Edit( ProAPlaneRes[Vi].FrameNbWithHit , PubPt_ADispFrNbWithTrigOrHit[Vi] ); + FFloat2Edit ( ProAPlaneRes[Vi].FramePCentWithHit , PubPt_ADispFrPCentWithTrigOrHit[Vi] ); + } + + // Update mean trig nb / frame ONLY if display pointer <> NULL + // because this GUI display is NOT available on GUI version < 20/05/2010 + + if ( PubPt_ADispCumFrTrigNb[Vi] != NULL ) { + FFloat2Edit ( ProAPlaneRes[Vi].CumFrameTrigNb, PubPt_ADispCumFrTrigNb[Vi] ); + } + + FDecInt2Edit( ProAPlaneRes[Vi].CumTotHitNb , PubPt_ADispCumTotHitNb[Vi] ); + FFloat2Edit ( ProAPlaneRes[Vi].CumFrHitNb , PubPt_ADispCumFrHitNb[Vi] ); + } + + err_retok (( ERR_OUT, "" )); +} + + + +// GUI END + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFSetPar ( MAPS__TDigTelPar* Pt ) { + + err_retnull ( Pt, (ERR_OUT,"Pt == NULL !") ); + + ProPar = *Pt; + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFSetPlanePar ( SInt8 Id, MAPS__TDigTelPlanePar* Pt ) { + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + err_retnull ( Pt, (ERR_OUT,"Pt == NULL !") ); + + ProAPlanePar[Id] = *Pt; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +MAPS__TDigTelPar* MAPS__TCDigTelMon::PubFGetPar () { + return (&ProPar); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +MAPS__TDigTelPlanePar* MAPS__TCDigTelMon::PubFGetPlanePar ( SInt8 Id ) { + + err_retfailnull ( PrivChkPlaneId (Id), (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); + + return ( &ProAPlanePar[Id] ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +MAPS__TDigTelPlaneData* MAPS__TCDigTelMon::PubFGetPlaneData ( SInt8 Id ) { + + err_retfailnull ( PrivChkPlaneId (Id), (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); + + return ( &ProAPlaneData[Id] ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFDisAllPlanesProcessing () { + + SInt8 Vi; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + ProAPlanePar[Vi].Process = 0; + } + + PubFSetGuiPar (); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFDisCumPlot () { + + SInt8 Vi; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + ProAPlanePar[Vi].PlotCum = 0; + } + + PubFSetGuiPar (); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFDisCoinPlot () { + + SInt8 Vi; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + ProAPlanePar[Vi].PlotCoin = 0; + } + + PubFSetGuiPar (); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFDisFramePlot () { + + SInt8 Vi; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + ProAPlanePar[Vi].PlotFrame = 0; + } + + PubFSetGuiPar (); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +MAPS__TDigTelPlaneRes* MAPS__TCDigTelMon::PubFSetPlaneRes ( SInt8 Id ) { + + err_retfailnull ( PrivChkPlaneId (Id), (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); + + return ( &ProAPlaneRes[Id] ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFGetPlotRqStatus () { + + return ( ProRequestPlot ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFResetPlotRqStatus () { + ProRequestPlot = 0; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt8* MAPS__TCDigTelMon::PubFGetPtPlotRq () { + + return ( &ProRequestPlot ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt8* MAPS__TCDigTelMon::PubFGetPtMonEnabled () { + return ( &ProPar.MonEnabled ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintPar () { + + msg (( MSG_OUT, "=============================" )); + msg (( MSG_OUT, "MonEnabled %4d", ProPar.MonEnabled )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "MaxBuffEvNb %4d", ProPar.MaxBuffEvNb )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "MapsNb %4d", ProPar.MapsNb )); + msg (( MSG_OUT, "MapsName %4d", ProPar.MapsName )); + msg (( MSG_OUT, "PlaneNb %4d", ProPar.PlaneNb )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "AcqFrNb %4d", ProPar.AcqFrNb )); + msg (( MSG_OUT, "ProcOneAcq %4d", ProPar.ProcOneAcq )); + msg (( MSG_OUT, "ProcEvNb %4d", ProPar.ProcEvNb )); + msg (( MSG_OUT, "ProcOnlyFrWithTrig %4d", ProPar.ProcOnlyFrWithTrig )); + msg (( MSG_OUT, "ListHitAllPlanesMode %4d", ProPar.ListHitAllPlanesMode )); + msg (( MSG_OUT, "HandleTrigPos %4d", ProPar.HandleTrigPos )); + msg (( MSG_OUT, "StopAtEndOfProc %4d", ProPar.StopAtEndOfProc )); + msg (( MSG_OUT, "StoreEvents %4d", ProPar.StoreEvents )); + msg (( MSG_OUT, "DispFrNbWith Trig / Hit %4d", ProPar.DispFrNbWithTrigOrFrNbWithHit )); + msg (( MSG_OUT, "DispFullMatrix %4d", ProPar.DispFullMatrix )); + msg (( MSG_OUT, "ProcMode %4d", ProPar.ProcMode )); + msg (( MSG_OUT, "CumPlotGrayOrBlueLevels %4d", ProPar.CumPlotGrayOrBlueLevels )); + msg (( MSG_OUT, "CumPlotHitOrHitCnt %4d", ProPar.CumPlotHitOrHitCnt )); + msg (( MSG_OUT, "PlotRawFrNo %4d", ProPar.GotoRawFrNo )); + msg (( MSG_OUT, "=============================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintInf () { + + msg (( MSG_OUT, "=========================" )); + msg (( MSG_OUT, "LastPlaneSelForCoin %4d", ProInf.LastPlaneSelForCoin )); + msg (( MSG_OUT, "CurEvNo %4d", ProInf.CurEvNo )); + msg (( MSG_OUT, "FirstEvToProc %4d", ProInf.FirstEvToProc )); + msg (( MSG_OUT, "LastEvToProc %4d", ProInf.LastEvToProc )); + msg (( MSG_OUT, "EvNbToProc %4d", ProInf.EvNbToProc )); + msg (( MSG_OUT, "=========================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintPlanePar ( SInt8 Id ) { + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + msg (( MSG_OUT, "=========================" )); + msg (( MSG_OUT, "Plane %d parameters", Id )); + msg (( MSG_OUT, "=========================" )); + msg (( MSG_OUT, "MapsId %4d", ProAPlanePar[Id].MapsId )); + msg (( MSG_OUT, "Process %4d", ProAPlanePar[Id].Process )); + msg (( MSG_OUT, "Revert X %4d", ProAPlanePar[Id].RevertXDir )); + msg (( MSG_OUT, "PlotCum %4d", ProAPlanePar[Id].PlotCum )); + msg (( MSG_OUT, "PlotCoin %4d", ProAPlanePar[Id].PlotCoin )); + msg (( MSG_OUT, "PlotFrame %4d", ProAPlanePar[Id].PlotFrame )); + msg (( MSG_OUT, "=========================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintAllPlanesPar () { + + SInt8 Vi; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + PubFPrintPlanePar (Vi); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintPlaneInf ( SInt8 Id ) { + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + msg (( MSG_OUT, "=========================" )); + msg (( MSG_OUT, "Plane %d inf", Id )); + msg (( MSG_OUT, "=========================" )); + msg (( MSG_OUT, "PrevProcState %4d", ProAPlaneInf[Id].PrevProcState )); + msg (( MSG_OUT, "CurProcStat %4d", ProAPlaneInf[Id].CurProcState )); + msg (( MSG_OUT, "=========================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintAllPlanesInf () { + + SInt8 Vi; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + PubFPrintPlaneInf (Vi); + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintPlaneData ( SInt8 Id ) { + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + + msg (( MSG_OUT, "=========================" )); + msg (( MSG_OUT, "Plane %d data", Id )); + msg (( MSG_OUT, "=========================" )); + msg (( MSG_OUT, "Nothing to print" )); + msg (( MSG_OUT, "=========================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintAllPlanesData () { + + SInt8 Vi; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + PubFPrintPlaneData (Vi); + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Rev : 20/05/2010 + : - Add CumTotTrigNb & CumFrameTrigNb + : +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintPlaneRes ( SInt8 Id ) { + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + msg (( MSG_OUT, "=========================" )); + msg (( MSG_OUT, "Plane %d results", Id )); + msg (( MSG_OUT, "=============================" )); + msg (( MSG_OUT, "PtMatCumTotHitCnt %4x", ProAPlaneRes[Id].PtMatCumTotHitCnt )); + msg (( MSG_OUT, "PtMatDiscriBit %4x", ProAPlaneRes[Id].PtMatDiscriBit )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "FrameNbWithTrig %4d", ProAPlaneRes[Id].FrameNbWithTrig )); + msg (( MSG_OUT, "FramePCentWithTrig %.2f",ProAPlaneRes[Id].FramePCentWithTrig )); + msg (( MSG_OUT, "CumTotTrigNb %.2f",ProAPlaneRes[Id].CumTotTrigNb )); + msg (( MSG_OUT, "CumFrameTrigNb %.2f",ProAPlaneRes[Id].CumFrameTrigNb )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "FrameNbWithHit %4d", ProAPlaneRes[Id].FrameNbWithHit )); + msg (( MSG_OUT, "FramePCentWithHit %.2f", ProAPlaneRes[Id].FramePCentWithHit )); + msg (( MSG_OUT, "CumTotHitNb %4d", ProAPlaneRes[Id].CumTotHitNb )); + msg (( MSG_OUT, "CumFrHitNb %.2f", ProAPlaneRes[Id].CumFrHitNb )); + msg (( MSG_OUT, "=============================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MAPS__TCDigTelMon::PubFPrintAllPlanesRes () { + + SInt8 Vi; + + for ( Vi=0; Vi < ProPar.PlaneNb; Vi++ ) { + PubFPrintPlaneRes (Vi); + } + + err_retok (( ERR_OUT, "" )); +} + + +#endif + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/maps.def b/include/pxi_daq_lib_v.2.1/maps.def new file mode 100755 index 0000000..a829d9d --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/maps.def @@ -0,0 +1,59 @@ +/******************************************************************************* +File : x:\lib\com\maps\maps.def +Goal : Macros definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_DEF +#define MAPS_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define MAPS__TCDigTelMon_MAX_EV_NB 300 +#define MAPS__TCDigTelMon_MAX_PLANE_NB 6 +#define MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB 10000 +#define MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE 1000 + +#define MAPS__TCDigTelMon_CHK_PLANE_ID(Id) { if ( (Id < 0) || (Id >= MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + +#define MAPS__TCDigTelMon_CHK_PLANE_NB(Nb) { if ( (Nb <= 0) || (Nb > MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Nb, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + + +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME 0 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL 1 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS 2 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR 3 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS 4 + +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES 0 +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE 1 + + +typedef enum { + + MAPS__MAPS_READ_MODE_A_FR0_FR1, + MAPS__MAPS_READ_MODE_A_READ_CALIB, + + MAPS__MAPS_READ_MODE_NB + +} MAPS__TMapsReadMode; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/maps.h b/include/pxi_daq_lib_v.2.1/maps.h new file mode 100755 index 0000000..1724d26 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/maps.h @@ -0,0 +1,38 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.h +Goal : Functions prototypes of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* MI26_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef MAPS_H + #define MAPS_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/maps.typ b/include/pxi_daq_lib_v.2.1/maps.typ new file mode 100755 index 0000000..63e1342 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/maps.typ @@ -0,0 +1,383 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.typ +Goal : Types definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_TYP +#define MAPS_TYP + + +#ifdef ROOT_ROOT + typedef UInt32 MAPS__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor MAPS__TColor; +#endif + + + +// 17/07/2009 + +typedef struct { + + SInt32 MaxBuffEvNb; + + // Hard coded parameters in next classes + + SInt8 MapsNb; // Nb of MAPS acquired by DAQ + SInt8 MapsName; + SInt8 PlaneNb; + + // Parameters from GUI + + SInt8 MonEnabled; + + SInt32 AcqFrNb; // Nb of frame in current acq to process + + SInt8 ProcOneAcq; // 1 => Process current ONLY acq + // 0 => Process ProcEvNb coming from GUI + // It can be more or less than one acq + + SInt32 ProcEvNb; // Ev nb to process, either + // - if ProcOneAcq = 1 => ev nb of one acq + // - if ProcOneAcq = 0 => from GUI + + SInt8 ProcOnlyFrWithHitOnAllPlanes; + + SInt8 ListHitAllPlanesMode; + + SInt8 ProcOnlyFrWithTrig; // Process only frames with hit + SInt8 HandleTrigPos; // Use trigger position to extract events + SInt8 StopAtEndOfProc; // Stop at end of processing, no automatic processing of next acq + SInt8 StoreEvents; // Store events + + SInt8 DispFrNbWithTrigOrFrNbWithHit; // Display in PubPt_ADispFrNbWithTrigOrHit & PubPt_ADispFrPCentWithTrigOrHit trig or hit nb + // 0 => Display frame nb & % with trigger + // 1 => Display frame nb & % with at least one hit + + SInt8 DispFullMatrix; // 0 => Display 1/2 scale matrix + // 1 => Display full matrix + + SInt8 ProcMode; // Processing mode + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + + SInt8 CumPlotGrayOrBlueLevels; // Cumul plot + // 0 => in gray levels + // 1 => in blue levels + + SInt8 CumPlotHitOrHitCnt; // Cumul plot + // 0 => binary display : count > 0 => set pixel in black / blue + // 1 => gray or blue levels display + + + SInt32 GotoRawFrNo; // Plot raw data of frame No + +} MAPS__TDigTelPar; + + +// 17/07/2009 + +typedef struct { + + SInt8 RunInProgress; + SInt8 LastPlaneSelForCoin; // Index of last plane selected for coincidence + + SInt32 CurEvNo; // Index of last event buffered + SInt32 FirstEvToProc; // Index of first event to process + SInt32 LastEvToProc; // Index of last event to process + SInt32 CurEvToProc; // Index of event to process + SInt32 EvNbToProc; // Ev nb to process + +} MAPS__TDigTelInf; + + +// 17/07/2009 + +typedef struct { + + SInt32 AcqFrNb; // Frame nb received from current acq + SInt32 ProFrNo; // Index of currently processed frame + SInt32 ProTimeMs; // Processing time + +} MAPS__TDigTelRes; + + +// 17/07/2009 + +typedef struct { + + SInt8 MapsId; // Id of the MAPS + MAPS__TColor PlotColor; + + SInt8 Process; // Process data of this plane + SInt8 RevertXDir; // Revert numbering of X direction ( columns ) in case planes are mounted back to back + SInt8 PlotCum; // Plot cumulated hit count over N events + SInt8 PlotCoin; // Plot coincidence + SInt8 PlotFrame; // Plot frame raw data + +} MAPS__TDigTelPlanePar; + + +// 22/07/2009 + +typedef struct { + + SInt8 PrevProcState; // Not used on 22/07/2009 + SInt8 CurProcState; // Not used on 22/07/2009 + + +} MAPS__TDigPlaneInf; + + +// 17/07/2009 + +typedef struct { + + void* AEvPt[MAPS__TCDigTelMon_MAX_EV_NB]; + void* CurEvPt; + +} MAPS__TDigTelPlaneData; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add CumTotTrigNb & CumFrameTrigNb + +typedef struct { + + void* PtMatDiscriBit; // Flat view of matrix X col x Y lines + void* PtMatCumTotHitCnt; // Hit count of each pixel over all events + + SInt32 FrameNbWithTrig; // Nb of frame with trigger + float FramePCentWithTrig; // % of frame with trigger + SInt32 CumTotTrigNb; // Total number of triggers + float CumFrameTrigNb; // Cumul MEAN trigger nb on frames WITH trigger + + SInt32 FrameNbWithHit; // Nb of frame with at least one hit + float FramePCentWithHit; // % of frame with at least one hit + SInt32 CumTotHitNb; // Total cumul hit nb over ALL frames ( with and without hit ) + float CumFrHitNb; // Cumul MEAN hit nb on frames WITH hit + +} MAPS__TDigTelPlaneRes; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add PubPt_ADispCumFrTrigNb + +#ifndef ROOT_ROOT + +class MAPS__TCDigTelMon { + + private: + + SInt8 PrivGuiConnected; + SInt8 PrivSetGuiParDontRead; + + SInt32 PrivFInit (); + + SInt32 PrivChkPlaneId ( SInt8 Id ); + + SInt32 PrivFSetGuiLabelsDispFrNbWithTrigOrFrNbWithHit (); + + protected: + + SInt8 ProRequestPlot; // Request plot from sw external to object + + MAPS__TDigTelPar ProPar; + MAPS__TDigTelInf ProInf; + MAPS__TDigTelRes ProRes; + MAPS__TDigTelPlanePar ProAPlanePar[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigPlaneInf ProAPlaneInf[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneData ProAPlaneData[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneRes ProAPlaneRes[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + public: + + // ---------------------------------- + // Fields to connect GUI components + // ---------------------------------- + + // Group + + TGroupBox* PubPt_GrpTelMon; + + // Label + + TLabel* PubPt_LbFrNbWithTrigOrHit; + TLabel* PubPt_LbFrPCentWithTrigOrHit; + + // Controls + + TCheckBox* PubPt_ChkEnableMonitor; + + TCheckBox* PubPt_AChkProc[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkRevertXDir[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TCheckBox* PubPt_ChkProcOneAcq; + TEdit* PubPt_EdFrNbToProc; + TCheckBox* PubPt_ChkProcOnlyFrWithTrig; + + TComboBox* PubPt_CbListHitAllPlanesMode; + + TCheckBox* PubPt_ChkTrigPosHanling; + TCheckBox* PubPt_ChkStopAtEndOfProc; + TCheckBox* PubPt_ChkStoreFr; + + TCheckBox* PubPt_ChkDispFrNbWithTrigOrFrNbWithHit; + TCheckBox* PubPt_ChkDispFullMatrix; + + TComboBox* PubPt_CbProcMode; + TCheckBox* PubPt_ChkCumPlotGrayOrBlueLevels; + TCheckBox* PubPt_ChkCumPlotHitOrHitCnt; + + TEdit* PubPt_EdGotoFr; + + TLabel* PubPt_ALbPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TRadioButton* PubPt_ARbPlotCum[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkPlotCoin[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TRadioButton* PubPt_ARdPlotFr[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // Indicators + + TEdit* PubPt_DispAcqFrNb; + TEdit* PubPt_DispCurProcFr; + + TEdit* PubPt_ADispFrNbWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispFrPCentWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_ADispCumFrTrigNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumTotHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumFrHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_DispProFrNo; + TEdit* PubPt_DispProcTimeMs; + + // Display + + TImage* PubPt_ImgMiniMatrix; + TImage* PubPt_ImgFullMatrix; + + + // ------------- + // Methods + // ------------- + + + MAPS__TCDigTelMon (); + ~MAPS__TCDigTelMon (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGuiEnablePlane ( SInt8 Id, SInt8 Enable ); + + SInt32 PubFSetGuiPar (); + SInt32 PubFSetGuiParGotoFr (); + + SInt32 PubFGetGuiPar (); + SInt32 PubFOnGuiParDispModeChangeFrNbWithTrigOrFrNbWithHit (); // Specific GUI behaviour + SInt32 PubFSetGuiStatus (); + SInt32 PubFSetGuiRes (); + + + // Set parameters + + SInt32 PubFSetPar ( MAPS__TDigTelPar* Pt ); + SInt32 PubFSetPlanePar ( SInt8 Id, MAPS__TDigTelPlanePar* Pt ); + + // Get parameters + + MAPS__TDigTelPar* PubFGetPar (); + MAPS__TDigTelPlanePar* PubFGetPlanePar ( SInt8 Id ); + MAPS__TDigTelPlaneData* PubFGetPlaneData ( SInt8 Id ); + + // Disable all planes processing + + SInt32 PubFDisAllPlanesProcessing (); + + // Disable group + + SInt32 PubFDisCumPlot (); + SInt32 PubFDisCoinPlot (); + SInt32 PubFDisFramePlot (); + + // Set results + + MAPS__TDigTelPlaneRes* PubFSetPlaneRes ( SInt8 Id ); + + // Poll plot request + + SInt32 PubFGetPlotRqStatus (); + SInt32 PubFResetPlotRqStatus (); + + SInt8* PubFGetPtPlotRq (); + SInt8* PubFGetPtMonEnabled (); + + + // Debug print + + SInt32 PubFPrintPar (); + SInt32 PubFPrintInf (); + + SInt32 PubFPrintPlanePar ( SInt8 Id ); + SInt32 PubFPrintAllPlanesPar (); + + SInt32 PubFPrintPlaneInf ( SInt8 Id ); + SInt32 PubFPrintAllPlanesInf (); + + SInt32 PubFPrintPlaneData ( SInt8 Id ); + SInt32 PubFPrintAllPlanesData (); + + SInt32 PubFPrintPlaneRes ( SInt8 Id ); + SInt32 PubFPrintAllPlanesRes (); + + +}; + +#endif + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 17/07/2009 */ +/* ============================= */ + +typedef struct { + + SInt8 Dummy; + +} MAPS__TContext; + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/maps.var b/include/pxi_daq_lib_v.2.1/maps.var new file mode 100755 index 0000000..cd0d91a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/maps.var @@ -0,0 +1,33 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.var +Goal : Variables definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_VAR +#define MAPS_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC MAPS__TContext MAPS__VGContext; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/math.c b/include/pxi_daq_lib_v.2.1/math.c new file mode 100755 index 0000000..c25ad6f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/math.c @@ -0,0 +1,4350 @@ + +/******************************************************************************* +File : x:\lib\com\math.c +Goal : Functions of +Prj date : //200 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MATH_C +#define MATH_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 MATH_FSInt32Ceil ( SInt32 Src ) { + return ( ceil ( (double) Src ) ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_FFloatPow ( float x, float y ) { + return ( pow ( x, y ) ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* 03/05/04 */ + +SInt32 MATH_FCpySInt32ToSInt16Array ( SInt32* PtSrc, SInt32 SrcEltSz, SInt16* PtDest, SInt32 DestEltSz ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( SrcEltSz > DestEltSz ) { + err_retfail ( -1, (ERR_OUT,"SrcEltSz=%d > DestEltSz=%d", SrcEltSz, DestEltSz) ); + } + + for ( Vi=0; Vi < SrcEltSz; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + +} + +// 14/08/2007 + +float MATH_FUInt8Avg ( UInt8* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +float MATH_FSInt8Avg ( SInt8* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +float MATH_FUInt16Avg ( UInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +float MATH_FSInt16Avg ( SInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +// 09/11/2010 +// Reject item == 0 from average calculation + +float MATH_FSInt16AvgNonZero ( SInt16* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + SInt32 VGoodEltCnt; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + VGoodEltCnt = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( Src[Vi] != 0 ) { + VSum = VSum + Src[Vi]; + ++VGoodEltCnt; + } + + } + + if ( VGoodEltCnt == 0 ) { + err_warning (( ERR_OUT, "No elt <> 0 to calculate average !" )); + return (0); + } + + return ( VSum / (float) VGoodEltCnt ); +} + + + +/* 21/06/2006 */ +/* Calculates the mean value of Src array selected elements */ +/* SelList[i] == 1 if the corresponding item must be used for processing */ + +float MATH_FSInt16DataListAvg ( SInt16* Src, SInt8* SelList, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VEltCnt; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( SelList, (ERR_OUT,"SelList == NULL") ); + + VEltCnt = 0; + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( SelList[Vi] != 1 ) { + continue; + } + + ++VEltCnt; + + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) VEltCnt ); +} + +// 14/08/2007 + +float MATH_FUInt32Avg ( UInt32* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + + +float MATH_FSInt32Avg ( SInt32* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + + +float MATH_FSInt32AvgNo1 ( SInt32 Src, SInt8 StartSearch, SInt8 DoCalc ) { + + static SInt64 VSum; + static SInt32 VEltCnt; + float VAvg = 0; + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VSum = 0; + return (0); + } + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Calculation not possible => bad elt nb = %d", VEltCnt) ); + } + + VAvg = (float) VSum / (float) VEltCnt; + err_retval ( VAvg, ( ERR_OUT, "Average of %d value = %.3f", VEltCnt, VAvg ) ); + } + + VSum += Src; + ++VEltCnt; + + + return (0); +} + + +// 21/05/2010 +// Calculation is done by setting DoCalc at 1 +// - current value of Src is added to sum before calculation +// - if one wants to calculate average "later", set Src=0 and DoCalc=1 + + +float MATH_FSInt32AvgNo2 ( SInt32 Src, SInt8 StartSearch, SInt8 DoCalc ) { + + static SInt64 VSum; + static SInt32 VEltCnt; + float VAvg = 0; + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VSum = 0; + } + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Calculation not possible => bad elt nb = %d", VEltCnt) ); + } + + VAvg = (float) VSum / (float) VEltCnt; + err_retval ( VAvg, ( ERR_OUT, "Average of %d value = %.3f", VEltCnt, VAvg ) ); + } + + VSum += Src; + ++VEltCnt; + + return (0); +} + + +// 11/08/2007 + +SInt32 MATH_FFloatMinMaxAvg ( float* Src, SInt32 EltNb, float* PtResMin, float* PtResMax, float* PtResAvg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + float VMin; + float VMax; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( PtResMin, (ERR_OUT,"PtResMin == NULL") ); + err_retnull ( PtResMax, (ERR_OUT,"PtResMax == NULL") ); + err_retnull ( PtResAvg, (ERR_OUT,"PtResAvg == NULL") ); + + VSum = 0; + VMin = Src[0]; + VMax = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + + VSum = VSum + Src[Vi]; + } + + *PtResMin = VMin; + *PtResMax = VMax; + *PtResAvg = ( VSum / (float) EltNb ); + + return (0); +} + + +float MATH_FFloatAvg ( float* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + + +float MATH_FFloatAvgNo1 ( float Src, SInt8 StartSearch, SInt8 DoCalc ) { + + static double VSum; + static SInt32 VEltCnt; + float VAvg = 0; + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VSum = 0; + return (0); + } + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Calculation not possible => bad elt nb = %d", VEltCnt) ); + } + + VAvg = (float) VSum / (float) VEltCnt; + err_retval ( VAvg, ( ERR_OUT, "Average of %d value = %.3f", VEltCnt, VAvg ) ); + } + + VSum += Src; + ++VEltCnt; + + + return (0); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + + +float MATH_FFloatAvgNo2 ( float Src, SInt8 StartSearch, SInt8 DoCalc ) { + + static double VSum; + static SInt32 VEltCnt; + float VAvg = 0; + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VSum = 0; + return (0); + } + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Calculation not possible => bad elt nb = %d", VEltCnt) ); + } + + VAvg = (float) VSum / (float) VEltCnt; + err_retval ( VAvg, ( ERR_OUT, "Average of %d value = %.3f", VEltCnt, VAvg ) ); + } + + VSum += Src; + ++VEltCnt; + + + return (0); +} + + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// The mean value = Avg parameters MUST be given on first call ! +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + +float MATH_FFloatSigma1No1 ( float Src, float Avg, SInt8 StartSearch, SInt8 DoCalc ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + static SInt32 VEltCnt; + static float VAvg; + static double VPrevSum2; + static double VSum2; + + + // Init + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VAvg = Avg; + VSum2 = 0; + VPrevSum2 = 0; + return (0); + } + + // Calculates sigma + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_error (( ERR_OUT, "Bad elt counter = %d", VEltCnt )); + return (-1); + } + + return ( sqrt ( VSum2 / (float) VEltCnt ) ); + } + + + // Process data + + VSum2 = VSum2 + ( (Src - VAvg) * (Src - VAvg) ); + + if ( VSum2 < VPrevSum2 ) { + err_error (( ERR_OUT, "VSum2 overflow !" )); + return (-1); + } + + VPrevSum2 = VSum2; + + ++VEltCnt; + + return (0); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// The mean value = Avg parameters MUST be given on first call ! +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + +float MATH_FFloatSigma1No2 ( float Src, float Avg, SInt8 StartSearch, SInt8 DoCalc ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + static SInt32 VEltCnt; + static float VAvg; + static double VPrevSum2; + static double VSum2; + + + // Init + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VAvg = Avg; + VSum2 = 0; + VPrevSum2 = 0; + return (0); + } + + // Calculates sigma + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_error (( ERR_OUT, "Bad elt counter = %d", VEltCnt )); + return (-1); + } + + return ( sqrt ( VSum2 / (float) VEltCnt ) ); + } + + + // Process data + + VSum2 = VSum2 + ( (Src - VAvg) * (Src - VAvg) ); + + if ( VSum2 < VPrevSum2 ) { + err_error (( ERR_OUT, "VSum2 overflow !" )); + return (-1); + } + + VPrevSum2 = VSum2; + + ++VEltCnt; + + return (0); +} + + + +float MATH_FFloatMinAndMinIndex ( float* Src, SInt32 EltNb, SInt32* PtMinIndex ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMinIndex; + float VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMinIndex = -1; + VMin = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + VMinIndex = Vi; + } + } + + if ( PtMinIndex != NULL ) { + *PtMinIndex = VMinIndex; + } + + return (VMin); +} + +float MATH_FFloatMin ( float* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + float VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + +float MATH_FFloatMaxAndMaxIndex ( float* Src, SInt32 EltNb, SInt32* PtMaxIndex ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + SInt32 VMaxIndex; + float VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMaxIndex = -1; + VMax = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + VMaxIndex = Vi; + } + } + + if ( PtMaxIndex != NULL ) { + *PtMaxIndex = VMaxIndex; + } + + return (VMax); +} + + +float MATH_FFloatMax ( float* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + float VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +float MATH_FFloatMinNo1 ( float Src, SInt8 StartSearch ) { + + static SInt8 VGetFirstElt = 0; + static float VMin; + + if ( StartSearch == 1 ) { + VGetFirstElt = 1; + return (0); + } + + if ( VGetFirstElt == 1 ) { + VGetFirstElt = 0; + VMin = Src; + return (VMin); + } + + if ( Src < VMin ) { + VMin = Src; + } + + return (VMin); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +float MATH_FFloatMinNo2 ( float Src, SInt8 StartSearch ) { + + static SInt8 VGetFirstElt = 0; + static float VMin; + + if ( StartSearch == 1 ) { + VGetFirstElt = 1; + return (0); + } + + if ( VGetFirstElt == 1 ) { + VGetFirstElt = 0; + VMin = Src; + return (VMin); + } + + if ( Src < VMin ) { + VMin = Src; + } + + return (VMin); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +float MATH_FFloatMaxNo1 ( float Src, SInt8 StartSearch ) { + + static SInt8 VGetFirstElt = 0; + static float VMax; + + if ( StartSearch == 1 ) { + VGetFirstElt = 1; + return (0); + } + + if ( VGetFirstElt == 1 ) { + VGetFirstElt = 0; + VMax = Src; + return (VMax); + } + + if ( Src > VMax ) { + VMax = Src; + } + + return (VMax); +} + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +float MATH_FFloatMaxNo2 ( float Src, SInt8 StartSearch ) { + + static SInt8 VGetFirstElt = 0; + static float VMax; + + if ( StartSearch == 1 ) { + VGetFirstElt = 1; + return (0); + } + + if ( VGetFirstElt == 1 ) { + VGetFirstElt = 0; + VMax = Src; + return (VMax); + } + + if ( Src > VMax ) { + VMax = Src; + } + + return (VMax); +} + + + +// 09/08/2007 + +SInt32 MATH_FUInt32Min ( UInt32* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + UInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 0xFFFFFFFF; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + + +// 09/08/2007 + +SInt32 MATH_FUInt32Max ( UInt32* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + UInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = 0; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + + +SInt32 MATH_FSInt32Min ( SInt32* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 0x7FFFFFFF; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +SInt32 MATH_FSInt32MinNo1 ( SInt32 Src, SInt8 StartSearch ) { + + static SInt32 VMin; + + if ( StartSearch == 1 ) { + VMin = TYP_MAX_SINT32; + return (0); + } + + if ( Src < VMin ) { + VMin = Src; + } + + return (VMin); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +SInt32 MATH_FSInt32MinNo2 ( SInt32 Src, SInt8 StartSearch ) { + + static SInt32 VMin; + + if ( StartSearch == 1 ) { + VMin = TYP_MAX_SINT32; + return (0); + } + + if ( Src < VMin ) { + VMin = Src; + } + + return (VMin); +} + + + +SInt32 MATH_FSInt32Max ( SInt32* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = ( ~ 0x7FFFFFFF ); + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +SInt32 MATH_FSInt32MaxNo1 ( SInt32 Src, SInt8 StartSearch ) { + + static SInt32 VMax; + + if ( StartSearch == 1 ) { + VMax = TYP_MIN_SINT32; + return (0); + } + + if ( Src > VMax ) { + VMax = Src; + } + + return (VMax); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +SInt32 MATH_FSInt32MaxNo2 ( SInt32 Src, SInt8 StartSearch ) { + + static SInt32 VMax; + + if ( StartSearch == 1 ) { + VMax = TYP_MIN_SINT32; + return (0); + } + + if ( Src > VMax ) { + VMax = Src; + } + + return (VMax); +} + + +// 09/08/2007 + +SInt32 MATH_FUInt16Min ( UInt16* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + UInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 65535; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + +// 09/08/2007 + +SInt32 MATH_FUInt16Max ( UInt16* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + UInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = 0; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + +/* -------------------- */ + +SInt32 MATH_FSInt16Min ( SInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 32767; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + +/* 20/06/2006 */ +/* Calculates the min value Src array selected elements */ +/* SelList[i] == 1 if the corresponding item must be used for min processing */ + +SInt32 MATH_FSInt16DataListMin ( SInt16* SrcData, SInt8* SelList, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( SelList, (ERR_OUT,"SelList == NULL") ); + + VMin = 32767; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( (SelList[Vi] == 1) && (SrcData[Vi] < VMin) ) { + VMin = SrcData[Vi]; + } + } + + return (VMin); +} + + + +SInt32 MATH_FSInt16Max ( SInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = -32768; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + +/* 20/06/2006 */ +/* Calculates the max value Src array selected elements */ +/* SelList[i] == 1 if the corresponding item must be used for max processing */ + +SInt32 MATH_FSInt16DataListMax ( SInt16* SrcData, SInt8* SelList, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( SelList, (ERR_OUT,"SelList == NULL") ); + + VMax = -32768; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( (SelList[Vi] == 1) && (SrcData[Vi] > VMax) ) { + VMax = SrcData[Vi]; + } + } + + return (VMax); +} + + + + + + + +/* ---- */ +// 12/04/2006 + +UInt8 MATH_FUInt8Min ( UInt8* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + UInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 255; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + +// 12/04/2006 + + +UInt8 MATH_FUInt8Max ( UInt8* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + UInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = 0; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + +/* ---- */ +// 07/08/2007 + +SInt8 MATH_FSInt8Min ( SInt8* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + SInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 127; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + +// 07/08/2007 + + +SInt8 MATH_FSInt8Max ( SInt8* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + SInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = -128; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + + +float MATH_FSInt32Sigma1 ( SInt32* Src, SInt32 EltNb, float Avg ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + for ( Vi=0; Vi < EltNb; Vi++) { + + /* VSum2 = VSum2 + ( (Src[Vi] *Src[Vi]) - VAvg2 ); */ + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// The mean value = Avg parameters MUST be given on first call ! +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + +float MATH_FSInt32Sigma1No1 ( SInt32 Src, float Avg, SInt8 StartSearch, SInt8 DoCalc ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + static SInt32 VEltCnt; + static float VAvg; + static double VPrevSum2; + static double VSum2; + + + // Init + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VAvg = Avg; + VSum2 = 0; + VPrevSum2 = 0; + return (0); + } + + // Calculates sigma + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_error (( ERR_OUT, "Bad elt counter = %d", VEltCnt )); + return (-1); + } + + return ( sqrt ( VSum2 / (float) VEltCnt ) ); + } + + + // Process data + + VSum2 = VSum2 + ( (Src - VAvg) * (Src - VAvg) ); + + if ( VSum2 < VPrevSum2 ) { + err_error (( ERR_OUT, "VSum2 overflow !" )); + return (-1); + } + + VPrevSum2 = VSum2; + + return (0); +} + + +float MATH_FSInt16Sigma1 ( SInt16* Src, SInt32 EltNb, float Avg ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + SInt32 VOutOfRangeCnt; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + VOutOfRangeCnt = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( ( Src[Vi] < (Avg-6) ) || (Src[Vi] > (Avg+6) ) ) { + ++VOutOfRangeCnt; + } + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + +// 14/08/2007 + +float MATH_FSInt8Sigma1 ( SInt8* Src, SInt32 EltNb, float Avg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + + for ( Vi=0; Vi < EltNb; Vi++) { + + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + + +// 14/08/2007 + +float MATH_FUInt32Sigma1 ( UInt32* Src, SInt32 EltNb, float Avg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + + for ( Vi=0; Vi < EltNb; Vi++) { + + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + +// 14/08/2007 + +float MATH_FUInt16Sigma1 ( UInt16* Src, SInt32 EltNb, float Avg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + + for ( Vi=0; Vi < EltNb; Vi++) { + + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + +// 14/08/2007 + +float MATH_FUInt8Sigma1 ( UInt8* Src, SInt32 EltNb, float Avg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + + for ( Vi=0; Vi < EltNb; Vi++) { + + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + + +/* 21/06/2006 */ +/* Calculates the sigma value of Src array selected elements */ +/* SelList[i] == 1 if the corresponding item must be used for processing */ + +float MATH_FSInt16DataListSigma1 ( SInt16* Src, SInt8* SelList, SInt32 EltNb, float Avg ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VEltCnt; + double VPrevSum2; + double VSum2; + double VAvg2; + SInt32 VOutOfRangeCnt; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( SelList, (ERR_OUT,"SelList == NULL") ); + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + VEltCnt = 0; + VOutOfRangeCnt = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( SelList[Vi] != 1 ) { + continue; + } + + ++VEltCnt; + + if ( ( Src[Vi] < (Avg-6) ) || (Src[Vi] > (Avg+6) ) ) { + ++VOutOfRangeCnt; + } + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + // return ( VOutOfRangeCnt ); + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) VEltCnt ) ); +} + + + + +float MATH_FFloatSigma1 ( float* Src, SInt32 EltNb, float Avg ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VAvg2 = Avg * Avg; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum2 = VSum2 + ( (Src[Vi] *Src[Vi]) - VAvg2 ); + /* VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); */ + } + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + + +void MATH_FDiffPedest ( SInt32* Src, float Pedest, float* Dest, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_error (( ERR_OUT, "Bad EltNb=%d => must be > 0", EltNb )); + return; + } + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Src[Vi] - Pedest; + } + +} + + + +void MATH_FDiffPedestUInt8FloatFloat ( UInt8* Src, float* Pedest, float* Dest, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_error (( ERR_OUT, "Bad EltNb=%d => must be > 0", EltNb )); + return; + } + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Src[Vi] - Pedest[Vi]; + } + +} + + +/* 07/12/04 */ + +SInt32 MATH_FScaleFloatVect ( float* Src, float* Dest, SInt32 EltNb, float Offset, float Slope ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = ( Src[Vi] * Slope ) + Offset; + } + + +} + +/* 02/01/05 */ + +SInt32 MATH_FIntInRange ( SInt32 Min, SInt32 Max, SInt32 Val ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + if ( (Val >= Min) && (Val <= Max)) { + return (1); + } + + err_retfail ( -1, (ERR_OUT,"Value = %d out of range <%d..%d> ", Val, Min, Max) ); +} + +/* 02/01/05 */ + +SInt32 MATH_FFloatInRange ( float Min, float Max, float Val ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + if ( (Val >= Min) && (Val <= Max)) { + return (1); + } + + err_retfail ( -1, (ERR_OUT,"Value = %d out of range <%d..%d> ", Val, Min, Max) ); +} + + +/* 26/04/06 */ + +SInt32 MATH_FOffsetSInt16Vect ( SInt16* Src, SInt16* Dest, SInt32 EltNb, SInt16 Offset ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Src[Vi] + Offset; + } + + return (0); +} + + +/* 26/04/06 */ + +SInt32 MATH_FTranslateSInt16ToUInt16Vect ( SInt16* Src, UInt16* Dest, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Src[Vi] + 32768; + } + + return (0); +} + +/* 30/04/06 */ + + +SInt32 MATH_FScaleSInt32Vect ( SInt32* Src, SInt32* Dest, SInt32 EltNb, SInt32 Offset, SInt32 Slope ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Offset + ( Src[Vi] * Slope ); + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 26/04/2006 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoSInt16Book ( SInt16 HistoId, SInt16 Min, SInt16 Max, SInt16 BinW ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + err_warning (( ERR_OUT, "Do nothing for the moment : reserved for future use" )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 26/04/2006 +Modif : 04/05/2006 + : - Add a test on BinNb <= MATH_HISTO_MAX_BIN_NB +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoSInt16Build ( SInt16 HistoId, SInt16* PtSrc, SInt32 EltNb, SInt16 Min, SInt16 Max, SInt16 BinW, SInt16* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, SInt32** PtPtDestX, SInt32** PtPtDestY, SInt8 DbgPlot ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + SInt16 VMin; + SInt16 VMax; + SInt16 VBinW; + SInt16 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + static SInt32 VADestX [MATH_HISTO_MAX_ID_NB][MATH_HISTO_MAX_BIN_NB + 1]; + static SInt32 VADestY [MATH_HISTO_MAX_ID_NB][MATH_HISTO_MAX_BIN_NB + 1]; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + /* Check histo ID */ + + err_retfail ( HistoId, (ERR_OUT,"HistoId=%d MUST be > 0", HistoId) ); + + if ( HistoId >= MATH_HISTO_MAX_ID_NB ) { + err_retfail ( -1, (ERR_OUT,"HistoId=%d >= MATH_HISTO_MAX_ID_NB=%d", HistoId, MATH_HISTO_MAX_ID_NB ) ); + } + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtPtDestX, (ERR_OUT,"PtPtDestX == NULL") ); + err_retnull ( PtPtDestY, (ERR_OUT,"PtPtDestY == NULL") ); + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + VADestX[HistoId][Vi] = 0; + VADestY[HistoId][Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ); + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * VBinNb ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++VADestY[HistoId][VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + VADestX[HistoId][Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + /* ---------------------------------------- */ + /* Init paramters pointers to result arrays */ + /* ---------------------------------------- */ + + *PtPtDestX = VADestX[HistoId]; + *PtPtDestY = VADestY[HistoId]; + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, VADestX[HistoId][Vi], VADestX[HistoId][Vi+1], VADestY[HistoId][Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, VADestX[HistoId][Vi], Vi, VADestY[HistoId][Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* 30/04/06 */ + +SInt32 MATH_FCpyUInt16ArrayToSInt32Array ( UInt16* PtSrc, SInt32 SrcEltSz, SInt32* PtDest, SInt32 DestEltSz ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( SrcEltSz > DestEltSz ) { + err_retfail ( -1, (ERR_OUT,"SrcEltSz=%d > DestEltSz=%d", SrcEltSz, DestEltSz) ); + } + + for ( Vi=0; Vi < SrcEltSz; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + +} + + +/* 30/04/06 */ + +SInt32 MATH_FCpySInt16ArrayToSInt32Array ( SInt16* PtSrc, SInt32 SrcEltSz, SInt32* PtDest, SInt32 DestEltSz ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + + SInt32 Vi; + + if ( SrcEltSz > DestEltSz ) { + err_retfail ( -1, (ERR_OUT,"SrcEltSz=%d > DestEltSz=%d", SrcEltSz, DestEltSz) ); + } + + for ( Vi=0; Vi < SrcEltSz; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + +} + + +/* TO REMOVE ONE DAY - Following lines are in comment */ + +/* + +UInt16 MATH_FSInt16Min ( UInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + UInt16 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + + + +UInt16 MATH_FSInt16Max ( UInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + UInt16 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + +*/ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FVoltageGain2dB ( float Gain ) { + + float VdB; + + if ( Gain <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Gain = %.3f must be > 0", Gain) ); + } + + VdB = 20 * log10 ( Gain ); + + return (VdB); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdB2VoltageGain ( float dB ) { + + float VGain; + + VGain = MATH_FFloatPow ( 10, ((float) dB / (float) 20) ); + + return (VGain); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FPowerGain2dB ( float Gain ) { + + float VdB; + + if ( Gain <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Gain = %.3f must be > 0", Gain) ); + } + + VdB = 10 * log10 ( Gain ); + + return (VdB); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdB2PowerGain ( float dB ) { + + float VGain; + + + VGain = MATH_FFloatPow ( 10, ((float) dB / (float) 10) ); + + return (VGain); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FV2dBV ( float Volt ) { + + float VdBV; + + if ( Volt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Vlot = %.3f must be > 0", Volt) ); + } + + VdBV = MATH_UCONV_FVoltageGain2dB ( Volt ); + + return (VdBV); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBV2V ( float dBV ) { + + float Volt; + + + Volt = MATH_UCONV_FdB2VoltageGain ( dBV ); + + return (Volt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FmV2dBV ( float mV ) { + + float VdBV; + + VdBV = MATH_UCONV_FV2dBV ( (float) mV / (float) 1000 ); + + return (VdBV); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBV2mV ( float dBV ) { + + float VmV; + + VmV = 1000 * MATH_UCONV_FdBV2V ( dBV ); + + return (VmV); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FV2dBmV ( float Volt ) { + + float VdBmV; + + if ( Volt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Vlot = %.3f must be > 0", Volt) ); + } + + VdBmV = MATH_UCONV_FVoltageGain2dB ( (float) Volt / (float) 0.001 ); + + return (VdBmV); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBmV2V ( float dBmV ) { + + float Volt; + + + Volt = 0.001 * MATH_UCONV_FdB2VoltageGain ( dBmV ); + + return (Volt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FV2dBm600 ( float Volt ) { + + float VPowerW; + float VdBm600; + + if ( Volt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Vlot = %.3f must be > 0", Volt) ); + } + + VPowerW = (float) (( Volt * Volt )) / (float) 600; + + VdBm600 = 10 * log10 ( VPowerW / 0.001 ); + + err_trace (( ERR_OUT, "V = %.3f - Power mW = %.3f - dBm = %.3f ", Volt, VPowerW, VdBm600 )); + + return (VdBm600); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBm600_2V ( float dBm600 ) { + + float VPowerW; + float VVolt; + + VPowerW = 0.001 * MATH_UCONV_FdB2PowerGain ( dBm600 ); + + VVolt = sqrt ( VPowerW * 600 ); + + return (VVolt); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FmV2dBm600 ( float mV ) { + + float VdBm600; + + VdBm600 = MATH_UCONV_FV2dBm600 ( (float) mV / (float) 1000 ); + + err_trace (( ERR_OUT, "mV = %.3f - dBm = %.3f ", mV, VdBm600 )); + + return (VdBm600); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FV2dBm50 ( float Volt ) { + + float VPowerW; + float VdBm50; + + if ( Volt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Vlot = %.3f must be > 0", Volt) ); + } + + VPowerW = (float) (( Volt * Volt )) / (float) 50; + + VdBm50 = 10 * log10 ( VPowerW / 0.001 ); + + return (VdBm50); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBm50_2V ( float dBm50 ) { + + float VPowerW; + float VVolt; + + VPowerW = 0.001 * MATH_UCONV_FdB2PowerGain ( dBm50 ); + + VVolt = sqrt ( VPowerW * 50 ); + + return (VVolt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FmV2dBm50 ( float mV ) { + + float VdBm50; + + VdBm50 = MATH_UCONV_FV2dBm50 ( (float) mV / (float) 1000 ) ; + + return (VdBm50); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/08/2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 DAM_FAllocResizeFloatBuffer ( SInt32 NewBuffESz, SInt32* PtCurBuffESz, float LowAdjustTheresholdRatio, float** PtPtBuff ) { + + float VBuffESzRatio; + + if ( (*PtCurBuffESz) != 0 ) { + VBuffESzRatio = (float) NewBuffESz / (float) (*PtCurBuffESz); + } + + else { + VBuffESzRatio = 1.1; + } + + if ( (NewBuffESz > (*PtCurBuffESz)) || (VBuffESzRatio < LowAdjustTheresholdRatio) ) { + + if ( (*PtPtBuff) != NULL ) { + free (*PtPtBuff); + } + + (*PtPtBuff) = (float*) malloc ( NewBuffESz * (sizeof (float)) ); + + err_retnull ( (*PtPtBuff), (ERR_OUT,"Allocation of %d SInt32 failed !", NewBuffESz) ); + + err_trace (( ERR_OUT, "Buffer size adjusted : Previous = %d SInt32 - New = %d SInt32", (*PtCurBuffESz), NewBuffESz )); + + (*PtCurBuffESz) = NewBuffESz; + } + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/08/2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 08/08/2007 + +SInt32 DAM_FCpyVectUInt8ToFloat ( UInt8* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectSInt8ToFloat ( SInt8* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectUInt16ToFloat ( UInt16* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectSInt16ToFloat ( SInt16* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectUInt32ToFloat ( UInt32* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectSInt32ToFloat ( SInt32* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + + +// 08/08/2007 + +SInt32 DAM_FCpyVectFloatToFloat ( float* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectUInt8 ( UInt8* PtSrc, SInt32 EltNb, UInt8 Min, UInt8 Max, UInt8 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + UInt8 VMin; + UInt8 VMax; + UInt8 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + err_trace (( ERR_OUT, "Min=%d - Max=%d - BinW=%d - BinNb=%d", VMin, VMax, VBinW, VBinNb )); + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectUInt16 ( UInt16* PtSrc, SInt32 EltNb, UInt16 Min, UInt16 Max, UInt16 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + UInt16 VMin; + UInt16 VMax; + UInt16 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectUInt32 ( UInt32* PtSrc, SInt32 EltNb, UInt32 Min, UInt32 Max, UInt32 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + UInt32 VMin; + UInt32 VMax; + UInt32 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 MATH_FHistoVectSInt8 ( SInt8* PtSrc, SInt32 EltNb, SInt8 Min, SInt8 Max, UInt8 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + SInt8 VMin; + SInt8 VMax; + UInt8 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectSInt16 ( SInt16* PtSrc, SInt32 EltNb, SInt16 Min, SInt16 Max, UInt16 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + SInt16 VMin; + SInt16 VMax; + UInt16 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectSInt32 ( SInt32* PtSrc, SInt32 EltNb, SInt32 Min, SInt32 Max, UInt32 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + SInt32 VMin; + SInt32 VMax; + UInt32 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectFloat ( float* PtSrc, SInt32 EltNb, float Min, float Max, float BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + float VMin; + float VMax; + float VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + + +// 14/08/2007 + +SInt8 MATH_FChkUInt8Range ( float Data ) { + + if ( (Data < 0) || (Data > 255) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [0..255]") ); + } + + return (0); +} + + +// 14/08/2007 + +SInt8 MATH_FChkUInt16Range ( float Data ) { + + if ( (Data < 0) || (Data > 65535) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [0..65535]") ); + } + + return (0); +} + +// 14/08/2007 + +SInt8 MATH_FChkUInt32Range ( float Data ) { + + if ( (Data < 0) || (Data > 0xFFFFFFFF) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [0..%d]", 0xFFFFFFFF) ); + } + + return (0); +} + + + + +// 14/08/2007 + +SInt8 MATH_FChkSInt8Range ( float Data ) { + + if ( (Data < -128) || (Data > 127) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [-128..127]") ); + } + + return (0); +} + + +// 14/08/2007 + +SInt8 MATH_FChkSInt16Range ( float Data ) { + + if ( (Data < -32768) || (Data > 32767) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [-32768..32767]") ); + } + + return (0); +} + +// 14/08/2007 + +SInt8 MATH_FChkSInt32Range ( float Data ) { + + +#ifdef INT_MAX + if ( (Data < (-INT_MAX-1)) || (Data > INT_MAX) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [%d..%d]", (-INT_MAX-1), INT_MAX) ); + } +#else + if ( (Data < (-MaxInt-1)) || (Data > MaxInt) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [%d..%d]", (-MaxInt-1), MaxInt) ); + } +#endif + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + +#endif + +// msg (( MSG_OUT, "Msg" )); diff --git a/include/pxi_daq_lib_v.2.1/math.def b/include/pxi_daq_lib_v.2.1/math.def new file mode 100755 index 0000000..f6e521a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/math.def @@ -0,0 +1,27 @@ + +/* 03/05/2004 */ + +#ifndef MATH_DEF +#define MATH_DEF + + +#define MATH_HISTO_MAX_ID_NB 10 +#define MATH_HISTO_MAX_BIN_NB 4096 + + +typedef enum { + + DAM_DATA_TYPE_NOT_SET, + DAM_DATA_TYPE_UINT8, + DAM_DATA_TYPE_UINT16, + DAM_DATA_TYPE_UINT32, + DAM_DATA_TYPE_SINT8, + DAM_DATA_TYPE_SINT16, + DAM_DATA_TYPE_SINT32, + DAM_DATA_TYPE_FLOAT, + +} DAM_EDataTypes; + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/math.h b/include/pxi_daq_lib_v.2.1/math.h new file mode 100755 index 0000000..caa84b9 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/math.h @@ -0,0 +1,69 @@ + +#ifndef MATH_H + +#include "func_header.def" + +// FHEAD (;) + + +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 MATH_FSInt32MaxNo1 ( SInt32 Src, SInt8 StartSearch );) +FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 MATH_FSInt32MinNo1 ( SInt32 Src, SInt8 StartSearch );) + + +FHEAD ( SInt32 MATH_FCpySInt32ToSInt16Array ( SInt32* PtSrc, SInt32 SrcEltSz, SInt16* PtDest, SInt32 DestEltSz );) + +FHEAD ( float MATH_FSInt32Avg ( SInt32* Src, SInt32 EltNb );) + +FHEAD ( float MATH_FFloatAvg ( float* Src, SInt32 EltNb );) + + +FHEAD ( float MATH_FFloatMin ( float* Src, SInt32 EltNb );) +FHEAD ( float MATH_FFloatMax ( float* Src, SInt32 EltNb );) + +FHEAD ( SInt32 MATH_FSInt32Min ( SInt32* Src, SInt32 EltNb );) +FHEAD ( SInt32 MATH_FSInt32Max ( SInt32* Src, SInt32 EltNb );) + + +FHEAD ( float MATH_FSInt32Sigma1 ( SInt32* Src, SInt32 EltNb, float Avg );) + +FHEAD ( float MATH_FFloat32Sigma1 ( float* Src, SInt32 EltNb, float Avg );) + +FHEAD ( void MATH_FDiffPedest ( SInt32* Src, float Pedest, float* Dest, SInt32 EltNb );) + +FHEAD ( SInt32 MATH_FScaleFloatVect ( float* Src, float* Dest, SInt32 EltNb, float Offset, float Slope );) + +FHEAD ( SInt32 MATH_FIntInRange ( SInt32 Min, SInt32 Max, SInt32 Val );) +FHEAD ( SInt32 MATH_FFLoatInRange ( float Min, float Max, float Val );) + +FHEAD ( float MATH_UCONV_FVoltageGain2dB ( float Gain );) +FHEAD ( float MATH_UCONV_FdB2VoltageGain ( float dB );) +FHEAD ( float MATH_UCONV_FPowerGain2dB ( float Gain );) +FHEAD ( float MATH_UCONV_FdB2PowerGain ( float dB );) +FHEAD ( float MATH_UCONV_FV2dBV ( float Volt );) +FHEAD ( float MATH_UCONV_FdBV2V ( float dBV );) +FHEAD ( float MATH_UCONV_FmV2dBV ( float mV );) +FHEAD ( float MATH_UCONV_FdBV2mV ( float dBV );) + +FHEAD ( float MATH_UCONV_FV2dBmV ( float Volt );) +FHEAD ( float MATH_UCONV_FdBmV2V ( float dBmV );) + +FHEAD ( float MATH_UCONV_FV2dBm600 ( float Volt );) +FHEAD ( float MATH_UCONV_FdBm600_2V ( float dBm600 );) +FHEAD ( float MATH_UCONV_FmV2dBm600 ( float mV );) +FHEAD ( float MATH_UCONV_FdBm50_2V ( float dBm50 );) +FHEAD ( float MATH_UCONV_FV2dBm50 ( float Volt );) +FHEAD ( float MATH_UCONV_FmV2dBm50 ( float mV );) + + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef MATH_H + #define MATH_H + #endif +#endif + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/math.typ b/include/pxi_daq_lib_v.2.1/math.typ new file mode 100755 index 0000000..7d10179 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/math.typ @@ -0,0 +1,8 @@ +/* 03/05/2004 */ + +#ifndef MATH_TYP +#define MATH_TYP + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/math.var b/include/pxi_daq_lib_v.2.1/math.var new file mode 100755 index 0000000..98cc61a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/math.var @@ -0,0 +1,7 @@ + +/* 03/05/2004 */ + +#ifndef MATH_VAR +#define MATH_VAR + +#endif diff --git a/include/pxi_daq_lib_v.2.1/mi26_usr.c b/include/pxi_daq_lib_v.2.1/mi26_usr.c new file mode 100755 index 0000000..25803b0 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/mi26_usr.c @@ -0,0 +1,115 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.c +Goal : Functions of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 205/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_C +#define MI26_USR_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MI26__FBegin ( SInt8 FileErrLogLvl, char* FileErrFile ) { + + MI26__VGContext.FileErrLogLvl = FileErrLogLvl; + strcpy ( MI26__VGContext.FileErrFile, FileErrFile ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 MI26__FEnd () { + + + err_retok (( ERR_OUT, "" )); +} + + + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/mi26_usr.def b/include/pxi_daq_lib_v.2.1/mi26_usr.def new file mode 100755 index 0000000..7771c7f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/mi26_usr.def @@ -0,0 +1,75 @@ +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.def +Goal : Macros definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_DEF +#define MI26_USR_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ 1152 + +#define MI26__ZS_FFRAME_RAW_MAX_W8 2280 +#define MI26__ZS_FFRAME_RAW_MAX_W16 1140 // 1142 +#define MI26__ZS_FFRAME_RAW_MAX_W32 570 +#define MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 + + +#define MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 +#define MI26__ZS_FFRAME_MAX_STATES_REC 576 // one per line + +// ====================================== +// For MI26 discri analysis tools +// ====================================== + +// Submatrices number + +#define MI26__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define MI26__REG_BIAS_NB 19 + +#define MI26__REG_BIAS_ICLPDISC 0 +#define MI26__REG_BIAS_IPWRSW 1 +#define MI26__REG_BIAS_IBUF 2 +#define MI26__REG_BIAS_ID1PWRS 3 +#define MI26__REG_BIAS_ID2PWRS 4 +#define MI26__REG_BIAS_ILVDSTX 5 +#define MI26__REG_BIAS_ILVDS 6 +#define MI26__REG_BIAS_IVTST1 7 +#define MI26__REG_BIAS_IVTST2 8 +#define MI26__REG_BIAS_IANABUF 9 +#define MI26__REG_BIAS_IVDREF1D 10 +#define MI26__REG_BIAS_IVDREF1C 11 +#define MI26__REG_BIAS_IVDREF1B 12 +#define MI26__REG_BIAS_IVDREF1A 13 +#define MI26__REG_BIAS_IVDREF2 14 +#define MI26__REG_BIAS_IDIS1 15 +#define MI26__REG_BIAS_IDIS2 16 +#define MI26__REG_BIAS_IPXI 17 +#define MI26__REG_BIAS_IKIMO 18 + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/mi26_usr.h b/include/pxi_daq_lib_v.2.1/mi26_usr.h new file mode 100755 index 0000000..b550582 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/mi26_usr.h @@ -0,0 +1,41 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.h +Goal : Functions prototypes of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/12/2007 +File date : 24/11/2008 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* MI26_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + +FHEAD ( SInt32 MI26_FBegin ( SInt8 FileErrLogLvl, char* FileErrFile );) +FHEAD ( SInt32 MI26_FEnd ();) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef MI26_USR_H + #define MI26_USR_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/mi26_usr.typ b/include/pxi_daq_lib_v.2.1/mi26_usr.typ new file mode 100755 index 0000000..006161a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/mi26_usr.typ @@ -0,0 +1,193 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.typ +Goal : Types definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_TYP +#define MI26_USR_TYP + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} MI26__TContext; + + +/* ======================================================= */ +/* Frame provided by Mi26 DAQ, it's independent of output */ +/* mode BUT data are not organized as in MI26__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by MI26__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + UInt32 Header; // Header of Mimosa 26 frame + UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 Trailer; // Trailer of Mimosa 26 frame + + UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + UInt16 ADataW16[MI26__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} MI26__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} MI26__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} MI26__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + MI26__TStatesLine StatesLine; + MI26__TState AStates[MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} MI26__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by Mi26, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a MI26 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + MI26__TZsFStatesRec AStatesRec[MI26__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} MI26__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/mi26_usr.var b/include/pxi_daq_lib_v.2.1/mi26_usr.var new file mode 100755 index 0000000..025a245 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/mi26_usr.var @@ -0,0 +1,33 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.var +Goal : Variables definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 24/11/2008 +File date : 24/11/2008 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_VAR +#define MI26_USR_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC MI26__TContext MI26__VGContext; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/msg.c b/include/pxi_daq_lib_v.2.1/msg.c new file mode 100755 index 0000000..7dd5585 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/msg.c @@ -0,0 +1,230 @@ + +/******************************************************************************* +File : x:\lib\com\msg\msg.c +Goal : Implement user messages print ( screen ) or log ( file ) functions. + : It's usefull to send debug messages. + : +Remark : The way it works is controlled by 3 globals variables + : MSG_VGLogClosed = 0 ( disable ) / 1 ( enable ) user messages + : MSG_VGLogPath = '/msg/msg.txt' = path of messages logfile + : MSG_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : There is the same variables with RMSG_ instead of MSG_ they are + : used for on-line remote monitoring messages. + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_C +#define MSG_C + + +SInt32 MSG_FGenEnableLog ( SInt8 Chan, SInt8 Enable ) { + MSG_VGALogClosed[Chan] = Enable; + MSG_VGALogEnabled[Chan] = Enable; + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGenGetLogEnabled ( SInt8 Chan ) { + return (MSG_VGALogEnabled[Chan]); +} + + +SInt32 MSG_FGenSetLogFilePath ( SInt8 Chan, char* LogFilePath ) { + sprintf ( MSG_VGALogPath[Chan], "%s", LogFilePath ); + return (0); +} + +char* MSG_FGenGetLogFilePath ( SInt8 Chan ) { + return ( MSG_VGALogPath[Chan] ); +} + +SInt32 MSG_FGenStopLog ( SInt8 Chan, SInt8 Stop ) { + MSG_VGADontLog[Chan] = Stop; + return (0); +} + + +SInt32 MSG_FGenBegin ( SInt8 Chan, SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( Chan, Enable ); + MSG_FGenSetLogFilePath ( Chan, FilePath ); + + return (0); +} + +SInt32 MSG_FBegin ( SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable ); + MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, FilePath ); + + return (0); +} + + +SInt32 MSG_FEnd () { + + return (0); +} + + +SInt32 MSG_FEnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt32 MSG_EnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt8 MSG_FGetLogEnabled () { + return ( MSG_FGenGetLogEnabled ( MSG_CHAN_MSG ) ); +} + +SInt32 MSG_FSetLogFilePath ( char* LogFilePath ) { + return ( MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, LogFilePath ) ); +} + +/* 11/06/2005 */ + +SInt32 MSG_FSetFileLogLevel ( SInt8 Level ) { + + MSG_VGFileLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_GSetFileLogLevel () { + return (MSG_VGFileLogLevel); +} + + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserLogLevel ( SInt8 Level ) { + + MSG_VGUserLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGetUserLogLevel () { + return (MSG_VGUserLogLevel); +} + +char* MSG_FGetLogFilePath ( void ) { + return ( MSG_FGenGetLogFilePath ( MSG_CHAN_MSG ) ); +} + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserMsgFunc ( TUserMsgFunc Func ) { + + MSG_VGUserMsgFunc = Func; + + return (0); +} + + +/* 07/04/2007 */ + +char* MSG_FGenGetMsgLogConfStr ( SInt8 Chan ) { + + static char VStr[MSG_CMT_SZ+1]; + + sprintf ( VStr, "Messages log configuration \n\n - Log enabled = %d \n - Stop log = %d \n - File log level = %d \n - Log file name = %s \n - User log level = %d \n\n ", MSG_VGALogEnabled[Chan], MSG_VGADontLog[Chan], MSG_VGFileLogLevel, MSG_VGALogPath[Chan], MSG_VGUserLogLevel ); + + return (VStr); +} + +/* 07/04/2007 */ + +char* MSG_FGetMsgLogConfStr () { + return ( MSG_FGenGetMsgLogConfStr (MSG_CHAN_MSG) ); +} + +SInt32 MSG_FGenMsg ( SInt8 Chan, SInt8 Level ) { + + static char VMsg[256 /* MSG_CMT_SZ include file not visble from ROOT => must be solved */]; + + if ( (MSG_VGFileLogLevel == 0) && (MSG_VGUserLogLevel == 0) ) { + return (0); + } + + sprintf ( VMsg, "MSG %.7d => %s \n", MSG_VGAMsgCnt[Chan]++, MSG_VGAStrMsg[Chan]); + + if ( (MSG_VGFileLogLevel != 0) && (MSG_VGFileLogLevel >= Level) ) { + + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + + // 29/10/2010 => Alway overwrite log file + + // if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + // MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + // } + + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "%s", VMsg ); + fflush ( MSG_VGALogFile[Chan] ); + } + + } /* End if ( Level >= MSG_VGFileLogLevel ) */ + + if ( (MSG_VGUserLogLevel != 0) && (MSG_VGUserLogLevel >= Level) ) { + + if ( MSG_VGUserMsgFunc != NULL ) { + MSG_VGUserMsgFunc ( VMsg ); + } + + } /* End if ( Level >= MSG_VGUserLogLevel ) */ + + + return (0); + +/* + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + } + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "MSG %.4d =>", MSG_VGAMsgCnt[Chan]++ ); + fprintf ( MSG_VGALogFile[Chan], MSG_VGAStrMsg[Chan] ); + fprintf ( MSG_VGALogFile[Chan], "\n" ); + fflush ( MSG_VGALogFile[Chan] ); + } + + return (0); + +*/ + +} + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/msg.def b/include/pxi_daq_lib_v.2.1/msg.def new file mode 100755 index 0000000..c709cc1 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/msg.def @@ -0,0 +1,63 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.def +Goal : Macros definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_DEF +#define MSG_DEF + + + +#define MSG_CMT_SZ 1024 + +#define MSG_CHAN_NB 2 +#define MSG_CHAN_MSG 0 +#define MSG_CHAN_RMSG 1 + + +/* Must be after variables definition, instead CINT will be unable to handle these macros */ + +#define MSG_VGLogFile MSG_VGALogFile[MSG_CHAN_MSG] +#define MSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_MSG] +#define MSG_VGDontLog MSG_VGADontLog[MSG_CHAN_MSG] +#define MSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_MSG] +#define MSG_VGLogPath MSG_VGALogPath[MSG_CHAN_MSG] + +#define RMSG_VGLogFile MSG_VGALogFile[MSG_CHAN_RMSG] +#define RMSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_RMSG] +#define RMSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_RMSG] +#define RMSG_VGLogPath MSG_VGALogPath[MSG_CHAN_RMSG] + +/* 07/04/2007 MSG_VGAStrMsg identifier replaced by MSG_OUT because of ROOT CINT macros limitations */ +/* #define MSG_OUT MSG_VGAStrMsg[MSG_CHAN_MSG] */ + +#define RMSG_OUT MSG_VGAStrMsg[MSG_CHAN_RMSG] + +#define MSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,127);} +#define msg(Msg) MSG_PRINTF(Msg) + +#define MSG_PRINTF_LVL(Msg,Lvl) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,Lvl); } +#define msgl(Msg,Lvl) MSG_PRINTF_LVL(Msg,Lvl) + + +#define RMSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_RMSG,127); } +#define msgr(Msg) RMSG_PRINTF(Msg) +#define rmsg(Msg) RMSG_PRINTF(Msg) + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/msg.h b/include/pxi_daq_lib_v.2.1/msg.h new file mode 100755 index 0000000..36e2d77 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/msg.h @@ -0,0 +1,69 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.typ +Goal : Functions prototypes of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_H + +#include "func_header.def" + +#include "msg.def" +#include "msg.typ" + + +// FHEAD (SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath );) + +FHEAD (SInt32 MSG_FGenEnableLog ( SInt8 Chan, SInt8 Enable );) +FHEAD (SInt8 MSG_FGenGetLogEnabled ( SInt8 Chan );) +FHEAD (SInt32 MSG_FGenSetLogFilePath ( SInt8 Chan, char* LogFilePath );) +FHEAD (char* MSG_FGenGetLogFilePath ( SInt8 Chan );) +FHEAD (SInt32 MSG_FGenStopLog ( SInt8 Chan, SInt8 Stop );) +FHEAD (char* MSG_FGenGetMsgLogConfStr ( SInt8 Chan );) +FHEAD (SInt32 MSG_FGenBegin ( SInt8 Chan, SInt8 Enable, char* FilePath );) +FHEAD (SInt32 MSG_FGenMsg ( SInt8 Chan, SInt8 Level );) + +FHEAD (SInt32 MSG_FBegin ( SInt8 Enable, char* FilePath );) +FHEAD (SInt32 MSG_EnableLog ( SInt8 Enable );) +FHEAD (SInt32 MSG_FEnableLog ( SInt8 Enable );) + + +FHEAD (SInt32 MSG_FSetFileLogLevel ( SInt8 Level );) +FHEAD (SInt32 MSG_FSetUserLogLevel ( SInt8 Level );) + +FHEAD (SInt32 MSG_FSetLogFilePath ( char* LogFilePath );) + +FHEAD (SInt32 MSG_FSetUserMsgFunc ( TUserMsgFunc Func );) + + +FHEAD (SInt8 MSG_FGetLogEnabled ();) +FHEAD (SInt8 MSG_FGetFileLogLevel ();) +FHEAD (SInt8 MSG_FGetUserLogLevel ();) +FHEAD (char* MSG_FGetMsgLogConfStr ();) + + +FHEAD (char* MSG_FGetLogFilePath ( void );) + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef MSG_H + #define MSG_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/msg.txt b/include/pxi_daq_lib_v.2.1/msg.txt new file mode 100755 index 0000000..646c1fe --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/msg.txt @@ -0,0 +1,4456 @@ +MSG 0000000 => ============================================================ +MSG 0000001 => = Print records size for alignment checking Windows / Unix = +MSG 0000002 => ------------------------------------------------------------ +MSG 0000003 => = System = Linux +MSG 0000004 => ============================================================ +MSG 0000005 => +MSG 0000006 => FIL__TCStreamFile_TBlocInf = 104 +MSG 0000007 => FIL__TCStreamFile_TRecInfFile = 144 +MSG 0000008 => EFRIO__TRunCont = 1628 +MSG 0000009 => ------------------------------------------------------------ +MSG 0000010 => EFRIO__TFrame = 280 +MSG 0000011 => EFRIO__TFrameHeader = 252 +MSG 0000012 => EFRIO__TFrameData = 12 +MSG 0000013 => EFRIO__TTriggerRec = 12 +MSG 0000014 => +MSG 0000015 => This is a general message - with default LogLvl = 1 - VMyVar=10 +MSG 0000016 => sizeof (EFRIO__TRunCont) = 1628 +MSG 0000017 => Run data file name = /Users/jeromeb/Data/cmos/fsbb/35400/RUN_35400.bin +MSG 0000018 => Run par file name = /Users/jeromeb/Data/cmos/fsbb/35400/RUN_35400.par +MSG 0000019 => ------------------------- +MSG 0000020 => Info file record +MSG 0000021 => ------------------------- +MSG 0000022 => Version = 1 +MSG 0000023 => ------------------------- +MSG 0000024 => Date create = 11/10/2014 +MSG 0000025 => Time create = 15:37:57|58 +MSG 0000026 => Date close = 11/10/2014 +MSG 0000027 => Time close = 15:39:14|76 +MSG 0000028 => ------------------------- +MSG 0000029 => FixedBlocSz = 0 +MSG 0000030 => MaxBlocSz = 32727040 +MSG 0000031 => BlocSz = 32727040 +MSG 0000032 => BlocNb = 30 +MSG 0000033 => ------------------------- +MSG 0000034 => ABlocInf[0].Offset = 0 +MSG 0000035 => ABlocInf[0].Sz = 11632640 +MSG 0000036 => ABlocInf[0].SpareW32InfoFormat = 1 +MSG 0000037 => ABlocInf[0].SpareW32InfoNb = 4 +MSG 0000038 => ABlocInf[0].ASpareW32Info[00] = 0 +MSG 0000039 => ABlocInf[0].ASpareW32Info[01] = 0 +MSG 0000040 => ABlocInf[0].ASpareW32Info[02] = 1500 +MSG 0000041 => ABlocInf[0].ASpareW32Info[03] = 4096 +MSG 0000042 => Bloc[0000] : Offset=000000000000 - Sz=00000000 [Bytes] - ASpare [0]=11632640 [1]=0000 [2]=0000 [3]=1500 +MSG 0000043 => Bloc[0001] : Offset=000011632640 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000044 => Bloc[0002] : Offset=000023306240 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000045 => Bloc[0003] : Offset=000034979840 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000046 => Bloc[0004] : Offset=000046653440 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000047 => Bloc[0005] : Offset=000058327040 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000048 => Bloc[0006] : Offset=000070000640 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000049 => Bloc[0007] : Offset=000081674240 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000050 => Bloc[0008] : Offset=000093347840 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000051 => Bloc[0009] : Offset=000105021440 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000052 => Bloc[0010] : Offset=000116695040 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000053 => Bloc[0011] : Offset=000128368640 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000054 => Bloc[0012] : Offset=000140042240 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000055 => Bloc[0013] : Offset=000151715840 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000056 => Bloc[0014] : Offset=000163389440 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000057 => Bloc[0015] : Offset=000175063040 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000058 => Bloc[0016] : Offset=000186736640 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000059 => Bloc[0017] : Offset=000198410240 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000060 => Bloc[0018] : Offset=000210083840 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000061 => Bloc[0019] : Offset=000221757440 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000062 => Bloc[0020] : Offset=000233431040 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000063 => Bloc[0021] : Offset=000245104640 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000064 => Bloc[0022] : Offset=000256778240 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000065 => Bloc[0023] : Offset=000268451840 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000066 => Bloc[0024] : Offset=000280125440 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000067 => Bloc[0025] : Offset=000291799040 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000068 => Bloc[0026] : Offset=000303472640 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000069 => Bloc[0027] : Offset=000315146240 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000070 => Bloc[0028] : Offset=000326819840 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000071 => Bloc[0029] : Offset=000338493440 - Sz=00000000 [Bytes] - ASpare [0]=11673600 [1]=0000 [2]=0000 [3]=1500 +MSG 0000072 => ------------------------- +MSG 0000073 => ============================================================ +MSG 0000074 => Run context record +MSG 0000075 => ============================================================ +MSG 0000076 => ------------------------------------------------------------ +MSG 0000077 => ParMi26Nb = 0006 +MSG 0000078 => ParFrameNbPerAcq = 1800 +MSG 0000079 => ------------------------------------------------------------ +MSG 0000080 => ParRunNo = 35400 +MSG 0000081 => ParTotEvNb = 1000000 +MSG 0000082 => ParEvNbPerFile = 0000 +MSG 0000083 => ParDataTransferMode = 0003 +MSG 0000084 => ParTrigMode = 0000 +MSG 0000085 => ParSaveOnDisk = 0002 +MSG 0000086 => ParSendOnEth = 0000 +MSG 0000087 => ParSendOnEthPCent = 0000 +MSG 0000088 => ParDestDir = D:\data\35400 +MSG 0000089 => ParFileNamePrefix = RUN_ +MSG 0000090 => ------------------------------------------------------------ +MSG 0000091 => ParJtagFileName = +MSG 0000092 => ------------------------------------------------------------ +MSG 0000093 => InfZsFFrameRawBuffSz = 0000 +MSG 0000094 => InfFrameBuffSz = 93808800 +MSG 0000095 => InfConfFileName = D:\data\35400\RUN_35400.par +MSG 0000096 => InfDataFileName = D:\data\35400\RUN_35400.bin +MSG 0000097 => InfSaveDataOnDiskRunning = 0000 +MSG 0000098 => ------------------------------------------------------------ +MSG 0000099 => CmdRun = -0001 +MSG 0000100 => ------------------------------------------------------------ +MSG 0000101 => ResAcqCnt = 0000 +MSG 0000102 => ResFrameCnt = 0000 +MSG 0000103 => ResEventCnt = 0000 +MSG 0000104 => ResDataRateMBytesPerSec = 0.000 +MSG 0000105 => ------------------------------------------------------------ +MSG 0000106 => PtZsFFrameRaw = 00000000 +MSG 0000107 => PtFrame = 00000000 +MSG 0000108 => ============================================================ +MSG 0000109 => ========================================== +MSG 0000110 => InfMaxFrameSz = 21396 +MSG 0000111 => ResRunCont.InfFrameBuffSz = 38512800 +MSG 0000112 => EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB = 928 +MSG 0000113 => EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ = 8 +MSG 0000114 => ========================================== +MSG 0000115 => ============================================================ +MSG 0000116 => Run context record +MSG 0000117 => ============================================================ +MSG 0000118 => ------------------------------------------------------------ +MSG 0000119 => ParMi26Nb = 0006 +MSG 0000120 => ParFrameNbPerAcq = 1800 +MSG 0000121 => ------------------------------------------------------------ +MSG 0000122 => ParRunNo = 35400 +MSG 0000123 => ParTotEvNb = 1000000 +MSG 0000124 => ParEvNbPerFile = 0000 +MSG 0000125 => ParDataTransferMode = 0003 +MSG 0000126 => ParTrigMode = 0000 +MSG 0000127 => ParSaveOnDisk = 0002 +MSG 0000128 => ParSendOnEth = 0000 +MSG 0000129 => ParSendOnEthPCent = 0000 +MSG 0000130 => ParDestDir = D:\data\35400 +MSG 0000131 => ParFileNamePrefix = RUN_ +MSG 0000132 => ------------------------------------------------------------ +MSG 0000133 => ParJtagFileName = +MSG 0000134 => ------------------------------------------------------------ +MSG 0000135 => InfZsFFrameRawBuffSz = 0000 +MSG 0000136 => InfFrameBuffSz = 38512800 +MSG 0000137 => InfConfFileName = D:\data\35400\RUN_35400.par +MSG 0000138 => InfDataFileName = D:\data\35400\RUN_35400.bin +MSG 0000139 => InfSaveDataOnDiskRunning = 0000 +MSG 0000140 => ------------------------------------------------------------ +MSG 0000141 => CmdRun = -0001 +MSG 0000142 => ------------------------------------------------------------ +MSG 0000143 => ResAcqCnt = 0000 +MSG 0000144 => ResFrameCnt = 0000 +MSG 0000145 => ResEventCnt = 0000 +MSG 0000146 => ResDataRateMBytesPerSec = 0.000 +MSG 0000147 => ------------------------------------------------------------ +MSG 0000148 => PtZsFFrameRaw = 00000000 +MSG 0000149 => PtFrame = 145d9000 +MSG 0000150 => ============================================================ +MSG 0000151 => ============================================== +MSG 0000152 => Tag = 55550000 [H] +MSG 0000153 => DaqVersion = 0000 [D] +MSG 0000154 => TotSz = 7780 [D] +MSG 0000155 => TrigRecOffset = 7768 [D] +MSG 0000156 => ---------------------------------------------- +MSG 0000157 => H.Tag = 00000001 [H] +MSG 0000158 => H.AcqStatus = 0000 [D] +MSG 0000159 => H.TrigStatus = 0000 [D] +MSG 0000160 => H.AcqId = 0000 [D] +MSG 0000161 => H.FrameIdInAcq = 0000 [D] +MSG 0000162 => H.MapsName = 0004 [D] +MSG 0000163 => H.MapsNb = 0006 [D] +MSG 0000164 => ---------------------------------------------- +MSG 0000165 => H.Header [0]=50004000 [1]=50014001 [2]=50024002 [3]=50034003 [4]=50044004 [5]=50054005 [6]=00000000 [7]=00000000 +MSG 0000166 => H.FrCnt [0]= 862622 [1]= 862622 [2]= 862622 [3]= 862622 [4]= 862622 [5]= 862622 [6]= 0 [7]= 0 +MSG 0000167 => H.DataSz [0]= 0 [1]= 104 [2]= 156 [3]= 208 [4]= 260 [5]= 312 [6]= 0 [7]= 0 +MSG 0000168 => H.Trailer [0]=70006000 [1]=70016001 [2]=70026002 [3]=70036003 [4]=70046004 [5]=70056005 [6]=00000000 [7]=00000000 +MSG 0000169 => ---------------------------------------------- +MSG 0000170 => H.TriggerNb = 0001 [D] +MSG 0000171 => H.TrigInfo line [0]=0063 [1]=0000 [2]=0000 +MSG 0000172 => H.TrigInfo TS [0]=0003 [1]=0000 [2]=0000 +MSG 0000173 => ---------------------------------------------- +MSG 0000174 => D.Tag = 00000002 [H] +MSG 0000175 => D.TotSz = 7488 [D] +MSG 0000176 => D.OneMapsSz = 1248 [D] +MSG 0000177 => =================================================================================== +MSG 0000178 => Fsbb0 No 0 +MSG 0000179 => =================================================================================== +MSG 0000180 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0000181 => Conv : VDataW30Length=0 +MSG 0000182 => *************************************************************************** +MSG 0000183 => * FSBB M [0] : Coordinates pixels with hit * +MSG 0000184 => *************************************************************************** +MSG 0000185 => +MSG 0000186 => =================================================================================== +MSG 0000187 => Fsbb0 No 1 +MSG 0000188 => =================================================================================== +MSG 0000189 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0000190 => Conv : VDataW30Length=104 +MSG 0000191 => *************************************************************************** +MSG 0000192 => * FSBB M [1] : Coordinates pixels with hit * +MSG 0000193 => *************************************************************************** +MSG 0000194 => Hit => Line [0000] - Col [0000] +MSG 0000195 => Hit => Line [0008] - Col [0000] +MSG 0000196 => Hit => Line [0016] - Col [0000] +MSG 0000197 => Hit => Line [0024] - Col [0000] +MSG 0000198 => Hit => Line [0032] - Col [0000] +MSG 0000199 => Hit => Line [0040] - Col [0000] +MSG 0000200 => Hit => Line [0048] - Col [0000] +MSG 0000201 => Hit => Line [0056] - Col [0000] +MSG 0000202 => Hit => Line [0064] - Col [0000] +MSG 0000203 => Hit => Line [0072] - Col [0000] +MSG 0000204 => Hit => Line [0080] - Col [0000] +MSG 0000205 => Hit => Line [0088] - Col [0000] +MSG 0000206 => Hit => Line [0096] - Col [0000] +MSG 0000207 => Hit => Line [0104] - Col [0000] +MSG 0000208 => Hit => Line [0112] - Col [0000] +MSG 0000209 => Hit => Line [0120] - Col [0000] +MSG 0000210 => Hit => Line [0128] - Col [0000] +MSG 0000211 => Hit => Line [0136] - Col [0000] +MSG 0000212 => Hit => Line [0144] - Col [0000] +MSG 0000213 => Hit => Line [0152] - Col [0000] +MSG 0000214 => Hit => Line [0160] - Col [0000] +MSG 0000215 => Hit => Line [0168] - Col [0000] +MSG 0000216 => Hit => Line [0176] - Col [0000] +MSG 0000217 => Hit => Line [0184] - Col [0000] +MSG 0000218 => Hit => Line [0192] - Col [0000] +MSG 0000219 => Hit => Line [0200] - Col [0000] +MSG 0000220 => Hit => Line [0208] - Col [0000] +MSG 0000221 => Hit => Line [0216] - Col [0000] +MSG 0000222 => Hit => Line [0224] - Col [0000] +MSG 0000223 => Hit => Line [0232] - Col [0000] +MSG 0000224 => Hit => Line [0240] - Col [0000] +MSG 0000225 => Hit => Line [0248] - Col [0000] +MSG 0000226 => Hit => Line [0256] - Col [0000] +MSG 0000227 => Hit => Line [0264] - Col [0000] +MSG 0000228 => Hit => Line [0272] - Col [0000] +MSG 0000229 => Hit => Line [0280] - Col [0000] +MSG 0000230 => Hit => Line [0288] - Col [0000] +MSG 0000231 => Hit => Line [0296] - Col [0000] +MSG 0000232 => Hit => Line [0304] - Col [0000] +MSG 0000233 => Hit => Line [0312] - Col [0000] +MSG 0000234 => Hit => Line [0320] - Col [0000] +MSG 0000235 => Hit => Line [0328] - Col [0000] +MSG 0000236 => Hit => Line [0336] - Col [0000] +MSG 0000237 => Hit => Line [0344] - Col [0000] +MSG 0000238 => Hit => Line [0352] - Col [0000] +MSG 0000239 => Hit => Line [0360] - Col [0000] +MSG 0000240 => Hit => Line [0368] - Col [0000] +MSG 0000241 => Hit => Line [0376] - Col [0000] +MSG 0000242 => Hit => Line [0384] - Col [0000] +MSG 0000243 => Hit => Line [0392] - Col [0000] +MSG 0000244 => Hit => Line [0400] - Col [0000] +MSG 0000245 => Hit => Line [0408] - Col [0000] +MSG 0000246 => +MSG 0000247 => =================================================================================== +MSG 0000248 => Fsbb0 No 2 +MSG 0000249 => =================================================================================== +MSG 0000250 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0000251 => Conv : VDataW30Length=156 +MSG 0000252 => *************************************************************************** +MSG 0000253 => * FSBB M [2] : Coordinates pixels with hit * +MSG 0000254 => *************************************************************************** +MSG 0000255 => Hit => Line [0000] - Col [0000] +MSG 0000256 => Hit => Line [0000] - Col [0008] +MSG 0000257 => Hit => Line [0008] - Col [0000] +MSG 0000258 => Hit => Line [0008] - Col [0008] +MSG 0000259 => Hit => Line [0016] - Col [0000] +MSG 0000260 => Hit => Line [0016] - Col [0008] +MSG 0000261 => Hit => Line [0024] - Col [0000] +MSG 0000262 => Hit => Line [0024] - Col [0008] +MSG 0000263 => Hit => Line [0032] - Col [0000] +MSG 0000264 => Hit => Line [0032] - Col [0008] +MSG 0000265 => Hit => Line [0040] - Col [0000] +MSG 0000266 => Hit => Line [0040] - Col [0008] +MSG 0000267 => Hit => Line [0048] - Col [0000] +MSG 0000268 => Hit => Line [0048] - Col [0008] +MSG 0000269 => Hit => Line [0056] - Col [0000] +MSG 0000270 => Hit => Line [0056] - Col [0008] +MSG 0000271 => Hit => Line [0064] - Col [0000] +MSG 0000272 => Hit => Line [0064] - Col [0008] +MSG 0000273 => Hit => Line [0072] - Col [0000] +MSG 0000274 => Hit => Line [0072] - Col [0008] +MSG 0000275 => Hit => Line [0080] - Col [0000] +MSG 0000276 => Hit => Line [0080] - Col [0008] +MSG 0000277 => Hit => Line [0088] - Col [0000] +MSG 0000278 => Hit => Line [0088] - Col [0008] +MSG 0000279 => Hit => Line [0096] - Col [0000] +MSG 0000280 => Hit => Line [0096] - Col [0008] +MSG 0000281 => Hit => Line [0104] - Col [0000] +MSG 0000282 => Hit => Line [0104] - Col [0008] +MSG 0000283 => Hit => Line [0112] - Col [0000] +MSG 0000284 => Hit => Line [0112] - Col [0008] +MSG 0000285 => Hit => Line [0120] - Col [0000] +MSG 0000286 => Hit => Line [0120] - Col [0008] +MSG 0000287 => Hit => Line [0128] - Col [0000] +MSG 0000288 => Hit => Line [0128] - Col [0008] +MSG 0000289 => Hit => Line [0136] - Col [0000] +MSG 0000290 => Hit => Line [0136] - Col [0008] +MSG 0000291 => Hit => Line [0144] - Col [0000] +MSG 0000292 => Hit => Line [0144] - Col [0008] +MSG 0000293 => Hit => Line [0152] - Col [0000] +MSG 0000294 => Hit => Line [0152] - Col [0008] +MSG 0000295 => Hit => Line [0160] - Col [0000] +MSG 0000296 => Hit => Line [0160] - Col [0008] +MSG 0000297 => Hit => Line [0168] - Col [0000] +MSG 0000298 => Hit => Line [0168] - Col [0008] +MSG 0000299 => Hit => Line [0176] - Col [0000] +MSG 0000300 => Hit => Line [0176] - Col [0008] +MSG 0000301 => Hit => Line [0184] - Col [0000] +MSG 0000302 => Hit => Line [0184] - Col [0008] +MSG 0000303 => Hit => Line [0192] - Col [0000] +MSG 0000304 => Hit => Line [0192] - Col [0008] +MSG 0000305 => Hit => Line [0200] - Col [0000] +MSG 0000306 => Hit => Line [0200] - Col [0008] +MSG 0000307 => Hit => Line [0208] - Col [0000] +MSG 0000308 => Hit => Line [0208] - Col [0008] +MSG 0000309 => Hit => Line [0216] - Col [0000] +MSG 0000310 => Hit => Line [0216] - Col [0008] +MSG 0000311 => Hit => Line [0224] - Col [0000] +MSG 0000312 => Hit => Line [0224] - Col [0008] +MSG 0000313 => Hit => Line [0232] - Col [0000] +MSG 0000314 => Hit => Line [0232] - Col [0008] +MSG 0000315 => Hit => Line [0240] - Col [0000] +MSG 0000316 => Hit => Line [0240] - Col [0008] +MSG 0000317 => Hit => Line [0248] - Col [0000] +MSG 0000318 => Hit => Line [0248] - Col [0008] +MSG 0000319 => Hit => Line [0256] - Col [0000] +MSG 0000320 => Hit => Line [0256] - Col [0008] +MSG 0000321 => Hit => Line [0264] - Col [0000] +MSG 0000322 => Hit => Line [0264] - Col [0008] +MSG 0000323 => Hit => Line [0272] - Col [0000] +MSG 0000324 => Hit => Line [0272] - Col [0008] +MSG 0000325 => Hit => Line [0280] - Col [0000] +MSG 0000326 => Hit => Line [0280] - Col [0008] +MSG 0000327 => Hit => Line [0288] - Col [0000] +MSG 0000328 => Hit => Line [0288] - Col [0008] +MSG 0000329 => Hit => Line [0296] - Col [0000] +MSG 0000330 => Hit => Line [0296] - Col [0008] +MSG 0000331 => Hit => Line [0304] - Col [0000] +MSG 0000332 => Hit => Line [0304] - Col [0008] +MSG 0000333 => Hit => Line [0312] - Col [0000] +MSG 0000334 => Hit => Line [0312] - Col [0008] +MSG 0000335 => Hit => Line [0320] - Col [0000] +MSG 0000336 => Hit => Line [0320] - Col [0008] +MSG 0000337 => Hit => Line [0328] - Col [0000] +MSG 0000338 => Hit => Line [0328] - Col [0008] +MSG 0000339 => Hit => Line [0336] - Col [0000] +MSG 0000340 => Hit => Line [0336] - Col [0008] +MSG 0000341 => Hit => Line [0344] - Col [0000] +MSG 0000342 => Hit => Line [0344] - Col [0008] +MSG 0000343 => Hit => Line [0352] - Col [0000] +MSG 0000344 => Hit => Line [0352] - Col [0008] +MSG 0000345 => Hit => Line [0360] - Col [0000] +MSG 0000346 => Hit => Line [0360] - Col [0008] +MSG 0000347 => Hit => Line [0368] - Col [0000] +MSG 0000348 => Hit => Line [0368] - Col [0008] +MSG 0000349 => Hit => Line [0376] - Col [0000] +MSG 0000350 => Hit => Line [0376] - Col [0008] +MSG 0000351 => Hit => Line [0384] - Col [0000] +MSG 0000352 => Hit => Line [0384] - Col [0008] +MSG 0000353 => Hit => Line [0392] - Col [0000] +MSG 0000354 => Hit => Line [0392] - Col [0008] +MSG 0000355 => Hit => Line [0400] - Col [0000] +MSG 0000356 => Hit => Line [0400] - Col [0008] +MSG 0000357 => Hit => Line [0408] - Col [0000] +MSG 0000358 => Hit => Line [0408] - Col [0008] +MSG 0000359 => +MSG 0000360 => =================================================================================== +MSG 0000361 => Fsbb0 No 3 +MSG 0000362 => =================================================================================== +MSG 0000363 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0000364 => Conv : VDataW30Length=208 +MSG 0000365 => *************************************************************************** +MSG 0000366 => * FSBB M [3] : Coordinates pixels with hit * +MSG 0000367 => *************************************************************************** +MSG 0000368 => Hit => Line [0000] - Col [0000] +MSG 0000369 => Hit => Line [0000] - Col [0008] +MSG 0000370 => Hit => Line [0000] - Col [0016] +MSG 0000371 => Hit => Line [0008] - Col [0000] +MSG 0000372 => Hit => Line [0008] - Col [0008] +MSG 0000373 => Hit => Line [0008] - Col [0016] +MSG 0000374 => Hit => Line [0016] - Col [0000] +MSG 0000375 => Hit => Line [0016] - Col [0008] +MSG 0000376 => Hit => Line [0016] - Col [0016] +MSG 0000377 => Hit => Line [0024] - Col [0000] +MSG 0000378 => Hit => Line [0024] - Col [0008] +MSG 0000379 => Hit => Line [0024] - Col [0016] +MSG 0000380 => Hit => Line [0032] - Col [0000] +MSG 0000381 => Hit => Line [0032] - Col [0008] +MSG 0000382 => Hit => Line [0032] - Col [0016] +MSG 0000383 => Hit => Line [0040] - Col [0000] +MSG 0000384 => Hit => Line [0040] - Col [0008] +MSG 0000385 => Hit => Line [0040] - Col [0016] +MSG 0000386 => Hit => Line [0048] - Col [0000] +MSG 0000387 => Hit => Line [0048] - Col [0008] +MSG 0000388 => Hit => Line [0048] - Col [0016] +MSG 0000389 => Hit => Line [0056] - Col [0000] +MSG 0000390 => Hit => Line [0056] - Col [0008] +MSG 0000391 => Hit => Line [0056] - Col [0016] +MSG 0000392 => Hit => Line [0064] - Col [0000] +MSG 0000393 => Hit => Line [0064] - Col [0008] +MSG 0000394 => Hit => Line [0064] - Col [0016] +MSG 0000395 => Hit => Line [0072] - Col [0000] +MSG 0000396 => Hit => Line [0072] - Col [0008] +MSG 0000397 => Hit => Line [0072] - Col [0016] +MSG 0000398 => Hit => Line [0080] - Col [0000] +MSG 0000399 => Hit => Line [0080] - Col [0008] +MSG 0000400 => Hit => Line [0080] - Col [0016] +MSG 0000401 => Hit => Line [0088] - Col [0000] +MSG 0000402 => Hit => Line [0088] - Col [0008] +MSG 0000403 => Hit => Line [0088] - Col [0016] +MSG 0000404 => Hit => Line [0096] - Col [0000] +MSG 0000405 => Hit => Line [0096] - Col [0008] +MSG 0000406 => Hit => Line [0096] - Col [0016] +MSG 0000407 => Hit => Line [0104] - Col [0000] +MSG 0000408 => Hit => Line [0104] - Col [0008] +MSG 0000409 => Hit => Line [0104] - Col [0016] +MSG 0000410 => Hit => Line [0112] - Col [0000] +MSG 0000411 => Hit => Line [0112] - Col [0008] +MSG 0000412 => Hit => Line [0112] - Col [0016] +MSG 0000413 => Hit => Line [0120] - Col [0000] +MSG 0000414 => Hit => Line [0120] - Col [0008] +MSG 0000415 => Hit => Line [0120] - Col [0016] +MSG 0000416 => Hit => Line [0128] - Col [0000] +MSG 0000417 => Hit => Line [0128] - Col [0008] +MSG 0000418 => Hit => Line [0128] - Col [0016] +MSG 0000419 => Hit => Line [0136] - Col [0000] +MSG 0000420 => Hit => Line [0136] - Col [0008] +MSG 0000421 => Hit => Line [0136] - Col [0016] +MSG 0000422 => Hit => Line [0144] - Col [0000] +MSG 0000423 => Hit => Line [0144] - Col [0008] +MSG 0000424 => Hit => Line [0144] - Col [0016] +MSG 0000425 => Hit => Line [0152] - Col [0000] +MSG 0000426 => Hit => Line [0152] - Col [0008] +MSG 0000427 => Hit => Line [0152] - Col [0016] +MSG 0000428 => Hit => Line [0160] - Col [0000] +MSG 0000429 => Hit => Line [0160] - Col [0008] +MSG 0000430 => Hit => Line [0160] - Col [0016] +MSG 0000431 => Hit => Line [0168] - Col [0000] +MSG 0000432 => Hit => Line [0168] - Col [0008] +MSG 0000433 => Hit => Line [0168] - Col [0016] +MSG 0000434 => Hit => Line [0176] - Col [0000] +MSG 0000435 => Hit => Line [0176] - Col [0008] +MSG 0000436 => Hit => Line [0176] - Col [0016] +MSG 0000437 => Hit => Line [0184] - Col [0000] +MSG 0000438 => Hit => Line [0184] - Col [0008] +MSG 0000439 => Hit => Line [0184] - Col [0016] +MSG 0000440 => Hit => Line [0192] - Col [0000] +MSG 0000441 => Hit => Line [0192] - Col [0008] +MSG 0000442 => Hit => Line [0192] - Col [0016] +MSG 0000443 => Hit => Line [0200] - Col [0000] +MSG 0000444 => Hit => Line [0200] - Col [0008] +MSG 0000445 => Hit => Line [0200] - Col [0016] +MSG 0000446 => Hit => Line [0208] - Col [0000] +MSG 0000447 => Hit => Line [0208] - Col [0008] +MSG 0000448 => Hit => Line [0208] - Col [0016] +MSG 0000449 => Hit => Line [0216] - Col [0000] +MSG 0000450 => Hit => Line [0216] - Col [0008] +MSG 0000451 => Hit => Line [0216] - Col [0016] +MSG 0000452 => Hit => Line [0224] - Col [0000] +MSG 0000453 => Hit => Line [0224] - Col [0008] +MSG 0000454 => Hit => Line [0224] - Col [0016] +MSG 0000455 => Hit => Line [0232] - Col [0000] +MSG 0000456 => Hit => Line [0232] - Col [0008] +MSG 0000457 => Hit => Line [0232] - Col [0016] +MSG 0000458 => Hit => Line [0240] - Col [0000] +MSG 0000459 => Hit => Line [0240] - Col [0008] +MSG 0000460 => Hit => Line [0240] - Col [0016] +MSG 0000461 => Hit => Line [0248] - Col [0000] +MSG 0000462 => Hit => Line [0248] - Col [0008] +MSG 0000463 => Hit => Line [0248] - Col [0016] +MSG 0000464 => Hit => Line [0256] - Col [0000] +MSG 0000465 => Hit => Line [0256] - Col [0008] +MSG 0000466 => Hit => Line [0256] - Col [0016] +MSG 0000467 => Hit => Line [0264] - Col [0000] +MSG 0000468 => Hit => Line [0264] - Col [0008] +MSG 0000469 => Hit => Line [0264] - Col [0016] +MSG 0000470 => Hit => Line [0272] - Col [0000] +MSG 0000471 => Hit => Line [0272] - Col [0008] +MSG 0000472 => Hit => Line [0272] - Col [0016] +MSG 0000473 => Hit => Line [0280] - Col [0000] +MSG 0000474 => Hit => Line [0280] - Col [0008] +MSG 0000475 => Hit => Line [0280] - Col [0016] +MSG 0000476 => Hit => Line [0288] - Col [0000] +MSG 0000477 => Hit => Line [0288] - Col [0008] +MSG 0000478 => Hit => Line [0288] - Col [0016] +MSG 0000479 => Hit => Line [0296] - Col [0000] +MSG 0000480 => Hit => Line [0296] - Col [0008] +MSG 0000481 => Hit => Line [0296] - Col [0016] +MSG 0000482 => Hit => Line [0304] - Col [0000] +MSG 0000483 => Hit => Line [0304] - Col [0008] +MSG 0000484 => Hit => Line [0304] - Col [0016] +MSG 0000485 => Hit => Line [0312] - Col [0000] +MSG 0000486 => Hit => Line [0312] - Col [0008] +MSG 0000487 => Hit => Line [0312] - Col [0016] +MSG 0000488 => Hit => Line [0320] - Col [0000] +MSG 0000489 => Hit => Line [0320] - Col [0008] +MSG 0000490 => Hit => Line [0320] - Col [0016] +MSG 0000491 => Hit => Line [0328] - Col [0000] +MSG 0000492 => Hit => Line [0328] - Col [0008] +MSG 0000493 => Hit => Line [0328] - Col [0016] +MSG 0000494 => Hit => Line [0336] - Col [0000] +MSG 0000495 => Hit => Line [0336] - Col [0008] +MSG 0000496 => Hit => Line [0336] - Col [0016] +MSG 0000497 => Hit => Line [0344] - Col [0000] +MSG 0000498 => Hit => Line [0344] - Col [0008] +MSG 0000499 => Hit => Line [0344] - Col [0016] +MSG 0000500 => Hit => Line [0352] - Col [0000] +MSG 0000501 => Hit => Line [0352] - Col [0008] +MSG 0000502 => Hit => Line [0352] - Col [0016] +MSG 0000503 => Hit => Line [0360] - Col [0000] +MSG 0000504 => Hit => Line [0360] - Col [0008] +MSG 0000505 => Hit => Line [0360] - Col [0016] +MSG 0000506 => Hit => Line [0368] - Col [0000] +MSG 0000507 => Hit => Line [0368] - Col [0008] +MSG 0000508 => Hit => Line [0368] - Col [0016] +MSG 0000509 => Hit => Line [0376] - Col [0000] +MSG 0000510 => Hit => Line [0376] - Col [0008] +MSG 0000511 => Hit => Line [0376] - Col [0016] +MSG 0000512 => Hit => Line [0384] - Col [0000] +MSG 0000513 => Hit => Line [0384] - Col [0008] +MSG 0000514 => Hit => Line [0384] - Col [0016] +MSG 0000515 => Hit => Line [0392] - Col [0000] +MSG 0000516 => Hit => Line [0392] - Col [0008] +MSG 0000517 => Hit => Line [0392] - Col [0016] +MSG 0000518 => Hit => Line [0400] - Col [0000] +MSG 0000519 => Hit => Line [0400] - Col [0008] +MSG 0000520 => Hit => Line [0400] - Col [0016] +MSG 0000521 => Hit => Line [0408] - Col [0000] +MSG 0000522 => Hit => Line [0408] - Col [0008] +MSG 0000523 => Hit => Line [0408] - Col [0016] +MSG 0000524 => +MSG 0000525 => =================================================================================== +MSG 0000526 => Fsbb0 No 4 +MSG 0000527 => =================================================================================== +MSG 0000528 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0000529 => Conv : VDataW30Length=260 +MSG 0000530 => *************************************************************************** +MSG 0000531 => * FSBB M [4] : Coordinates pixels with hit * +MSG 0000532 => *************************************************************************** +MSG 0000533 => Hit => Line [0000] - Col [0000] +MSG 0000534 => Hit => Line [0000] - Col [0008] +MSG 0000535 => Hit => Line [0000] - Col [0016] +MSG 0000536 => Hit => Line [0000] - Col [0023] +MSG 0000537 => Hit => Line [0008] - Col [0000] +MSG 0000538 => Hit => Line [0008] - Col [0008] +MSG 0000539 => Hit => Line [0008] - Col [0016] +MSG 0000540 => Hit => Line [0008] - Col [0023] +MSG 0000541 => Hit => Line [0016] - Col [0000] +MSG 0000542 => Hit => Line [0016] - Col [0008] +MSG 0000543 => Hit => Line [0016] - Col [0016] +MSG 0000544 => Hit => Line [0016] - Col [0023] +MSG 0000545 => Hit => Line [0024] - Col [0000] +MSG 0000546 => Hit => Line [0024] - Col [0008] +MSG 0000547 => Hit => Line [0024] - Col [0016] +MSG 0000548 => Hit => Line [0024] - Col [0023] +MSG 0000549 => Hit => Line [0032] - Col [0000] +MSG 0000550 => Hit => Line [0032] - Col [0008] +MSG 0000551 => Hit => Line [0032] - Col [0016] +MSG 0000552 => Hit => Line [0032] - Col [0023] +MSG 0000553 => Hit => Line [0040] - Col [0000] +MSG 0000554 => Hit => Line [0040] - Col [0008] +MSG 0000555 => Hit => Line [0040] - Col [0016] +MSG 0000556 => Hit => Line [0040] - Col [0023] +MSG 0000557 => Hit => Line [0048] - Col [0000] +MSG 0000558 => Hit => Line [0048] - Col [0008] +MSG 0000559 => Hit => Line [0048] - Col [0016] +MSG 0000560 => Hit => Line [0048] - Col [0023] +MSG 0000561 => Hit => Line [0056] - Col [0000] +MSG 0000562 => Hit => Line [0056] - Col [0008] +MSG 0000563 => Hit => Line [0056] - Col [0016] +MSG 0000564 => Hit => Line [0056] - Col [0023] +MSG 0000565 => Hit => Line [0064] - Col [0000] +MSG 0000566 => Hit => Line [0064] - Col [0008] +MSG 0000567 => Hit => Line [0064] - Col [0016] +MSG 0000568 => Hit => Line [0064] - Col [0023] +MSG 0000569 => Hit => Line [0072] - Col [0000] +MSG 0000570 => Hit => Line [0072] - Col [0008] +MSG 0000571 => Hit => Line [0072] - Col [0016] +MSG 0000572 => Hit => Line [0072] - Col [0023] +MSG 0000573 => Hit => Line [0080] - Col [0000] +MSG 0000574 => Hit => Line [0080] - Col [0008] +MSG 0000575 => Hit => Line [0080] - Col [0016] +MSG 0000576 => Hit => Line [0080] - Col [0023] +MSG 0000577 => Hit => Line [0088] - Col [0000] +MSG 0000578 => Hit => Line [0088] - Col [0008] +MSG 0000579 => Hit => Line [0088] - Col [0016] +MSG 0000580 => Hit => Line [0088] - Col [0023] +MSG 0000581 => Hit => Line [0096] - Col [0000] +MSG 0000582 => Hit => Line [0096] - Col [0008] +MSG 0000583 => Hit => Line [0096] - Col [0016] +MSG 0000584 => Hit => Line [0096] - Col [0023] +MSG 0000585 => Hit => Line [0104] - Col [0000] +MSG 0000586 => Hit => Line [0104] - Col [0008] +MSG 0000587 => Hit => Line [0104] - Col [0016] +MSG 0000588 => Hit => Line [0104] - Col [0023] +MSG 0000589 => Hit => Line [0112] - Col [0000] +MSG 0000590 => Hit => Line [0112] - Col [0008] +MSG 0000591 => Hit => Line [0112] - Col [0016] +MSG 0000592 => Hit => Line [0112] - Col [0023] +MSG 0000593 => Hit => Line [0120] - Col [0000] +MSG 0000594 => Hit => Line [0120] - Col [0008] +MSG 0000595 => Hit => Line [0120] - Col [0016] +MSG 0000596 => Hit => Line [0120] - Col [0023] +MSG 0000597 => Hit => Line [0128] - Col [0000] +MSG 0000598 => Hit => Line [0128] - Col [0008] +MSG 0000599 => Hit => Line [0128] - Col [0016] +MSG 0000600 => Hit => Line [0128] - Col [0023] +MSG 0000601 => Hit => Line [0136] - Col [0000] +MSG 0000602 => Hit => Line [0136] - Col [0008] +MSG 0000603 => Hit => Line [0136] - Col [0016] +MSG 0000604 => Hit => Line [0136] - Col [0023] +MSG 0000605 => Hit => Line [0144] - Col [0000] +MSG 0000606 => Hit => Line [0144] - Col [0008] +MSG 0000607 => Hit => Line [0144] - Col [0016] +MSG 0000608 => Hit => Line [0144] - Col [0023] +MSG 0000609 => Hit => Line [0152] - Col [0000] +MSG 0000610 => Hit => Line [0152] - Col [0008] +MSG 0000611 => Hit => Line [0152] - Col [0016] +MSG 0000612 => Hit => Line [0152] - Col [0023] +MSG 0000613 => Hit => Line [0160] - Col [0000] +MSG 0000614 => Hit => Line [0160] - Col [0008] +MSG 0000615 => Hit => Line [0160] - Col [0016] +MSG 0000616 => Hit => Line [0160] - Col [0023] +MSG 0000617 => Hit => Line [0168] - Col [0000] +MSG 0000618 => Hit => Line [0168] - Col [0008] +MSG 0000619 => Hit => Line [0168] - Col [0016] +MSG 0000620 => Hit => Line [0168] - Col [0023] +MSG 0000621 => Hit => Line [0176] - Col [0000] +MSG 0000622 => Hit => Line [0176] - Col [0008] +MSG 0000623 => Hit => Line [0176] - Col [0016] +MSG 0000624 => Hit => Line [0176] - Col [0023] +MSG 0000625 => Hit => Line [0184] - Col [0000] +MSG 0000626 => Hit => Line [0184] - Col [0008] +MSG 0000627 => Hit => Line [0184] - Col [0016] +MSG 0000628 => Hit => Line [0184] - Col [0023] +MSG 0000629 => Hit => Line [0192] - Col [0000] +MSG 0000630 => Hit => Line [0192] - Col [0008] +MSG 0000631 => Hit => Line [0192] - Col [0016] +MSG 0000632 => Hit => Line [0192] - Col [0023] +MSG 0000633 => Hit => Line [0200] - Col [0000] +MSG 0000634 => Hit => Line [0200] - Col [0008] +MSG 0000635 => Hit => Line [0200] - Col [0016] +MSG 0000636 => Hit => Line [0200] - Col [0023] +MSG 0000637 => Hit => Line [0208] - Col [0000] +MSG 0000638 => Hit => Line [0208] - Col [0008] +MSG 0000639 => Hit => Line [0208] - Col [0016] +MSG 0000640 => Hit => Line [0208] - Col [0023] +MSG 0000641 => Hit => Line [0216] - Col [0000] +MSG 0000642 => Hit => Line [0216] - Col [0008] +MSG 0000643 => Hit => Line [0216] - Col [0016] +MSG 0000644 => Hit => Line [0216] - Col [0023] +MSG 0000645 => Hit => Line [0224] - Col [0000] +MSG 0000646 => Hit => Line [0224] - Col [0008] +MSG 0000647 => Hit => Line [0224] - Col [0016] +MSG 0000648 => Hit => Line [0224] - Col [0023] +MSG 0000649 => Hit => Line [0232] - Col [0000] +MSG 0000650 => Hit => Line [0232] - Col [0008] +MSG 0000651 => Hit => Line [0232] - Col [0016] +MSG 0000652 => Hit => Line [0232] - Col [0023] +MSG 0000653 => Hit => Line [0240] - Col [0000] +MSG 0000654 => Hit => Line [0240] - Col [0008] +MSG 0000655 => Hit => Line [0240] - Col [0016] +MSG 0000656 => Hit => Line [0240] - Col [0023] +MSG 0000657 => Hit => Line [0248] - Col [0000] +MSG 0000658 => Hit => Line [0248] - Col [0008] +MSG 0000659 => Hit => Line [0248] - Col [0016] +MSG 0000660 => Hit => Line [0248] - Col [0023] +MSG 0000661 => Hit => Line [0256] - Col [0000] +MSG 0000662 => Hit => Line [0256] - Col [0008] +MSG 0000663 => Hit => Line [0256] - Col [0016] +MSG 0000664 => Hit => Line [0256] - Col [0023] +MSG 0000665 => Hit => Line [0264] - Col [0000] +MSG 0000666 => Hit => Line [0264] - Col [0008] +MSG 0000667 => Hit => Line [0264] - Col [0016] +MSG 0000668 => Hit => Line [0264] - Col [0023] +MSG 0000669 => Hit => Line [0272] - Col [0000] +MSG 0000670 => Hit => Line [0272] - Col [0008] +MSG 0000671 => Hit => Line [0272] - Col [0016] +MSG 0000672 => Hit => Line [0272] - Col [0023] +MSG 0000673 => Hit => Line [0280] - Col [0000] +MSG 0000674 => Hit => Line [0280] - Col [0008] +MSG 0000675 => Hit => Line [0280] - Col [0016] +MSG 0000676 => Hit => Line [0280] - Col [0023] +MSG 0000677 => Hit => Line [0288] - Col [0000] +MSG 0000678 => Hit => Line [0288] - Col [0008] +MSG 0000679 => Hit => Line [0288] - Col [0016] +MSG 0000680 => Hit => Line [0288] - Col [0023] +MSG 0000681 => Hit => Line [0296] - Col [0000] +MSG 0000682 => Hit => Line [0296] - Col [0008] +MSG 0000683 => Hit => Line [0296] - Col [0016] +MSG 0000684 => Hit => Line [0296] - Col [0023] +MSG 0000685 => Hit => Line [0304] - Col [0000] +MSG 0000686 => Hit => Line [0304] - Col [0008] +MSG 0000687 => Hit => Line [0304] - Col [0016] +MSG 0000688 => Hit => Line [0304] - Col [0023] +MSG 0000689 => Hit => Line [0312] - Col [0000] +MSG 0000690 => Hit => Line [0312] - Col [0008] +MSG 0000691 => Hit => Line [0312] - Col [0016] +MSG 0000692 => Hit => Line [0312] - Col [0023] +MSG 0000693 => Hit => Line [0320] - Col [0000] +MSG 0000694 => Hit => Line [0320] - Col [0008] +MSG 0000695 => Hit => Line [0320] - Col [0016] +MSG 0000696 => Hit => Line [0320] - Col [0023] +MSG 0000697 => Hit => Line [0328] - Col [0000] +MSG 0000698 => Hit => Line [0328] - Col [0008] +MSG 0000699 => Hit => Line [0328] - Col [0016] +MSG 0000700 => Hit => Line [0328] - Col [0023] +MSG 0000701 => Hit => Line [0336] - Col [0000] +MSG 0000702 => Hit => Line [0336] - Col [0008] +MSG 0000703 => Hit => Line [0336] - Col [0016] +MSG 0000704 => Hit => Line [0336] - Col [0023] +MSG 0000705 => Hit => Line [0344] - Col [0000] +MSG 0000706 => Hit => Line [0344] - Col [0008] +MSG 0000707 => Hit => Line [0344] - Col [0016] +MSG 0000708 => Hit => Line [0344] - Col [0023] +MSG 0000709 => Hit => Line [0352] - Col [0000] +MSG 0000710 => Hit => Line [0352] - Col [0008] +MSG 0000711 => Hit => Line [0352] - Col [0016] +MSG 0000712 => Hit => Line [0352] - Col [0023] +MSG 0000713 => Hit => Line [0360] - Col [0000] +MSG 0000714 => Hit => Line [0360] - Col [0008] +MSG 0000715 => Hit => Line [0360] - Col [0016] +MSG 0000716 => Hit => Line [0360] - Col [0023] +MSG 0000717 => Hit => Line [0368] - Col [0000] +MSG 0000718 => Hit => Line [0368] - Col [0008] +MSG 0000719 => Hit => Line [0368] - Col [0016] +MSG 0000720 => Hit => Line [0368] - Col [0023] +MSG 0000721 => Hit => Line [0376] - Col [0000] +MSG 0000722 => Hit => Line [0376] - Col [0008] +MSG 0000723 => Hit => Line [0376] - Col [0016] +MSG 0000724 => Hit => Line [0376] - Col [0023] +MSG 0000725 => Hit => Line [0384] - Col [0000] +MSG 0000726 => Hit => Line [0384] - Col [0008] +MSG 0000727 => Hit => Line [0384] - Col [0016] +MSG 0000728 => Hit => Line [0384] - Col [0023] +MSG 0000729 => Hit => Line [0392] - Col [0000] +MSG 0000730 => Hit => Line [0392] - Col [0008] +MSG 0000731 => Hit => Line [0392] - Col [0016] +MSG 0000732 => Hit => Line [0392] - Col [0023] +MSG 0000733 => Hit => Line [0400] - Col [0000] +MSG 0000734 => Hit => Line [0400] - Col [0008] +MSG 0000735 => Hit => Line [0400] - Col [0016] +MSG 0000736 => Hit => Line [0400] - Col [0023] +MSG 0000737 => Hit => Line [0408] - Col [0000] +MSG 0000738 => Hit => Line [0408] - Col [0008] +MSG 0000739 => Hit => Line [0408] - Col [0016] +MSG 0000740 => Hit => Line [0408] - Col [0023] +MSG 0000741 => +MSG 0000742 => =================================================================================== +MSG 0000743 => Fsbb0 No 5 +MSG 0000744 => =================================================================================== +MSG 0000745 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0000746 => Conv : VDataW30Length=312 +MSG 0000747 => *************************************************************************** +MSG 0000748 => * FSBB M [5] : Coordinates pixels with hit * +MSG 0000749 => *************************************************************************** +MSG 0000750 => Hit => Line [0000] - Col [0000] +MSG 0000751 => Hit => Line [0000] - Col [0032] +MSG 0000752 => Hit => Line [0000] - Col [0064] +MSG 0000753 => Hit => Line [0000] - Col [0096] +MSG 0000754 => Hit => Line [0000] - Col [0128] +MSG 0000755 => Hit => Line [0008] - Col [0000] +MSG 0000756 => Hit => Line [0008] - Col [0032] +MSG 0000757 => Hit => Line [0008] - Col [0064] +MSG 0000758 => Hit => Line [0008] - Col [0096] +MSG 0000759 => Hit => Line [0008] - Col [0128] +MSG 0000760 => Hit => Line [0016] - Col [0000] +MSG 0000761 => Hit => Line [0016] - Col [0032] +MSG 0000762 => Hit => Line [0016] - Col [0064] +MSG 0000763 => Hit => Line [0016] - Col [0096] +MSG 0000764 => Hit => Line [0016] - Col [0128] +MSG 0000765 => Hit => Line [0024] - Col [0000] +MSG 0000766 => Hit => Line [0024] - Col [0032] +MSG 0000767 => Hit => Line [0024] - Col [0064] +MSG 0000768 => Hit => Line [0024] - Col [0096] +MSG 0000769 => Hit => Line [0024] - Col [0128] +MSG 0000770 => Hit => Line [0032] - Col [0000] +MSG 0000771 => Hit => Line [0032] - Col [0032] +MSG 0000772 => Hit => Line [0032] - Col [0064] +MSG 0000773 => Hit => Line [0032] - Col [0096] +MSG 0000774 => Hit => Line [0032] - Col [0128] +MSG 0000775 => Hit => Line [0040] - Col [0000] +MSG 0000776 => Hit => Line [0040] - Col [0032] +MSG 0000777 => Hit => Line [0040] - Col [0064] +MSG 0000778 => Hit => Line [0040] - Col [0096] +MSG 0000779 => Hit => Line [0040] - Col [0128] +MSG 0000780 => Hit => Line [0048] - Col [0000] +MSG 0000781 => Hit => Line [0048] - Col [0032] +MSG 0000782 => Hit => Line [0048] - Col [0064] +MSG 0000783 => Hit => Line [0048] - Col [0096] +MSG 0000784 => Hit => Line [0048] - Col [0128] +MSG 0000785 => Hit => Line [0056] - Col [0000] +MSG 0000786 => Hit => Line [0056] - Col [0032] +MSG 0000787 => Hit => Line [0056] - Col [0064] +MSG 0000788 => Hit => Line [0056] - Col [0096] +MSG 0000789 => Hit => Line [0056] - Col [0128] +MSG 0000790 => Hit => Line [0064] - Col [0000] +MSG 0000791 => Hit => Line [0064] - Col [0032] +MSG 0000792 => Hit => Line [0064] - Col [0064] +MSG 0000793 => Hit => Line [0064] - Col [0096] +MSG 0000794 => Hit => Line [0064] - Col [0128] +MSG 0000795 => Hit => Line [0072] - Col [0000] +MSG 0000796 => Hit => Line [0072] - Col [0032] +MSG 0000797 => Hit => Line [0072] - Col [0064] +MSG 0000798 => Hit => Line [0072] - Col [0096] +MSG 0000799 => Hit => Line [0072] - Col [0128] +MSG 0000800 => Hit => Line [0080] - Col [0000] +MSG 0000801 => Hit => Line [0080] - Col [0032] +MSG 0000802 => Hit => Line [0080] - Col [0064] +MSG 0000803 => Hit => Line [0080] - Col [0096] +MSG 0000804 => Hit => Line [0080] - Col [0128] +MSG 0000805 => Hit => Line [0088] - Col [0000] +MSG 0000806 => Hit => Line [0088] - Col [0032] +MSG 0000807 => Hit => Line [0088] - Col [0064] +MSG 0000808 => Hit => Line [0088] - Col [0096] +MSG 0000809 => Hit => Line [0088] - Col [0128] +MSG 0000810 => Hit => Line [0096] - Col [0000] +MSG 0000811 => Hit => Line [0096] - Col [0032] +MSG 0000812 => Hit => Line [0096] - Col [0064] +MSG 0000813 => Hit => Line [0096] - Col [0096] +MSG 0000814 => Hit => Line [0096] - Col [0128] +MSG 0000815 => Hit => Line [0104] - Col [0000] +MSG 0000816 => Hit => Line [0104] - Col [0032] +MSG 0000817 => Hit => Line [0104] - Col [0064] +MSG 0000818 => Hit => Line [0104] - Col [0096] +MSG 0000819 => Hit => Line [0104] - Col [0128] +MSG 0000820 => Hit => Line [0112] - Col [0000] +MSG 0000821 => Hit => Line [0112] - Col [0032] +MSG 0000822 => Hit => Line [0112] - Col [0064] +MSG 0000823 => Hit => Line [0112] - Col [0096] +MSG 0000824 => Hit => Line [0112] - Col [0128] +MSG 0000825 => Hit => Line [0120] - Col [0000] +MSG 0000826 => Hit => Line [0120] - Col [0032] +MSG 0000827 => Hit => Line [0120] - Col [0064] +MSG 0000828 => Hit => Line [0120] - Col [0096] +MSG 0000829 => Hit => Line [0120] - Col [0128] +MSG 0000830 => Hit => Line [0128] - Col [0000] +MSG 0000831 => Hit => Line [0128] - Col [0032] +MSG 0000832 => Hit => Line [0128] - Col [0064] +MSG 0000833 => Hit => Line [0128] - Col [0096] +MSG 0000834 => Hit => Line [0128] - Col [0128] +MSG 0000835 => Hit => Line [0136] - Col [0000] +MSG 0000836 => Hit => Line [0136] - Col [0032] +MSG 0000837 => Hit => Line [0136] - Col [0064] +MSG 0000838 => Hit => Line [0136] - Col [0096] +MSG 0000839 => Hit => Line [0136] - Col [0128] +MSG 0000840 => Hit => Line [0144] - Col [0000] +MSG 0000841 => Hit => Line [0144] - Col [0032] +MSG 0000842 => Hit => Line [0144] - Col [0064] +MSG 0000843 => Hit => Line [0144] - Col [0096] +MSG 0000844 => Hit => Line [0144] - Col [0128] +MSG 0000845 => Hit => Line [0152] - Col [0000] +MSG 0000846 => Hit => Line [0152] - Col [0032] +MSG 0000847 => Hit => Line [0152] - Col [0064] +MSG 0000848 => Hit => Line [0152] - Col [0096] +MSG 0000849 => Hit => Line [0152] - Col [0128] +MSG 0000850 => Hit => Line [0160] - Col [0000] +MSG 0000851 => Hit => Line [0160] - Col [0032] +MSG 0000852 => Hit => Line [0160] - Col [0064] +MSG 0000853 => Hit => Line [0160] - Col [0096] +MSG 0000854 => Hit => Line [0160] - Col [0128] +MSG 0000855 => Hit => Line [0168] - Col [0000] +MSG 0000856 => Hit => Line [0168] - Col [0032] +MSG 0000857 => Hit => Line [0168] - Col [0064] +MSG 0000858 => Hit => Line [0168] - Col [0096] +MSG 0000859 => Hit => Line [0168] - Col [0128] +MSG 0000860 => Hit => Line [0176] - Col [0000] +MSG 0000861 => Hit => Line [0176] - Col [0032] +MSG 0000862 => Hit => Line [0176] - Col [0064] +MSG 0000863 => Hit => Line [0176] - Col [0096] +MSG 0000864 => Hit => Line [0176] - Col [0128] +MSG 0000865 => Hit => Line [0184] - Col [0000] +MSG 0000866 => Hit => Line [0184] - Col [0032] +MSG 0000867 => Hit => Line [0184] - Col [0064] +MSG 0000868 => Hit => Line [0184] - Col [0096] +MSG 0000869 => Hit => Line [0184] - Col [0128] +MSG 0000870 => Hit => Line [0192] - Col [0000] +MSG 0000871 => Hit => Line [0192] - Col [0032] +MSG 0000872 => Hit => Line [0192] - Col [0064] +MSG 0000873 => Hit => Line [0192] - Col [0096] +MSG 0000874 => Hit => Line [0192] - Col [0128] +MSG 0000875 => Hit => Line [0200] - Col [0000] +MSG 0000876 => Hit => Line [0200] - Col [0032] +MSG 0000877 => Hit => Line [0200] - Col [0064] +MSG 0000878 => Hit => Line [0200] - Col [0096] +MSG 0000879 => Hit => Line [0200] - Col [0128] +MSG 0000880 => Hit => Line [0208] - Col [0000] +MSG 0000881 => Hit => Line [0208] - Col [0032] +MSG 0000882 => Hit => Line [0208] - Col [0064] +MSG 0000883 => Hit => Line [0208] - Col [0096] +MSG 0000884 => Hit => Line [0208] - Col [0128] +MSG 0000885 => Hit => Line [0216] - Col [0000] +MSG 0000886 => Hit => Line [0216] - Col [0032] +MSG 0000887 => Hit => Line [0216] - Col [0064] +MSG 0000888 => Hit => Line [0216] - Col [0096] +MSG 0000889 => Hit => Line [0216] - Col [0128] +MSG 0000890 => Hit => Line [0224] - Col [0000] +MSG 0000891 => Hit => Line [0224] - Col [0032] +MSG 0000892 => Hit => Line [0224] - Col [0064] +MSG 0000893 => Hit => Line [0224] - Col [0096] +MSG 0000894 => Hit => Line [0224] - Col [0128] +MSG 0000895 => Hit => Line [0232] - Col [0000] +MSG 0000896 => Hit => Line [0232] - Col [0032] +MSG 0000897 => Hit => Line [0232] - Col [0064] +MSG 0000898 => Hit => Line [0232] - Col [0096] +MSG 0000899 => Hit => Line [0232] - Col [0128] +MSG 0000900 => Hit => Line [0240] - Col [0000] +MSG 0000901 => Hit => Line [0240] - Col [0032] +MSG 0000902 => Hit => Line [0240] - Col [0064] +MSG 0000903 => Hit => Line [0240] - Col [0096] +MSG 0000904 => Hit => Line [0240] - Col [0128] +MSG 0000905 => Hit => Line [0248] - Col [0000] +MSG 0000906 => Hit => Line [0248] - Col [0032] +MSG 0000907 => Hit => Line [0248] - Col [0064] +MSG 0000908 => Hit => Line [0248] - Col [0096] +MSG 0000909 => Hit => Line [0248] - Col [0128] +MSG 0000910 => Hit => Line [0256] - Col [0000] +MSG 0000911 => Hit => Line [0256] - Col [0032] +MSG 0000912 => Hit => Line [0256] - Col [0064] +MSG 0000913 => Hit => Line [0256] - Col [0096] +MSG 0000914 => Hit => Line [0256] - Col [0128] +MSG 0000915 => Hit => Line [0264] - Col [0000] +MSG 0000916 => Hit => Line [0264] - Col [0032] +MSG 0000917 => Hit => Line [0264] - Col [0064] +MSG 0000918 => Hit => Line [0264] - Col [0096] +MSG 0000919 => Hit => Line [0264] - Col [0128] +MSG 0000920 => Hit => Line [0272] - Col [0000] +MSG 0000921 => Hit => Line [0272] - Col [0032] +MSG 0000922 => Hit => Line [0272] - Col [0064] +MSG 0000923 => Hit => Line [0272] - Col [0096] +MSG 0000924 => Hit => Line [0272] - Col [0128] +MSG 0000925 => Hit => Line [0280] - Col [0000] +MSG 0000926 => Hit => Line [0280] - Col [0032] +MSG 0000927 => Hit => Line [0280] - Col [0064] +MSG 0000928 => Hit => Line [0280] - Col [0096] +MSG 0000929 => Hit => Line [0280] - Col [0128] +MSG 0000930 => Hit => Line [0288] - Col [0000] +MSG 0000931 => Hit => Line [0288] - Col [0032] +MSG 0000932 => Hit => Line [0288] - Col [0064] +MSG 0000933 => Hit => Line [0288] - Col [0096] +MSG 0000934 => Hit => Line [0288] - Col [0128] +MSG 0000935 => Hit => Line [0296] - Col [0000] +MSG 0000936 => Hit => Line [0296] - Col [0032] +MSG 0000937 => Hit => Line [0296] - Col [0064] +MSG 0000938 => Hit => Line [0296] - Col [0096] +MSG 0000939 => Hit => Line [0296] - Col [0128] +MSG 0000940 => Hit => Line [0304] - Col [0000] +MSG 0000941 => Hit => Line [0304] - Col [0032] +MSG 0000942 => Hit => Line [0304] - Col [0064] +MSG 0000943 => Hit => Line [0304] - Col [0096] +MSG 0000944 => Hit => Line [0304] - Col [0128] +MSG 0000945 => Hit => Line [0312] - Col [0000] +MSG 0000946 => Hit => Line [0312] - Col [0032] +MSG 0000947 => Hit => Line [0312] - Col [0064] +MSG 0000948 => Hit => Line [0312] - Col [0096] +MSG 0000949 => Hit => Line [0312] - Col [0128] +MSG 0000950 => Hit => Line [0320] - Col [0000] +MSG 0000951 => Hit => Line [0320] - Col [0032] +MSG 0000952 => Hit => Line [0320] - Col [0064] +MSG 0000953 => Hit => Line [0320] - Col [0096] +MSG 0000954 => Hit => Line [0320] - Col [0128] +MSG 0000955 => Hit => Line [0328] - Col [0000] +MSG 0000956 => Hit => Line [0328] - Col [0032] +MSG 0000957 => Hit => Line [0328] - Col [0064] +MSG 0000958 => Hit => Line [0328] - Col [0096] +MSG 0000959 => Hit => Line [0328] - Col [0128] +MSG 0000960 => Hit => Line [0336] - Col [0000] +MSG 0000961 => Hit => Line [0336] - Col [0032] +MSG 0000962 => Hit => Line [0336] - Col [0064] +MSG 0000963 => Hit => Line [0336] - Col [0096] +MSG 0000964 => Hit => Line [0336] - Col [0128] +MSG 0000965 => Hit => Line [0344] - Col [0000] +MSG 0000966 => Hit => Line [0344] - Col [0032] +MSG 0000967 => Hit => Line [0344] - Col [0064] +MSG 0000968 => Hit => Line [0344] - Col [0096] +MSG 0000969 => Hit => Line [0344] - Col [0128] +MSG 0000970 => Hit => Line [0352] - Col [0000] +MSG 0000971 => Hit => Line [0352] - Col [0032] +MSG 0000972 => Hit => Line [0352] - Col [0064] +MSG 0000973 => Hit => Line [0352] - Col [0096] +MSG 0000974 => Hit => Line [0352] - Col [0128] +MSG 0000975 => Hit => Line [0360] - Col [0000] +MSG 0000976 => Hit => Line [0360] - Col [0032] +MSG 0000977 => Hit => Line [0360] - Col [0064] +MSG 0000978 => Hit => Line [0360] - Col [0096] +MSG 0000979 => Hit => Line [0360] - Col [0128] +MSG 0000980 => Hit => Line [0368] - Col [0000] +MSG 0000981 => Hit => Line [0368] - Col [0032] +MSG 0000982 => Hit => Line [0368] - Col [0064] +MSG 0000983 => Hit => Line [0368] - Col [0096] +MSG 0000984 => Hit => Line [0368] - Col [0128] +MSG 0000985 => Hit => Line [0376] - Col [0000] +MSG 0000986 => Hit => Line [0376] - Col [0032] +MSG 0000987 => Hit => Line [0376] - Col [0064] +MSG 0000988 => Hit => Line [0376] - Col [0096] +MSG 0000989 => Hit => Line [0376] - Col [0128] +MSG 0000990 => Hit => Line [0384] - Col [0000] +MSG 0000991 => Hit => Line [0384] - Col [0032] +MSG 0000992 => Hit => Line [0384] - Col [0064] +MSG 0000993 => Hit => Line [0384] - Col [0096] +MSG 0000994 => Hit => Line [0384] - Col [0128] +MSG 0000995 => Hit => Line [0392] - Col [0000] +MSG 0000996 => Hit => Line [0392] - Col [0032] +MSG 0000997 => Hit => Line [0392] - Col [0064] +MSG 0000998 => Hit => Line [0392] - Col [0096] +MSG 0000999 => Hit => Line [0392] - Col [0128] +MSG 0001000 => Hit => Line [0400] - Col [0000] +MSG 0001001 => Hit => Line [0400] - Col [0032] +MSG 0001002 => Hit => Line [0400] - Col [0064] +MSG 0001003 => Hit => Line [0400] - Col [0096] +MSG 0001004 => Hit => Line [0400] - Col [0128] +MSG 0001005 => Hit => Line [0408] - Col [0000] +MSG 0001006 => Hit => Line [0408] - Col [0032] +MSG 0001007 => Hit => Line [0408] - Col [0064] +MSG 0001008 => Hit => Line [0408] - Col [0096] +MSG 0001009 => Hit => Line [0408] - Col [0128] +MSG 0001010 => +MSG 0001011 => =================================================================================== +MSG 0001012 => ============================================== +MSG 0001013 => Tag = 55550000 [H] +MSG 0001014 => DaqVersion = 0000 [D] +MSG 0001015 => TotSz = 7780 [D] +MSG 0001016 => TrigRecOffset = 7768 [D] +MSG 0001017 => ---------------------------------------------- +MSG 0001018 => H.Tag = 00000001 [H] +MSG 0001019 => H.AcqStatus = 0000 [D] +MSG 0001020 => H.TrigStatus = 0000 [D] +MSG 0001021 => H.AcqId = 0000 [D] +MSG 0001022 => H.FrameIdInAcq = 0002 [D] +MSG 0001023 => H.MapsName = 0004 [D] +MSG 0001024 => H.MapsNb = 0006 [D] +MSG 0001025 => ---------------------------------------------- +MSG 0001026 => H.Header [0]=50004000 [1]=50014001 [2]=50024002 [3]=50034003 [4]=50044004 [5]=50054005 [6]=00000000 [7]=00000000 +MSG 0001027 => H.FrCnt [0]= 871589 [1]= 871589 [2]= 871589 [3]= 871589 [4]= 871589 [5]= 871589 [6]= 0 [7]= 0 +MSG 0001028 => H.DataSz [0]= 0 [1]= 104 [2]= 156 [3]= 208 [4]= 260 [5]= 312 [6]= 0 [7]= 0 +MSG 0001029 => H.Trailer [0]=70006000 [1]=70016001 [2]=70026002 [3]=70036003 [4]=70046004 [5]=70056005 [6]=00000000 [7]=00000000 +MSG 0001030 => ---------------------------------------------- +MSG 0001031 => H.TriggerNb = 0001 [D] +MSG 0001032 => H.TrigInfo line [0]=0370 [1]=0000 [2]=0000 +MSG 0001033 => H.TrigInfo TS [0]=0004 [1]=0000 [2]=0000 +MSG 0001034 => ---------------------------------------------- +MSG 0001035 => D.Tag = 00000002 [H] +MSG 0001036 => D.TotSz = 7488 [D] +MSG 0001037 => D.OneMapsSz = 1248 [D] +MSG 0001038 => =================================================================================== +MSG 0001039 => Fsbb0 No 0 +MSG 0001040 => =================================================================================== +MSG 0001041 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001042 => Conv : VDataW30Length=0 +MSG 0001043 => *************************************************************************** +MSG 0001044 => * FSBB M [0] : Coordinates pixels with hit * +MSG 0001045 => *************************************************************************** +MSG 0001046 => +MSG 0001047 => =================================================================================== +MSG 0001048 => Fsbb0 No 1 +MSG 0001049 => =================================================================================== +MSG 0001050 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001051 => Conv : VDataW30Length=104 +MSG 0001052 => *************************************************************************** +MSG 0001053 => * FSBB M [1] : Coordinates pixels with hit * +MSG 0001054 => *************************************************************************** +MSG 0001055 => Hit => Line [0000] - Col [0000] +MSG 0001056 => Hit => Line [0008] - Col [0000] +MSG 0001057 => Hit => Line [0016] - Col [0000] +MSG 0001058 => Hit => Line [0024] - Col [0000] +MSG 0001059 => Hit => Line [0032] - Col [0000] +MSG 0001060 => Hit => Line [0040] - Col [0000] +MSG 0001061 => Hit => Line [0048] - Col [0000] +MSG 0001062 => Hit => Line [0056] - Col [0000] +MSG 0001063 => Hit => Line [0064] - Col [0000] +MSG 0001064 => Hit => Line [0072] - Col [0000] +MSG 0001065 => Hit => Line [0080] - Col [0000] +MSG 0001066 => Hit => Line [0088] - Col [0000] +MSG 0001067 => Hit => Line [0096] - Col [0000] +MSG 0001068 => Hit => Line [0104] - Col [0000] +MSG 0001069 => Hit => Line [0112] - Col [0000] +MSG 0001070 => Hit => Line [0120] - Col [0000] +MSG 0001071 => Hit => Line [0128] - Col [0000] +MSG 0001072 => Hit => Line [0136] - Col [0000] +MSG 0001073 => Hit => Line [0144] - Col [0000] +MSG 0001074 => Hit => Line [0152] - Col [0000] +MSG 0001075 => Hit => Line [0160] - Col [0000] +MSG 0001076 => Hit => Line [0168] - Col [0000] +MSG 0001077 => Hit => Line [0176] - Col [0000] +MSG 0001078 => Hit => Line [0184] - Col [0000] +MSG 0001079 => Hit => Line [0192] - Col [0000] +MSG 0001080 => Hit => Line [0200] - Col [0000] +MSG 0001081 => Hit => Line [0208] - Col [0000] +MSG 0001082 => Hit => Line [0216] - Col [0000] +MSG 0001083 => Hit => Line [0224] - Col [0000] +MSG 0001084 => Hit => Line [0232] - Col [0000] +MSG 0001085 => Hit => Line [0240] - Col [0000] +MSG 0001086 => Hit => Line [0248] - Col [0000] +MSG 0001087 => Hit => Line [0256] - Col [0000] +MSG 0001088 => Hit => Line [0264] - Col [0000] +MSG 0001089 => Hit => Line [0272] - Col [0000] +MSG 0001090 => Hit => Line [0280] - Col [0000] +MSG 0001091 => Hit => Line [0288] - Col [0000] +MSG 0001092 => Hit => Line [0296] - Col [0000] +MSG 0001093 => Hit => Line [0304] - Col [0000] +MSG 0001094 => Hit => Line [0312] - Col [0000] +MSG 0001095 => Hit => Line [0320] - Col [0000] +MSG 0001096 => Hit => Line [0328] - Col [0000] +MSG 0001097 => Hit => Line [0336] - Col [0000] +MSG 0001098 => Hit => Line [0344] - Col [0000] +MSG 0001099 => Hit => Line [0352] - Col [0000] +MSG 0001100 => Hit => Line [0360] - Col [0000] +MSG 0001101 => Hit => Line [0368] - Col [0000] +MSG 0001102 => Hit => Line [0376] - Col [0000] +MSG 0001103 => Hit => Line [0384] - Col [0000] +MSG 0001104 => Hit => Line [0392] - Col [0000] +MSG 0001105 => Hit => Line [0400] - Col [0000] +MSG 0001106 => Hit => Line [0408] - Col [0000] +MSG 0001107 => +MSG 0001108 => =================================================================================== +MSG 0001109 => Fsbb0 No 2 +MSG 0001110 => =================================================================================== +MSG 0001111 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001112 => Conv : VDataW30Length=156 +MSG 0001113 => *************************************************************************** +MSG 0001114 => * FSBB M [2] : Coordinates pixels with hit * +MSG 0001115 => *************************************************************************** +MSG 0001116 => Hit => Line [0000] - Col [0000] +MSG 0001117 => Hit => Line [0000] - Col [0008] +MSG 0001118 => Hit => Line [0008] - Col [0000] +MSG 0001119 => Hit => Line [0008] - Col [0008] +MSG 0001120 => Hit => Line [0016] - Col [0000] +MSG 0001121 => Hit => Line [0016] - Col [0008] +MSG 0001122 => Hit => Line [0024] - Col [0000] +MSG 0001123 => Hit => Line [0024] - Col [0008] +MSG 0001124 => Hit => Line [0032] - Col [0000] +MSG 0001125 => Hit => Line [0032] - Col [0008] +MSG 0001126 => Hit => Line [0040] - Col [0000] +MSG 0001127 => Hit => Line [0040] - Col [0008] +MSG 0001128 => Hit => Line [0048] - Col [0000] +MSG 0001129 => Hit => Line [0048] - Col [0008] +MSG 0001130 => Hit => Line [0056] - Col [0000] +MSG 0001131 => Hit => Line [0056] - Col [0008] +MSG 0001132 => Hit => Line [0064] - Col [0000] +MSG 0001133 => Hit => Line [0064] - Col [0008] +MSG 0001134 => Hit => Line [0072] - Col [0000] +MSG 0001135 => Hit => Line [0072] - Col [0008] +MSG 0001136 => Hit => Line [0080] - Col [0000] +MSG 0001137 => Hit => Line [0080] - Col [0008] +MSG 0001138 => Hit => Line [0088] - Col [0000] +MSG 0001139 => Hit => Line [0088] - Col [0008] +MSG 0001140 => Hit => Line [0096] - Col [0000] +MSG 0001141 => Hit => Line [0096] - Col [0008] +MSG 0001142 => Hit => Line [0104] - Col [0000] +MSG 0001143 => Hit => Line [0104] - Col [0008] +MSG 0001144 => Hit => Line [0112] - Col [0000] +MSG 0001145 => Hit => Line [0112] - Col [0008] +MSG 0001146 => Hit => Line [0120] - Col [0000] +MSG 0001147 => Hit => Line [0120] - Col [0008] +MSG 0001148 => Hit => Line [0128] - Col [0000] +MSG 0001149 => Hit => Line [0128] - Col [0008] +MSG 0001150 => Hit => Line [0136] - Col [0000] +MSG 0001151 => Hit => Line [0136] - Col [0008] +MSG 0001152 => Hit => Line [0144] - Col [0000] +MSG 0001153 => Hit => Line [0144] - Col [0008] +MSG 0001154 => Hit => Line [0152] - Col [0000] +MSG 0001155 => Hit => Line [0152] - Col [0008] +MSG 0001156 => Hit => Line [0160] - Col [0000] +MSG 0001157 => Hit => Line [0160] - Col [0008] +MSG 0001158 => Hit => Line [0168] - Col [0000] +MSG 0001159 => Hit => Line [0168] - Col [0008] +MSG 0001160 => Hit => Line [0176] - Col [0000] +MSG 0001161 => Hit => Line [0176] - Col [0008] +MSG 0001162 => Hit => Line [0184] - Col [0000] +MSG 0001163 => Hit => Line [0184] - Col [0008] +MSG 0001164 => Hit => Line [0192] - Col [0000] +MSG 0001165 => Hit => Line [0192] - Col [0008] +MSG 0001166 => Hit => Line [0200] - Col [0000] +MSG 0001167 => Hit => Line [0200] - Col [0008] +MSG 0001168 => Hit => Line [0208] - Col [0000] +MSG 0001169 => Hit => Line [0208] - Col [0008] +MSG 0001170 => Hit => Line [0216] - Col [0000] +MSG 0001171 => Hit => Line [0216] - Col [0008] +MSG 0001172 => Hit => Line [0224] - Col [0000] +MSG 0001173 => Hit => Line [0224] - Col [0008] +MSG 0001174 => Hit => Line [0232] - Col [0000] +MSG 0001175 => Hit => Line [0232] - Col [0008] +MSG 0001176 => Hit => Line [0240] - Col [0000] +MSG 0001177 => Hit => Line [0240] - Col [0008] +MSG 0001178 => Hit => Line [0248] - Col [0000] +MSG 0001179 => Hit => Line [0248] - Col [0008] +MSG 0001180 => Hit => Line [0256] - Col [0000] +MSG 0001181 => Hit => Line [0256] - Col [0008] +MSG 0001182 => Hit => Line [0264] - Col [0000] +MSG 0001183 => Hit => Line [0264] - Col [0008] +MSG 0001184 => Hit => Line [0272] - Col [0000] +MSG 0001185 => Hit => Line [0272] - Col [0008] +MSG 0001186 => Hit => Line [0280] - Col [0000] +MSG 0001187 => Hit => Line [0280] - Col [0008] +MSG 0001188 => Hit => Line [0288] - Col [0000] +MSG 0001189 => Hit => Line [0288] - Col [0008] +MSG 0001190 => Hit => Line [0296] - Col [0000] +MSG 0001191 => Hit => Line [0296] - Col [0008] +MSG 0001192 => Hit => Line [0304] - Col [0000] +MSG 0001193 => Hit => Line [0304] - Col [0008] +MSG 0001194 => Hit => Line [0312] - Col [0000] +MSG 0001195 => Hit => Line [0312] - Col [0008] +MSG 0001196 => Hit => Line [0320] - Col [0000] +MSG 0001197 => Hit => Line [0320] - Col [0008] +MSG 0001198 => Hit => Line [0328] - Col [0000] +MSG 0001199 => Hit => Line [0328] - Col [0008] +MSG 0001200 => Hit => Line [0336] - Col [0000] +MSG 0001201 => Hit => Line [0336] - Col [0008] +MSG 0001202 => Hit => Line [0344] - Col [0000] +MSG 0001203 => Hit => Line [0344] - Col [0008] +MSG 0001204 => Hit => Line [0352] - Col [0000] +MSG 0001205 => Hit => Line [0352] - Col [0008] +MSG 0001206 => Hit => Line [0360] - Col [0000] +MSG 0001207 => Hit => Line [0360] - Col [0008] +MSG 0001208 => Hit => Line [0368] - Col [0000] +MSG 0001209 => Hit => Line [0368] - Col [0008] +MSG 0001210 => Hit => Line [0376] - Col [0000] +MSG 0001211 => Hit => Line [0376] - Col [0008] +MSG 0001212 => Hit => Line [0384] - Col [0000] +MSG 0001213 => Hit => Line [0384] - Col [0008] +MSG 0001214 => Hit => Line [0392] - Col [0000] +MSG 0001215 => Hit => Line [0392] - Col [0008] +MSG 0001216 => Hit => Line [0400] - Col [0000] +MSG 0001217 => Hit => Line [0400] - Col [0008] +MSG 0001218 => Hit => Line [0408] - Col [0000] +MSG 0001219 => Hit => Line [0408] - Col [0008] +MSG 0001220 => +MSG 0001221 => =================================================================================== +MSG 0001222 => Fsbb0 No 3 +MSG 0001223 => =================================================================================== +MSG 0001224 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001225 => Conv : VDataW30Length=208 +MSG 0001226 => *************************************************************************** +MSG 0001227 => * FSBB M [3] : Coordinates pixels with hit * +MSG 0001228 => *************************************************************************** +MSG 0001229 => Hit => Line [0000] - Col [0000] +MSG 0001230 => Hit => Line [0000] - Col [0008] +MSG 0001231 => Hit => Line [0000] - Col [0016] +MSG 0001232 => Hit => Line [0008] - Col [0000] +MSG 0001233 => Hit => Line [0008] - Col [0008] +MSG 0001234 => Hit => Line [0008] - Col [0016] +MSG 0001235 => Hit => Line [0016] - Col [0000] +MSG 0001236 => Hit => Line [0016] - Col [0008] +MSG 0001237 => Hit => Line [0016] - Col [0016] +MSG 0001238 => Hit => Line [0024] - Col [0000] +MSG 0001239 => Hit => Line [0024] - Col [0008] +MSG 0001240 => Hit => Line [0024] - Col [0016] +MSG 0001241 => Hit => Line [0032] - Col [0000] +MSG 0001242 => Hit => Line [0032] - Col [0008] +MSG 0001243 => Hit => Line [0032] - Col [0016] +MSG 0001244 => Hit => Line [0040] - Col [0000] +MSG 0001245 => Hit => Line [0040] - Col [0008] +MSG 0001246 => Hit => Line [0040] - Col [0016] +MSG 0001247 => Hit => Line [0048] - Col [0000] +MSG 0001248 => Hit => Line [0048] - Col [0008] +MSG 0001249 => Hit => Line [0048] - Col [0016] +MSG 0001250 => Hit => Line [0056] - Col [0000] +MSG 0001251 => Hit => Line [0056] - Col [0008] +MSG 0001252 => Hit => Line [0056] - Col [0016] +MSG 0001253 => Hit => Line [0064] - Col [0000] +MSG 0001254 => Hit => Line [0064] - Col [0008] +MSG 0001255 => Hit => Line [0064] - Col [0016] +MSG 0001256 => Hit => Line [0072] - Col [0000] +MSG 0001257 => Hit => Line [0072] - Col [0008] +MSG 0001258 => Hit => Line [0072] - Col [0016] +MSG 0001259 => Hit => Line [0080] - Col [0000] +MSG 0001260 => Hit => Line [0080] - Col [0008] +MSG 0001261 => Hit => Line [0080] - Col [0016] +MSG 0001262 => Hit => Line [0088] - Col [0000] +MSG 0001263 => Hit => Line [0088] - Col [0008] +MSG 0001264 => Hit => Line [0088] - Col [0016] +MSG 0001265 => Hit => Line [0096] - Col [0000] +MSG 0001266 => Hit => Line [0096] - Col [0008] +MSG 0001267 => Hit => Line [0096] - Col [0016] +MSG 0001268 => Hit => Line [0104] - Col [0000] +MSG 0001269 => Hit => Line [0104] - Col [0008] +MSG 0001270 => Hit => Line [0104] - Col [0016] +MSG 0001271 => Hit => Line [0112] - Col [0000] +MSG 0001272 => Hit => Line [0112] - Col [0008] +MSG 0001273 => Hit => Line [0112] - Col [0016] +MSG 0001274 => Hit => Line [0120] - Col [0000] +MSG 0001275 => Hit => Line [0120] - Col [0008] +MSG 0001276 => Hit => Line [0120] - Col [0016] +MSG 0001277 => Hit => Line [0128] - Col [0000] +MSG 0001278 => Hit => Line [0128] - Col [0008] +MSG 0001279 => Hit => Line [0128] - Col [0016] +MSG 0001280 => Hit => Line [0136] - Col [0000] +MSG 0001281 => Hit => Line [0136] - Col [0008] +MSG 0001282 => Hit => Line [0136] - Col [0016] +MSG 0001283 => Hit => Line [0144] - Col [0000] +MSG 0001284 => Hit => Line [0144] - Col [0008] +MSG 0001285 => Hit => Line [0144] - Col [0016] +MSG 0001286 => Hit => Line [0152] - Col [0000] +MSG 0001287 => Hit => Line [0152] - Col [0008] +MSG 0001288 => Hit => Line [0152] - Col [0016] +MSG 0001289 => Hit => Line [0160] - Col [0000] +MSG 0001290 => Hit => Line [0160] - Col [0008] +MSG 0001291 => Hit => Line [0160] - Col [0016] +MSG 0001292 => Hit => Line [0168] - Col [0000] +MSG 0001293 => Hit => Line [0168] - Col [0008] +MSG 0001294 => Hit => Line [0168] - Col [0016] +MSG 0001295 => Hit => Line [0176] - Col [0000] +MSG 0001296 => Hit => Line [0176] - Col [0008] +MSG 0001297 => Hit => Line [0176] - Col [0016] +MSG 0001298 => Hit => Line [0184] - Col [0000] +MSG 0001299 => Hit => Line [0184] - Col [0008] +MSG 0001300 => Hit => Line [0184] - Col [0016] +MSG 0001301 => Hit => Line [0192] - Col [0000] +MSG 0001302 => Hit => Line [0192] - Col [0008] +MSG 0001303 => Hit => Line [0192] - Col [0016] +MSG 0001304 => Hit => Line [0200] - Col [0000] +MSG 0001305 => Hit => Line [0200] - Col [0008] +MSG 0001306 => Hit => Line [0200] - Col [0016] +MSG 0001307 => Hit => Line [0208] - Col [0000] +MSG 0001308 => Hit => Line [0208] - Col [0008] +MSG 0001309 => Hit => Line [0208] - Col [0016] +MSG 0001310 => Hit => Line [0216] - Col [0000] +MSG 0001311 => Hit => Line [0216] - Col [0008] +MSG 0001312 => Hit => Line [0216] - Col [0016] +MSG 0001313 => Hit => Line [0224] - Col [0000] +MSG 0001314 => Hit => Line [0224] - Col [0008] +MSG 0001315 => Hit => Line [0224] - Col [0016] +MSG 0001316 => Hit => Line [0232] - Col [0000] +MSG 0001317 => Hit => Line [0232] - Col [0008] +MSG 0001318 => Hit => Line [0232] - Col [0016] +MSG 0001319 => Hit => Line [0240] - Col [0000] +MSG 0001320 => Hit => Line [0240] - Col [0008] +MSG 0001321 => Hit => Line [0240] - Col [0016] +MSG 0001322 => Hit => Line [0248] - Col [0000] +MSG 0001323 => Hit => Line [0248] - Col [0008] +MSG 0001324 => Hit => Line [0248] - Col [0016] +MSG 0001325 => Hit => Line [0256] - Col [0000] +MSG 0001326 => Hit => Line [0256] - Col [0008] +MSG 0001327 => Hit => Line [0256] - Col [0016] +MSG 0001328 => Hit => Line [0264] - Col [0000] +MSG 0001329 => Hit => Line [0264] - Col [0008] +MSG 0001330 => Hit => Line [0264] - Col [0016] +MSG 0001331 => Hit => Line [0272] - Col [0000] +MSG 0001332 => Hit => Line [0272] - Col [0008] +MSG 0001333 => Hit => Line [0272] - Col [0016] +MSG 0001334 => Hit => Line [0280] - Col [0000] +MSG 0001335 => Hit => Line [0280] - Col [0008] +MSG 0001336 => Hit => Line [0280] - Col [0016] +MSG 0001337 => Hit => Line [0288] - Col [0000] +MSG 0001338 => Hit => Line [0288] - Col [0008] +MSG 0001339 => Hit => Line [0288] - Col [0016] +MSG 0001340 => Hit => Line [0296] - Col [0000] +MSG 0001341 => Hit => Line [0296] - Col [0008] +MSG 0001342 => Hit => Line [0296] - Col [0016] +MSG 0001343 => Hit => Line [0304] - Col [0000] +MSG 0001344 => Hit => Line [0304] - Col [0008] +MSG 0001345 => Hit => Line [0304] - Col [0016] +MSG 0001346 => Hit => Line [0312] - Col [0000] +MSG 0001347 => Hit => Line [0312] - Col [0008] +MSG 0001348 => Hit => Line [0312] - Col [0016] +MSG 0001349 => Hit => Line [0320] - Col [0000] +MSG 0001350 => Hit => Line [0320] - Col [0008] +MSG 0001351 => Hit => Line [0320] - Col [0016] +MSG 0001352 => Hit => Line [0328] - Col [0000] +MSG 0001353 => Hit => Line [0328] - Col [0008] +MSG 0001354 => Hit => Line [0328] - Col [0016] +MSG 0001355 => Hit => Line [0336] - Col [0000] +MSG 0001356 => Hit => Line [0336] - Col [0008] +MSG 0001357 => Hit => Line [0336] - Col [0016] +MSG 0001358 => Hit => Line [0344] - Col [0000] +MSG 0001359 => Hit => Line [0344] - Col [0008] +MSG 0001360 => Hit => Line [0344] - Col [0016] +MSG 0001361 => Hit => Line [0352] - Col [0000] +MSG 0001362 => Hit => Line [0352] - Col [0008] +MSG 0001363 => Hit => Line [0352] - Col [0016] +MSG 0001364 => Hit => Line [0360] - Col [0000] +MSG 0001365 => Hit => Line [0360] - Col [0008] +MSG 0001366 => Hit => Line [0360] - Col [0016] +MSG 0001367 => Hit => Line [0368] - Col [0000] +MSG 0001368 => Hit => Line [0368] - Col [0008] +MSG 0001369 => Hit => Line [0368] - Col [0016] +MSG 0001370 => Hit => Line [0376] - Col [0000] +MSG 0001371 => Hit => Line [0376] - Col [0008] +MSG 0001372 => Hit => Line [0376] - Col [0016] +MSG 0001373 => Hit => Line [0384] - Col [0000] +MSG 0001374 => Hit => Line [0384] - Col [0008] +MSG 0001375 => Hit => Line [0384] - Col [0016] +MSG 0001376 => Hit => Line [0392] - Col [0000] +MSG 0001377 => Hit => Line [0392] - Col [0008] +MSG 0001378 => Hit => Line [0392] - Col [0016] +MSG 0001379 => Hit => Line [0400] - Col [0000] +MSG 0001380 => Hit => Line [0400] - Col [0008] +MSG 0001381 => Hit => Line [0400] - Col [0016] +MSG 0001382 => Hit => Line [0408] - Col [0000] +MSG 0001383 => Hit => Line [0408] - Col [0008] +MSG 0001384 => Hit => Line [0408] - Col [0016] +MSG 0001385 => +MSG 0001386 => =================================================================================== +MSG 0001387 => Fsbb0 No 4 +MSG 0001388 => =================================================================================== +MSG 0001389 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001390 => Conv : VDataW30Length=260 +MSG 0001391 => *************************************************************************** +MSG 0001392 => * FSBB M [4] : Coordinates pixels with hit * +MSG 0001393 => *************************************************************************** +MSG 0001394 => Hit => Line [0000] - Col [0000] +MSG 0001395 => Hit => Line [0000] - Col [0008] +MSG 0001396 => Hit => Line [0000] - Col [0016] +MSG 0001397 => Hit => Line [0000] - Col [0023] +MSG 0001398 => Hit => Line [0008] - Col [0000] +MSG 0001399 => Hit => Line [0008] - Col [0008] +MSG 0001400 => Hit => Line [0008] - Col [0016] +MSG 0001401 => Hit => Line [0008] - Col [0023] +MSG 0001402 => Hit => Line [0016] - Col [0000] +MSG 0001403 => Hit => Line [0016] - Col [0008] +MSG 0001404 => Hit => Line [0016] - Col [0016] +MSG 0001405 => Hit => Line [0016] - Col [0023] +MSG 0001406 => Hit => Line [0024] - Col [0000] +MSG 0001407 => Hit => Line [0024] - Col [0008] +MSG 0001408 => Hit => Line [0024] - Col [0016] +MSG 0001409 => Hit => Line [0024] - Col [0023] +MSG 0001410 => Hit => Line [0032] - Col [0000] +MSG 0001411 => Hit => Line [0032] - Col [0008] +MSG 0001412 => Hit => Line [0032] - Col [0016] +MSG 0001413 => Hit => Line [0032] - Col [0023] +MSG 0001414 => Hit => Line [0040] - Col [0000] +MSG 0001415 => Hit => Line [0040] - Col [0008] +MSG 0001416 => Hit => Line [0040] - Col [0016] +MSG 0001417 => Hit => Line [0040] - Col [0023] +MSG 0001418 => Hit => Line [0048] - Col [0000] +MSG 0001419 => Hit => Line [0048] - Col [0008] +MSG 0001420 => Hit => Line [0048] - Col [0016] +MSG 0001421 => Hit => Line [0048] - Col [0023] +MSG 0001422 => Hit => Line [0056] - Col [0000] +MSG 0001423 => Hit => Line [0056] - Col [0008] +MSG 0001424 => Hit => Line [0056] - Col [0016] +MSG 0001425 => Hit => Line [0056] - Col [0023] +MSG 0001426 => Hit => Line [0064] - Col [0000] +MSG 0001427 => Hit => Line [0064] - Col [0008] +MSG 0001428 => Hit => Line [0064] - Col [0016] +MSG 0001429 => Hit => Line [0064] - Col [0023] +MSG 0001430 => Hit => Line [0072] - Col [0000] +MSG 0001431 => Hit => Line [0072] - Col [0008] +MSG 0001432 => Hit => Line [0072] - Col [0016] +MSG 0001433 => Hit => Line [0072] - Col [0023] +MSG 0001434 => Hit => Line [0080] - Col [0000] +MSG 0001435 => Hit => Line [0080] - Col [0008] +MSG 0001436 => Hit => Line [0080] - Col [0016] +MSG 0001437 => Hit => Line [0080] - Col [0023] +MSG 0001438 => Hit => Line [0088] - Col [0000] +MSG 0001439 => Hit => Line [0088] - Col [0008] +MSG 0001440 => Hit => Line [0088] - Col [0016] +MSG 0001441 => Hit => Line [0088] - Col [0023] +MSG 0001442 => Hit => Line [0096] - Col [0000] +MSG 0001443 => Hit => Line [0096] - Col [0008] +MSG 0001444 => Hit => Line [0096] - Col [0016] +MSG 0001445 => Hit => Line [0096] - Col [0023] +MSG 0001446 => Hit => Line [0104] - Col [0000] +MSG 0001447 => Hit => Line [0104] - Col [0008] +MSG 0001448 => Hit => Line [0104] - Col [0016] +MSG 0001449 => Hit => Line [0104] - Col [0023] +MSG 0001450 => Hit => Line [0112] - Col [0000] +MSG 0001451 => Hit => Line [0112] - Col [0008] +MSG 0001452 => Hit => Line [0112] - Col [0016] +MSG 0001453 => Hit => Line [0112] - Col [0023] +MSG 0001454 => Hit => Line [0120] - Col [0000] +MSG 0001455 => Hit => Line [0120] - Col [0008] +MSG 0001456 => Hit => Line [0120] - Col [0016] +MSG 0001457 => Hit => Line [0120] - Col [0023] +MSG 0001458 => Hit => Line [0128] - Col [0000] +MSG 0001459 => Hit => Line [0128] - Col [0008] +MSG 0001460 => Hit => Line [0128] - Col [0016] +MSG 0001461 => Hit => Line [0128] - Col [0023] +MSG 0001462 => Hit => Line [0136] - Col [0000] +MSG 0001463 => Hit => Line [0136] - Col [0008] +MSG 0001464 => Hit => Line [0136] - Col [0016] +MSG 0001465 => Hit => Line [0136] - Col [0023] +MSG 0001466 => Hit => Line [0144] - Col [0000] +MSG 0001467 => Hit => Line [0144] - Col [0008] +MSG 0001468 => Hit => Line [0144] - Col [0016] +MSG 0001469 => Hit => Line [0144] - Col [0023] +MSG 0001470 => Hit => Line [0152] - Col [0000] +MSG 0001471 => Hit => Line [0152] - Col [0008] +MSG 0001472 => Hit => Line [0152] - Col [0016] +MSG 0001473 => Hit => Line [0152] - Col [0023] +MSG 0001474 => Hit => Line [0160] - Col [0000] +MSG 0001475 => Hit => Line [0160] - Col [0008] +MSG 0001476 => Hit => Line [0160] - Col [0016] +MSG 0001477 => Hit => Line [0160] - Col [0023] +MSG 0001478 => Hit => Line [0168] - Col [0000] +MSG 0001479 => Hit => Line [0168] - Col [0008] +MSG 0001480 => Hit => Line [0168] - Col [0016] +MSG 0001481 => Hit => Line [0168] - Col [0023] +MSG 0001482 => Hit => Line [0176] - Col [0000] +MSG 0001483 => Hit => Line [0176] - Col [0008] +MSG 0001484 => Hit => Line [0176] - Col [0016] +MSG 0001485 => Hit => Line [0176] - Col [0023] +MSG 0001486 => Hit => Line [0184] - Col [0000] +MSG 0001487 => Hit => Line [0184] - Col [0008] +MSG 0001488 => Hit => Line [0184] - Col [0016] +MSG 0001489 => Hit => Line [0184] - Col [0023] +MSG 0001490 => Hit => Line [0192] - Col [0000] +MSG 0001491 => Hit => Line [0192] - Col [0008] +MSG 0001492 => Hit => Line [0192] - Col [0016] +MSG 0001493 => Hit => Line [0192] - Col [0023] +MSG 0001494 => Hit => Line [0200] - Col [0000] +MSG 0001495 => Hit => Line [0200] - Col [0008] +MSG 0001496 => Hit => Line [0200] - Col [0016] +MSG 0001497 => Hit => Line [0200] - Col [0023] +MSG 0001498 => Hit => Line [0208] - Col [0000] +MSG 0001499 => Hit => Line [0208] - Col [0008] +MSG 0001500 => Hit => Line [0208] - Col [0016] +MSG 0001501 => Hit => Line [0208] - Col [0023] +MSG 0001502 => Hit => Line [0216] - Col [0000] +MSG 0001503 => Hit => Line [0216] - Col [0008] +MSG 0001504 => Hit => Line [0216] - Col [0016] +MSG 0001505 => Hit => Line [0216] - Col [0023] +MSG 0001506 => Hit => Line [0224] - Col [0000] +MSG 0001507 => Hit => Line [0224] - Col [0008] +MSG 0001508 => Hit => Line [0224] - Col [0016] +MSG 0001509 => Hit => Line [0224] - Col [0023] +MSG 0001510 => Hit => Line [0232] - Col [0000] +MSG 0001511 => Hit => Line [0232] - Col [0008] +MSG 0001512 => Hit => Line [0232] - Col [0016] +MSG 0001513 => Hit => Line [0232] - Col [0023] +MSG 0001514 => Hit => Line [0240] - Col [0000] +MSG 0001515 => Hit => Line [0240] - Col [0008] +MSG 0001516 => Hit => Line [0240] - Col [0016] +MSG 0001517 => Hit => Line [0240] - Col [0023] +MSG 0001518 => Hit => Line [0248] - Col [0000] +MSG 0001519 => Hit => Line [0248] - Col [0008] +MSG 0001520 => Hit => Line [0248] - Col [0016] +MSG 0001521 => Hit => Line [0248] - Col [0023] +MSG 0001522 => Hit => Line [0256] - Col [0000] +MSG 0001523 => Hit => Line [0256] - Col [0008] +MSG 0001524 => Hit => Line [0256] - Col [0016] +MSG 0001525 => Hit => Line [0256] - Col [0023] +MSG 0001526 => Hit => Line [0264] - Col [0000] +MSG 0001527 => Hit => Line [0264] - Col [0008] +MSG 0001528 => Hit => Line [0264] - Col [0016] +MSG 0001529 => Hit => Line [0264] - Col [0023] +MSG 0001530 => Hit => Line [0272] - Col [0000] +MSG 0001531 => Hit => Line [0272] - Col [0008] +MSG 0001532 => Hit => Line [0272] - Col [0016] +MSG 0001533 => Hit => Line [0272] - Col [0023] +MSG 0001534 => Hit => Line [0280] - Col [0000] +MSG 0001535 => Hit => Line [0280] - Col [0008] +MSG 0001536 => Hit => Line [0280] - Col [0016] +MSG 0001537 => Hit => Line [0280] - Col [0023] +MSG 0001538 => Hit => Line [0288] - Col [0000] +MSG 0001539 => Hit => Line [0288] - Col [0008] +MSG 0001540 => Hit => Line [0288] - Col [0016] +MSG 0001541 => Hit => Line [0288] - Col [0023] +MSG 0001542 => Hit => Line [0296] - Col [0000] +MSG 0001543 => Hit => Line [0296] - Col [0008] +MSG 0001544 => Hit => Line [0296] - Col [0016] +MSG 0001545 => Hit => Line [0296] - Col [0023] +MSG 0001546 => Hit => Line [0304] - Col [0000] +MSG 0001547 => Hit => Line [0304] - Col [0008] +MSG 0001548 => Hit => Line [0304] - Col [0016] +MSG 0001549 => Hit => Line [0304] - Col [0023] +MSG 0001550 => Hit => Line [0312] - Col [0000] +MSG 0001551 => Hit => Line [0312] - Col [0008] +MSG 0001552 => Hit => Line [0312] - Col [0016] +MSG 0001553 => Hit => Line [0312] - Col [0023] +MSG 0001554 => Hit => Line [0320] - Col [0000] +MSG 0001555 => Hit => Line [0320] - Col [0008] +MSG 0001556 => Hit => Line [0320] - Col [0016] +MSG 0001557 => Hit => Line [0320] - Col [0023] +MSG 0001558 => Hit => Line [0328] - Col [0000] +MSG 0001559 => Hit => Line [0328] - Col [0008] +MSG 0001560 => Hit => Line [0328] - Col [0016] +MSG 0001561 => Hit => Line [0328] - Col [0023] +MSG 0001562 => Hit => Line [0336] - Col [0000] +MSG 0001563 => Hit => Line [0336] - Col [0008] +MSG 0001564 => Hit => Line [0336] - Col [0016] +MSG 0001565 => Hit => Line [0336] - Col [0023] +MSG 0001566 => Hit => Line [0344] - Col [0000] +MSG 0001567 => Hit => Line [0344] - Col [0008] +MSG 0001568 => Hit => Line [0344] - Col [0016] +MSG 0001569 => Hit => Line [0344] - Col [0023] +MSG 0001570 => Hit => Line [0352] - Col [0000] +MSG 0001571 => Hit => Line [0352] - Col [0008] +MSG 0001572 => Hit => Line [0352] - Col [0016] +MSG 0001573 => Hit => Line [0352] - Col [0023] +MSG 0001574 => Hit => Line [0360] - Col [0000] +MSG 0001575 => Hit => Line [0360] - Col [0008] +MSG 0001576 => Hit => Line [0360] - Col [0016] +MSG 0001577 => Hit => Line [0360] - Col [0023] +MSG 0001578 => Hit => Line [0368] - Col [0000] +MSG 0001579 => Hit => Line [0368] - Col [0008] +MSG 0001580 => Hit => Line [0368] - Col [0016] +MSG 0001581 => Hit => Line [0368] - Col [0023] +MSG 0001582 => Hit => Line [0376] - Col [0000] +MSG 0001583 => Hit => Line [0376] - Col [0008] +MSG 0001584 => Hit => Line [0376] - Col [0016] +MSG 0001585 => Hit => Line [0376] - Col [0023] +MSG 0001586 => Hit => Line [0384] - Col [0000] +MSG 0001587 => Hit => Line [0384] - Col [0008] +MSG 0001588 => Hit => Line [0384] - Col [0016] +MSG 0001589 => Hit => Line [0384] - Col [0023] +MSG 0001590 => Hit => Line [0392] - Col [0000] +MSG 0001591 => Hit => Line [0392] - Col [0008] +MSG 0001592 => Hit => Line [0392] - Col [0016] +MSG 0001593 => Hit => Line [0392] - Col [0023] +MSG 0001594 => Hit => Line [0400] - Col [0000] +MSG 0001595 => Hit => Line [0400] - Col [0008] +MSG 0001596 => Hit => Line [0400] - Col [0016] +MSG 0001597 => Hit => Line [0400] - Col [0023] +MSG 0001598 => Hit => Line [0408] - Col [0000] +MSG 0001599 => Hit => Line [0408] - Col [0008] +MSG 0001600 => Hit => Line [0408] - Col [0016] +MSG 0001601 => Hit => Line [0408] - Col [0023] +MSG 0001602 => +MSG 0001603 => =================================================================================== +MSG 0001604 => Fsbb0 No 5 +MSG 0001605 => =================================================================================== +MSG 0001606 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001607 => Conv : VDataW30Length=312 +MSG 0001608 => *************************************************************************** +MSG 0001609 => * FSBB M [5] : Coordinates pixels with hit * +MSG 0001610 => *************************************************************************** +MSG 0001611 => Hit => Line [0000] - Col [0000] +MSG 0001612 => Hit => Line [0000] - Col [0032] +MSG 0001613 => Hit => Line [0000] - Col [0064] +MSG 0001614 => Hit => Line [0000] - Col [0096] +MSG 0001615 => Hit => Line [0000] - Col [0128] +MSG 0001616 => Hit => Line [0008] - Col [0000] +MSG 0001617 => Hit => Line [0008] - Col [0032] +MSG 0001618 => Hit => Line [0008] - Col [0064] +MSG 0001619 => Hit => Line [0008] - Col [0096] +MSG 0001620 => Hit => Line [0008] - Col [0128] +MSG 0001621 => Hit => Line [0016] - Col [0000] +MSG 0001622 => Hit => Line [0016] - Col [0032] +MSG 0001623 => Hit => Line [0016] - Col [0064] +MSG 0001624 => Hit => Line [0016] - Col [0096] +MSG 0001625 => Hit => Line [0016] - Col [0128] +MSG 0001626 => Hit => Line [0024] - Col [0000] +MSG 0001627 => Hit => Line [0024] - Col [0032] +MSG 0001628 => Hit => Line [0024] - Col [0064] +MSG 0001629 => Hit => Line [0024] - Col [0096] +MSG 0001630 => Hit => Line [0024] - Col [0128] +MSG 0001631 => Hit => Line [0032] - Col [0000] +MSG 0001632 => Hit => Line [0032] - Col [0032] +MSG 0001633 => Hit => Line [0032] - Col [0064] +MSG 0001634 => Hit => Line [0032] - Col [0096] +MSG 0001635 => Hit => Line [0032] - Col [0128] +MSG 0001636 => Hit => Line [0040] - Col [0000] +MSG 0001637 => Hit => Line [0040] - Col [0032] +MSG 0001638 => Hit => Line [0040] - Col [0064] +MSG 0001639 => Hit => Line [0040] - Col [0096] +MSG 0001640 => Hit => Line [0040] - Col [0128] +MSG 0001641 => Hit => Line [0048] - Col [0000] +MSG 0001642 => Hit => Line [0048] - Col [0032] +MSG 0001643 => Hit => Line [0048] - Col [0064] +MSG 0001644 => Hit => Line [0048] - Col [0096] +MSG 0001645 => Hit => Line [0048] - Col [0128] +MSG 0001646 => Hit => Line [0056] - Col [0000] +MSG 0001647 => Hit => Line [0056] - Col [0032] +MSG 0001648 => Hit => Line [0056] - Col [0064] +MSG 0001649 => Hit => Line [0056] - Col [0096] +MSG 0001650 => Hit => Line [0056] - Col [0128] +MSG 0001651 => Hit => Line [0064] - Col [0000] +MSG 0001652 => Hit => Line [0064] - Col [0032] +MSG 0001653 => Hit => Line [0064] - Col [0064] +MSG 0001654 => Hit => Line [0064] - Col [0096] +MSG 0001655 => Hit => Line [0064] - Col [0128] +MSG 0001656 => Hit => Line [0072] - Col [0000] +MSG 0001657 => Hit => Line [0072] - Col [0032] +MSG 0001658 => Hit => Line [0072] - Col [0064] +MSG 0001659 => Hit => Line [0072] - Col [0096] +MSG 0001660 => Hit => Line [0072] - Col [0128] +MSG 0001661 => Hit => Line [0080] - Col [0000] +MSG 0001662 => Hit => Line [0080] - Col [0032] +MSG 0001663 => Hit => Line [0080] - Col [0064] +MSG 0001664 => Hit => Line [0080] - Col [0096] +MSG 0001665 => Hit => Line [0080] - Col [0128] +MSG 0001666 => Hit => Line [0088] - Col [0000] +MSG 0001667 => Hit => Line [0088] - Col [0032] +MSG 0001668 => Hit => Line [0088] - Col [0064] +MSG 0001669 => Hit => Line [0088] - Col [0096] +MSG 0001670 => Hit => Line [0088] - Col [0128] +MSG 0001671 => Hit => Line [0096] - Col [0000] +MSG 0001672 => Hit => Line [0096] - Col [0032] +MSG 0001673 => Hit => Line [0096] - Col [0064] +MSG 0001674 => Hit => Line [0096] - Col [0096] +MSG 0001675 => Hit => Line [0096] - Col [0128] +MSG 0001676 => Hit => Line [0104] - Col [0000] +MSG 0001677 => Hit => Line [0104] - Col [0032] +MSG 0001678 => Hit => Line [0104] - Col [0064] +MSG 0001679 => Hit => Line [0104] - Col [0096] +MSG 0001680 => Hit => Line [0104] - Col [0128] +MSG 0001681 => Hit => Line [0112] - Col [0000] +MSG 0001682 => Hit => Line [0112] - Col [0032] +MSG 0001683 => Hit => Line [0112] - Col [0064] +MSG 0001684 => Hit => Line [0112] - Col [0096] +MSG 0001685 => Hit => Line [0112] - Col [0128] +MSG 0001686 => Hit => Line [0120] - Col [0000] +MSG 0001687 => Hit => Line [0120] - Col [0032] +MSG 0001688 => Hit => Line [0120] - Col [0064] +MSG 0001689 => Hit => Line [0120] - Col [0096] +MSG 0001690 => Hit => Line [0120] - Col [0128] +MSG 0001691 => Hit => Line [0128] - Col [0000] +MSG 0001692 => Hit => Line [0128] - Col [0032] +MSG 0001693 => Hit => Line [0128] - Col [0064] +MSG 0001694 => Hit => Line [0128] - Col [0096] +MSG 0001695 => Hit => Line [0128] - Col [0128] +MSG 0001696 => Hit => Line [0136] - Col [0000] +MSG 0001697 => Hit => Line [0136] - Col [0032] +MSG 0001698 => Hit => Line [0136] - Col [0064] +MSG 0001699 => Hit => Line [0136] - Col [0096] +MSG 0001700 => Hit => Line [0136] - Col [0128] +MSG 0001701 => Hit => Line [0144] - Col [0000] +MSG 0001702 => Hit => Line [0144] - Col [0032] +MSG 0001703 => Hit => Line [0144] - Col [0064] +MSG 0001704 => Hit => Line [0144] - Col [0096] +MSG 0001705 => Hit => Line [0144] - Col [0128] +MSG 0001706 => Hit => Line [0152] - Col [0000] +MSG 0001707 => Hit => Line [0152] - Col [0032] +MSG 0001708 => Hit => Line [0152] - Col [0064] +MSG 0001709 => Hit => Line [0152] - Col [0096] +MSG 0001710 => Hit => Line [0152] - Col [0128] +MSG 0001711 => Hit => Line [0160] - Col [0000] +MSG 0001712 => Hit => Line [0160] - Col [0032] +MSG 0001713 => Hit => Line [0160] - Col [0064] +MSG 0001714 => Hit => Line [0160] - Col [0096] +MSG 0001715 => Hit => Line [0160] - Col [0128] +MSG 0001716 => Hit => Line [0168] - Col [0000] +MSG 0001717 => Hit => Line [0168] - Col [0032] +MSG 0001718 => Hit => Line [0168] - Col [0064] +MSG 0001719 => Hit => Line [0168] - Col [0096] +MSG 0001720 => Hit => Line [0168] - Col [0128] +MSG 0001721 => Hit => Line [0176] - Col [0000] +MSG 0001722 => Hit => Line [0176] - Col [0032] +MSG 0001723 => Hit => Line [0176] - Col [0064] +MSG 0001724 => Hit => Line [0176] - Col [0096] +MSG 0001725 => Hit => Line [0176] - Col [0128] +MSG 0001726 => Hit => Line [0184] - Col [0000] +MSG 0001727 => Hit => Line [0184] - Col [0032] +MSG 0001728 => Hit => Line [0184] - Col [0064] +MSG 0001729 => Hit => Line [0184] - Col [0096] +MSG 0001730 => Hit => Line [0184] - Col [0128] +MSG 0001731 => Hit => Line [0192] - Col [0000] +MSG 0001732 => Hit => Line [0192] - Col [0032] +MSG 0001733 => Hit => Line [0192] - Col [0064] +MSG 0001734 => Hit => Line [0192] - Col [0096] +MSG 0001735 => Hit => Line [0192] - Col [0128] +MSG 0001736 => Hit => Line [0200] - Col [0000] +MSG 0001737 => Hit => Line [0200] - Col [0032] +MSG 0001738 => Hit => Line [0200] - Col [0064] +MSG 0001739 => Hit => Line [0200] - Col [0096] +MSG 0001740 => Hit => Line [0200] - Col [0128] +MSG 0001741 => Hit => Line [0208] - Col [0000] +MSG 0001742 => Hit => Line [0208] - Col [0032] +MSG 0001743 => Hit => Line [0208] - Col [0064] +MSG 0001744 => Hit => Line [0208] - Col [0096] +MSG 0001745 => Hit => Line [0208] - Col [0128] +MSG 0001746 => Hit => Line [0216] - Col [0000] +MSG 0001747 => Hit => Line [0216] - Col [0032] +MSG 0001748 => Hit => Line [0216] - Col [0064] +MSG 0001749 => Hit => Line [0216] - Col [0096] +MSG 0001750 => Hit => Line [0216] - Col [0128] +MSG 0001751 => Hit => Line [0224] - Col [0000] +MSG 0001752 => Hit => Line [0224] - Col [0032] +MSG 0001753 => Hit => Line [0224] - Col [0064] +MSG 0001754 => Hit => Line [0224] - Col [0096] +MSG 0001755 => Hit => Line [0224] - Col [0128] +MSG 0001756 => Hit => Line [0232] - Col [0000] +MSG 0001757 => Hit => Line [0232] - Col [0032] +MSG 0001758 => Hit => Line [0232] - Col [0064] +MSG 0001759 => Hit => Line [0232] - Col [0096] +MSG 0001760 => Hit => Line [0232] - Col [0128] +MSG 0001761 => Hit => Line [0240] - Col [0000] +MSG 0001762 => Hit => Line [0240] - Col [0032] +MSG 0001763 => Hit => Line [0240] - Col [0064] +MSG 0001764 => Hit => Line [0240] - Col [0096] +MSG 0001765 => Hit => Line [0240] - Col [0128] +MSG 0001766 => Hit => Line [0248] - Col [0000] +MSG 0001767 => Hit => Line [0248] - Col [0032] +MSG 0001768 => Hit => Line [0248] - Col [0064] +MSG 0001769 => Hit => Line [0248] - Col [0096] +MSG 0001770 => Hit => Line [0248] - Col [0128] +MSG 0001771 => Hit => Line [0256] - Col [0000] +MSG 0001772 => Hit => Line [0256] - Col [0032] +MSG 0001773 => Hit => Line [0256] - Col [0064] +MSG 0001774 => Hit => Line [0256] - Col [0096] +MSG 0001775 => Hit => Line [0256] - Col [0128] +MSG 0001776 => Hit => Line [0264] - Col [0000] +MSG 0001777 => Hit => Line [0264] - Col [0032] +MSG 0001778 => Hit => Line [0264] - Col [0064] +MSG 0001779 => Hit => Line [0264] - Col [0096] +MSG 0001780 => Hit => Line [0264] - Col [0128] +MSG 0001781 => Hit => Line [0272] - Col [0000] +MSG 0001782 => Hit => Line [0272] - Col [0032] +MSG 0001783 => Hit => Line [0272] - Col [0064] +MSG 0001784 => Hit => Line [0272] - Col [0096] +MSG 0001785 => Hit => Line [0272] - Col [0128] +MSG 0001786 => Hit => Line [0280] - Col [0000] +MSG 0001787 => Hit => Line [0280] - Col [0032] +MSG 0001788 => Hit => Line [0280] - Col [0064] +MSG 0001789 => Hit => Line [0280] - Col [0096] +MSG 0001790 => Hit => Line [0280] - Col [0128] +MSG 0001791 => Hit => Line [0288] - Col [0000] +MSG 0001792 => Hit => Line [0288] - Col [0032] +MSG 0001793 => Hit => Line [0288] - Col [0064] +MSG 0001794 => Hit => Line [0288] - Col [0096] +MSG 0001795 => Hit => Line [0288] - Col [0128] +MSG 0001796 => Hit => Line [0296] - Col [0000] +MSG 0001797 => Hit => Line [0296] - Col [0032] +MSG 0001798 => Hit => Line [0296] - Col [0064] +MSG 0001799 => Hit => Line [0296] - Col [0096] +MSG 0001800 => Hit => Line [0296] - Col [0128] +MSG 0001801 => Hit => Line [0304] - Col [0000] +MSG 0001802 => Hit => Line [0304] - Col [0032] +MSG 0001803 => Hit => Line [0304] - Col [0064] +MSG 0001804 => Hit => Line [0304] - Col [0096] +MSG 0001805 => Hit => Line [0304] - Col [0128] +MSG 0001806 => Hit => Line [0312] - Col [0000] +MSG 0001807 => Hit => Line [0312] - Col [0032] +MSG 0001808 => Hit => Line [0312] - Col [0064] +MSG 0001809 => Hit => Line [0312] - Col [0096] +MSG 0001810 => Hit => Line [0312] - Col [0128] +MSG 0001811 => Hit => Line [0320] - Col [0000] +MSG 0001812 => Hit => Line [0320] - Col [0032] +MSG 0001813 => Hit => Line [0320] - Col [0064] +MSG 0001814 => Hit => Line [0320] - Col [0096] +MSG 0001815 => Hit => Line [0320] - Col [0128] +MSG 0001816 => Hit => Line [0328] - Col [0000] +MSG 0001817 => Hit => Line [0328] - Col [0032] +MSG 0001818 => Hit => Line [0328] - Col [0064] +MSG 0001819 => Hit => Line [0328] - Col [0096] +MSG 0001820 => Hit => Line [0328] - Col [0128] +MSG 0001821 => Hit => Line [0336] - Col [0000] +MSG 0001822 => Hit => Line [0336] - Col [0032] +MSG 0001823 => Hit => Line [0336] - Col [0064] +MSG 0001824 => Hit => Line [0336] - Col [0096] +MSG 0001825 => Hit => Line [0336] - Col [0128] +MSG 0001826 => Hit => Line [0344] - Col [0000] +MSG 0001827 => Hit => Line [0344] - Col [0032] +MSG 0001828 => Hit => Line [0344] - Col [0064] +MSG 0001829 => Hit => Line [0344] - Col [0096] +MSG 0001830 => Hit => Line [0344] - Col [0128] +MSG 0001831 => Hit => Line [0352] - Col [0000] +MSG 0001832 => Hit => Line [0352] - Col [0032] +MSG 0001833 => Hit => Line [0352] - Col [0064] +MSG 0001834 => Hit => Line [0352] - Col [0096] +MSG 0001835 => Hit => Line [0352] - Col [0128] +MSG 0001836 => Hit => Line [0360] - Col [0000] +MSG 0001837 => Hit => Line [0360] - Col [0032] +MSG 0001838 => Hit => Line [0360] - Col [0064] +MSG 0001839 => Hit => Line [0360] - Col [0096] +MSG 0001840 => Hit => Line [0360] - Col [0128] +MSG 0001841 => Hit => Line [0368] - Col [0000] +MSG 0001842 => Hit => Line [0368] - Col [0032] +MSG 0001843 => Hit => Line [0368] - Col [0064] +MSG 0001844 => Hit => Line [0368] - Col [0096] +MSG 0001845 => Hit => Line [0368] - Col [0128] +MSG 0001846 => Hit => Line [0376] - Col [0000] +MSG 0001847 => Hit => Line [0376] - Col [0032] +MSG 0001848 => Hit => Line [0376] - Col [0064] +MSG 0001849 => Hit => Line [0376] - Col [0096] +MSG 0001850 => Hit => Line [0376] - Col [0128] +MSG 0001851 => Hit => Line [0384] - Col [0000] +MSG 0001852 => Hit => Line [0384] - Col [0032] +MSG 0001853 => Hit => Line [0384] - Col [0064] +MSG 0001854 => Hit => Line [0384] - Col [0096] +MSG 0001855 => Hit => Line [0384] - Col [0128] +MSG 0001856 => Hit => Line [0392] - Col [0000] +MSG 0001857 => Hit => Line [0392] - Col [0032] +MSG 0001858 => Hit => Line [0392] - Col [0064] +MSG 0001859 => Hit => Line [0392] - Col [0096] +MSG 0001860 => Hit => Line [0392] - Col [0128] +MSG 0001861 => Hit => Line [0400] - Col [0000] +MSG 0001862 => Hit => Line [0400] - Col [0032] +MSG 0001863 => Hit => Line [0400] - Col [0064] +MSG 0001864 => Hit => Line [0400] - Col [0096] +MSG 0001865 => Hit => Line [0400] - Col [0128] +MSG 0001866 => Hit => Line [0408] - Col [0000] +MSG 0001867 => Hit => Line [0408] - Col [0032] +MSG 0001868 => Hit => Line [0408] - Col [0064] +MSG 0001869 => Hit => Line [0408] - Col [0096] +MSG 0001870 => Hit => Line [0408] - Col [0128] +MSG 0001871 => +MSG 0001872 => =================================================================================== +MSG 0001873 => ============================================== +MSG 0001874 => Tag = 55550000 [H] +MSG 0001875 => DaqVersion = 0000 [D] +MSG 0001876 => TotSz = 7780 [D] +MSG 0001877 => TrigRecOffset = 7768 [D] +MSG 0001878 => ---------------------------------------------- +MSG 0001879 => H.Tag = 00000001 [H] +MSG 0001880 => H.AcqStatus = 0000 [D] +MSG 0001881 => H.TrigStatus = 0000 [D] +MSG 0001882 => H.AcqId = 0010 [D] +MSG 0001883 => H.FrameIdInAcq = 0005 [D] +MSG 0001884 => H.MapsName = 0004 [D] +MSG 0001885 => H.MapsNb = 0006 [D] +MSG 0001886 => ---------------------------------------------- +MSG 0001887 => H.Header [0]=50004000 [1]=50014001 [2]=50024002 [3]=50034003 [4]=50044004 [5]=50054005 [6]=00000000 [7]=00000000 +MSG 0001888 => H.FrCnt [0]= 198585 [1]= 198585 [2]= 198585 [3]= 198585 [4]= 198585 [5]= 198585 [6]= 0 [7]= 0 +MSG 0001889 => H.DataSz [0]= 0 [1]= 104 [2]= 156 [3]= 208 [4]= 260 [5]= 312 [6]= 0 [7]= 0 +MSG 0001890 => H.Trailer [0]=70006000 [1]=70016001 [2]=70026002 [3]=70036003 [4]=70046004 [5]=70056005 [6]=00000000 [7]=00000000 +MSG 0001891 => ---------------------------------------------- +MSG 0001892 => H.TriggerNb = 0001 [D] +MSG 0001893 => H.TrigInfo line [0]=0009 [1]=0000 [2]=0000 +MSG 0001894 => H.TrigInfo TS [0]=0003 [1]=0000 [2]=0000 +MSG 0001895 => ---------------------------------------------- +MSG 0001896 => D.Tag = 00000002 [H] +MSG 0001897 => D.TotSz = 7488 [D] +MSG 0001898 => D.OneMapsSz = 1248 [D] +MSG 0001899 => =================================================================================== +MSG 0001900 => Fsbb0 No 0 +MSG 0001901 => =================================================================================== +MSG 0001902 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001903 => Conv : VDataW30Length=0 +MSG 0001904 => *************************************************************************** +MSG 0001905 => * FSBB M [0] : Coordinates pixels with hit * +MSG 0001906 => *************************************************************************** +MSG 0001907 => +MSG 0001908 => =================================================================================== +MSG 0001909 => Fsbb0 No 1 +MSG 0001910 => =================================================================================== +MSG 0001911 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001912 => Conv : VDataW30Length=104 +MSG 0001913 => *************************************************************************** +MSG 0001914 => * FSBB M [1] : Coordinates pixels with hit * +MSG 0001915 => *************************************************************************** +MSG 0001916 => Hit => Line [0000] - Col [0000] +MSG 0001917 => Hit => Line [0008] - Col [0000] +MSG 0001918 => Hit => Line [0016] - Col [0000] +MSG 0001919 => Hit => Line [0024] - Col [0000] +MSG 0001920 => Hit => Line [0032] - Col [0000] +MSG 0001921 => Hit => Line [0040] - Col [0000] +MSG 0001922 => Hit => Line [0048] - Col [0000] +MSG 0001923 => Hit => Line [0056] - Col [0000] +MSG 0001924 => Hit => Line [0064] - Col [0000] +MSG 0001925 => Hit => Line [0072] - Col [0000] +MSG 0001926 => Hit => Line [0080] - Col [0000] +MSG 0001927 => Hit => Line [0088] - Col [0000] +MSG 0001928 => Hit => Line [0096] - Col [0000] +MSG 0001929 => Hit => Line [0104] - Col [0000] +MSG 0001930 => Hit => Line [0112] - Col [0000] +MSG 0001931 => Hit => Line [0120] - Col [0000] +MSG 0001932 => Hit => Line [0128] - Col [0000] +MSG 0001933 => Hit => Line [0136] - Col [0000] +MSG 0001934 => Hit => Line [0144] - Col [0000] +MSG 0001935 => Hit => Line [0152] - Col [0000] +MSG 0001936 => Hit => Line [0160] - Col [0000] +MSG 0001937 => Hit => Line [0168] - Col [0000] +MSG 0001938 => Hit => Line [0176] - Col [0000] +MSG 0001939 => Hit => Line [0184] - Col [0000] +MSG 0001940 => Hit => Line [0192] - Col [0000] +MSG 0001941 => Hit => Line [0200] - Col [0000] +MSG 0001942 => Hit => Line [0208] - Col [0000] +MSG 0001943 => Hit => Line [0216] - Col [0000] +MSG 0001944 => Hit => Line [0224] - Col [0000] +MSG 0001945 => Hit => Line [0232] - Col [0000] +MSG 0001946 => Hit => Line [0240] - Col [0000] +MSG 0001947 => Hit => Line [0248] - Col [0000] +MSG 0001948 => Hit => Line [0256] - Col [0000] +MSG 0001949 => Hit => Line [0264] - Col [0000] +MSG 0001950 => Hit => Line [0272] - Col [0000] +MSG 0001951 => Hit => Line [0280] - Col [0000] +MSG 0001952 => Hit => Line [0288] - Col [0000] +MSG 0001953 => Hit => Line [0296] - Col [0000] +MSG 0001954 => Hit => Line [0304] - Col [0000] +MSG 0001955 => Hit => Line [0312] - Col [0000] +MSG 0001956 => Hit => Line [0320] - Col [0000] +MSG 0001957 => Hit => Line [0328] - Col [0000] +MSG 0001958 => Hit => Line [0336] - Col [0000] +MSG 0001959 => Hit => Line [0344] - Col [0000] +MSG 0001960 => Hit => Line [0352] - Col [0000] +MSG 0001961 => Hit => Line [0360] - Col [0000] +MSG 0001962 => Hit => Line [0368] - Col [0000] +MSG 0001963 => Hit => Line [0376] - Col [0000] +MSG 0001964 => Hit => Line [0384] - Col [0000] +MSG 0001965 => Hit => Line [0392] - Col [0000] +MSG 0001966 => Hit => Line [0400] - Col [0000] +MSG 0001967 => Hit => Line [0408] - Col [0000] +MSG 0001968 => +MSG 0001969 => =================================================================================== +MSG 0001970 => Fsbb0 No 2 +MSG 0001971 => =================================================================================== +MSG 0001972 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0001973 => Conv : VDataW30Length=156 +MSG 0001974 => *************************************************************************** +MSG 0001975 => * FSBB M [2] : Coordinates pixels with hit * +MSG 0001976 => *************************************************************************** +MSG 0001977 => Hit => Line [0000] - Col [0000] +MSG 0001978 => Hit => Line [0000] - Col [0008] +MSG 0001979 => Hit => Line [0008] - Col [0000] +MSG 0001980 => Hit => Line [0008] - Col [0008] +MSG 0001981 => Hit => Line [0016] - Col [0000] +MSG 0001982 => Hit => Line [0016] - Col [0008] +MSG 0001983 => Hit => Line [0024] - Col [0000] +MSG 0001984 => Hit => Line [0024] - Col [0008] +MSG 0001985 => Hit => Line [0032] - Col [0000] +MSG 0001986 => Hit => Line [0032] - Col [0008] +MSG 0001987 => Hit => Line [0040] - Col [0000] +MSG 0001988 => Hit => Line [0040] - Col [0008] +MSG 0001989 => Hit => Line [0048] - Col [0000] +MSG 0001990 => Hit => Line [0048] - Col [0008] +MSG 0001991 => Hit => Line [0056] - Col [0000] +MSG 0001992 => Hit => Line [0056] - Col [0008] +MSG 0001993 => Hit => Line [0064] - Col [0000] +MSG 0001994 => Hit => Line [0064] - Col [0008] +MSG 0001995 => Hit => Line [0072] - Col [0000] +MSG 0001996 => Hit => Line [0072] - Col [0008] +MSG 0001997 => Hit => Line [0080] - Col [0000] +MSG 0001998 => Hit => Line [0080] - Col [0008] +MSG 0001999 => Hit => Line [0088] - Col [0000] +MSG 0002000 => Hit => Line [0088] - Col [0008] +MSG 0002001 => Hit => Line [0096] - Col [0000] +MSG 0002002 => Hit => Line [0096] - Col [0008] +MSG 0002003 => Hit => Line [0104] - Col [0000] +MSG 0002004 => Hit => Line [0104] - Col [0008] +MSG 0002005 => Hit => Line [0112] - Col [0000] +MSG 0002006 => Hit => Line [0112] - Col [0008] +MSG 0002007 => Hit => Line [0120] - Col [0000] +MSG 0002008 => Hit => Line [0120] - Col [0008] +MSG 0002009 => Hit => Line [0128] - Col [0000] +MSG 0002010 => Hit => Line [0128] - Col [0008] +MSG 0002011 => Hit => Line [0136] - Col [0000] +MSG 0002012 => Hit => Line [0136] - Col [0008] +MSG 0002013 => Hit => Line [0144] - Col [0000] +MSG 0002014 => Hit => Line [0144] - Col [0008] +MSG 0002015 => Hit => Line [0152] - Col [0000] +MSG 0002016 => Hit => Line [0152] - Col [0008] +MSG 0002017 => Hit => Line [0160] - Col [0000] +MSG 0002018 => Hit => Line [0160] - Col [0008] +MSG 0002019 => Hit => Line [0168] - Col [0000] +MSG 0002020 => Hit => Line [0168] - Col [0008] +MSG 0002021 => Hit => Line [0176] - Col [0000] +MSG 0002022 => Hit => Line [0176] - Col [0008] +MSG 0002023 => Hit => Line [0184] - Col [0000] +MSG 0002024 => Hit => Line [0184] - Col [0008] +MSG 0002025 => Hit => Line [0192] - Col [0000] +MSG 0002026 => Hit => Line [0192] - Col [0008] +MSG 0002027 => Hit => Line [0200] - Col [0000] +MSG 0002028 => Hit => Line [0200] - Col [0008] +MSG 0002029 => Hit => Line [0208] - Col [0000] +MSG 0002030 => Hit => Line [0208] - Col [0008] +MSG 0002031 => Hit => Line [0216] - Col [0000] +MSG 0002032 => Hit => Line [0216] - Col [0008] +MSG 0002033 => Hit => Line [0224] - Col [0000] +MSG 0002034 => Hit => Line [0224] - Col [0008] +MSG 0002035 => Hit => Line [0232] - Col [0000] +MSG 0002036 => Hit => Line [0232] - Col [0008] +MSG 0002037 => Hit => Line [0240] - Col [0000] +MSG 0002038 => Hit => Line [0240] - Col [0008] +MSG 0002039 => Hit => Line [0248] - Col [0000] +MSG 0002040 => Hit => Line [0248] - Col [0008] +MSG 0002041 => Hit => Line [0256] - Col [0000] +MSG 0002042 => Hit => Line [0256] - Col [0008] +MSG 0002043 => Hit => Line [0264] - Col [0000] +MSG 0002044 => Hit => Line [0264] - Col [0008] +MSG 0002045 => Hit => Line [0272] - Col [0000] +MSG 0002046 => Hit => Line [0272] - Col [0008] +MSG 0002047 => Hit => Line [0280] - Col [0000] +MSG 0002048 => Hit => Line [0280] - Col [0008] +MSG 0002049 => Hit => Line [0288] - Col [0000] +MSG 0002050 => Hit => Line [0288] - Col [0008] +MSG 0002051 => Hit => Line [0296] - Col [0000] +MSG 0002052 => Hit => Line [0296] - Col [0008] +MSG 0002053 => Hit => Line [0304] - Col [0000] +MSG 0002054 => Hit => Line [0304] - Col [0008] +MSG 0002055 => Hit => Line [0312] - Col [0000] +MSG 0002056 => Hit => Line [0312] - Col [0008] +MSG 0002057 => Hit => Line [0320] - Col [0000] +MSG 0002058 => Hit => Line [0320] - Col [0008] +MSG 0002059 => Hit => Line [0328] - Col [0000] +MSG 0002060 => Hit => Line [0328] - Col [0008] +MSG 0002061 => Hit => Line [0336] - Col [0000] +MSG 0002062 => Hit => Line [0336] - Col [0008] +MSG 0002063 => Hit => Line [0344] - Col [0000] +MSG 0002064 => Hit => Line [0344] - Col [0008] +MSG 0002065 => Hit => Line [0352] - Col [0000] +MSG 0002066 => Hit => Line [0352] - Col [0008] +MSG 0002067 => Hit => Line [0360] - Col [0000] +MSG 0002068 => Hit => Line [0360] - Col [0008] +MSG 0002069 => Hit => Line [0368] - Col [0000] +MSG 0002070 => Hit => Line [0368] - Col [0008] +MSG 0002071 => Hit => Line [0376] - Col [0000] +MSG 0002072 => Hit => Line [0376] - Col [0008] +MSG 0002073 => Hit => Line [0384] - Col [0000] +MSG 0002074 => Hit => Line [0384] - Col [0008] +MSG 0002075 => Hit => Line [0392] - Col [0000] +MSG 0002076 => Hit => Line [0392] - Col [0008] +MSG 0002077 => Hit => Line [0400] - Col [0000] +MSG 0002078 => Hit => Line [0400] - Col [0008] +MSG 0002079 => Hit => Line [0408] - Col [0000] +MSG 0002080 => Hit => Line [0408] - Col [0008] +MSG 0002081 => +MSG 0002082 => =================================================================================== +MSG 0002083 => Fsbb0 No 3 +MSG 0002084 => =================================================================================== +MSG 0002085 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0002086 => Conv : VDataW30Length=208 +MSG 0002087 => *************************************************************************** +MSG 0002088 => * FSBB M [3] : Coordinates pixels with hit * +MSG 0002089 => *************************************************************************** +MSG 0002090 => Hit => Line [0000] - Col [0000] +MSG 0002091 => Hit => Line [0000] - Col [0008] +MSG 0002092 => Hit => Line [0000] - Col [0016] +MSG 0002093 => Hit => Line [0008] - Col [0000] +MSG 0002094 => Hit => Line [0008] - Col [0008] +MSG 0002095 => Hit => Line [0008] - Col [0016] +MSG 0002096 => Hit => Line [0016] - Col [0000] +MSG 0002097 => Hit => Line [0016] - Col [0008] +MSG 0002098 => Hit => Line [0016] - Col [0016] +MSG 0002099 => Hit => Line [0024] - Col [0000] +MSG 0002100 => Hit => Line [0024] - Col [0008] +MSG 0002101 => Hit => Line [0024] - Col [0016] +MSG 0002102 => Hit => Line [0032] - Col [0000] +MSG 0002103 => Hit => Line [0032] - Col [0008] +MSG 0002104 => Hit => Line [0032] - Col [0016] +MSG 0002105 => Hit => Line [0040] - Col [0000] +MSG 0002106 => Hit => Line [0040] - Col [0008] +MSG 0002107 => Hit => Line [0040] - Col [0016] +MSG 0002108 => Hit => Line [0048] - Col [0000] +MSG 0002109 => Hit => Line [0048] - Col [0008] +MSG 0002110 => Hit => Line [0048] - Col [0016] +MSG 0002111 => Hit => Line [0056] - Col [0000] +MSG 0002112 => Hit => Line [0056] - Col [0008] +MSG 0002113 => Hit => Line [0056] - Col [0016] +MSG 0002114 => Hit => Line [0064] - Col [0000] +MSG 0002115 => Hit => Line [0064] - Col [0008] +MSG 0002116 => Hit => Line [0064] - Col [0016] +MSG 0002117 => Hit => Line [0072] - Col [0000] +MSG 0002118 => Hit => Line [0072] - Col [0008] +MSG 0002119 => Hit => Line [0072] - Col [0016] +MSG 0002120 => Hit => Line [0080] - Col [0000] +MSG 0002121 => Hit => Line [0080] - Col [0008] +MSG 0002122 => Hit => Line [0080] - Col [0016] +MSG 0002123 => Hit => Line [0088] - Col [0000] +MSG 0002124 => Hit => Line [0088] - Col [0008] +MSG 0002125 => Hit => Line [0088] - Col [0016] +MSG 0002126 => Hit => Line [0096] - Col [0000] +MSG 0002127 => Hit => Line [0096] - Col [0008] +MSG 0002128 => Hit => Line [0096] - Col [0016] +MSG 0002129 => Hit => Line [0104] - Col [0000] +MSG 0002130 => Hit => Line [0104] - Col [0008] +MSG 0002131 => Hit => Line [0104] - Col [0016] +MSG 0002132 => Hit => Line [0112] - Col [0000] +MSG 0002133 => Hit => Line [0112] - Col [0008] +MSG 0002134 => Hit => Line [0112] - Col [0016] +MSG 0002135 => Hit => Line [0120] - Col [0000] +MSG 0002136 => Hit => Line [0120] - Col [0008] +MSG 0002137 => Hit => Line [0120] - Col [0016] +MSG 0002138 => Hit => Line [0128] - Col [0000] +MSG 0002139 => Hit => Line [0128] - Col [0008] +MSG 0002140 => Hit => Line [0128] - Col [0016] +MSG 0002141 => Hit => Line [0136] - Col [0000] +MSG 0002142 => Hit => Line [0136] - Col [0008] +MSG 0002143 => Hit => Line [0136] - Col [0016] +MSG 0002144 => Hit => Line [0144] - Col [0000] +MSG 0002145 => Hit => Line [0144] - Col [0008] +MSG 0002146 => Hit => Line [0144] - Col [0016] +MSG 0002147 => Hit => Line [0152] - Col [0000] +MSG 0002148 => Hit => Line [0152] - Col [0008] +MSG 0002149 => Hit => Line [0152] - Col [0016] +MSG 0002150 => Hit => Line [0160] - Col [0000] +MSG 0002151 => Hit => Line [0160] - Col [0008] +MSG 0002152 => Hit => Line [0160] - Col [0016] +MSG 0002153 => Hit => Line [0168] - Col [0000] +MSG 0002154 => Hit => Line [0168] - Col [0008] +MSG 0002155 => Hit => Line [0168] - Col [0016] +MSG 0002156 => Hit => Line [0176] - Col [0000] +MSG 0002157 => Hit => Line [0176] - Col [0008] +MSG 0002158 => Hit => Line [0176] - Col [0016] +MSG 0002159 => Hit => Line [0184] - Col [0000] +MSG 0002160 => Hit => Line [0184] - Col [0008] +MSG 0002161 => Hit => Line [0184] - Col [0016] +MSG 0002162 => Hit => Line [0192] - Col [0000] +MSG 0002163 => Hit => Line [0192] - Col [0008] +MSG 0002164 => Hit => Line [0192] - Col [0016] +MSG 0002165 => Hit => Line [0200] - Col [0000] +MSG 0002166 => Hit => Line [0200] - Col [0008] +MSG 0002167 => Hit => Line [0200] - Col [0016] +MSG 0002168 => Hit => Line [0208] - Col [0000] +MSG 0002169 => Hit => Line [0208] - Col [0008] +MSG 0002170 => Hit => Line [0208] - Col [0016] +MSG 0002171 => Hit => Line [0216] - Col [0000] +MSG 0002172 => Hit => Line [0216] - Col [0008] +MSG 0002173 => Hit => Line [0216] - Col [0016] +MSG 0002174 => Hit => Line [0224] - Col [0000] +MSG 0002175 => Hit => Line [0224] - Col [0008] +MSG 0002176 => Hit => Line [0224] - Col [0016] +MSG 0002177 => Hit => Line [0232] - Col [0000] +MSG 0002178 => Hit => Line [0232] - Col [0008] +MSG 0002179 => Hit => Line [0232] - Col [0016] +MSG 0002180 => Hit => Line [0240] - Col [0000] +MSG 0002181 => Hit => Line [0240] - Col [0008] +MSG 0002182 => Hit => Line [0240] - Col [0016] +MSG 0002183 => Hit => Line [0248] - Col [0000] +MSG 0002184 => Hit => Line [0248] - Col [0008] +MSG 0002185 => Hit => Line [0248] - Col [0016] +MSG 0002186 => Hit => Line [0256] - Col [0000] +MSG 0002187 => Hit => Line [0256] - Col [0008] +MSG 0002188 => Hit => Line [0256] - Col [0016] +MSG 0002189 => Hit => Line [0264] - Col [0000] +MSG 0002190 => Hit => Line [0264] - Col [0008] +MSG 0002191 => Hit => Line [0264] - Col [0016] +MSG 0002192 => Hit => Line [0272] - Col [0000] +MSG 0002193 => Hit => Line [0272] - Col [0008] +MSG 0002194 => Hit => Line [0272] - Col [0016] +MSG 0002195 => Hit => Line [0280] - Col [0000] +MSG 0002196 => Hit => Line [0280] - Col [0008] +MSG 0002197 => Hit => Line [0280] - Col [0016] +MSG 0002198 => Hit => Line [0288] - Col [0000] +MSG 0002199 => Hit => Line [0288] - Col [0008] +MSG 0002200 => Hit => Line [0288] - Col [0016] +MSG 0002201 => Hit => Line [0296] - Col [0000] +MSG 0002202 => Hit => Line [0296] - Col [0008] +MSG 0002203 => Hit => Line [0296] - Col [0016] +MSG 0002204 => Hit => Line [0304] - Col [0000] +MSG 0002205 => Hit => Line [0304] - Col [0008] +MSG 0002206 => Hit => Line [0304] - Col [0016] +MSG 0002207 => Hit => Line [0312] - Col [0000] +MSG 0002208 => Hit => Line [0312] - Col [0008] +MSG 0002209 => Hit => Line [0312] - Col [0016] +MSG 0002210 => Hit => Line [0320] - Col [0000] +MSG 0002211 => Hit => Line [0320] - Col [0008] +MSG 0002212 => Hit => Line [0320] - Col [0016] +MSG 0002213 => Hit => Line [0328] - Col [0000] +MSG 0002214 => Hit => Line [0328] - Col [0008] +MSG 0002215 => Hit => Line [0328] - Col [0016] +MSG 0002216 => Hit => Line [0336] - Col [0000] +MSG 0002217 => Hit => Line [0336] - Col [0008] +MSG 0002218 => Hit => Line [0336] - Col [0016] +MSG 0002219 => Hit => Line [0344] - Col [0000] +MSG 0002220 => Hit => Line [0344] - Col [0008] +MSG 0002221 => Hit => Line [0344] - Col [0016] +MSG 0002222 => Hit => Line [0352] - Col [0000] +MSG 0002223 => Hit => Line [0352] - Col [0008] +MSG 0002224 => Hit => Line [0352] - Col [0016] +MSG 0002225 => Hit => Line [0360] - Col [0000] +MSG 0002226 => Hit => Line [0360] - Col [0008] +MSG 0002227 => Hit => Line [0360] - Col [0016] +MSG 0002228 => Hit => Line [0368] - Col [0000] +MSG 0002229 => Hit => Line [0368] - Col [0008] +MSG 0002230 => Hit => Line [0368] - Col [0016] +MSG 0002231 => Hit => Line [0376] - Col [0000] +MSG 0002232 => Hit => Line [0376] - Col [0008] +MSG 0002233 => Hit => Line [0376] - Col [0016] +MSG 0002234 => Hit => Line [0384] - Col [0000] +MSG 0002235 => Hit => Line [0384] - Col [0008] +MSG 0002236 => Hit => Line [0384] - Col [0016] +MSG 0002237 => Hit => Line [0392] - Col [0000] +MSG 0002238 => Hit => Line [0392] - Col [0008] +MSG 0002239 => Hit => Line [0392] - Col [0016] +MSG 0002240 => Hit => Line [0400] - Col [0000] +MSG 0002241 => Hit => Line [0400] - Col [0008] +MSG 0002242 => Hit => Line [0400] - Col [0016] +MSG 0002243 => Hit => Line [0408] - Col [0000] +MSG 0002244 => Hit => Line [0408] - Col [0008] +MSG 0002245 => Hit => Line [0408] - Col [0016] +MSG 0002246 => +MSG 0002247 => =================================================================================== +MSG 0002248 => Fsbb0 No 4 +MSG 0002249 => =================================================================================== +MSG 0002250 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0002251 => Conv : VDataW30Length=260 +MSG 0002252 => *************************************************************************** +MSG 0002253 => * FSBB M [4] : Coordinates pixels with hit * +MSG 0002254 => *************************************************************************** +MSG 0002255 => Hit => Line [0000] - Col [0000] +MSG 0002256 => Hit => Line [0000] - Col [0008] +MSG 0002257 => Hit => Line [0000] - Col [0016] +MSG 0002258 => Hit => Line [0000] - Col [0023] +MSG 0002259 => Hit => Line [0008] - Col [0000] +MSG 0002260 => Hit => Line [0008] - Col [0008] +MSG 0002261 => Hit => Line [0008] - Col [0016] +MSG 0002262 => Hit => Line [0008] - Col [0023] +MSG 0002263 => Hit => Line [0016] - Col [0000] +MSG 0002264 => Hit => Line [0016] - Col [0008] +MSG 0002265 => Hit => Line [0016] - Col [0016] +MSG 0002266 => Hit => Line [0016] - Col [0023] +MSG 0002267 => Hit => Line [0024] - Col [0000] +MSG 0002268 => Hit => Line [0024] - Col [0008] +MSG 0002269 => Hit => Line [0024] - Col [0016] +MSG 0002270 => Hit => Line [0024] - Col [0023] +MSG 0002271 => Hit => Line [0032] - Col [0000] +MSG 0002272 => Hit => Line [0032] - Col [0008] +MSG 0002273 => Hit => Line [0032] - Col [0016] +MSG 0002274 => Hit => Line [0032] - Col [0023] +MSG 0002275 => Hit => Line [0040] - Col [0000] +MSG 0002276 => Hit => Line [0040] - Col [0008] +MSG 0002277 => Hit => Line [0040] - Col [0016] +MSG 0002278 => Hit => Line [0040] - Col [0023] +MSG 0002279 => Hit => Line [0048] - Col [0000] +MSG 0002280 => Hit => Line [0048] - Col [0008] +MSG 0002281 => Hit => Line [0048] - Col [0016] +MSG 0002282 => Hit => Line [0048] - Col [0023] +MSG 0002283 => Hit => Line [0056] - Col [0000] +MSG 0002284 => Hit => Line [0056] - Col [0008] +MSG 0002285 => Hit => Line [0056] - Col [0016] +MSG 0002286 => Hit => Line [0056] - Col [0023] +MSG 0002287 => Hit => Line [0064] - Col [0000] +MSG 0002288 => Hit => Line [0064] - Col [0008] +MSG 0002289 => Hit => Line [0064] - Col [0016] +MSG 0002290 => Hit => Line [0064] - Col [0023] +MSG 0002291 => Hit => Line [0072] - Col [0000] +MSG 0002292 => Hit => Line [0072] - Col [0008] +MSG 0002293 => Hit => Line [0072] - Col [0016] +MSG 0002294 => Hit => Line [0072] - Col [0023] +MSG 0002295 => Hit => Line [0080] - Col [0000] +MSG 0002296 => Hit => Line [0080] - Col [0008] +MSG 0002297 => Hit => Line [0080] - Col [0016] +MSG 0002298 => Hit => Line [0080] - Col [0023] +MSG 0002299 => Hit => Line [0088] - Col [0000] +MSG 0002300 => Hit => Line [0088] - Col [0008] +MSG 0002301 => Hit => Line [0088] - Col [0016] +MSG 0002302 => Hit => Line [0088] - Col [0023] +MSG 0002303 => Hit => Line [0096] - Col [0000] +MSG 0002304 => Hit => Line [0096] - Col [0008] +MSG 0002305 => Hit => Line [0096] - Col [0016] +MSG 0002306 => Hit => Line [0096] - Col [0023] +MSG 0002307 => Hit => Line [0104] - Col [0000] +MSG 0002308 => Hit => Line [0104] - Col [0008] +MSG 0002309 => Hit => Line [0104] - Col [0016] +MSG 0002310 => Hit => Line [0104] - Col [0023] +MSG 0002311 => Hit => Line [0112] - Col [0000] +MSG 0002312 => Hit => Line [0112] - Col [0008] +MSG 0002313 => Hit => Line [0112] - Col [0016] +MSG 0002314 => Hit => Line [0112] - Col [0023] +MSG 0002315 => Hit => Line [0120] - Col [0000] +MSG 0002316 => Hit => Line [0120] - Col [0008] +MSG 0002317 => Hit => Line [0120] - Col [0016] +MSG 0002318 => Hit => Line [0120] - Col [0023] +MSG 0002319 => Hit => Line [0128] - Col [0000] +MSG 0002320 => Hit => Line [0128] - Col [0008] +MSG 0002321 => Hit => Line [0128] - Col [0016] +MSG 0002322 => Hit => Line [0128] - Col [0023] +MSG 0002323 => Hit => Line [0136] - Col [0000] +MSG 0002324 => Hit => Line [0136] - Col [0008] +MSG 0002325 => Hit => Line [0136] - Col [0016] +MSG 0002326 => Hit => Line [0136] - Col [0023] +MSG 0002327 => Hit => Line [0144] - Col [0000] +MSG 0002328 => Hit => Line [0144] - Col [0008] +MSG 0002329 => Hit => Line [0144] - Col [0016] +MSG 0002330 => Hit => Line [0144] - Col [0023] +MSG 0002331 => Hit => Line [0152] - Col [0000] +MSG 0002332 => Hit => Line [0152] - Col [0008] +MSG 0002333 => Hit => Line [0152] - Col [0016] +MSG 0002334 => Hit => Line [0152] - Col [0023] +MSG 0002335 => Hit => Line [0160] - Col [0000] +MSG 0002336 => Hit => Line [0160] - Col [0008] +MSG 0002337 => Hit => Line [0160] - Col [0016] +MSG 0002338 => Hit => Line [0160] - Col [0023] +MSG 0002339 => Hit => Line [0168] - Col [0000] +MSG 0002340 => Hit => Line [0168] - Col [0008] +MSG 0002341 => Hit => Line [0168] - Col [0016] +MSG 0002342 => Hit => Line [0168] - Col [0023] +MSG 0002343 => Hit => Line [0176] - Col [0000] +MSG 0002344 => Hit => Line [0176] - Col [0008] +MSG 0002345 => Hit => Line [0176] - Col [0016] +MSG 0002346 => Hit => Line [0176] - Col [0023] +MSG 0002347 => Hit => Line [0184] - Col [0000] +MSG 0002348 => Hit => Line [0184] - Col [0008] +MSG 0002349 => Hit => Line [0184] - Col [0016] +MSG 0002350 => Hit => Line [0184] - Col [0023] +MSG 0002351 => Hit => Line [0192] - Col [0000] +MSG 0002352 => Hit => Line [0192] - Col [0008] +MSG 0002353 => Hit => Line [0192] - Col [0016] +MSG 0002354 => Hit => Line [0192] - Col [0023] +MSG 0002355 => Hit => Line [0200] - Col [0000] +MSG 0002356 => Hit => Line [0200] - Col [0008] +MSG 0002357 => Hit => Line [0200] - Col [0016] +MSG 0002358 => Hit => Line [0200] - Col [0023] +MSG 0002359 => Hit => Line [0208] - Col [0000] +MSG 0002360 => Hit => Line [0208] - Col [0008] +MSG 0002361 => Hit => Line [0208] - Col [0016] +MSG 0002362 => Hit => Line [0208] - Col [0023] +MSG 0002363 => Hit => Line [0216] - Col [0000] +MSG 0002364 => Hit => Line [0216] - Col [0008] +MSG 0002365 => Hit => Line [0216] - Col [0016] +MSG 0002366 => Hit => Line [0216] - Col [0023] +MSG 0002367 => Hit => Line [0224] - Col [0000] +MSG 0002368 => Hit => Line [0224] - Col [0008] +MSG 0002369 => Hit => Line [0224] - Col [0016] +MSG 0002370 => Hit => Line [0224] - Col [0023] +MSG 0002371 => Hit => Line [0232] - Col [0000] +MSG 0002372 => Hit => Line [0232] - Col [0008] +MSG 0002373 => Hit => Line [0232] - Col [0016] +MSG 0002374 => Hit => Line [0232] - Col [0023] +MSG 0002375 => Hit => Line [0240] - Col [0000] +MSG 0002376 => Hit => Line [0240] - Col [0008] +MSG 0002377 => Hit => Line [0240] - Col [0016] +MSG 0002378 => Hit => Line [0240] - Col [0023] +MSG 0002379 => Hit => Line [0248] - Col [0000] +MSG 0002380 => Hit => Line [0248] - Col [0008] +MSG 0002381 => Hit => Line [0248] - Col [0016] +MSG 0002382 => Hit => Line [0248] - Col [0023] +MSG 0002383 => Hit => Line [0256] - Col [0000] +MSG 0002384 => Hit => Line [0256] - Col [0008] +MSG 0002385 => Hit => Line [0256] - Col [0016] +MSG 0002386 => Hit => Line [0256] - Col [0023] +MSG 0002387 => Hit => Line [0264] - Col [0000] +MSG 0002388 => Hit => Line [0264] - Col [0008] +MSG 0002389 => Hit => Line [0264] - Col [0016] +MSG 0002390 => Hit => Line [0264] - Col [0023] +MSG 0002391 => Hit => Line [0272] - Col [0000] +MSG 0002392 => Hit => Line [0272] - Col [0008] +MSG 0002393 => Hit => Line [0272] - Col [0016] +MSG 0002394 => Hit => Line [0272] - Col [0023] +MSG 0002395 => Hit => Line [0280] - Col [0000] +MSG 0002396 => Hit => Line [0280] - Col [0008] +MSG 0002397 => Hit => Line [0280] - Col [0016] +MSG 0002398 => Hit => Line [0280] - Col [0023] +MSG 0002399 => Hit => Line [0288] - Col [0000] +MSG 0002400 => Hit => Line [0288] - Col [0008] +MSG 0002401 => Hit => Line [0288] - Col [0016] +MSG 0002402 => Hit => Line [0288] - Col [0023] +MSG 0002403 => Hit => Line [0296] - Col [0000] +MSG 0002404 => Hit => Line [0296] - Col [0008] +MSG 0002405 => Hit => Line [0296] - Col [0016] +MSG 0002406 => Hit => Line [0296] - Col [0023] +MSG 0002407 => Hit => Line [0304] - Col [0000] +MSG 0002408 => Hit => Line [0304] - Col [0008] +MSG 0002409 => Hit => Line [0304] - Col [0016] +MSG 0002410 => Hit => Line [0304] - Col [0023] +MSG 0002411 => Hit => Line [0312] - Col [0000] +MSG 0002412 => Hit => Line [0312] - Col [0008] +MSG 0002413 => Hit => Line [0312] - Col [0016] +MSG 0002414 => Hit => Line [0312] - Col [0023] +MSG 0002415 => Hit => Line [0320] - Col [0000] +MSG 0002416 => Hit => Line [0320] - Col [0008] +MSG 0002417 => Hit => Line [0320] - Col [0016] +MSG 0002418 => Hit => Line [0320] - Col [0023] +MSG 0002419 => Hit => Line [0328] - Col [0000] +MSG 0002420 => Hit => Line [0328] - Col [0008] +MSG 0002421 => Hit => Line [0328] - Col [0016] +MSG 0002422 => Hit => Line [0328] - Col [0023] +MSG 0002423 => Hit => Line [0336] - Col [0000] +MSG 0002424 => Hit => Line [0336] - Col [0008] +MSG 0002425 => Hit => Line [0336] - Col [0016] +MSG 0002426 => Hit => Line [0336] - Col [0023] +MSG 0002427 => Hit => Line [0344] - Col [0000] +MSG 0002428 => Hit => Line [0344] - Col [0008] +MSG 0002429 => Hit => Line [0344] - Col [0016] +MSG 0002430 => Hit => Line [0344] - Col [0023] +MSG 0002431 => Hit => Line [0352] - Col [0000] +MSG 0002432 => Hit => Line [0352] - Col [0008] +MSG 0002433 => Hit => Line [0352] - Col [0016] +MSG 0002434 => Hit => Line [0352] - Col [0023] +MSG 0002435 => Hit => Line [0360] - Col [0000] +MSG 0002436 => Hit => Line [0360] - Col [0008] +MSG 0002437 => Hit => Line [0360] - Col [0016] +MSG 0002438 => Hit => Line [0360] - Col [0023] +MSG 0002439 => Hit => Line [0368] - Col [0000] +MSG 0002440 => Hit => Line [0368] - Col [0008] +MSG 0002441 => Hit => Line [0368] - Col [0016] +MSG 0002442 => Hit => Line [0368] - Col [0023] +MSG 0002443 => Hit => Line [0376] - Col [0000] +MSG 0002444 => Hit => Line [0376] - Col [0008] +MSG 0002445 => Hit => Line [0376] - Col [0016] +MSG 0002446 => Hit => Line [0376] - Col [0023] +MSG 0002447 => Hit => Line [0384] - Col [0000] +MSG 0002448 => Hit => Line [0384] - Col [0008] +MSG 0002449 => Hit => Line [0384] - Col [0016] +MSG 0002450 => Hit => Line [0384] - Col [0023] +MSG 0002451 => Hit => Line [0392] - Col [0000] +MSG 0002452 => Hit => Line [0392] - Col [0008] +MSG 0002453 => Hit => Line [0392] - Col [0016] +MSG 0002454 => Hit => Line [0392] - Col [0023] +MSG 0002455 => Hit => Line [0400] - Col [0000] +MSG 0002456 => Hit => Line [0400] - Col [0008] +MSG 0002457 => Hit => Line [0400] - Col [0016] +MSG 0002458 => Hit => Line [0400] - Col [0023] +MSG 0002459 => Hit => Line [0408] - Col [0000] +MSG 0002460 => Hit => Line [0408] - Col [0008] +MSG 0002461 => Hit => Line [0408] - Col [0016] +MSG 0002462 => Hit => Line [0408] - Col [0023] +MSG 0002463 => +MSG 0002464 => =================================================================================== +MSG 0002465 => Fsbb0 No 5 +MSG 0002466 => =================================================================================== +MSG 0002467 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0002468 => Conv : VDataW30Length=312 +MSG 0002469 => *************************************************************************** +MSG 0002470 => * FSBB M [5] : Coordinates pixels with hit * +MSG 0002471 => *************************************************************************** +MSG 0002472 => Hit => Line [0000] - Col [0000] +MSG 0002473 => Hit => Line [0000] - Col [0032] +MSG 0002474 => Hit => Line [0000] - Col [0064] +MSG 0002475 => Hit => Line [0000] - Col [0096] +MSG 0002476 => Hit => Line [0000] - Col [0128] +MSG 0002477 => Hit => Line [0008] - Col [0000] +MSG 0002478 => Hit => Line [0008] - Col [0032] +MSG 0002479 => Hit => Line [0008] - Col [0064] +MSG 0002480 => Hit => Line [0008] - Col [0096] +MSG 0002481 => Hit => Line [0008] - Col [0128] +MSG 0002482 => Hit => Line [0016] - Col [0000] +MSG 0002483 => Hit => Line [0016] - Col [0032] +MSG 0002484 => Hit => Line [0016] - Col [0064] +MSG 0002485 => Hit => Line [0016] - Col [0096] +MSG 0002486 => Hit => Line [0016] - Col [0128] +MSG 0002487 => Hit => Line [0024] - Col [0000] +MSG 0002488 => Hit => Line [0024] - Col [0032] +MSG 0002489 => Hit => Line [0024] - Col [0064] +MSG 0002490 => Hit => Line [0024] - Col [0096] +MSG 0002491 => Hit => Line [0024] - Col [0128] +MSG 0002492 => Hit => Line [0032] - Col [0000] +MSG 0002493 => Hit => Line [0032] - Col [0032] +MSG 0002494 => Hit => Line [0032] - Col [0064] +MSG 0002495 => Hit => Line [0032] - Col [0096] +MSG 0002496 => Hit => Line [0032] - Col [0128] +MSG 0002497 => Hit => Line [0040] - Col [0000] +MSG 0002498 => Hit => Line [0040] - Col [0032] +MSG 0002499 => Hit => Line [0040] - Col [0064] +MSG 0002500 => Hit => Line [0040] - Col [0096] +MSG 0002501 => Hit => Line [0040] - Col [0128] +MSG 0002502 => Hit => Line [0048] - Col [0000] +MSG 0002503 => Hit => Line [0048] - Col [0032] +MSG 0002504 => Hit => Line [0048] - Col [0064] +MSG 0002505 => Hit => Line [0048] - Col [0096] +MSG 0002506 => Hit => Line [0048] - Col [0128] +MSG 0002507 => Hit => Line [0056] - Col [0000] +MSG 0002508 => Hit => Line [0056] - Col [0032] +MSG 0002509 => Hit => Line [0056] - Col [0064] +MSG 0002510 => Hit => Line [0056] - Col [0096] +MSG 0002511 => Hit => Line [0056] - Col [0128] +MSG 0002512 => Hit => Line [0064] - Col [0000] +MSG 0002513 => Hit => Line [0064] - Col [0032] +MSG 0002514 => Hit => Line [0064] - Col [0064] +MSG 0002515 => Hit => Line [0064] - Col [0096] +MSG 0002516 => Hit => Line [0064] - Col [0128] +MSG 0002517 => Hit => Line [0072] - Col [0000] +MSG 0002518 => Hit => Line [0072] - Col [0032] +MSG 0002519 => Hit => Line [0072] - Col [0064] +MSG 0002520 => Hit => Line [0072] - Col [0096] +MSG 0002521 => Hit => Line [0072] - Col [0128] +MSG 0002522 => Hit => Line [0080] - Col [0000] +MSG 0002523 => Hit => Line [0080] - Col [0032] +MSG 0002524 => Hit => Line [0080] - Col [0064] +MSG 0002525 => Hit => Line [0080] - Col [0096] +MSG 0002526 => Hit => Line [0080] - Col [0128] +MSG 0002527 => Hit => Line [0088] - Col [0000] +MSG 0002528 => Hit => Line [0088] - Col [0032] +MSG 0002529 => Hit => Line [0088] - Col [0064] +MSG 0002530 => Hit => Line [0088] - Col [0096] +MSG 0002531 => Hit => Line [0088] - Col [0128] +MSG 0002532 => Hit => Line [0096] - Col [0000] +MSG 0002533 => Hit => Line [0096] - Col [0032] +MSG 0002534 => Hit => Line [0096] - Col [0064] +MSG 0002535 => Hit => Line [0096] - Col [0096] +MSG 0002536 => Hit => Line [0096] - Col [0128] +MSG 0002537 => Hit => Line [0104] - Col [0000] +MSG 0002538 => Hit => Line [0104] - Col [0032] +MSG 0002539 => Hit => Line [0104] - Col [0064] +MSG 0002540 => Hit => Line [0104] - Col [0096] +MSG 0002541 => Hit => Line [0104] - Col [0128] +MSG 0002542 => Hit => Line [0112] - Col [0000] +MSG 0002543 => Hit => Line [0112] - Col [0032] +MSG 0002544 => Hit => Line [0112] - Col [0064] +MSG 0002545 => Hit => Line [0112] - Col [0096] +MSG 0002546 => Hit => Line [0112] - Col [0128] +MSG 0002547 => Hit => Line [0120] - Col [0000] +MSG 0002548 => Hit => Line [0120] - Col [0032] +MSG 0002549 => Hit => Line [0120] - Col [0064] +MSG 0002550 => Hit => Line [0120] - Col [0096] +MSG 0002551 => Hit => Line [0120] - Col [0128] +MSG 0002552 => Hit => Line [0128] - Col [0000] +MSG 0002553 => Hit => Line [0128] - Col [0032] +MSG 0002554 => Hit => Line [0128] - Col [0064] +MSG 0002555 => Hit => Line [0128] - Col [0096] +MSG 0002556 => Hit => Line [0128] - Col [0128] +MSG 0002557 => Hit => Line [0136] - Col [0000] +MSG 0002558 => Hit => Line [0136] - Col [0032] +MSG 0002559 => Hit => Line [0136] - Col [0064] +MSG 0002560 => Hit => Line [0136] - Col [0096] +MSG 0002561 => Hit => Line [0136] - Col [0128] +MSG 0002562 => Hit => Line [0144] - Col [0000] +MSG 0002563 => Hit => Line [0144] - Col [0032] +MSG 0002564 => Hit => Line [0144] - Col [0064] +MSG 0002565 => Hit => Line [0144] - Col [0096] +MSG 0002566 => Hit => Line [0144] - Col [0128] +MSG 0002567 => Hit => Line [0152] - Col [0000] +MSG 0002568 => Hit => Line [0152] - Col [0032] +MSG 0002569 => Hit => Line [0152] - Col [0064] +MSG 0002570 => Hit => Line [0152] - Col [0096] +MSG 0002571 => Hit => Line [0152] - Col [0128] +MSG 0002572 => Hit => Line [0160] - Col [0000] +MSG 0002573 => Hit => Line [0160] - Col [0032] +MSG 0002574 => Hit => Line [0160] - Col [0064] +MSG 0002575 => Hit => Line [0160] - Col [0096] +MSG 0002576 => Hit => Line [0160] - Col [0128] +MSG 0002577 => Hit => Line [0168] - Col [0000] +MSG 0002578 => Hit => Line [0168] - Col [0032] +MSG 0002579 => Hit => Line [0168] - Col [0064] +MSG 0002580 => Hit => Line [0168] - Col [0096] +MSG 0002581 => Hit => Line [0168] - Col [0128] +MSG 0002582 => Hit => Line [0176] - Col [0000] +MSG 0002583 => Hit => Line [0176] - Col [0032] +MSG 0002584 => Hit => Line [0176] - Col [0064] +MSG 0002585 => Hit => Line [0176] - Col [0096] +MSG 0002586 => Hit => Line [0176] - Col [0128] +MSG 0002587 => Hit => Line [0184] - Col [0000] +MSG 0002588 => Hit => Line [0184] - Col [0032] +MSG 0002589 => Hit => Line [0184] - Col [0064] +MSG 0002590 => Hit => Line [0184] - Col [0096] +MSG 0002591 => Hit => Line [0184] - Col [0128] +MSG 0002592 => Hit => Line [0192] - Col [0000] +MSG 0002593 => Hit => Line [0192] - Col [0032] +MSG 0002594 => Hit => Line [0192] - Col [0064] +MSG 0002595 => Hit => Line [0192] - Col [0096] +MSG 0002596 => Hit => Line [0192] - Col [0128] +MSG 0002597 => Hit => Line [0200] - Col [0000] +MSG 0002598 => Hit => Line [0200] - Col [0032] +MSG 0002599 => Hit => Line [0200] - Col [0064] +MSG 0002600 => Hit => Line [0200] - Col [0096] +MSG 0002601 => Hit => Line [0200] - Col [0128] +MSG 0002602 => Hit => Line [0208] - Col [0000] +MSG 0002603 => Hit => Line [0208] - Col [0032] +MSG 0002604 => Hit => Line [0208] - Col [0064] +MSG 0002605 => Hit => Line [0208] - Col [0096] +MSG 0002606 => Hit => Line [0208] - Col [0128] +MSG 0002607 => Hit => Line [0216] - Col [0000] +MSG 0002608 => Hit => Line [0216] - Col [0032] +MSG 0002609 => Hit => Line [0216] - Col [0064] +MSG 0002610 => Hit => Line [0216] - Col [0096] +MSG 0002611 => Hit => Line [0216] - Col [0128] +MSG 0002612 => Hit => Line [0224] - Col [0000] +MSG 0002613 => Hit => Line [0224] - Col [0032] +MSG 0002614 => Hit => Line [0224] - Col [0064] +MSG 0002615 => Hit => Line [0224] - Col [0096] +MSG 0002616 => Hit => Line [0224] - Col [0128] +MSG 0002617 => Hit => Line [0232] - Col [0000] +MSG 0002618 => Hit => Line [0232] - Col [0032] +MSG 0002619 => Hit => Line [0232] - Col [0064] +MSG 0002620 => Hit => Line [0232] - Col [0096] +MSG 0002621 => Hit => Line [0232] - Col [0128] +MSG 0002622 => Hit => Line [0240] - Col [0000] +MSG 0002623 => Hit => Line [0240] - Col [0032] +MSG 0002624 => Hit => Line [0240] - Col [0064] +MSG 0002625 => Hit => Line [0240] - Col [0096] +MSG 0002626 => Hit => Line [0240] - Col [0128] +MSG 0002627 => Hit => Line [0248] - Col [0000] +MSG 0002628 => Hit => Line [0248] - Col [0032] +MSG 0002629 => Hit => Line [0248] - Col [0064] +MSG 0002630 => Hit => Line [0248] - Col [0096] +MSG 0002631 => Hit => Line [0248] - Col [0128] +MSG 0002632 => Hit => Line [0256] - Col [0000] +MSG 0002633 => Hit => Line [0256] - Col [0032] +MSG 0002634 => Hit => Line [0256] - Col [0064] +MSG 0002635 => Hit => Line [0256] - Col [0096] +MSG 0002636 => Hit => Line [0256] - Col [0128] +MSG 0002637 => Hit => Line [0264] - Col [0000] +MSG 0002638 => Hit => Line [0264] - Col [0032] +MSG 0002639 => Hit => Line [0264] - Col [0064] +MSG 0002640 => Hit => Line [0264] - Col [0096] +MSG 0002641 => Hit => Line [0264] - Col [0128] +MSG 0002642 => Hit => Line [0272] - Col [0000] +MSG 0002643 => Hit => Line [0272] - Col [0032] +MSG 0002644 => Hit => Line [0272] - Col [0064] +MSG 0002645 => Hit => Line [0272] - Col [0096] +MSG 0002646 => Hit => Line [0272] - Col [0128] +MSG 0002647 => Hit => Line [0280] - Col [0000] +MSG 0002648 => Hit => Line [0280] - Col [0032] +MSG 0002649 => Hit => Line [0280] - Col [0064] +MSG 0002650 => Hit => Line [0280] - Col [0096] +MSG 0002651 => Hit => Line [0280] - Col [0128] +MSG 0002652 => Hit => Line [0288] - Col [0000] +MSG 0002653 => Hit => Line [0288] - Col [0032] +MSG 0002654 => Hit => Line [0288] - Col [0064] +MSG 0002655 => Hit => Line [0288] - Col [0096] +MSG 0002656 => Hit => Line [0288] - Col [0128] +MSG 0002657 => Hit => Line [0296] - Col [0000] +MSG 0002658 => Hit => Line [0296] - Col [0032] +MSG 0002659 => Hit => Line [0296] - Col [0064] +MSG 0002660 => Hit => Line [0296] - Col [0096] +MSG 0002661 => Hit => Line [0296] - Col [0128] +MSG 0002662 => Hit => Line [0304] - Col [0000] +MSG 0002663 => Hit => Line [0304] - Col [0032] +MSG 0002664 => Hit => Line [0304] - Col [0064] +MSG 0002665 => Hit => Line [0304] - Col [0096] +MSG 0002666 => Hit => Line [0304] - Col [0128] +MSG 0002667 => Hit => Line [0312] - Col [0000] +MSG 0002668 => Hit => Line [0312] - Col [0032] +MSG 0002669 => Hit => Line [0312] - Col [0064] +MSG 0002670 => Hit => Line [0312] - Col [0096] +MSG 0002671 => Hit => Line [0312] - Col [0128] +MSG 0002672 => Hit => Line [0320] - Col [0000] +MSG 0002673 => Hit => Line [0320] - Col [0032] +MSG 0002674 => Hit => Line [0320] - Col [0064] +MSG 0002675 => Hit => Line [0320] - Col [0096] +MSG 0002676 => Hit => Line [0320] - Col [0128] +MSG 0002677 => Hit => Line [0328] - Col [0000] +MSG 0002678 => Hit => Line [0328] - Col [0032] +MSG 0002679 => Hit => Line [0328] - Col [0064] +MSG 0002680 => Hit => Line [0328] - Col [0096] +MSG 0002681 => Hit => Line [0328] - Col [0128] +MSG 0002682 => Hit => Line [0336] - Col [0000] +MSG 0002683 => Hit => Line [0336] - Col [0032] +MSG 0002684 => Hit => Line [0336] - Col [0064] +MSG 0002685 => Hit => Line [0336] - Col [0096] +MSG 0002686 => Hit => Line [0336] - Col [0128] +MSG 0002687 => Hit => Line [0344] - Col [0000] +MSG 0002688 => Hit => Line [0344] - Col [0032] +MSG 0002689 => Hit => Line [0344] - Col [0064] +MSG 0002690 => Hit => Line [0344] - Col [0096] +MSG 0002691 => Hit => Line [0344] - Col [0128] +MSG 0002692 => Hit => Line [0352] - Col [0000] +MSG 0002693 => Hit => Line [0352] - Col [0032] +MSG 0002694 => Hit => Line [0352] - Col [0064] +MSG 0002695 => Hit => Line [0352] - Col [0096] +MSG 0002696 => Hit => Line [0352] - Col [0128] +MSG 0002697 => Hit => Line [0360] - Col [0000] +MSG 0002698 => Hit => Line [0360] - Col [0032] +MSG 0002699 => Hit => Line [0360] - Col [0064] +MSG 0002700 => Hit => Line [0360] - Col [0096] +MSG 0002701 => Hit => Line [0360] - Col [0128] +MSG 0002702 => Hit => Line [0368] - Col [0000] +MSG 0002703 => Hit => Line [0368] - Col [0032] +MSG 0002704 => Hit => Line [0368] - Col [0064] +MSG 0002705 => Hit => Line [0368] - Col [0096] +MSG 0002706 => Hit => Line [0368] - Col [0128] +MSG 0002707 => Hit => Line [0376] - Col [0000] +MSG 0002708 => Hit => Line [0376] - Col [0032] +MSG 0002709 => Hit => Line [0376] - Col [0064] +MSG 0002710 => Hit => Line [0376] - Col [0096] +MSG 0002711 => Hit => Line [0376] - Col [0128] +MSG 0002712 => Hit => Line [0384] - Col [0000] +MSG 0002713 => Hit => Line [0384] - Col [0032] +MSG 0002714 => Hit => Line [0384] - Col [0064] +MSG 0002715 => Hit => Line [0384] - Col [0096] +MSG 0002716 => Hit => Line [0384] - Col [0128] +MSG 0002717 => Hit => Line [0392] - Col [0000] +MSG 0002718 => Hit => Line [0392] - Col [0032] +MSG 0002719 => Hit => Line [0392] - Col [0064] +MSG 0002720 => Hit => Line [0392] - Col [0096] +MSG 0002721 => Hit => Line [0392] - Col [0128] +MSG 0002722 => Hit => Line [0400] - Col [0000] +MSG 0002723 => Hit => Line [0400] - Col [0032] +MSG 0002724 => Hit => Line [0400] - Col [0064] +MSG 0002725 => Hit => Line [0400] - Col [0096] +MSG 0002726 => Hit => Line [0400] - Col [0128] +MSG 0002727 => Hit => Line [0408] - Col [0000] +MSG 0002728 => Hit => Line [0408] - Col [0032] +MSG 0002729 => Hit => Line [0408] - Col [0064] +MSG 0002730 => Hit => Line [0408] - Col [0096] +MSG 0002731 => Hit => Line [0408] - Col [0128] +MSG 0002732 => +MSG 0002733 => =================================================================================== +MSG 0002734 => ============================================== +MSG 0002735 => Tag = 55550000 [H] +MSG 0002736 => DaqVersion = 0000 [D] +MSG 0002737 => TotSz = 7780 [D] +MSG 0002738 => TrigRecOffset = 7768 [D] +MSG 0002739 => ---------------------------------------------- +MSG 0002740 => H.Tag = 00000001 [H] +MSG 0002741 => H.AcqStatus = 0000 [D] +MSG 0002742 => H.TrigStatus = 0000 [D] +MSG 0002743 => H.AcqId = 0020 [D] +MSG 0002744 => H.FrameIdInAcq = 0002 [D] +MSG 0002745 => H.MapsName = 0004 [D] +MSG 0002746 => H.MapsNb = 0006 [D] +MSG 0002747 => ---------------------------------------------- +MSG 0002748 => H.Header [0]=50004000 [1]=50014001 [2]=50024002 [3]=50034003 [4]=50044004 [5]=50054005 [6]=00000000 [7]=00000000 +MSG 0002749 => H.FrCnt [0]= 627910 [1]= 627910 [2]= 627910 [3]= 627910 [4]= 627910 [5]= 627910 [6]= 0 [7]= 0 +MSG 0002750 => H.DataSz [0]= 0 [1]= 104 [2]= 156 [3]= 208 [4]= 260 [5]= 312 [6]= 0 [7]= 0 +MSG 0002751 => H.Trailer [0]=70006000 [1]=70016001 [2]=70026002 [3]=70036003 [4]=70046004 [5]=70056005 [6]=00000000 [7]=00000000 +MSG 0002752 => ---------------------------------------------- +MSG 0002753 => H.TriggerNb = 0001 [D] +MSG 0002754 => H.TrigInfo line [0]=0426 [1]=0000 [2]=0000 +MSG 0002755 => H.TrigInfo TS [0]=0007 [1]=0000 [2]=0000 +MSG 0002756 => ---------------------------------------------- +MSG 0002757 => D.Tag = 00000002 [H] +MSG 0002758 => D.TotSz = 7488 [D] +MSG 0002759 => D.OneMapsSz = 1248 [D] +MSG 0002760 => =================================================================================== +MSG 0002761 => Fsbb0 No 0 +MSG 0002762 => =================================================================================== +MSG 0002763 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0002764 => Conv : VDataW30Length=0 +MSG 0002765 => *************************************************************************** +MSG 0002766 => * FSBB M [0] : Coordinates pixels with hit * +MSG 0002767 => *************************************************************************** +MSG 0002768 => +MSG 0002769 => =================================================================================== +MSG 0002770 => Fsbb0 No 1 +MSG 0002771 => =================================================================================== +MSG 0002772 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0002773 => Conv : VDataW30Length=104 +MSG 0002774 => *************************************************************************** +MSG 0002775 => * FSBB M [1] : Coordinates pixels with hit * +MSG 0002776 => *************************************************************************** +MSG 0002777 => Hit => Line [0000] - Col [0000] +MSG 0002778 => Hit => Line [0008] - Col [0000] +MSG 0002779 => Hit => Line [0016] - Col [0000] +MSG 0002780 => Hit => Line [0024] - Col [0000] +MSG 0002781 => Hit => Line [0032] - Col [0000] +MSG 0002782 => Hit => Line [0040] - Col [0000] +MSG 0002783 => Hit => Line [0048] - Col [0000] +MSG 0002784 => Hit => Line [0056] - Col [0000] +MSG 0002785 => Hit => Line [0064] - Col [0000] +MSG 0002786 => Hit => Line [0072] - Col [0000] +MSG 0002787 => Hit => Line [0080] - Col [0000] +MSG 0002788 => Hit => Line [0088] - Col [0000] +MSG 0002789 => Hit => Line [0096] - Col [0000] +MSG 0002790 => Hit => Line [0104] - Col [0000] +MSG 0002791 => Hit => Line [0112] - Col [0000] +MSG 0002792 => Hit => Line [0120] - Col [0000] +MSG 0002793 => Hit => Line [0128] - Col [0000] +MSG 0002794 => Hit => Line [0136] - Col [0000] +MSG 0002795 => Hit => Line [0144] - Col [0000] +MSG 0002796 => Hit => Line [0152] - Col [0000] +MSG 0002797 => Hit => Line [0160] - Col [0000] +MSG 0002798 => Hit => Line [0168] - Col [0000] +MSG 0002799 => Hit => Line [0176] - Col [0000] +MSG 0002800 => Hit => Line [0184] - Col [0000] +MSG 0002801 => Hit => Line [0192] - Col [0000] +MSG 0002802 => Hit => Line [0200] - Col [0000] +MSG 0002803 => Hit => Line [0208] - Col [0000] +MSG 0002804 => Hit => Line [0216] - Col [0000] +MSG 0002805 => Hit => Line [0224] - Col [0000] +MSG 0002806 => Hit => Line [0232] - Col [0000] +MSG 0002807 => Hit => Line [0240] - Col [0000] +MSG 0002808 => Hit => Line [0248] - Col [0000] +MSG 0002809 => Hit => Line [0256] - Col [0000] +MSG 0002810 => Hit => Line [0264] - Col [0000] +MSG 0002811 => Hit => Line [0272] - Col [0000] +MSG 0002812 => Hit => Line [0280] - Col [0000] +MSG 0002813 => Hit => Line [0288] - Col [0000] +MSG 0002814 => Hit => Line [0296] - Col [0000] +MSG 0002815 => Hit => Line [0304] - Col [0000] +MSG 0002816 => Hit => Line [0312] - Col [0000] +MSG 0002817 => Hit => Line [0320] - Col [0000] +MSG 0002818 => Hit => Line [0328] - Col [0000] +MSG 0002819 => Hit => Line [0336] - Col [0000] +MSG 0002820 => Hit => Line [0344] - Col [0000] +MSG 0002821 => Hit => Line [0352] - Col [0000] +MSG 0002822 => Hit => Line [0360] - Col [0000] +MSG 0002823 => Hit => Line [0368] - Col [0000] +MSG 0002824 => Hit => Line [0376] - Col [0000] +MSG 0002825 => Hit => Line [0384] - Col [0000] +MSG 0002826 => Hit => Line [0392] - Col [0000] +MSG 0002827 => Hit => Line [0400] - Col [0000] +MSG 0002828 => Hit => Line [0408] - Col [0000] +MSG 0002829 => +MSG 0002830 => =================================================================================== +MSG 0002831 => Fsbb0 No 2 +MSG 0002832 => =================================================================================== +MSG 0002833 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0002834 => Conv : VDataW30Length=156 +MSG 0002835 => *************************************************************************** +MSG 0002836 => * FSBB M [2] : Coordinates pixels with hit * +MSG 0002837 => *************************************************************************** +MSG 0002838 => Hit => Line [0000] - Col [0000] +MSG 0002839 => Hit => Line [0000] - Col [0008] +MSG 0002840 => Hit => Line [0008] - Col [0000] +MSG 0002841 => Hit => Line [0008] - Col [0008] +MSG 0002842 => Hit => Line [0016] - Col [0000] +MSG 0002843 => Hit => Line [0016] - Col [0008] +MSG 0002844 => Hit => Line [0024] - Col [0000] +MSG 0002845 => Hit => Line [0024] - Col [0008] +MSG 0002846 => Hit => Line [0032] - Col [0000] +MSG 0002847 => Hit => Line [0032] - Col [0008] +MSG 0002848 => Hit => Line [0040] - Col [0000] +MSG 0002849 => Hit => Line [0040] - Col [0008] +MSG 0002850 => Hit => Line [0048] - Col [0000] +MSG 0002851 => Hit => Line [0048] - Col [0008] +MSG 0002852 => Hit => Line [0056] - Col [0000] +MSG 0002853 => Hit => Line [0056] - Col [0008] +MSG 0002854 => Hit => Line [0064] - Col [0000] +MSG 0002855 => Hit => Line [0064] - Col [0008] +MSG 0002856 => Hit => Line [0072] - Col [0000] +MSG 0002857 => Hit => Line [0072] - Col [0008] +MSG 0002858 => Hit => Line [0080] - Col [0000] +MSG 0002859 => Hit => Line [0080] - Col [0008] +MSG 0002860 => Hit => Line [0088] - Col [0000] +MSG 0002861 => Hit => Line [0088] - Col [0008] +MSG 0002862 => Hit => Line [0096] - Col [0000] +MSG 0002863 => Hit => Line [0096] - Col [0008] +MSG 0002864 => Hit => Line [0104] - Col [0000] +MSG 0002865 => Hit => Line [0104] - Col [0008] +MSG 0002866 => Hit => Line [0112] - Col [0000] +MSG 0002867 => Hit => Line [0112] - Col [0008] +MSG 0002868 => Hit => Line [0120] - Col [0000] +MSG 0002869 => Hit => Line [0120] - Col [0008] +MSG 0002870 => Hit => Line [0128] - Col [0000] +MSG 0002871 => Hit => Line [0128] - Col [0008] +MSG 0002872 => Hit => Line [0136] - Col [0000] +MSG 0002873 => Hit => Line [0136] - Col [0008] +MSG 0002874 => Hit => Line [0144] - Col [0000] +MSG 0002875 => Hit => Line [0144] - Col [0008] +MSG 0002876 => Hit => Line [0152] - Col [0000] +MSG 0002877 => Hit => Line [0152] - Col [0008] +MSG 0002878 => Hit => Line [0160] - Col [0000] +MSG 0002879 => Hit => Line [0160] - Col [0008] +MSG 0002880 => Hit => Line [0168] - Col [0000] +MSG 0002881 => Hit => Line [0168] - Col [0008] +MSG 0002882 => Hit => Line [0176] - Col [0000] +MSG 0002883 => Hit => Line [0176] - Col [0008] +MSG 0002884 => Hit => Line [0184] - Col [0000] +MSG 0002885 => Hit => Line [0184] - Col [0008] +MSG 0002886 => Hit => Line [0192] - Col [0000] +MSG 0002887 => Hit => Line [0192] - Col [0008] +MSG 0002888 => Hit => Line [0200] - Col [0000] +MSG 0002889 => Hit => Line [0200] - Col [0008] +MSG 0002890 => Hit => Line [0208] - Col [0000] +MSG 0002891 => Hit => Line [0208] - Col [0008] +MSG 0002892 => Hit => Line [0216] - Col [0000] +MSG 0002893 => Hit => Line [0216] - Col [0008] +MSG 0002894 => Hit => Line [0224] - Col [0000] +MSG 0002895 => Hit => Line [0224] - Col [0008] +MSG 0002896 => Hit => Line [0232] - Col [0000] +MSG 0002897 => Hit => Line [0232] - Col [0008] +MSG 0002898 => Hit => Line [0240] - Col [0000] +MSG 0002899 => Hit => Line [0240] - Col [0008] +MSG 0002900 => Hit => Line [0248] - Col [0000] +MSG 0002901 => Hit => Line [0248] - Col [0008] +MSG 0002902 => Hit => Line [0256] - Col [0000] +MSG 0002903 => Hit => Line [0256] - Col [0008] +MSG 0002904 => Hit => Line [0264] - Col [0000] +MSG 0002905 => Hit => Line [0264] - Col [0008] +MSG 0002906 => Hit => Line [0272] - Col [0000] +MSG 0002907 => Hit => Line [0272] - Col [0008] +MSG 0002908 => Hit => Line [0280] - Col [0000] +MSG 0002909 => Hit => Line [0280] - Col [0008] +MSG 0002910 => Hit => Line [0288] - Col [0000] +MSG 0002911 => Hit => Line [0288] - Col [0008] +MSG 0002912 => Hit => Line [0296] - Col [0000] +MSG 0002913 => Hit => Line [0296] - Col [0008] +MSG 0002914 => Hit => Line [0304] - Col [0000] +MSG 0002915 => Hit => Line [0304] - Col [0008] +MSG 0002916 => Hit => Line [0312] - Col [0000] +MSG 0002917 => Hit => Line [0312] - Col [0008] +MSG 0002918 => Hit => Line [0320] - Col [0000] +MSG 0002919 => Hit => Line [0320] - Col [0008] +MSG 0002920 => Hit => Line [0328] - Col [0000] +MSG 0002921 => Hit => Line [0328] - Col [0008] +MSG 0002922 => Hit => Line [0336] - Col [0000] +MSG 0002923 => Hit => Line [0336] - Col [0008] +MSG 0002924 => Hit => Line [0344] - Col [0000] +MSG 0002925 => Hit => Line [0344] - Col [0008] +MSG 0002926 => Hit => Line [0352] - Col [0000] +MSG 0002927 => Hit => Line [0352] - Col [0008] +MSG 0002928 => Hit => Line [0360] - Col [0000] +MSG 0002929 => Hit => Line [0360] - Col [0008] +MSG 0002930 => Hit => Line [0368] - Col [0000] +MSG 0002931 => Hit => Line [0368] - Col [0008] +MSG 0002932 => Hit => Line [0376] - Col [0000] +MSG 0002933 => Hit => Line [0376] - Col [0008] +MSG 0002934 => Hit => Line [0384] - Col [0000] +MSG 0002935 => Hit => Line [0384] - Col [0008] +MSG 0002936 => Hit => Line [0392] - Col [0000] +MSG 0002937 => Hit => Line [0392] - Col [0008] +MSG 0002938 => Hit => Line [0400] - Col [0000] +MSG 0002939 => Hit => Line [0400] - Col [0008] +MSG 0002940 => Hit => Line [0408] - Col [0000] +MSG 0002941 => Hit => Line [0408] - Col [0008] +MSG 0002942 => +MSG 0002943 => =================================================================================== +MSG 0002944 => Fsbb0 No 3 +MSG 0002945 => =================================================================================== +MSG 0002946 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0002947 => Conv : VDataW30Length=208 +MSG 0002948 => *************************************************************************** +MSG 0002949 => * FSBB M [3] : Coordinates pixels with hit * +MSG 0002950 => *************************************************************************** +MSG 0002951 => Hit => Line [0000] - Col [0000] +MSG 0002952 => Hit => Line [0000] - Col [0008] +MSG 0002953 => Hit => Line [0000] - Col [0016] +MSG 0002954 => Hit => Line [0008] - Col [0000] +MSG 0002955 => Hit => Line [0008] - Col [0008] +MSG 0002956 => Hit => Line [0008] - Col [0016] +MSG 0002957 => Hit => Line [0016] - Col [0000] +MSG 0002958 => Hit => Line [0016] - Col [0008] +MSG 0002959 => Hit => Line [0016] - Col [0016] +MSG 0002960 => Hit => Line [0024] - Col [0000] +MSG 0002961 => Hit => Line [0024] - Col [0008] +MSG 0002962 => Hit => Line [0024] - Col [0016] +MSG 0002963 => Hit => Line [0032] - Col [0000] +MSG 0002964 => Hit => Line [0032] - Col [0008] +MSG 0002965 => Hit => Line [0032] - Col [0016] +MSG 0002966 => Hit => Line [0040] - Col [0000] +MSG 0002967 => Hit => Line [0040] - Col [0008] +MSG 0002968 => Hit => Line [0040] - Col [0016] +MSG 0002969 => Hit => Line [0048] - Col [0000] +MSG 0002970 => Hit => Line [0048] - Col [0008] +MSG 0002971 => Hit => Line [0048] - Col [0016] +MSG 0002972 => Hit => Line [0056] - Col [0000] +MSG 0002973 => Hit => Line [0056] - Col [0008] +MSG 0002974 => Hit => Line [0056] - Col [0016] +MSG 0002975 => Hit => Line [0064] - Col [0000] +MSG 0002976 => Hit => Line [0064] - Col [0008] +MSG 0002977 => Hit => Line [0064] - Col [0016] +MSG 0002978 => Hit => Line [0072] - Col [0000] +MSG 0002979 => Hit => Line [0072] - Col [0008] +MSG 0002980 => Hit => Line [0072] - Col [0016] +MSG 0002981 => Hit => Line [0080] - Col [0000] +MSG 0002982 => Hit => Line [0080] - Col [0008] +MSG 0002983 => Hit => Line [0080] - Col [0016] +MSG 0002984 => Hit => Line [0088] - Col [0000] +MSG 0002985 => Hit => Line [0088] - Col [0008] +MSG 0002986 => Hit => Line [0088] - Col [0016] +MSG 0002987 => Hit => Line [0096] - Col [0000] +MSG 0002988 => Hit => Line [0096] - Col [0008] +MSG 0002989 => Hit => Line [0096] - Col [0016] +MSG 0002990 => Hit => Line [0104] - Col [0000] +MSG 0002991 => Hit => Line [0104] - Col [0008] +MSG 0002992 => Hit => Line [0104] - Col [0016] +MSG 0002993 => Hit => Line [0112] - Col [0000] +MSG 0002994 => Hit => Line [0112] - Col [0008] +MSG 0002995 => Hit => Line [0112] - Col [0016] +MSG 0002996 => Hit => Line [0120] - Col [0000] +MSG 0002997 => Hit => Line [0120] - Col [0008] +MSG 0002998 => Hit => Line [0120] - Col [0016] +MSG 0002999 => Hit => Line [0128] - Col [0000] +MSG 0003000 => Hit => Line [0128] - Col [0008] +MSG 0003001 => Hit => Line [0128] - Col [0016] +MSG 0003002 => Hit => Line [0136] - Col [0000] +MSG 0003003 => Hit => Line [0136] - Col [0008] +MSG 0003004 => Hit => Line [0136] - Col [0016] +MSG 0003005 => Hit => Line [0144] - Col [0000] +MSG 0003006 => Hit => Line [0144] - Col [0008] +MSG 0003007 => Hit => Line [0144] - Col [0016] +MSG 0003008 => Hit => Line [0152] - Col [0000] +MSG 0003009 => Hit => Line [0152] - Col [0008] +MSG 0003010 => Hit => Line [0152] - Col [0016] +MSG 0003011 => Hit => Line [0160] - Col [0000] +MSG 0003012 => Hit => Line [0160] - Col [0008] +MSG 0003013 => Hit => Line [0160] - Col [0016] +MSG 0003014 => Hit => Line [0168] - Col [0000] +MSG 0003015 => Hit => Line [0168] - Col [0008] +MSG 0003016 => Hit => Line [0168] - Col [0016] +MSG 0003017 => Hit => Line [0176] - Col [0000] +MSG 0003018 => Hit => Line [0176] - Col [0008] +MSG 0003019 => Hit => Line [0176] - Col [0016] +MSG 0003020 => Hit => Line [0184] - Col [0000] +MSG 0003021 => Hit => Line [0184] - Col [0008] +MSG 0003022 => Hit => Line [0184] - Col [0016] +MSG 0003023 => Hit => Line [0192] - Col [0000] +MSG 0003024 => Hit => Line [0192] - Col [0008] +MSG 0003025 => Hit => Line [0192] - Col [0016] +MSG 0003026 => Hit => Line [0200] - Col [0000] +MSG 0003027 => Hit => Line [0200] - Col [0008] +MSG 0003028 => Hit => Line [0200] - Col [0016] +MSG 0003029 => Hit => Line [0208] - Col [0000] +MSG 0003030 => Hit => Line [0208] - Col [0008] +MSG 0003031 => Hit => Line [0208] - Col [0016] +MSG 0003032 => Hit => Line [0216] - Col [0000] +MSG 0003033 => Hit => Line [0216] - Col [0008] +MSG 0003034 => Hit => Line [0216] - Col [0016] +MSG 0003035 => Hit => Line [0224] - Col [0000] +MSG 0003036 => Hit => Line [0224] - Col [0008] +MSG 0003037 => Hit => Line [0224] - Col [0016] +MSG 0003038 => Hit => Line [0232] - Col [0000] +MSG 0003039 => Hit => Line [0232] - Col [0008] +MSG 0003040 => Hit => Line [0232] - Col [0016] +MSG 0003041 => Hit => Line [0240] - Col [0000] +MSG 0003042 => Hit => Line [0240] - Col [0008] +MSG 0003043 => Hit => Line [0240] - Col [0016] +MSG 0003044 => Hit => Line [0248] - Col [0000] +MSG 0003045 => Hit => Line [0248] - Col [0008] +MSG 0003046 => Hit => Line [0248] - Col [0016] +MSG 0003047 => Hit => Line [0256] - Col [0000] +MSG 0003048 => Hit => Line [0256] - Col [0008] +MSG 0003049 => Hit => Line [0256] - Col [0016] +MSG 0003050 => Hit => Line [0264] - Col [0000] +MSG 0003051 => Hit => Line [0264] - Col [0008] +MSG 0003052 => Hit => Line [0264] - Col [0016] +MSG 0003053 => Hit => Line [0272] - Col [0000] +MSG 0003054 => Hit => Line [0272] - Col [0008] +MSG 0003055 => Hit => Line [0272] - Col [0016] +MSG 0003056 => Hit => Line [0280] - Col [0000] +MSG 0003057 => Hit => Line [0280] - Col [0008] +MSG 0003058 => Hit => Line [0280] - Col [0016] +MSG 0003059 => Hit => Line [0288] - Col [0000] +MSG 0003060 => Hit => Line [0288] - Col [0008] +MSG 0003061 => Hit => Line [0288] - Col [0016] +MSG 0003062 => Hit => Line [0296] - Col [0000] +MSG 0003063 => Hit => Line [0296] - Col [0008] +MSG 0003064 => Hit => Line [0296] - Col [0016] +MSG 0003065 => Hit => Line [0304] - Col [0000] +MSG 0003066 => Hit => Line [0304] - Col [0008] +MSG 0003067 => Hit => Line [0304] - Col [0016] +MSG 0003068 => Hit => Line [0312] - Col [0000] +MSG 0003069 => Hit => Line [0312] - Col [0008] +MSG 0003070 => Hit => Line [0312] - Col [0016] +MSG 0003071 => Hit => Line [0320] - Col [0000] +MSG 0003072 => Hit => Line [0320] - Col [0008] +MSG 0003073 => Hit => Line [0320] - Col [0016] +MSG 0003074 => Hit => Line [0328] - Col [0000] +MSG 0003075 => Hit => Line [0328] - Col [0008] +MSG 0003076 => Hit => Line [0328] - Col [0016] +MSG 0003077 => Hit => Line [0336] - Col [0000] +MSG 0003078 => Hit => Line [0336] - Col [0008] +MSG 0003079 => Hit => Line [0336] - Col [0016] +MSG 0003080 => Hit => Line [0344] - Col [0000] +MSG 0003081 => Hit => Line [0344] - Col [0008] +MSG 0003082 => Hit => Line [0344] - Col [0016] +MSG 0003083 => Hit => Line [0352] - Col [0000] +MSG 0003084 => Hit => Line [0352] - Col [0008] +MSG 0003085 => Hit => Line [0352] - Col [0016] +MSG 0003086 => Hit => Line [0360] - Col [0000] +MSG 0003087 => Hit => Line [0360] - Col [0008] +MSG 0003088 => Hit => Line [0360] - Col [0016] +MSG 0003089 => Hit => Line [0368] - Col [0000] +MSG 0003090 => Hit => Line [0368] - Col [0008] +MSG 0003091 => Hit => Line [0368] - Col [0016] +MSG 0003092 => Hit => Line [0376] - Col [0000] +MSG 0003093 => Hit => Line [0376] - Col [0008] +MSG 0003094 => Hit => Line [0376] - Col [0016] +MSG 0003095 => Hit => Line [0384] - Col [0000] +MSG 0003096 => Hit => Line [0384] - Col [0008] +MSG 0003097 => Hit => Line [0384] - Col [0016] +MSG 0003098 => Hit => Line [0392] - Col [0000] +MSG 0003099 => Hit => Line [0392] - Col [0008] +MSG 0003100 => Hit => Line [0392] - Col [0016] +MSG 0003101 => Hit => Line [0400] - Col [0000] +MSG 0003102 => Hit => Line [0400] - Col [0008] +MSG 0003103 => Hit => Line [0400] - Col [0016] +MSG 0003104 => Hit => Line [0408] - Col [0000] +MSG 0003105 => Hit => Line [0408] - Col [0008] +MSG 0003106 => Hit => Line [0408] - Col [0016] +MSG 0003107 => +MSG 0003108 => =================================================================================== +MSG 0003109 => Fsbb0 No 4 +MSG 0003110 => =================================================================================== +MSG 0003111 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0003112 => Conv : VDataW30Length=260 +MSG 0003113 => *************************************************************************** +MSG 0003114 => * FSBB M [4] : Coordinates pixels with hit * +MSG 0003115 => *************************************************************************** +MSG 0003116 => Hit => Line [0000] - Col [0000] +MSG 0003117 => Hit => Line [0000] - Col [0008] +MSG 0003118 => Hit => Line [0000] - Col [0016] +MSG 0003119 => Hit => Line [0000] - Col [0023] +MSG 0003120 => Hit => Line [0008] - Col [0000] +MSG 0003121 => Hit => Line [0008] - Col [0008] +MSG 0003122 => Hit => Line [0008] - Col [0016] +MSG 0003123 => Hit => Line [0008] - Col [0023] +MSG 0003124 => Hit => Line [0016] - Col [0000] +MSG 0003125 => Hit => Line [0016] - Col [0008] +MSG 0003126 => Hit => Line [0016] - Col [0016] +MSG 0003127 => Hit => Line [0016] - Col [0023] +MSG 0003128 => Hit => Line [0024] - Col [0000] +MSG 0003129 => Hit => Line [0024] - Col [0008] +MSG 0003130 => Hit => Line [0024] - Col [0016] +MSG 0003131 => Hit => Line [0024] - Col [0023] +MSG 0003132 => Hit => Line [0032] - Col [0000] +MSG 0003133 => Hit => Line [0032] - Col [0008] +MSG 0003134 => Hit => Line [0032] - Col [0016] +MSG 0003135 => Hit => Line [0032] - Col [0023] +MSG 0003136 => Hit => Line [0040] - Col [0000] +MSG 0003137 => Hit => Line [0040] - Col [0008] +MSG 0003138 => Hit => Line [0040] - Col [0016] +MSG 0003139 => Hit => Line [0040] - Col [0023] +MSG 0003140 => Hit => Line [0048] - Col [0000] +MSG 0003141 => Hit => Line [0048] - Col [0008] +MSG 0003142 => Hit => Line [0048] - Col [0016] +MSG 0003143 => Hit => Line [0048] - Col [0023] +MSG 0003144 => Hit => Line [0056] - Col [0000] +MSG 0003145 => Hit => Line [0056] - Col [0008] +MSG 0003146 => Hit => Line [0056] - Col [0016] +MSG 0003147 => Hit => Line [0056] - Col [0023] +MSG 0003148 => Hit => Line [0064] - Col [0000] +MSG 0003149 => Hit => Line [0064] - Col [0008] +MSG 0003150 => Hit => Line [0064] - Col [0016] +MSG 0003151 => Hit => Line [0064] - Col [0023] +MSG 0003152 => Hit => Line [0072] - Col [0000] +MSG 0003153 => Hit => Line [0072] - Col [0008] +MSG 0003154 => Hit => Line [0072] - Col [0016] +MSG 0003155 => Hit => Line [0072] - Col [0023] +MSG 0003156 => Hit => Line [0080] - Col [0000] +MSG 0003157 => Hit => Line [0080] - Col [0008] +MSG 0003158 => Hit => Line [0080] - Col [0016] +MSG 0003159 => Hit => Line [0080] - Col [0023] +MSG 0003160 => Hit => Line [0088] - Col [0000] +MSG 0003161 => Hit => Line [0088] - Col [0008] +MSG 0003162 => Hit => Line [0088] - Col [0016] +MSG 0003163 => Hit => Line [0088] - Col [0023] +MSG 0003164 => Hit => Line [0096] - Col [0000] +MSG 0003165 => Hit => Line [0096] - Col [0008] +MSG 0003166 => Hit => Line [0096] - Col [0016] +MSG 0003167 => Hit => Line [0096] - Col [0023] +MSG 0003168 => Hit => Line [0104] - Col [0000] +MSG 0003169 => Hit => Line [0104] - Col [0008] +MSG 0003170 => Hit => Line [0104] - Col [0016] +MSG 0003171 => Hit => Line [0104] - Col [0023] +MSG 0003172 => Hit => Line [0112] - Col [0000] +MSG 0003173 => Hit => Line [0112] - Col [0008] +MSG 0003174 => Hit => Line [0112] - Col [0016] +MSG 0003175 => Hit => Line [0112] - Col [0023] +MSG 0003176 => Hit => Line [0120] - Col [0000] +MSG 0003177 => Hit => Line [0120] - Col [0008] +MSG 0003178 => Hit => Line [0120] - Col [0016] +MSG 0003179 => Hit => Line [0120] - Col [0023] +MSG 0003180 => Hit => Line [0128] - Col [0000] +MSG 0003181 => Hit => Line [0128] - Col [0008] +MSG 0003182 => Hit => Line [0128] - Col [0016] +MSG 0003183 => Hit => Line [0128] - Col [0023] +MSG 0003184 => Hit => Line [0136] - Col [0000] +MSG 0003185 => Hit => Line [0136] - Col [0008] +MSG 0003186 => Hit => Line [0136] - Col [0016] +MSG 0003187 => Hit => Line [0136] - Col [0023] +MSG 0003188 => Hit => Line [0144] - Col [0000] +MSG 0003189 => Hit => Line [0144] - Col [0008] +MSG 0003190 => Hit => Line [0144] - Col [0016] +MSG 0003191 => Hit => Line [0144] - Col [0023] +MSG 0003192 => Hit => Line [0152] - Col [0000] +MSG 0003193 => Hit => Line [0152] - Col [0008] +MSG 0003194 => Hit => Line [0152] - Col [0016] +MSG 0003195 => Hit => Line [0152] - Col [0023] +MSG 0003196 => Hit => Line [0160] - Col [0000] +MSG 0003197 => Hit => Line [0160] - Col [0008] +MSG 0003198 => Hit => Line [0160] - Col [0016] +MSG 0003199 => Hit => Line [0160] - Col [0023] +MSG 0003200 => Hit => Line [0168] - Col [0000] +MSG 0003201 => Hit => Line [0168] - Col [0008] +MSG 0003202 => Hit => Line [0168] - Col [0016] +MSG 0003203 => Hit => Line [0168] - Col [0023] +MSG 0003204 => Hit => Line [0176] - Col [0000] +MSG 0003205 => Hit => Line [0176] - Col [0008] +MSG 0003206 => Hit => Line [0176] - Col [0016] +MSG 0003207 => Hit => Line [0176] - Col [0023] +MSG 0003208 => Hit => Line [0184] - Col [0000] +MSG 0003209 => Hit => Line [0184] - Col [0008] +MSG 0003210 => Hit => Line [0184] - Col [0016] +MSG 0003211 => Hit => Line [0184] - Col [0023] +MSG 0003212 => Hit => Line [0192] - Col [0000] +MSG 0003213 => Hit => Line [0192] - Col [0008] +MSG 0003214 => Hit => Line [0192] - Col [0016] +MSG 0003215 => Hit => Line [0192] - Col [0023] +MSG 0003216 => Hit => Line [0200] - Col [0000] +MSG 0003217 => Hit => Line [0200] - Col [0008] +MSG 0003218 => Hit => Line [0200] - Col [0016] +MSG 0003219 => Hit => Line [0200] - Col [0023] +MSG 0003220 => Hit => Line [0208] - Col [0000] +MSG 0003221 => Hit => Line [0208] - Col [0008] +MSG 0003222 => Hit => Line [0208] - Col [0016] +MSG 0003223 => Hit => Line [0208] - Col [0023] +MSG 0003224 => Hit => Line [0216] - Col [0000] +MSG 0003225 => Hit => Line [0216] - Col [0008] +MSG 0003226 => Hit => Line [0216] - Col [0016] +MSG 0003227 => Hit => Line [0216] - Col [0023] +MSG 0003228 => Hit => Line [0224] - Col [0000] +MSG 0003229 => Hit => Line [0224] - Col [0008] +MSG 0003230 => Hit => Line [0224] - Col [0016] +MSG 0003231 => Hit => Line [0224] - Col [0023] +MSG 0003232 => Hit => Line [0232] - Col [0000] +MSG 0003233 => Hit => Line [0232] - Col [0008] +MSG 0003234 => Hit => Line [0232] - Col [0016] +MSG 0003235 => Hit => Line [0232] - Col [0023] +MSG 0003236 => Hit => Line [0240] - Col [0000] +MSG 0003237 => Hit => Line [0240] - Col [0008] +MSG 0003238 => Hit => Line [0240] - Col [0016] +MSG 0003239 => Hit => Line [0240] - Col [0023] +MSG 0003240 => Hit => Line [0248] - Col [0000] +MSG 0003241 => Hit => Line [0248] - Col [0008] +MSG 0003242 => Hit => Line [0248] - Col [0016] +MSG 0003243 => Hit => Line [0248] - Col [0023] +MSG 0003244 => Hit => Line [0256] - Col [0000] +MSG 0003245 => Hit => Line [0256] - Col [0008] +MSG 0003246 => Hit => Line [0256] - Col [0016] +MSG 0003247 => Hit => Line [0256] - Col [0023] +MSG 0003248 => Hit => Line [0264] - Col [0000] +MSG 0003249 => Hit => Line [0264] - Col [0008] +MSG 0003250 => Hit => Line [0264] - Col [0016] +MSG 0003251 => Hit => Line [0264] - Col [0023] +MSG 0003252 => Hit => Line [0272] - Col [0000] +MSG 0003253 => Hit => Line [0272] - Col [0008] +MSG 0003254 => Hit => Line [0272] - Col [0016] +MSG 0003255 => Hit => Line [0272] - Col [0023] +MSG 0003256 => Hit => Line [0280] - Col [0000] +MSG 0003257 => Hit => Line [0280] - Col [0008] +MSG 0003258 => Hit => Line [0280] - Col [0016] +MSG 0003259 => Hit => Line [0280] - Col [0023] +MSG 0003260 => Hit => Line [0288] - Col [0000] +MSG 0003261 => Hit => Line [0288] - Col [0008] +MSG 0003262 => Hit => Line [0288] - Col [0016] +MSG 0003263 => Hit => Line [0288] - Col [0023] +MSG 0003264 => Hit => Line [0296] - Col [0000] +MSG 0003265 => Hit => Line [0296] - Col [0008] +MSG 0003266 => Hit => Line [0296] - Col [0016] +MSG 0003267 => Hit => Line [0296] - Col [0023] +MSG 0003268 => Hit => Line [0304] - Col [0000] +MSG 0003269 => Hit => Line [0304] - Col [0008] +MSG 0003270 => Hit => Line [0304] - Col [0016] +MSG 0003271 => Hit => Line [0304] - Col [0023] +MSG 0003272 => Hit => Line [0312] - Col [0000] +MSG 0003273 => Hit => Line [0312] - Col [0008] +MSG 0003274 => Hit => Line [0312] - Col [0016] +MSG 0003275 => Hit => Line [0312] - Col [0023] +MSG 0003276 => Hit => Line [0320] - Col [0000] +MSG 0003277 => Hit => Line [0320] - Col [0008] +MSG 0003278 => Hit => Line [0320] - Col [0016] +MSG 0003279 => Hit => Line [0320] - Col [0023] +MSG 0003280 => Hit => Line [0328] - Col [0000] +MSG 0003281 => Hit => Line [0328] - Col [0008] +MSG 0003282 => Hit => Line [0328] - Col [0016] +MSG 0003283 => Hit => Line [0328] - Col [0023] +MSG 0003284 => Hit => Line [0336] - Col [0000] +MSG 0003285 => Hit => Line [0336] - Col [0008] +MSG 0003286 => Hit => Line [0336] - Col [0016] +MSG 0003287 => Hit => Line [0336] - Col [0023] +MSG 0003288 => Hit => Line [0344] - Col [0000] +MSG 0003289 => Hit => Line [0344] - Col [0008] +MSG 0003290 => Hit => Line [0344] - Col [0016] +MSG 0003291 => Hit => Line [0344] - Col [0023] +MSG 0003292 => Hit => Line [0352] - Col [0000] +MSG 0003293 => Hit => Line [0352] - Col [0008] +MSG 0003294 => Hit => Line [0352] - Col [0016] +MSG 0003295 => Hit => Line [0352] - Col [0023] +MSG 0003296 => Hit => Line [0360] - Col [0000] +MSG 0003297 => Hit => Line [0360] - Col [0008] +MSG 0003298 => Hit => Line [0360] - Col [0016] +MSG 0003299 => Hit => Line [0360] - Col [0023] +MSG 0003300 => Hit => Line [0368] - Col [0000] +MSG 0003301 => Hit => Line [0368] - Col [0008] +MSG 0003302 => Hit => Line [0368] - Col [0016] +MSG 0003303 => Hit => Line [0368] - Col [0023] +MSG 0003304 => Hit => Line [0376] - Col [0000] +MSG 0003305 => Hit => Line [0376] - Col [0008] +MSG 0003306 => Hit => Line [0376] - Col [0016] +MSG 0003307 => Hit => Line [0376] - Col [0023] +MSG 0003308 => Hit => Line [0384] - Col [0000] +MSG 0003309 => Hit => Line [0384] - Col [0008] +MSG 0003310 => Hit => Line [0384] - Col [0016] +MSG 0003311 => Hit => Line [0384] - Col [0023] +MSG 0003312 => Hit => Line [0392] - Col [0000] +MSG 0003313 => Hit => Line [0392] - Col [0008] +MSG 0003314 => Hit => Line [0392] - Col [0016] +MSG 0003315 => Hit => Line [0392] - Col [0023] +MSG 0003316 => Hit => Line [0400] - Col [0000] +MSG 0003317 => Hit => Line [0400] - Col [0008] +MSG 0003318 => Hit => Line [0400] - Col [0016] +MSG 0003319 => Hit => Line [0400] - Col [0023] +MSG 0003320 => Hit => Line [0408] - Col [0000] +MSG 0003321 => Hit => Line [0408] - Col [0008] +MSG 0003322 => Hit => Line [0408] - Col [0016] +MSG 0003323 => Hit => Line [0408] - Col [0023] +MSG 0003324 => +MSG 0003325 => =================================================================================== +MSG 0003326 => Fsbb0 No 5 +MSG 0003327 => =================================================================================== +MSG 0003328 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0003329 => Conv : VDataW30Length=312 +MSG 0003330 => *************************************************************************** +MSG 0003331 => * FSBB M [5] : Coordinates pixels with hit * +MSG 0003332 => *************************************************************************** +MSG 0003333 => Hit => Line [0000] - Col [0000] +MSG 0003334 => Hit => Line [0000] - Col [0032] +MSG 0003335 => Hit => Line [0000] - Col [0064] +MSG 0003336 => Hit => Line [0000] - Col [0096] +MSG 0003337 => Hit => Line [0000] - Col [0128] +MSG 0003338 => Hit => Line [0008] - Col [0000] +MSG 0003339 => Hit => Line [0008] - Col [0032] +MSG 0003340 => Hit => Line [0008] - Col [0064] +MSG 0003341 => Hit => Line [0008] - Col [0096] +MSG 0003342 => Hit => Line [0008] - Col [0128] +MSG 0003343 => Hit => Line [0016] - Col [0000] +MSG 0003344 => Hit => Line [0016] - Col [0032] +MSG 0003345 => Hit => Line [0016] - Col [0064] +MSG 0003346 => Hit => Line [0016] - Col [0096] +MSG 0003347 => Hit => Line [0016] - Col [0128] +MSG 0003348 => Hit => Line [0024] - Col [0000] +MSG 0003349 => Hit => Line [0024] - Col [0032] +MSG 0003350 => Hit => Line [0024] - Col [0064] +MSG 0003351 => Hit => Line [0024] - Col [0096] +MSG 0003352 => Hit => Line [0024] - Col [0128] +MSG 0003353 => Hit => Line [0032] - Col [0000] +MSG 0003354 => Hit => Line [0032] - Col [0032] +MSG 0003355 => Hit => Line [0032] - Col [0064] +MSG 0003356 => Hit => Line [0032] - Col [0096] +MSG 0003357 => Hit => Line [0032] - Col [0128] +MSG 0003358 => Hit => Line [0040] - Col [0000] +MSG 0003359 => Hit => Line [0040] - Col [0032] +MSG 0003360 => Hit => Line [0040] - Col [0064] +MSG 0003361 => Hit => Line [0040] - Col [0096] +MSG 0003362 => Hit => Line [0040] - Col [0128] +MSG 0003363 => Hit => Line [0048] - Col [0000] +MSG 0003364 => Hit => Line [0048] - Col [0032] +MSG 0003365 => Hit => Line [0048] - Col [0064] +MSG 0003366 => Hit => Line [0048] - Col [0096] +MSG 0003367 => Hit => Line [0048] - Col [0128] +MSG 0003368 => Hit => Line [0056] - Col [0000] +MSG 0003369 => Hit => Line [0056] - Col [0032] +MSG 0003370 => Hit => Line [0056] - Col [0064] +MSG 0003371 => Hit => Line [0056] - Col [0096] +MSG 0003372 => Hit => Line [0056] - Col [0128] +MSG 0003373 => Hit => Line [0064] - Col [0000] +MSG 0003374 => Hit => Line [0064] - Col [0032] +MSG 0003375 => Hit => Line [0064] - Col [0064] +MSG 0003376 => Hit => Line [0064] - Col [0096] +MSG 0003377 => Hit => Line [0064] - Col [0128] +MSG 0003378 => Hit => Line [0072] - Col [0000] +MSG 0003379 => Hit => Line [0072] - Col [0032] +MSG 0003380 => Hit => Line [0072] - Col [0064] +MSG 0003381 => Hit => Line [0072] - Col [0096] +MSG 0003382 => Hit => Line [0072] - Col [0128] +MSG 0003383 => Hit => Line [0080] - Col [0000] +MSG 0003384 => Hit => Line [0080] - Col [0032] +MSG 0003385 => Hit => Line [0080] - Col [0064] +MSG 0003386 => Hit => Line [0080] - Col [0096] +MSG 0003387 => Hit => Line [0080] - Col [0128] +MSG 0003388 => Hit => Line [0088] - Col [0000] +MSG 0003389 => Hit => Line [0088] - Col [0032] +MSG 0003390 => Hit => Line [0088] - Col [0064] +MSG 0003391 => Hit => Line [0088] - Col [0096] +MSG 0003392 => Hit => Line [0088] - Col [0128] +MSG 0003393 => Hit => Line [0096] - Col [0000] +MSG 0003394 => Hit => Line [0096] - Col [0032] +MSG 0003395 => Hit => Line [0096] - Col [0064] +MSG 0003396 => Hit => Line [0096] - Col [0096] +MSG 0003397 => Hit => Line [0096] - Col [0128] +MSG 0003398 => Hit => Line [0104] - Col [0000] +MSG 0003399 => Hit => Line [0104] - Col [0032] +MSG 0003400 => Hit => Line [0104] - Col [0064] +MSG 0003401 => Hit => Line [0104] - Col [0096] +MSG 0003402 => Hit => Line [0104] - Col [0128] +MSG 0003403 => Hit => Line [0112] - Col [0000] +MSG 0003404 => Hit => Line [0112] - Col [0032] +MSG 0003405 => Hit => Line [0112] - Col [0064] +MSG 0003406 => Hit => Line [0112] - Col [0096] +MSG 0003407 => Hit => Line [0112] - Col [0128] +MSG 0003408 => Hit => Line [0120] - Col [0000] +MSG 0003409 => Hit => Line [0120] - Col [0032] +MSG 0003410 => Hit => Line [0120] - Col [0064] +MSG 0003411 => Hit => Line [0120] - Col [0096] +MSG 0003412 => Hit => Line [0120] - Col [0128] +MSG 0003413 => Hit => Line [0128] - Col [0000] +MSG 0003414 => Hit => Line [0128] - Col [0032] +MSG 0003415 => Hit => Line [0128] - Col [0064] +MSG 0003416 => Hit => Line [0128] - Col [0096] +MSG 0003417 => Hit => Line [0128] - Col [0128] +MSG 0003418 => Hit => Line [0136] - Col [0000] +MSG 0003419 => Hit => Line [0136] - Col [0032] +MSG 0003420 => Hit => Line [0136] - Col [0064] +MSG 0003421 => Hit => Line [0136] - Col [0096] +MSG 0003422 => Hit => Line [0136] - Col [0128] +MSG 0003423 => Hit => Line [0144] - Col [0000] +MSG 0003424 => Hit => Line [0144] - Col [0032] +MSG 0003425 => Hit => Line [0144] - Col [0064] +MSG 0003426 => Hit => Line [0144] - Col [0096] +MSG 0003427 => Hit => Line [0144] - Col [0128] +MSG 0003428 => Hit => Line [0152] - Col [0000] +MSG 0003429 => Hit => Line [0152] - Col [0032] +MSG 0003430 => Hit => Line [0152] - Col [0064] +MSG 0003431 => Hit => Line [0152] - Col [0096] +MSG 0003432 => Hit => Line [0152] - Col [0128] +MSG 0003433 => Hit => Line [0160] - Col [0000] +MSG 0003434 => Hit => Line [0160] - Col [0032] +MSG 0003435 => Hit => Line [0160] - Col [0064] +MSG 0003436 => Hit => Line [0160] - Col [0096] +MSG 0003437 => Hit => Line [0160] - Col [0128] +MSG 0003438 => Hit => Line [0168] - Col [0000] +MSG 0003439 => Hit => Line [0168] - Col [0032] +MSG 0003440 => Hit => Line [0168] - Col [0064] +MSG 0003441 => Hit => Line [0168] - Col [0096] +MSG 0003442 => Hit => Line [0168] - Col [0128] +MSG 0003443 => Hit => Line [0176] - Col [0000] +MSG 0003444 => Hit => Line [0176] - Col [0032] +MSG 0003445 => Hit => Line [0176] - Col [0064] +MSG 0003446 => Hit => Line [0176] - Col [0096] +MSG 0003447 => Hit => Line [0176] - Col [0128] +MSG 0003448 => Hit => Line [0184] - Col [0000] +MSG 0003449 => Hit => Line [0184] - Col [0032] +MSG 0003450 => Hit => Line [0184] - Col [0064] +MSG 0003451 => Hit => Line [0184] - Col [0096] +MSG 0003452 => Hit => Line [0184] - Col [0128] +MSG 0003453 => Hit => Line [0192] - Col [0000] +MSG 0003454 => Hit => Line [0192] - Col [0032] +MSG 0003455 => Hit => Line [0192] - Col [0064] +MSG 0003456 => Hit => Line [0192] - Col [0096] +MSG 0003457 => Hit => Line [0192] - Col [0128] +MSG 0003458 => Hit => Line [0200] - Col [0000] +MSG 0003459 => Hit => Line [0200] - Col [0032] +MSG 0003460 => Hit => Line [0200] - Col [0064] +MSG 0003461 => Hit => Line [0200] - Col [0096] +MSG 0003462 => Hit => Line [0200] - Col [0128] +MSG 0003463 => Hit => Line [0208] - Col [0000] +MSG 0003464 => Hit => Line [0208] - Col [0032] +MSG 0003465 => Hit => Line [0208] - Col [0064] +MSG 0003466 => Hit => Line [0208] - Col [0096] +MSG 0003467 => Hit => Line [0208] - Col [0128] +MSG 0003468 => Hit => Line [0216] - Col [0000] +MSG 0003469 => Hit => Line [0216] - Col [0032] +MSG 0003470 => Hit => Line [0216] - Col [0064] +MSG 0003471 => Hit => Line [0216] - Col [0096] +MSG 0003472 => Hit => Line [0216] - Col [0128] +MSG 0003473 => Hit => Line [0224] - Col [0000] +MSG 0003474 => Hit => Line [0224] - Col [0032] +MSG 0003475 => Hit => Line [0224] - Col [0064] +MSG 0003476 => Hit => Line [0224] - Col [0096] +MSG 0003477 => Hit => Line [0224] - Col [0128] +MSG 0003478 => Hit => Line [0232] - Col [0000] +MSG 0003479 => Hit => Line [0232] - Col [0032] +MSG 0003480 => Hit => Line [0232] - Col [0064] +MSG 0003481 => Hit => Line [0232] - Col [0096] +MSG 0003482 => Hit => Line [0232] - Col [0128] +MSG 0003483 => Hit => Line [0240] - Col [0000] +MSG 0003484 => Hit => Line [0240] - Col [0032] +MSG 0003485 => Hit => Line [0240] - Col [0064] +MSG 0003486 => Hit => Line [0240] - Col [0096] +MSG 0003487 => Hit => Line [0240] - Col [0128] +MSG 0003488 => Hit => Line [0248] - Col [0000] +MSG 0003489 => Hit => Line [0248] - Col [0032] +MSG 0003490 => Hit => Line [0248] - Col [0064] +MSG 0003491 => Hit => Line [0248] - Col [0096] +MSG 0003492 => Hit => Line [0248] - Col [0128] +MSG 0003493 => Hit => Line [0256] - Col [0000] +MSG 0003494 => Hit => Line [0256] - Col [0032] +MSG 0003495 => Hit => Line [0256] - Col [0064] +MSG 0003496 => Hit => Line [0256] - Col [0096] +MSG 0003497 => Hit => Line [0256] - Col [0128] +MSG 0003498 => Hit => Line [0264] - Col [0000] +MSG 0003499 => Hit => Line [0264] - Col [0032] +MSG 0003500 => Hit => Line [0264] - Col [0064] +MSG 0003501 => Hit => Line [0264] - Col [0096] +MSG 0003502 => Hit => Line [0264] - Col [0128] +MSG 0003503 => Hit => Line [0272] - Col [0000] +MSG 0003504 => Hit => Line [0272] - Col [0032] +MSG 0003505 => Hit => Line [0272] - Col [0064] +MSG 0003506 => Hit => Line [0272] - Col [0096] +MSG 0003507 => Hit => Line [0272] - Col [0128] +MSG 0003508 => Hit => Line [0280] - Col [0000] +MSG 0003509 => Hit => Line [0280] - Col [0032] +MSG 0003510 => Hit => Line [0280] - Col [0064] +MSG 0003511 => Hit => Line [0280] - Col [0096] +MSG 0003512 => Hit => Line [0280] - Col [0128] +MSG 0003513 => Hit => Line [0288] - Col [0000] +MSG 0003514 => Hit => Line [0288] - Col [0032] +MSG 0003515 => Hit => Line [0288] - Col [0064] +MSG 0003516 => Hit => Line [0288] - Col [0096] +MSG 0003517 => Hit => Line [0288] - Col [0128] +MSG 0003518 => Hit => Line [0296] - Col [0000] +MSG 0003519 => Hit => Line [0296] - Col [0032] +MSG 0003520 => Hit => Line [0296] - Col [0064] +MSG 0003521 => Hit => Line [0296] - Col [0096] +MSG 0003522 => Hit => Line [0296] - Col [0128] +MSG 0003523 => Hit => Line [0304] - Col [0000] +MSG 0003524 => Hit => Line [0304] - Col [0032] +MSG 0003525 => Hit => Line [0304] - Col [0064] +MSG 0003526 => Hit => Line [0304] - Col [0096] +MSG 0003527 => Hit => Line [0304] - Col [0128] +MSG 0003528 => Hit => Line [0312] - Col [0000] +MSG 0003529 => Hit => Line [0312] - Col [0032] +MSG 0003530 => Hit => Line [0312] - Col [0064] +MSG 0003531 => Hit => Line [0312] - Col [0096] +MSG 0003532 => Hit => Line [0312] - Col [0128] +MSG 0003533 => Hit => Line [0320] - Col [0000] +MSG 0003534 => Hit => Line [0320] - Col [0032] +MSG 0003535 => Hit => Line [0320] - Col [0064] +MSG 0003536 => Hit => Line [0320] - Col [0096] +MSG 0003537 => Hit => Line [0320] - Col [0128] +MSG 0003538 => Hit => Line [0328] - Col [0000] +MSG 0003539 => Hit => Line [0328] - Col [0032] +MSG 0003540 => Hit => Line [0328] - Col [0064] +MSG 0003541 => Hit => Line [0328] - Col [0096] +MSG 0003542 => Hit => Line [0328] - Col [0128] +MSG 0003543 => Hit => Line [0336] - Col [0000] +MSG 0003544 => Hit => Line [0336] - Col [0032] +MSG 0003545 => Hit => Line [0336] - Col [0064] +MSG 0003546 => Hit => Line [0336] - Col [0096] +MSG 0003547 => Hit => Line [0336] - Col [0128] +MSG 0003548 => Hit => Line [0344] - Col [0000] +MSG 0003549 => Hit => Line [0344] - Col [0032] +MSG 0003550 => Hit => Line [0344] - Col [0064] +MSG 0003551 => Hit => Line [0344] - Col [0096] +MSG 0003552 => Hit => Line [0344] - Col [0128] +MSG 0003553 => Hit => Line [0352] - Col [0000] +MSG 0003554 => Hit => Line [0352] - Col [0032] +MSG 0003555 => Hit => Line [0352] - Col [0064] +MSG 0003556 => Hit => Line [0352] - Col [0096] +MSG 0003557 => Hit => Line [0352] - Col [0128] +MSG 0003558 => Hit => Line [0360] - Col [0000] +MSG 0003559 => Hit => Line [0360] - Col [0032] +MSG 0003560 => Hit => Line [0360] - Col [0064] +MSG 0003561 => Hit => Line [0360] - Col [0096] +MSG 0003562 => Hit => Line [0360] - Col [0128] +MSG 0003563 => Hit => Line [0368] - Col [0000] +MSG 0003564 => Hit => Line [0368] - Col [0032] +MSG 0003565 => Hit => Line [0368] - Col [0064] +MSG 0003566 => Hit => Line [0368] - Col [0096] +MSG 0003567 => Hit => Line [0368] - Col [0128] +MSG 0003568 => Hit => Line [0376] - Col [0000] +MSG 0003569 => Hit => Line [0376] - Col [0032] +MSG 0003570 => Hit => Line [0376] - Col [0064] +MSG 0003571 => Hit => Line [0376] - Col [0096] +MSG 0003572 => Hit => Line [0376] - Col [0128] +MSG 0003573 => Hit => Line [0384] - Col [0000] +MSG 0003574 => Hit => Line [0384] - Col [0032] +MSG 0003575 => Hit => Line [0384] - Col [0064] +MSG 0003576 => Hit => Line [0384] - Col [0096] +MSG 0003577 => Hit => Line [0384] - Col [0128] +MSG 0003578 => Hit => Line [0392] - Col [0000] +MSG 0003579 => Hit => Line [0392] - Col [0032] +MSG 0003580 => Hit => Line [0392] - Col [0064] +MSG 0003581 => Hit => Line [0392] - Col [0096] +MSG 0003582 => Hit => Line [0392] - Col [0128] +MSG 0003583 => Hit => Line [0400] - Col [0000] +MSG 0003584 => Hit => Line [0400] - Col [0032] +MSG 0003585 => Hit => Line [0400] - Col [0064] +MSG 0003586 => Hit => Line [0400] - Col [0096] +MSG 0003587 => Hit => Line [0400] - Col [0128] +MSG 0003588 => Hit => Line [0408] - Col [0000] +MSG 0003589 => Hit => Line [0408] - Col [0032] +MSG 0003590 => Hit => Line [0408] - Col [0064] +MSG 0003591 => Hit => Line [0408] - Col [0096] +MSG 0003592 => Hit => Line [0408] - Col [0128] +MSG 0003593 => +MSG 0003594 => =================================================================================== +MSG 0003595 => ============================================== +MSG 0003596 => Tag = 55550000 [H] +MSG 0003597 => DaqVersion = 0000 [D] +MSG 0003598 => TotSz = 7780 [D] +MSG 0003599 => TrigRecOffset = 7768 [D] +MSG 0003600 => ---------------------------------------------- +MSG 0003601 => H.Tag = 00000001 [H] +MSG 0003602 => H.AcqStatus = 0000 [D] +MSG 0003603 => H.TrigStatus = 0000 [D] +MSG 0003604 => H.AcqId = 0020 [D] +MSG 0003605 => H.FrameIdInAcq = 0005 [D] +MSG 0003606 => H.MapsName = 0004 [D] +MSG 0003607 => H.MapsNb = 0006 [D] +MSG 0003608 => ---------------------------------------------- +MSG 0003609 => H.Header [0]=50004000 [1]=50014001 [2]=50024002 [3]=50034003 [4]=50044004 [5]=50054005 [6]=00000000 [7]=00000000 +MSG 0003610 => H.FrCnt [0]= 627915 [1]= 627915 [2]= 627915 [3]= 627915 [4]= 627915 [5]= 627915 [6]= 0 [7]= 0 +MSG 0003611 => H.DataSz [0]= 0 [1]= 104 [2]= 156 [3]= 208 [4]= 260 [5]= 312 [6]= 0 [7]= 0 +MSG 0003612 => H.Trailer [0]=70006000 [1]=70016001 [2]=70026002 [3]=70036003 [4]=70046004 [5]=70056005 [6]=00000000 [7]=00000000 +MSG 0003613 => ---------------------------------------------- +MSG 0003614 => H.TriggerNb = 0001 [D] +MSG 0003615 => H.TrigInfo line [0]=0602 [1]=0000 [2]=0000 +MSG 0003616 => H.TrigInfo TS [0]=0005 [1]=0000 [2]=0000 +MSG 0003617 => ---------------------------------------------- +MSG 0003618 => D.Tag = 00000002 [H] +MSG 0003619 => D.TotSz = 7488 [D] +MSG 0003620 => D.OneMapsSz = 1248 [D] +MSG 0003621 => =================================================================================== +MSG 0003622 => Fsbb0 No 0 +MSG 0003623 => =================================================================================== +MSG 0003624 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0003625 => Conv : VDataW30Length=0 +MSG 0003626 => *************************************************************************** +MSG 0003627 => * FSBB M [0] : Coordinates pixels with hit * +MSG 0003628 => *************************************************************************** +MSG 0003629 => +MSG 0003630 => =================================================================================== +MSG 0003631 => Fsbb0 No 1 +MSG 0003632 => =================================================================================== +MSG 0003633 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0003634 => Conv : VDataW30Length=104 +MSG 0003635 => *************************************************************************** +MSG 0003636 => * FSBB M [1] : Coordinates pixels with hit * +MSG 0003637 => *************************************************************************** +MSG 0003638 => Hit => Line [0000] - Col [0000] +MSG 0003639 => Hit => Line [0008] - Col [0000] +MSG 0003640 => Hit => Line [0016] - Col [0000] +MSG 0003641 => Hit => Line [0024] - Col [0000] +MSG 0003642 => Hit => Line [0032] - Col [0000] +MSG 0003643 => Hit => Line [0040] - Col [0000] +MSG 0003644 => Hit => Line [0048] - Col [0000] +MSG 0003645 => Hit => Line [0056] - Col [0000] +MSG 0003646 => Hit => Line [0064] - Col [0000] +MSG 0003647 => Hit => Line [0072] - Col [0000] +MSG 0003648 => Hit => Line [0080] - Col [0000] +MSG 0003649 => Hit => Line [0088] - Col [0000] +MSG 0003650 => Hit => Line [0096] - Col [0000] +MSG 0003651 => Hit => Line [0104] - Col [0000] +MSG 0003652 => Hit => Line [0112] - Col [0000] +MSG 0003653 => Hit => Line [0120] - Col [0000] +MSG 0003654 => Hit => Line [0128] - Col [0000] +MSG 0003655 => Hit => Line [0136] - Col [0000] +MSG 0003656 => Hit => Line [0144] - Col [0000] +MSG 0003657 => Hit => Line [0152] - Col [0000] +MSG 0003658 => Hit => Line [0160] - Col [0000] +MSG 0003659 => Hit => Line [0168] - Col [0000] +MSG 0003660 => Hit => Line [0176] - Col [0000] +MSG 0003661 => Hit => Line [0184] - Col [0000] +MSG 0003662 => Hit => Line [0192] - Col [0000] +MSG 0003663 => Hit => Line [0200] - Col [0000] +MSG 0003664 => Hit => Line [0208] - Col [0000] +MSG 0003665 => Hit => Line [0216] - Col [0000] +MSG 0003666 => Hit => Line [0224] - Col [0000] +MSG 0003667 => Hit => Line [0232] - Col [0000] +MSG 0003668 => Hit => Line [0240] - Col [0000] +MSG 0003669 => Hit => Line [0248] - Col [0000] +MSG 0003670 => Hit => Line [0256] - Col [0000] +MSG 0003671 => Hit => Line [0264] - Col [0000] +MSG 0003672 => Hit => Line [0272] - Col [0000] +MSG 0003673 => Hit => Line [0280] - Col [0000] +MSG 0003674 => Hit => Line [0288] - Col [0000] +MSG 0003675 => Hit => Line [0296] - Col [0000] +MSG 0003676 => Hit => Line [0304] - Col [0000] +MSG 0003677 => Hit => Line [0312] - Col [0000] +MSG 0003678 => Hit => Line [0320] - Col [0000] +MSG 0003679 => Hit => Line [0328] - Col [0000] +MSG 0003680 => Hit => Line [0336] - Col [0000] +MSG 0003681 => Hit => Line [0344] - Col [0000] +MSG 0003682 => Hit => Line [0352] - Col [0000] +MSG 0003683 => Hit => Line [0360] - Col [0000] +MSG 0003684 => Hit => Line [0368] - Col [0000] +MSG 0003685 => Hit => Line [0376] - Col [0000] +MSG 0003686 => Hit => Line [0384] - Col [0000] +MSG 0003687 => Hit => Line [0392] - Col [0000] +MSG 0003688 => Hit => Line [0400] - Col [0000] +MSG 0003689 => Hit => Line [0408] - Col [0000] +MSG 0003690 => +MSG 0003691 => =================================================================================== +MSG 0003692 => Fsbb0 No 2 +MSG 0003693 => =================================================================================== +MSG 0003694 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0003695 => Conv : VDataW30Length=156 +MSG 0003696 => *************************************************************************** +MSG 0003697 => * FSBB M [2] : Coordinates pixels with hit * +MSG 0003698 => *************************************************************************** +MSG 0003699 => Hit => Line [0000] - Col [0000] +MSG 0003700 => Hit => Line [0000] - Col [0008] +MSG 0003701 => Hit => Line [0008] - Col [0000] +MSG 0003702 => Hit => Line [0008] - Col [0008] +MSG 0003703 => Hit => Line [0016] - Col [0000] +MSG 0003704 => Hit => Line [0016] - Col [0008] +MSG 0003705 => Hit => Line [0024] - Col [0000] +MSG 0003706 => Hit => Line [0024] - Col [0008] +MSG 0003707 => Hit => Line [0032] - Col [0000] +MSG 0003708 => Hit => Line [0032] - Col [0008] +MSG 0003709 => Hit => Line [0040] - Col [0000] +MSG 0003710 => Hit => Line [0040] - Col [0008] +MSG 0003711 => Hit => Line [0048] - Col [0000] +MSG 0003712 => Hit => Line [0048] - Col [0008] +MSG 0003713 => Hit => Line [0056] - Col [0000] +MSG 0003714 => Hit => Line [0056] - Col [0008] +MSG 0003715 => Hit => Line [0064] - Col [0000] +MSG 0003716 => Hit => Line [0064] - Col [0008] +MSG 0003717 => Hit => Line [0072] - Col [0000] +MSG 0003718 => Hit => Line [0072] - Col [0008] +MSG 0003719 => Hit => Line [0080] - Col [0000] +MSG 0003720 => Hit => Line [0080] - Col [0008] +MSG 0003721 => Hit => Line [0088] - Col [0000] +MSG 0003722 => Hit => Line [0088] - Col [0008] +MSG 0003723 => Hit => Line [0096] - Col [0000] +MSG 0003724 => Hit => Line [0096] - Col [0008] +MSG 0003725 => Hit => Line [0104] - Col [0000] +MSG 0003726 => Hit => Line [0104] - Col [0008] +MSG 0003727 => Hit => Line [0112] - Col [0000] +MSG 0003728 => Hit => Line [0112] - Col [0008] +MSG 0003729 => Hit => Line [0120] - Col [0000] +MSG 0003730 => Hit => Line [0120] - Col [0008] +MSG 0003731 => Hit => Line [0128] - Col [0000] +MSG 0003732 => Hit => Line [0128] - Col [0008] +MSG 0003733 => Hit => Line [0136] - Col [0000] +MSG 0003734 => Hit => Line [0136] - Col [0008] +MSG 0003735 => Hit => Line [0144] - Col [0000] +MSG 0003736 => Hit => Line [0144] - Col [0008] +MSG 0003737 => Hit => Line [0152] - Col [0000] +MSG 0003738 => Hit => Line [0152] - Col [0008] +MSG 0003739 => Hit => Line [0160] - Col [0000] +MSG 0003740 => Hit => Line [0160] - Col [0008] +MSG 0003741 => Hit => Line [0168] - Col [0000] +MSG 0003742 => Hit => Line [0168] - Col [0008] +MSG 0003743 => Hit => Line [0176] - Col [0000] +MSG 0003744 => Hit => Line [0176] - Col [0008] +MSG 0003745 => Hit => Line [0184] - Col [0000] +MSG 0003746 => Hit => Line [0184] - Col [0008] +MSG 0003747 => Hit => Line [0192] - Col [0000] +MSG 0003748 => Hit => Line [0192] - Col [0008] +MSG 0003749 => Hit => Line [0200] - Col [0000] +MSG 0003750 => Hit => Line [0200] - Col [0008] +MSG 0003751 => Hit => Line [0208] - Col [0000] +MSG 0003752 => Hit => Line [0208] - Col [0008] +MSG 0003753 => Hit => Line [0216] - Col [0000] +MSG 0003754 => Hit => Line [0216] - Col [0008] +MSG 0003755 => Hit => Line [0224] - Col [0000] +MSG 0003756 => Hit => Line [0224] - Col [0008] +MSG 0003757 => Hit => Line [0232] - Col [0000] +MSG 0003758 => Hit => Line [0232] - Col [0008] +MSG 0003759 => Hit => Line [0240] - Col [0000] +MSG 0003760 => Hit => Line [0240] - Col [0008] +MSG 0003761 => Hit => Line [0248] - Col [0000] +MSG 0003762 => Hit => Line [0248] - Col [0008] +MSG 0003763 => Hit => Line [0256] - Col [0000] +MSG 0003764 => Hit => Line [0256] - Col [0008] +MSG 0003765 => Hit => Line [0264] - Col [0000] +MSG 0003766 => Hit => Line [0264] - Col [0008] +MSG 0003767 => Hit => Line [0272] - Col [0000] +MSG 0003768 => Hit => Line [0272] - Col [0008] +MSG 0003769 => Hit => Line [0280] - Col [0000] +MSG 0003770 => Hit => Line [0280] - Col [0008] +MSG 0003771 => Hit => Line [0288] - Col [0000] +MSG 0003772 => Hit => Line [0288] - Col [0008] +MSG 0003773 => Hit => Line [0296] - Col [0000] +MSG 0003774 => Hit => Line [0296] - Col [0008] +MSG 0003775 => Hit => Line [0304] - Col [0000] +MSG 0003776 => Hit => Line [0304] - Col [0008] +MSG 0003777 => Hit => Line [0312] - Col [0000] +MSG 0003778 => Hit => Line [0312] - Col [0008] +MSG 0003779 => Hit => Line [0320] - Col [0000] +MSG 0003780 => Hit => Line [0320] - Col [0008] +MSG 0003781 => Hit => Line [0328] - Col [0000] +MSG 0003782 => Hit => Line [0328] - Col [0008] +MSG 0003783 => Hit => Line [0336] - Col [0000] +MSG 0003784 => Hit => Line [0336] - Col [0008] +MSG 0003785 => Hit => Line [0344] - Col [0000] +MSG 0003786 => Hit => Line [0344] - Col [0008] +MSG 0003787 => Hit => Line [0352] - Col [0000] +MSG 0003788 => Hit => Line [0352] - Col [0008] +MSG 0003789 => Hit => Line [0360] - Col [0000] +MSG 0003790 => Hit => Line [0360] - Col [0008] +MSG 0003791 => Hit => Line [0368] - Col [0000] +MSG 0003792 => Hit => Line [0368] - Col [0008] +MSG 0003793 => Hit => Line [0376] - Col [0000] +MSG 0003794 => Hit => Line [0376] - Col [0008] +MSG 0003795 => Hit => Line [0384] - Col [0000] +MSG 0003796 => Hit => Line [0384] - Col [0008] +MSG 0003797 => Hit => Line [0392] - Col [0000] +MSG 0003798 => Hit => Line [0392] - Col [0008] +MSG 0003799 => Hit => Line [0400] - Col [0000] +MSG 0003800 => Hit => Line [0400] - Col [0008] +MSG 0003801 => Hit => Line [0408] - Col [0000] +MSG 0003802 => Hit => Line [0408] - Col [0008] +MSG 0003803 => +MSG 0003804 => =================================================================================== +MSG 0003805 => Fsbb0 No 3 +MSG 0003806 => =================================================================================== +MSG 0003807 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0003808 => Conv : VDataW30Length=208 +MSG 0003809 => *************************************************************************** +MSG 0003810 => * FSBB M [3] : Coordinates pixels with hit * +MSG 0003811 => *************************************************************************** +MSG 0003812 => Hit => Line [0000] - Col [0000] +MSG 0003813 => Hit => Line [0000] - Col [0008] +MSG 0003814 => Hit => Line [0000] - Col [0016] +MSG 0003815 => Hit => Line [0008] - Col [0000] +MSG 0003816 => Hit => Line [0008] - Col [0008] +MSG 0003817 => Hit => Line [0008] - Col [0016] +MSG 0003818 => Hit => Line [0016] - Col [0000] +MSG 0003819 => Hit => Line [0016] - Col [0008] +MSG 0003820 => Hit => Line [0016] - Col [0016] +MSG 0003821 => Hit => Line [0024] - Col [0000] +MSG 0003822 => Hit => Line [0024] - Col [0008] +MSG 0003823 => Hit => Line [0024] - Col [0016] +MSG 0003824 => Hit => Line [0032] - Col [0000] +MSG 0003825 => Hit => Line [0032] - Col [0008] +MSG 0003826 => Hit => Line [0032] - Col [0016] +MSG 0003827 => Hit => Line [0040] - Col [0000] +MSG 0003828 => Hit => Line [0040] - Col [0008] +MSG 0003829 => Hit => Line [0040] - Col [0016] +MSG 0003830 => Hit => Line [0048] - Col [0000] +MSG 0003831 => Hit => Line [0048] - Col [0008] +MSG 0003832 => Hit => Line [0048] - Col [0016] +MSG 0003833 => Hit => Line [0056] - Col [0000] +MSG 0003834 => Hit => Line [0056] - Col [0008] +MSG 0003835 => Hit => Line [0056] - Col [0016] +MSG 0003836 => Hit => Line [0064] - Col [0000] +MSG 0003837 => Hit => Line [0064] - Col [0008] +MSG 0003838 => Hit => Line [0064] - Col [0016] +MSG 0003839 => Hit => Line [0072] - Col [0000] +MSG 0003840 => Hit => Line [0072] - Col [0008] +MSG 0003841 => Hit => Line [0072] - Col [0016] +MSG 0003842 => Hit => Line [0080] - Col [0000] +MSG 0003843 => Hit => Line [0080] - Col [0008] +MSG 0003844 => Hit => Line [0080] - Col [0016] +MSG 0003845 => Hit => Line [0088] - Col [0000] +MSG 0003846 => Hit => Line [0088] - Col [0008] +MSG 0003847 => Hit => Line [0088] - Col [0016] +MSG 0003848 => Hit => Line [0096] - Col [0000] +MSG 0003849 => Hit => Line [0096] - Col [0008] +MSG 0003850 => Hit => Line [0096] - Col [0016] +MSG 0003851 => Hit => Line [0104] - Col [0000] +MSG 0003852 => Hit => Line [0104] - Col [0008] +MSG 0003853 => Hit => Line [0104] - Col [0016] +MSG 0003854 => Hit => Line [0112] - Col [0000] +MSG 0003855 => Hit => Line [0112] - Col [0008] +MSG 0003856 => Hit => Line [0112] - Col [0016] +MSG 0003857 => Hit => Line [0120] - Col [0000] +MSG 0003858 => Hit => Line [0120] - Col [0008] +MSG 0003859 => Hit => Line [0120] - Col [0016] +MSG 0003860 => Hit => Line [0128] - Col [0000] +MSG 0003861 => Hit => Line [0128] - Col [0008] +MSG 0003862 => Hit => Line [0128] - Col [0016] +MSG 0003863 => Hit => Line [0136] - Col [0000] +MSG 0003864 => Hit => Line [0136] - Col [0008] +MSG 0003865 => Hit => Line [0136] - Col [0016] +MSG 0003866 => Hit => Line [0144] - Col [0000] +MSG 0003867 => Hit => Line [0144] - Col [0008] +MSG 0003868 => Hit => Line [0144] - Col [0016] +MSG 0003869 => Hit => Line [0152] - Col [0000] +MSG 0003870 => Hit => Line [0152] - Col [0008] +MSG 0003871 => Hit => Line [0152] - Col [0016] +MSG 0003872 => Hit => Line [0160] - Col [0000] +MSG 0003873 => Hit => Line [0160] - Col [0008] +MSG 0003874 => Hit => Line [0160] - Col [0016] +MSG 0003875 => Hit => Line [0168] - Col [0000] +MSG 0003876 => Hit => Line [0168] - Col [0008] +MSG 0003877 => Hit => Line [0168] - Col [0016] +MSG 0003878 => Hit => Line [0176] - Col [0000] +MSG 0003879 => Hit => Line [0176] - Col [0008] +MSG 0003880 => Hit => Line [0176] - Col [0016] +MSG 0003881 => Hit => Line [0184] - Col [0000] +MSG 0003882 => Hit => Line [0184] - Col [0008] +MSG 0003883 => Hit => Line [0184] - Col [0016] +MSG 0003884 => Hit => Line [0192] - Col [0000] +MSG 0003885 => Hit => Line [0192] - Col [0008] +MSG 0003886 => Hit => Line [0192] - Col [0016] +MSG 0003887 => Hit => Line [0200] - Col [0000] +MSG 0003888 => Hit => Line [0200] - Col [0008] +MSG 0003889 => Hit => Line [0200] - Col [0016] +MSG 0003890 => Hit => Line [0208] - Col [0000] +MSG 0003891 => Hit => Line [0208] - Col [0008] +MSG 0003892 => Hit => Line [0208] - Col [0016] +MSG 0003893 => Hit => Line [0216] - Col [0000] +MSG 0003894 => Hit => Line [0216] - Col [0008] +MSG 0003895 => Hit => Line [0216] - Col [0016] +MSG 0003896 => Hit => Line [0224] - Col [0000] +MSG 0003897 => Hit => Line [0224] - Col [0008] +MSG 0003898 => Hit => Line [0224] - Col [0016] +MSG 0003899 => Hit => Line [0232] - Col [0000] +MSG 0003900 => Hit => Line [0232] - Col [0008] +MSG 0003901 => Hit => Line [0232] - Col [0016] +MSG 0003902 => Hit => Line [0240] - Col [0000] +MSG 0003903 => Hit => Line [0240] - Col [0008] +MSG 0003904 => Hit => Line [0240] - Col [0016] +MSG 0003905 => Hit => Line [0248] - Col [0000] +MSG 0003906 => Hit => Line [0248] - Col [0008] +MSG 0003907 => Hit => Line [0248] - Col [0016] +MSG 0003908 => Hit => Line [0256] - Col [0000] +MSG 0003909 => Hit => Line [0256] - Col [0008] +MSG 0003910 => Hit => Line [0256] - Col [0016] +MSG 0003911 => Hit => Line [0264] - Col [0000] +MSG 0003912 => Hit => Line [0264] - Col [0008] +MSG 0003913 => Hit => Line [0264] - Col [0016] +MSG 0003914 => Hit => Line [0272] - Col [0000] +MSG 0003915 => Hit => Line [0272] - Col [0008] +MSG 0003916 => Hit => Line [0272] - Col [0016] +MSG 0003917 => Hit => Line [0280] - Col [0000] +MSG 0003918 => Hit => Line [0280] - Col [0008] +MSG 0003919 => Hit => Line [0280] - Col [0016] +MSG 0003920 => Hit => Line [0288] - Col [0000] +MSG 0003921 => Hit => Line [0288] - Col [0008] +MSG 0003922 => Hit => Line [0288] - Col [0016] +MSG 0003923 => Hit => Line [0296] - Col [0000] +MSG 0003924 => Hit => Line [0296] - Col [0008] +MSG 0003925 => Hit => Line [0296] - Col [0016] +MSG 0003926 => Hit => Line [0304] - Col [0000] +MSG 0003927 => Hit => Line [0304] - Col [0008] +MSG 0003928 => Hit => Line [0304] - Col [0016] +MSG 0003929 => Hit => Line [0312] - Col [0000] +MSG 0003930 => Hit => Line [0312] - Col [0008] +MSG 0003931 => Hit => Line [0312] - Col [0016] +MSG 0003932 => Hit => Line [0320] - Col [0000] +MSG 0003933 => Hit => Line [0320] - Col [0008] +MSG 0003934 => Hit => Line [0320] - Col [0016] +MSG 0003935 => Hit => Line [0328] - Col [0000] +MSG 0003936 => Hit => Line [0328] - Col [0008] +MSG 0003937 => Hit => Line [0328] - Col [0016] +MSG 0003938 => Hit => Line [0336] - Col [0000] +MSG 0003939 => Hit => Line [0336] - Col [0008] +MSG 0003940 => Hit => Line [0336] - Col [0016] +MSG 0003941 => Hit => Line [0344] - Col [0000] +MSG 0003942 => Hit => Line [0344] - Col [0008] +MSG 0003943 => Hit => Line [0344] - Col [0016] +MSG 0003944 => Hit => Line [0352] - Col [0000] +MSG 0003945 => Hit => Line [0352] - Col [0008] +MSG 0003946 => Hit => Line [0352] - Col [0016] +MSG 0003947 => Hit => Line [0360] - Col [0000] +MSG 0003948 => Hit => Line [0360] - Col [0008] +MSG 0003949 => Hit => Line [0360] - Col [0016] +MSG 0003950 => Hit => Line [0368] - Col [0000] +MSG 0003951 => Hit => Line [0368] - Col [0008] +MSG 0003952 => Hit => Line [0368] - Col [0016] +MSG 0003953 => Hit => Line [0376] - Col [0000] +MSG 0003954 => Hit => Line [0376] - Col [0008] +MSG 0003955 => Hit => Line [0376] - Col [0016] +MSG 0003956 => Hit => Line [0384] - Col [0000] +MSG 0003957 => Hit => Line [0384] - Col [0008] +MSG 0003958 => Hit => Line [0384] - Col [0016] +MSG 0003959 => Hit => Line [0392] - Col [0000] +MSG 0003960 => Hit => Line [0392] - Col [0008] +MSG 0003961 => Hit => Line [0392] - Col [0016] +MSG 0003962 => Hit => Line [0400] - Col [0000] +MSG 0003963 => Hit => Line [0400] - Col [0008] +MSG 0003964 => Hit => Line [0400] - Col [0016] +MSG 0003965 => Hit => Line [0408] - Col [0000] +MSG 0003966 => Hit => Line [0408] - Col [0008] +MSG 0003967 => Hit => Line [0408] - Col [0016] +MSG 0003968 => +MSG 0003969 => =================================================================================== +MSG 0003970 => Fsbb0 No 4 +MSG 0003971 => =================================================================================== +MSG 0003972 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0003973 => Conv : VDataW30Length=260 +MSG 0003974 => *************************************************************************** +MSG 0003975 => * FSBB M [4] : Coordinates pixels with hit * +MSG 0003976 => *************************************************************************** +MSG 0003977 => Hit => Line [0000] - Col [0000] +MSG 0003978 => Hit => Line [0000] - Col [0008] +MSG 0003979 => Hit => Line [0000] - Col [0016] +MSG 0003980 => Hit => Line [0000] - Col [0023] +MSG 0003981 => Hit => Line [0008] - Col [0000] +MSG 0003982 => Hit => Line [0008] - Col [0008] +MSG 0003983 => Hit => Line [0008] - Col [0016] +MSG 0003984 => Hit => Line [0008] - Col [0023] +MSG 0003985 => Hit => Line [0016] - Col [0000] +MSG 0003986 => Hit => Line [0016] - Col [0008] +MSG 0003987 => Hit => Line [0016] - Col [0016] +MSG 0003988 => Hit => Line [0016] - Col [0023] +MSG 0003989 => Hit => Line [0024] - Col [0000] +MSG 0003990 => Hit => Line [0024] - Col [0008] +MSG 0003991 => Hit => Line [0024] - Col [0016] +MSG 0003992 => Hit => Line [0024] - Col [0023] +MSG 0003993 => Hit => Line [0032] - Col [0000] +MSG 0003994 => Hit => Line [0032] - Col [0008] +MSG 0003995 => Hit => Line [0032] - Col [0016] +MSG 0003996 => Hit => Line [0032] - Col [0023] +MSG 0003997 => Hit => Line [0040] - Col [0000] +MSG 0003998 => Hit => Line [0040] - Col [0008] +MSG 0003999 => Hit => Line [0040] - Col [0016] +MSG 0004000 => Hit => Line [0040] - Col [0023] +MSG 0004001 => Hit => Line [0048] - Col [0000] +MSG 0004002 => Hit => Line [0048] - Col [0008] +MSG 0004003 => Hit => Line [0048] - Col [0016] +MSG 0004004 => Hit => Line [0048] - Col [0023] +MSG 0004005 => Hit => Line [0056] - Col [0000] +MSG 0004006 => Hit => Line [0056] - Col [0008] +MSG 0004007 => Hit => Line [0056] - Col [0016] +MSG 0004008 => Hit => Line [0056] - Col [0023] +MSG 0004009 => Hit => Line [0064] - Col [0000] +MSG 0004010 => Hit => Line [0064] - Col [0008] +MSG 0004011 => Hit => Line [0064] - Col [0016] +MSG 0004012 => Hit => Line [0064] - Col [0023] +MSG 0004013 => Hit => Line [0072] - Col [0000] +MSG 0004014 => Hit => Line [0072] - Col [0008] +MSG 0004015 => Hit => Line [0072] - Col [0016] +MSG 0004016 => Hit => Line [0072] - Col [0023] +MSG 0004017 => Hit => Line [0080] - Col [0000] +MSG 0004018 => Hit => Line [0080] - Col [0008] +MSG 0004019 => Hit => Line [0080] - Col [0016] +MSG 0004020 => Hit => Line [0080] - Col [0023] +MSG 0004021 => Hit => Line [0088] - Col [0000] +MSG 0004022 => Hit => Line [0088] - Col [0008] +MSG 0004023 => Hit => Line [0088] - Col [0016] +MSG 0004024 => Hit => Line [0088] - Col [0023] +MSG 0004025 => Hit => Line [0096] - Col [0000] +MSG 0004026 => Hit => Line [0096] - Col [0008] +MSG 0004027 => Hit => Line [0096] - Col [0016] +MSG 0004028 => Hit => Line [0096] - Col [0023] +MSG 0004029 => Hit => Line [0104] - Col [0000] +MSG 0004030 => Hit => Line [0104] - Col [0008] +MSG 0004031 => Hit => Line [0104] - Col [0016] +MSG 0004032 => Hit => Line [0104] - Col [0023] +MSG 0004033 => Hit => Line [0112] - Col [0000] +MSG 0004034 => Hit => Line [0112] - Col [0008] +MSG 0004035 => Hit => Line [0112] - Col [0016] +MSG 0004036 => Hit => Line [0112] - Col [0023] +MSG 0004037 => Hit => Line [0120] - Col [0000] +MSG 0004038 => Hit => Line [0120] - Col [0008] +MSG 0004039 => Hit => Line [0120] - Col [0016] +MSG 0004040 => Hit => Line [0120] - Col [0023] +MSG 0004041 => Hit => Line [0128] - Col [0000] +MSG 0004042 => Hit => Line [0128] - Col [0008] +MSG 0004043 => Hit => Line [0128] - Col [0016] +MSG 0004044 => Hit => Line [0128] - Col [0023] +MSG 0004045 => Hit => Line [0136] - Col [0000] +MSG 0004046 => Hit => Line [0136] - Col [0008] +MSG 0004047 => Hit => Line [0136] - Col [0016] +MSG 0004048 => Hit => Line [0136] - Col [0023] +MSG 0004049 => Hit => Line [0144] - Col [0000] +MSG 0004050 => Hit => Line [0144] - Col [0008] +MSG 0004051 => Hit => Line [0144] - Col [0016] +MSG 0004052 => Hit => Line [0144] - Col [0023] +MSG 0004053 => Hit => Line [0152] - Col [0000] +MSG 0004054 => Hit => Line [0152] - Col [0008] +MSG 0004055 => Hit => Line [0152] - Col [0016] +MSG 0004056 => Hit => Line [0152] - Col [0023] +MSG 0004057 => Hit => Line [0160] - Col [0000] +MSG 0004058 => Hit => Line [0160] - Col [0008] +MSG 0004059 => Hit => Line [0160] - Col [0016] +MSG 0004060 => Hit => Line [0160] - Col [0023] +MSG 0004061 => Hit => Line [0168] - Col [0000] +MSG 0004062 => Hit => Line [0168] - Col [0008] +MSG 0004063 => Hit => Line [0168] - Col [0016] +MSG 0004064 => Hit => Line [0168] - Col [0023] +MSG 0004065 => Hit => Line [0176] - Col [0000] +MSG 0004066 => Hit => Line [0176] - Col [0008] +MSG 0004067 => Hit => Line [0176] - Col [0016] +MSG 0004068 => Hit => Line [0176] - Col [0023] +MSG 0004069 => Hit => Line [0184] - Col [0000] +MSG 0004070 => Hit => Line [0184] - Col [0008] +MSG 0004071 => Hit => Line [0184] - Col [0016] +MSG 0004072 => Hit => Line [0184] - Col [0023] +MSG 0004073 => Hit => Line [0192] - Col [0000] +MSG 0004074 => Hit => Line [0192] - Col [0008] +MSG 0004075 => Hit => Line [0192] - Col [0016] +MSG 0004076 => Hit => Line [0192] - Col [0023] +MSG 0004077 => Hit => Line [0200] - Col [0000] +MSG 0004078 => Hit => Line [0200] - Col [0008] +MSG 0004079 => Hit => Line [0200] - Col [0016] +MSG 0004080 => Hit => Line [0200] - Col [0023] +MSG 0004081 => Hit => Line [0208] - Col [0000] +MSG 0004082 => Hit => Line [0208] - Col [0008] +MSG 0004083 => Hit => Line [0208] - Col [0016] +MSG 0004084 => Hit => Line [0208] - Col [0023] +MSG 0004085 => Hit => Line [0216] - Col [0000] +MSG 0004086 => Hit => Line [0216] - Col [0008] +MSG 0004087 => Hit => Line [0216] - Col [0016] +MSG 0004088 => Hit => Line [0216] - Col [0023] +MSG 0004089 => Hit => Line [0224] - Col [0000] +MSG 0004090 => Hit => Line [0224] - Col [0008] +MSG 0004091 => Hit => Line [0224] - Col [0016] +MSG 0004092 => Hit => Line [0224] - Col [0023] +MSG 0004093 => Hit => Line [0232] - Col [0000] +MSG 0004094 => Hit => Line [0232] - Col [0008] +MSG 0004095 => Hit => Line [0232] - Col [0016] +MSG 0004096 => Hit => Line [0232] - Col [0023] +MSG 0004097 => Hit => Line [0240] - Col [0000] +MSG 0004098 => Hit => Line [0240] - Col [0008] +MSG 0004099 => Hit => Line [0240] - Col [0016] +MSG 0004100 => Hit => Line [0240] - Col [0023] +MSG 0004101 => Hit => Line [0248] - Col [0000] +MSG 0004102 => Hit => Line [0248] - Col [0008] +MSG 0004103 => Hit => Line [0248] - Col [0016] +MSG 0004104 => Hit => Line [0248] - Col [0023] +MSG 0004105 => Hit => Line [0256] - Col [0000] +MSG 0004106 => Hit => Line [0256] - Col [0008] +MSG 0004107 => Hit => Line [0256] - Col [0016] +MSG 0004108 => Hit => Line [0256] - Col [0023] +MSG 0004109 => Hit => Line [0264] - Col [0000] +MSG 0004110 => Hit => Line [0264] - Col [0008] +MSG 0004111 => Hit => Line [0264] - Col [0016] +MSG 0004112 => Hit => Line [0264] - Col [0023] +MSG 0004113 => Hit => Line [0272] - Col [0000] +MSG 0004114 => Hit => Line [0272] - Col [0008] +MSG 0004115 => Hit => Line [0272] - Col [0016] +MSG 0004116 => Hit => Line [0272] - Col [0023] +MSG 0004117 => Hit => Line [0280] - Col [0000] +MSG 0004118 => Hit => Line [0280] - Col [0008] +MSG 0004119 => Hit => Line [0280] - Col [0016] +MSG 0004120 => Hit => Line [0280] - Col [0023] +MSG 0004121 => Hit => Line [0288] - Col [0000] +MSG 0004122 => Hit => Line [0288] - Col [0008] +MSG 0004123 => Hit => Line [0288] - Col [0016] +MSG 0004124 => Hit => Line [0288] - Col [0023] +MSG 0004125 => Hit => Line [0296] - Col [0000] +MSG 0004126 => Hit => Line [0296] - Col [0008] +MSG 0004127 => Hit => Line [0296] - Col [0016] +MSG 0004128 => Hit => Line [0296] - Col [0023] +MSG 0004129 => Hit => Line [0304] - Col [0000] +MSG 0004130 => Hit => Line [0304] - Col [0008] +MSG 0004131 => Hit => Line [0304] - Col [0016] +MSG 0004132 => Hit => Line [0304] - Col [0023] +MSG 0004133 => Hit => Line [0312] - Col [0000] +MSG 0004134 => Hit => Line [0312] - Col [0008] +MSG 0004135 => Hit => Line [0312] - Col [0016] +MSG 0004136 => Hit => Line [0312] - Col [0023] +MSG 0004137 => Hit => Line [0320] - Col [0000] +MSG 0004138 => Hit => Line [0320] - Col [0008] +MSG 0004139 => Hit => Line [0320] - Col [0016] +MSG 0004140 => Hit => Line [0320] - Col [0023] +MSG 0004141 => Hit => Line [0328] - Col [0000] +MSG 0004142 => Hit => Line [0328] - Col [0008] +MSG 0004143 => Hit => Line [0328] - Col [0016] +MSG 0004144 => Hit => Line [0328] - Col [0023] +MSG 0004145 => Hit => Line [0336] - Col [0000] +MSG 0004146 => Hit => Line [0336] - Col [0008] +MSG 0004147 => Hit => Line [0336] - Col [0016] +MSG 0004148 => Hit => Line [0336] - Col [0023] +MSG 0004149 => Hit => Line [0344] - Col [0000] +MSG 0004150 => Hit => Line [0344] - Col [0008] +MSG 0004151 => Hit => Line [0344] - Col [0016] +MSG 0004152 => Hit => Line [0344] - Col [0023] +MSG 0004153 => Hit => Line [0352] - Col [0000] +MSG 0004154 => Hit => Line [0352] - Col [0008] +MSG 0004155 => Hit => Line [0352] - Col [0016] +MSG 0004156 => Hit => Line [0352] - Col [0023] +MSG 0004157 => Hit => Line [0360] - Col [0000] +MSG 0004158 => Hit => Line [0360] - Col [0008] +MSG 0004159 => Hit => Line [0360] - Col [0016] +MSG 0004160 => Hit => Line [0360] - Col [0023] +MSG 0004161 => Hit => Line [0368] - Col [0000] +MSG 0004162 => Hit => Line [0368] - Col [0008] +MSG 0004163 => Hit => Line [0368] - Col [0016] +MSG 0004164 => Hit => Line [0368] - Col [0023] +MSG 0004165 => Hit => Line [0376] - Col [0000] +MSG 0004166 => Hit => Line [0376] - Col [0008] +MSG 0004167 => Hit => Line [0376] - Col [0016] +MSG 0004168 => Hit => Line [0376] - Col [0023] +MSG 0004169 => Hit => Line [0384] - Col [0000] +MSG 0004170 => Hit => Line [0384] - Col [0008] +MSG 0004171 => Hit => Line [0384] - Col [0016] +MSG 0004172 => Hit => Line [0384] - Col [0023] +MSG 0004173 => Hit => Line [0392] - Col [0000] +MSG 0004174 => Hit => Line [0392] - Col [0008] +MSG 0004175 => Hit => Line [0392] - Col [0016] +MSG 0004176 => Hit => Line [0392] - Col [0023] +MSG 0004177 => Hit => Line [0400] - Col [0000] +MSG 0004178 => Hit => Line [0400] - Col [0008] +MSG 0004179 => Hit => Line [0400] - Col [0016] +MSG 0004180 => Hit => Line [0400] - Col [0023] +MSG 0004181 => Hit => Line [0408] - Col [0000] +MSG 0004182 => Hit => Line [0408] - Col [0008] +MSG 0004183 => Hit => Line [0408] - Col [0016] +MSG 0004184 => Hit => Line [0408] - Col [0023] +MSG 0004185 => +MSG 0004186 => =================================================================================== +MSG 0004187 => Fsbb0 No 5 +MSG 0004188 => =================================================================================== +MSG 0004189 => Conv : VOneMapsSzW32=312 - TotSzW32=1872 +MSG 0004190 => Conv : VDataW30Length=312 +MSG 0004191 => *************************************************************************** +MSG 0004192 => * FSBB M [5] : Coordinates pixels with hit * +MSG 0004193 => *************************************************************************** +MSG 0004194 => Hit => Line [0000] - Col [0000] +MSG 0004195 => Hit => Line [0000] - Col [0032] +MSG 0004196 => Hit => Line [0000] - Col [0064] +MSG 0004197 => Hit => Line [0000] - Col [0096] +MSG 0004198 => Hit => Line [0000] - Col [0128] +MSG 0004199 => Hit => Line [0008] - Col [0000] +MSG 0004200 => Hit => Line [0008] - Col [0032] +MSG 0004201 => Hit => Line [0008] - Col [0064] +MSG 0004202 => Hit => Line [0008] - Col [0096] +MSG 0004203 => Hit => Line [0008] - Col [0128] +MSG 0004204 => Hit => Line [0016] - Col [0000] +MSG 0004205 => Hit => Line [0016] - Col [0032] +MSG 0004206 => Hit => Line [0016] - Col [0064] +MSG 0004207 => Hit => Line [0016] - Col [0096] +MSG 0004208 => Hit => Line [0016] - Col [0128] +MSG 0004209 => Hit => Line [0024] - Col [0000] +MSG 0004210 => Hit => Line [0024] - Col [0032] +MSG 0004211 => Hit => Line [0024] - Col [0064] +MSG 0004212 => Hit => Line [0024] - Col [0096] +MSG 0004213 => Hit => Line [0024] - Col [0128] +MSG 0004214 => Hit => Line [0032] - Col [0000] +MSG 0004215 => Hit => Line [0032] - Col [0032] +MSG 0004216 => Hit => Line [0032] - Col [0064] +MSG 0004217 => Hit => Line [0032] - Col [0096] +MSG 0004218 => Hit => Line [0032] - Col [0128] +MSG 0004219 => Hit => Line [0040] - Col [0000] +MSG 0004220 => Hit => Line [0040] - Col [0032] +MSG 0004221 => Hit => Line [0040] - Col [0064] +MSG 0004222 => Hit => Line [0040] - Col [0096] +MSG 0004223 => Hit => Line [0040] - Col [0128] +MSG 0004224 => Hit => Line [0048] - Col [0000] +MSG 0004225 => Hit => Line [0048] - Col [0032] +MSG 0004226 => Hit => Line [0048] - Col [0064] +MSG 0004227 => Hit => Line [0048] - Col [0096] +MSG 0004228 => Hit => Line [0048] - Col [0128] +MSG 0004229 => Hit => Line [0056] - Col [0000] +MSG 0004230 => Hit => Line [0056] - Col [0032] +MSG 0004231 => Hit => Line [0056] - Col [0064] +MSG 0004232 => Hit => Line [0056] - Col [0096] +MSG 0004233 => Hit => Line [0056] - Col [0128] +MSG 0004234 => Hit => Line [0064] - Col [0000] +MSG 0004235 => Hit => Line [0064] - Col [0032] +MSG 0004236 => Hit => Line [0064] - Col [0064] +MSG 0004237 => Hit => Line [0064] - Col [0096] +MSG 0004238 => Hit => Line [0064] - Col [0128] +MSG 0004239 => Hit => Line [0072] - Col [0000] +MSG 0004240 => Hit => Line [0072] - Col [0032] +MSG 0004241 => Hit => Line [0072] - Col [0064] +MSG 0004242 => Hit => Line [0072] - Col [0096] +MSG 0004243 => Hit => Line [0072] - Col [0128] +MSG 0004244 => Hit => Line [0080] - Col [0000] +MSG 0004245 => Hit => Line [0080] - Col [0032] +MSG 0004246 => Hit => Line [0080] - Col [0064] +MSG 0004247 => Hit => Line [0080] - Col [0096] +MSG 0004248 => Hit => Line [0080] - Col [0128] +MSG 0004249 => Hit => Line [0088] - Col [0000] +MSG 0004250 => Hit => Line [0088] - Col [0032] +MSG 0004251 => Hit => Line [0088] - Col [0064] +MSG 0004252 => Hit => Line [0088] - Col [0096] +MSG 0004253 => Hit => Line [0088] - Col [0128] +MSG 0004254 => Hit => Line [0096] - Col [0000] +MSG 0004255 => Hit => Line [0096] - Col [0032] +MSG 0004256 => Hit => Line [0096] - Col [0064] +MSG 0004257 => Hit => Line [0096] - Col [0096] +MSG 0004258 => Hit => Line [0096] - Col [0128] +MSG 0004259 => Hit => Line [0104] - Col [0000] +MSG 0004260 => Hit => Line [0104] - Col [0032] +MSG 0004261 => Hit => Line [0104] - Col [0064] +MSG 0004262 => Hit => Line [0104] - Col [0096] +MSG 0004263 => Hit => Line [0104] - Col [0128] +MSG 0004264 => Hit => Line [0112] - Col [0000] +MSG 0004265 => Hit => Line [0112] - Col [0032] +MSG 0004266 => Hit => Line [0112] - Col [0064] +MSG 0004267 => Hit => Line [0112] - Col [0096] +MSG 0004268 => Hit => Line [0112] - Col [0128] +MSG 0004269 => Hit => Line [0120] - Col [0000] +MSG 0004270 => Hit => Line [0120] - Col [0032] +MSG 0004271 => Hit => Line [0120] - Col [0064] +MSG 0004272 => Hit => Line [0120] - Col [0096] +MSG 0004273 => Hit => Line [0120] - Col [0128] +MSG 0004274 => Hit => Line [0128] - Col [0000] +MSG 0004275 => Hit => Line [0128] - Col [0032] +MSG 0004276 => Hit => Line [0128] - Col [0064] +MSG 0004277 => Hit => Line [0128] - Col [0096] +MSG 0004278 => Hit => Line [0128] - Col [0128] +MSG 0004279 => Hit => Line [0136] - Col [0000] +MSG 0004280 => Hit => Line [0136] - Col [0032] +MSG 0004281 => Hit => Line [0136] - Col [0064] +MSG 0004282 => Hit => Line [0136] - Col [0096] +MSG 0004283 => Hit => Line [0136] - Col [0128] +MSG 0004284 => Hit => Line [0144] - Col [0000] +MSG 0004285 => Hit => Line [0144] - Col [0032] +MSG 0004286 => Hit => Line [0144] - Col [0064] +MSG 0004287 => Hit => Line [0144] - Col [0096] +MSG 0004288 => Hit => Line [0144] - Col [0128] +MSG 0004289 => Hit => Line [0152] - Col [0000] +MSG 0004290 => Hit => Line [0152] - Col [0032] +MSG 0004291 => Hit => Line [0152] - Col [0064] +MSG 0004292 => Hit => Line [0152] - Col [0096] +MSG 0004293 => Hit => Line [0152] - Col [0128] +MSG 0004294 => Hit => Line [0160] - Col [0000] +MSG 0004295 => Hit => Line [0160] - Col [0032] +MSG 0004296 => Hit => Line [0160] - Col [0064] +MSG 0004297 => Hit => Line [0160] - Col [0096] +MSG 0004298 => Hit => Line [0160] - Col [0128] +MSG 0004299 => Hit => Line [0168] - Col [0000] +MSG 0004300 => Hit => Line [0168] - Col [0032] +MSG 0004301 => Hit => Line [0168] - Col [0064] +MSG 0004302 => Hit => Line [0168] - Col [0096] +MSG 0004303 => Hit => Line [0168] - Col [0128] +MSG 0004304 => Hit => Line [0176] - Col [0000] +MSG 0004305 => Hit => Line [0176] - Col [0032] +MSG 0004306 => Hit => Line [0176] - Col [0064] +MSG 0004307 => Hit => Line [0176] - Col [0096] +MSG 0004308 => Hit => Line [0176] - Col [0128] +MSG 0004309 => Hit => Line [0184] - Col [0000] +MSG 0004310 => Hit => Line [0184] - Col [0032] +MSG 0004311 => Hit => Line [0184] - Col [0064] +MSG 0004312 => Hit => Line [0184] - Col [0096] +MSG 0004313 => Hit => Line [0184] - Col [0128] +MSG 0004314 => Hit => Line [0192] - Col [0000] +MSG 0004315 => Hit => Line [0192] - Col [0032] +MSG 0004316 => Hit => Line [0192] - Col [0064] +MSG 0004317 => Hit => Line [0192] - Col [0096] +MSG 0004318 => Hit => Line [0192] - Col [0128] +MSG 0004319 => Hit => Line [0200] - Col [0000] +MSG 0004320 => Hit => Line [0200] - Col [0032] +MSG 0004321 => Hit => Line [0200] - Col [0064] +MSG 0004322 => Hit => Line [0200] - Col [0096] +MSG 0004323 => Hit => Line [0200] - Col [0128] +MSG 0004324 => Hit => Line [0208] - Col [0000] +MSG 0004325 => Hit => Line [0208] - Col [0032] +MSG 0004326 => Hit => Line [0208] - Col [0064] +MSG 0004327 => Hit => Line [0208] - Col [0096] +MSG 0004328 => Hit => Line [0208] - Col [0128] +MSG 0004329 => Hit => Line [0216] - Col [0000] +MSG 0004330 => Hit => Line [0216] - Col [0032] +MSG 0004331 => Hit => Line [0216] - Col [0064] +MSG 0004332 => Hit => Line [0216] - Col [0096] +MSG 0004333 => Hit => Line [0216] - Col [0128] +MSG 0004334 => Hit => Line [0224] - Col [0000] +MSG 0004335 => Hit => Line [0224] - Col [0032] +MSG 0004336 => Hit => Line [0224] - Col [0064] +MSG 0004337 => Hit => Line [0224] - Col [0096] +MSG 0004338 => Hit => Line [0224] - Col [0128] +MSG 0004339 => Hit => Line [0232] - Col [0000] +MSG 0004340 => Hit => Line [0232] - Col [0032] +MSG 0004341 => Hit => Line [0232] - Col [0064] +MSG 0004342 => Hit => Line [0232] - Col [0096] +MSG 0004343 => Hit => Line [0232] - Col [0128] +MSG 0004344 => Hit => Line [0240] - Col [0000] +MSG 0004345 => Hit => Line [0240] - Col [0032] +MSG 0004346 => Hit => Line [0240] - Col [0064] +MSG 0004347 => Hit => Line [0240] - Col [0096] +MSG 0004348 => Hit => Line [0240] - Col [0128] +MSG 0004349 => Hit => Line [0248] - Col [0000] +MSG 0004350 => Hit => Line [0248] - Col [0032] +MSG 0004351 => Hit => Line [0248] - Col [0064] +MSG 0004352 => Hit => Line [0248] - Col [0096] +MSG 0004353 => Hit => Line [0248] - Col [0128] +MSG 0004354 => Hit => Line [0256] - Col [0000] +MSG 0004355 => Hit => Line [0256] - Col [0032] +MSG 0004356 => Hit => Line [0256] - Col [0064] +MSG 0004357 => Hit => Line [0256] - Col [0096] +MSG 0004358 => Hit => Line [0256] - Col [0128] +MSG 0004359 => Hit => Line [0264] - Col [0000] +MSG 0004360 => Hit => Line [0264] - Col [0032] +MSG 0004361 => Hit => Line [0264] - Col [0064] +MSG 0004362 => Hit => Line [0264] - Col [0096] +MSG 0004363 => Hit => Line [0264] - Col [0128] +MSG 0004364 => Hit => Line [0272] - Col [0000] +MSG 0004365 => Hit => Line [0272] - Col [0032] +MSG 0004366 => Hit => Line [0272] - Col [0064] +MSG 0004367 => Hit => Line [0272] - Col [0096] +MSG 0004368 => Hit => Line [0272] - Col [0128] +MSG 0004369 => Hit => Line [0280] - Col [0000] +MSG 0004370 => Hit => Line [0280] - Col [0032] +MSG 0004371 => Hit => Line [0280] - Col [0064] +MSG 0004372 => Hit => Line [0280] - Col [0096] +MSG 0004373 => Hit => Line [0280] - Col [0128] +MSG 0004374 => Hit => Line [0288] - Col [0000] +MSG 0004375 => Hit => Line [0288] - Col [0032] +MSG 0004376 => Hit => Line [0288] - Col [0064] +MSG 0004377 => Hit => Line [0288] - Col [0096] +MSG 0004378 => Hit => Line [0288] - Col [0128] +MSG 0004379 => Hit => Line [0296] - Col [0000] +MSG 0004380 => Hit => Line [0296] - Col [0032] +MSG 0004381 => Hit => Line [0296] - Col [0064] +MSG 0004382 => Hit => Line [0296] - Col [0096] +MSG 0004383 => Hit => Line [0296] - Col [0128] +MSG 0004384 => Hit => Line [0304] - Col [0000] +MSG 0004385 => Hit => Line [0304] - Col [0032] +MSG 0004386 => Hit => Line [0304] - Col [0064] +MSG 0004387 => Hit => Line [0304] - Col [0096] +MSG 0004388 => Hit => Line [0304] - Col [0128] +MSG 0004389 => Hit => Line [0312] - Col [0000] +MSG 0004390 => Hit => Line [0312] - Col [0032] +MSG 0004391 => Hit => Line [0312] - Col [0064] +MSG 0004392 => Hit => Line [0312] - Col [0096] +MSG 0004393 => Hit => Line [0312] - Col [0128] +MSG 0004394 => Hit => Line [0320] - Col [0000] +MSG 0004395 => Hit => Line [0320] - Col [0032] +MSG 0004396 => Hit => Line [0320] - Col [0064] +MSG 0004397 => Hit => Line [0320] - Col [0096] +MSG 0004398 => Hit => Line [0320] - Col [0128] +MSG 0004399 => Hit => Line [0328] - Col [0000] +MSG 0004400 => Hit => Line [0328] - Col [0032] +MSG 0004401 => Hit => Line [0328] - Col [0064] +MSG 0004402 => Hit => Line [0328] - Col [0096] +MSG 0004403 => Hit => Line [0328] - Col [0128] +MSG 0004404 => Hit => Line [0336] - Col [0000] +MSG 0004405 => Hit => Line [0336] - Col [0032] +MSG 0004406 => Hit => Line [0336] - Col [0064] +MSG 0004407 => Hit => Line [0336] - Col [0096] +MSG 0004408 => Hit => Line [0336] - Col [0128] +MSG 0004409 => Hit => Line [0344] - Col [0000] +MSG 0004410 => Hit => Line [0344] - Col [0032] +MSG 0004411 => Hit => Line [0344] - Col [0064] +MSG 0004412 => Hit => Line [0344] - Col [0096] +MSG 0004413 => Hit => Line [0344] - Col [0128] +MSG 0004414 => Hit => Line [0352] - Col [0000] +MSG 0004415 => Hit => Line [0352] - Col [0032] +MSG 0004416 => Hit => Line [0352] - Col [0064] +MSG 0004417 => Hit => Line [0352] - Col [0096] +MSG 0004418 => Hit => Line [0352] - Col [0128] +MSG 0004419 => Hit => Line [0360] - Col [0000] +MSG 0004420 => Hit => Line [0360] - Col [0032] +MSG 0004421 => Hit => Line [0360] - Col [0064] +MSG 0004422 => Hit => Line [0360] - Col [0096] +MSG 0004423 => Hit => Line [0360] - Col [0128] +MSG 0004424 => Hit => Line [0368] - Col [0000] +MSG 0004425 => Hit => Line [0368] - Col [0032] +MSG 0004426 => Hit => Line [0368] - Col [0064] +MSG 0004427 => Hit => Line [0368] - Col [0096] +MSG 0004428 => Hit => Line [0368] - Col [0128] +MSG 0004429 => Hit => Line [0376] - Col [0000] +MSG 0004430 => Hit => Line [0376] - Col [0032] +MSG 0004431 => Hit => Line [0376] - Col [0064] +MSG 0004432 => Hit => Line [0376] - Col [0096] +MSG 0004433 => Hit => Line [0376] - Col [0128] +MSG 0004434 => Hit => Line [0384] - Col [0000] +MSG 0004435 => Hit => Line [0384] - Col [0032] +MSG 0004436 => Hit => Line [0384] - Col [0064] +MSG 0004437 => Hit => Line [0384] - Col [0096] +MSG 0004438 => Hit => Line [0384] - Col [0128] +MSG 0004439 => Hit => Line [0392] - Col [0000] +MSG 0004440 => Hit => Line [0392] - Col [0032] +MSG 0004441 => Hit => Line [0392] - Col [0064] +MSG 0004442 => Hit => Line [0392] - Col [0096] +MSG 0004443 => Hit => Line [0392] - Col [0128] +MSG 0004444 => Hit => Line [0400] - Col [0000] +MSG 0004445 => Hit => Line [0400] - Col [0032] +MSG 0004446 => Hit => Line [0400] - Col [0064] +MSG 0004447 => Hit => Line [0400] - Col [0096] +MSG 0004448 => Hit => Line [0400] - Col [0128] +MSG 0004449 => Hit => Line [0408] - Col [0000] +MSG 0004450 => Hit => Line [0408] - Col [0032] +MSG 0004451 => Hit => Line [0408] - Col [0064] +MSG 0004452 => Hit => Line [0408] - Col [0096] +MSG 0004453 => Hit => Line [0408] - Col [0128] +MSG 0004454 => +MSG 0004455 => =================================================================================== diff --git a/include/pxi_daq_lib_v.2.1/msg.typ b/include/pxi_daq_lib_v.2.1/msg.typ new file mode 100755 index 0000000..0f62f1d --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/msg.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.typ +Goal : Types definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef MSG_TYP +#define MSG_TYP + +typedef SInt32 (*TUserMsgFunc) ( char* Msg ); + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/msg.var b/include/pxi_daq_lib_v.2.1/msg.var new file mode 100755 index 0000000..2e8fc8b --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/msg.var @@ -0,0 +1,59 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.var +Goal : Variables definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_VAR +#define MSG_VAR + +/* + +EXTERN VAR_STATIC FILE* MSG_VGALogFile[MSG_CHAN_NB] VAR_INIT_A2(NULL,NULL); +EXTERN VAR_STATIC SInt8 MSG_VGALogClosed[MSG_CHAN_NB] VAR_INIT_A2(1,1); +EXTERN VAR_STATIC SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt8 MSG_VGADontLog[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ] VAR_INIT_A2("/dd/tmp/pc/msg.txt","/dev/rmsg"); +EXTERN VAR_STATIC char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ]; +EXTERN VAR_STATIC SInt8 MSG_VGFileLogLevel VAR_INIT (0); +EXTERN VAR_STATIC SInt8 MSG_VGUserLogLevel VAR_INIT (0); +EXTERN VAR_STATIC TUserMsgFunc MSG_VGUserMsgFunc VAR_INIT (NULL); + +*/ + +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, FILE* MSG_VGALogFile[MSG_CHAN_NB] , NULL, NULL ); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogClosed[MSG_CHAN_NB] , 1, 1); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGADontLog[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ], "/dd/tmp/pc/msg.txt","/dev/rmsg" ); + + +VAR_DCL ( EXTERN, VAR_STATIC, char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ] ); + +/* 07/04/2007 Replace macro MSG_OUT by a variable which points to MSG_VGAStrMsg[MSG_CHAN_MSG] because of ROOT CINT macros limitations */ + + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char* MSG_OUT , MSG_VGAStrMsg[MSG_CHAN_MSG] ); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGFileLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGUserLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, TUserMsgFunc MSG_VGUserMsgFunc , NULL); + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/pipe.c b/include/pxi_daq_lib_v.2.1/pipe.c new file mode 100755 index 0000000..24c9e01 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/pipe.c @@ -0,0 +1,1142 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/pipe/ +Goal : Functions of pipe unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef PIP_C +#define PIP_C + +/******************************************************************************* +Prototype : SInt32 PIP_FBegin ( SInt8 ObjId, + : SInt32 SendPipeId, SInt32 SendBuffSz, PIP_TSendFunc PtSendFunc, + : SInt32 RecPipeId , SInt32 RecBuffSz , PIP_TGetFunc PtGetFunc ) + : +Goal : Initialize the unit, must be called before using any unit function. + : +Inputs : ObjId - the Object identifier ( the unit can handle many objects ) + : SendPipeId - a number ( 1 to n ) which identify the data sender pipe + : SendBuffSz - the maximal block size for the sender pipe + : PIP_TSendFunc - a pointer to the low level sender function + : RecPipeId - a number ( 1 to n ) which identify the data receiver pipe + : RecBuffSz - the maximal block size for the receiver pipe + : PIP_TGetFunc - a pointer to the low level receiver function + : +Ouputs : O if ok, negative number if inialization fails ... +Globals : +Remark : +Level : This is a user level function +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FBegin ( SInt8 ObjId, + SInt32 SendPipeId, SInt32 SendBuffSz, PIP_TSendFunc PtSendFunc, + SInt32 RecPipeId , SInt32 RecBuffSz , PIP_TGetFunc PtGetFunc ) { + + PIP_TContext* VPt; + + PIP_CHK_OBJ_ID (ObjId); + + VPt = &PIP_VGContext[ObjId]; + + + VPt->PtSendFunc = NULL; + VPt->PtSendBuff = NULL; + VPt->SendPipeId = -1; + VPt->SendStatus = 0; + VPt->SendBlkIndex = 0; + VPt->SendBlkTotSz = 0; + VPt->SendBlkSz = 0; + VPt->SendTransSz = 0; + VPt->SendDataSzDone = 0; + + + VPt->PtGetFunc = NULL; + VPt->PtRecBuff = NULL; + VPt->RecPipeId = -1; + VPt->RecStatus = 0; + VPt->RecBlkIndex = 0; + VPt->RecBlkTotSz = 0; + VPt->RecBlkSz = 0; + VPt->RecTransSz = 0; + VPt->RecDataSzDone = 0; + + + if ( SendBuffSz > PIP_MAX_SEND_BUFF_SZ ) { + err_retfail ( -1, (ERR_OUT,"SendBuffSz=%d > %d", SendBuffSz, PIP_MAX_SEND_BUFF_SZ ) ); + } + + VPt->SendBlkSz = SendBuffSz; + VPt->SendBlkTotSz = SendBuffSz + (PIP_DATA_HEAD_W32SZ * 4); + + if ( ( VPt->PtSendBuff = (SInt32*) malloc (VPt->SendBlkTotSz) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,"Malloc of SendBuff ( %d bytes ) fail !", VPt->SendBlkTotSz) ); + } + + VPt->SendPipeId = SendPipeId; + + if ( RecBuffSz > PIP_MAX_REC_BUFF_SZ ) { + err_retfail ( -1, (ERR_OUT,"RecBuffSz=%d > %d", RecBuffSz, PIP_MAX_REC_BUFF_SZ ) ); + } + + VPt->RecBlkSz = RecBuffSz; + VPt->RecBlkTotSz = RecBuffSz + (PIP_DATA_HEAD_W32SZ * 4); + + if ( ( VPt->PtRecBuff = (SInt32*) malloc (VPt->RecBlkTotSz) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,"Malloc of RecBuff ( %d bytes ) fail !", VPt->RecBlkTotSz) ); + } + + VPt->RecPipeId = RecPipeId; + + VPt->PtSendFunc = PtSendFunc; + VPt->PtGetFunc = PtGetFunc; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : SInt32 PIP_FEnd ( SInt8 ObjId ) + : +Goal : Close unit ( free allocated memory, ... ) must be called at program end. +Inputs : The object identifier. +Ouputs : 0 is ok, negative value in case of error. +Globals : +Remark : Now, this function must be called for each object, next version + : will scan itself for allocated objects and remove them. +Level : This is a user level function +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FEnd ( SInt8 ObjId ) { + + PIP_TContext* VPt; + + PIP_CHK_OBJ_ID (ObjId); + + VPt = &PIP_VGContext[ObjId]; + + if ( VPt->PtSendBuff != NULL ) { + free ( VPt->PtSendBuff ); + } + + if ( VPt->PtRecBuff != NULL ) { + free ( VPt->PtRecBuff ); + } + + return (0); +} + +/******************************************************************************* +Prototype : char* PIP_FStrSendStatus ( SInt8 ObjId ) +Goal : Return a string with sender side status of object. +Inputs : The object identifier. +Ouputs : A pointer to the string ( stored in a function static variable ). +Globals : +Remark : +Level : This is a user level function +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +char* PIP_FStrSendStatus ( SInt8 ObjId ) { + + static char VStr[255]; + PIP_TContext* VPt; + + if ( ObjId >= PIP_OBJ_NB ) { + err_error (( ERR_OUT, "ObjId=%d >= PIP_OBJ_NB=%d", ObjId, PIP_OBJ_NB )); + return (NULL); + } + + VPt = &PIP_VGContext[ObjId]; + + sprintf ( VStr, "Obj=%d - Status=%d - Block alloc Sz=%d - Transaction Sz=%d - Block Sz=%d - Send sz done=%d - Block index=%d", ObjId, VPt->SendStatus, VPt->SendBlkTotSz, VPt->SendTransSz, VPt->SendBlkSz, VPt->SendDataSzDone, VPt->SendBlkIndex ); + + return (VStr); +} + +/******************************************************************************* +Prototype : char* PIP_FStrGetStatus ( SInt8 ObjId ) +Goal : Return a string with receiver side status of object. +Inputs : The object identifier. +Ouputs : A pointer to the string ( stored in a function static variable ). +Globals : +Remark : +Level : This is a user level function +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +char* PIP_FStrGetStatus ( SInt8 ObjId ) { + + static char VStr[255]; + PIP_TContext* VPt; + + if ( ObjId >= PIP_OBJ_NB ) { + err_error (( ERR_OUT, "ObjId=%d >= PIP_OBJ_NB=%d", ObjId, PIP_OBJ_NB )); + return (NULL); + } + + VPt = &PIP_VGContext[ObjId]; + + sprintf ( VStr, "Obj=%d - Status=%d - Transaction Sz=%d - Block Sz=%d - Received sz done=%d - Block index=%d", ObjId, VPt->RecStatus, VPt->RecTransSz, VPt->RecBlkSz, VPt->RecDataSzDone, VPt->RecBlkIndex ); + + return (VStr); +} + + +/******************************************************************************* +Prototype : SInt32 PIP_FSendBlk ( SInt8 ObjId, UInt8 FirstBlk, SInt32 MsgType + : UInt32 *PtSrc, UInt32 BlkSz, UInt32 TotSz ) + : +Goal : Send the block of BlkSz bytes pointed by PtSrc. + : +Inputs : ObjId - object identifer + : FirstBlk - 1 if it's the first block of a transaction, else 0. + : MsgTYpe - type of message + : PIP_TRANS_MSG_TYPE_COMMAND, + : PIP_TRANS_MSG_TYPE_DATA + : PtSrc - the block pointer + : BlkSz - the block size + : TotSz - the total transaction size + : +Ouputs : 0 if block send with success, + : 1 if it's the transaction end ( last block to send ), + : negative value in case of error. +Globals : +Remark : A copy of the block in object memory is done before starting to send, + : therefore you can free the source block when the function returns, + : the bloc is bufferised. +Level : This is a UNIT PRIVATE level function. +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FSendBlk ( SInt8 ObjId, UInt8 FirstBlk, SInt32 MsgType, /* UInt32 */ UInt8* PtSrc, UInt32 BlkSz, UInt32 TotSz ) { + + SInt32 VRet; + PIP_TContext* VPt; + + PIP_CHK_OBJ_ID (ObjId); + + + VPt = &PIP_VGContext[ObjId]; + + if ( VPt->PtSendFunc == NULL ) { + err_retfail ( -1, (ERR_OUT,"No SendFunction connected !") ); + } + + if ( BlkSz > VPt->SendBlkSz ) { + err_retfail ( -1, (ERR_OUT,"BlkSz=%d > Buffer size=%d", BlkSz, VPt->SendBlkSz ) ); + } + + VPt->PtSendBuff[PIP_TRANS_MSG_TYPE_HD_INDEX] = MsgType; + + /* First block => write PIP_TRANS_TAG_BEGIN */ + + if ( FirstBlk ) { + VPt->SendTransSz = TotSz; + VPt->SendBlkIndex = 0; + VPt->SendDataSzDone = 0; + VPt->SendStatus = PIP_TRANS_STATUS_FIRST_BLK; + VPt->PtSendBuff[PIP_TRANS_TAG_HD_INDEX] = PIP_TRANS_TAG_BEGIN; + } + + /* Next blocks => write block no */ + + else { + ++(VPt->SendBlkIndex); + VPt->SendStatus = PIP_TRANS_STATUS_RUN; + VPt->PtSendBuff[PIP_TRANS_TAG_HD_INDEX] = VPt->SendBlkIndex; + } + + VPt->PtSendBuff[PIP_TRANS_TOT_SZ_HD_INDEX] = TotSz; + VPt->PtSendBuff[PIP_TRANS_BLK_SZ_HD_INDEX] = BlkSz; + + memcpy ( &(VPt->PtSendBuff[PIP_DATA_INDEX]), PtSrc, BlkSz ); + + + VRet = VPt->PtSendFunc ( ObjId, VPt->SendPipeId, VPt->SendStatus /* TransStatus */, NULL /* PtExtParam */, VPt->PtSendBuff, VPt->SendBlkTotSz, -1 /* MaxDataSz */ ); + + + err_retfail ( VRet, (ERR_OUT,"SendFunction fail => return %d", VRet) ); + + VPt->SendDataSzDone += BlkSz; + + /* If end of transcation => return 1 */ + + if ( VPt->SendDataSzDone >= VPt->SendTransSz ) { + err_retval ( 1, ( ERR_OUT, "Transaction done %d data bytes send", VPt->SendTransSz ) ); + } + + /* Else, return 0 */ + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : SInt32 PIP_FPutDatas ( SInt8 ObjId, SInt8 MultiExec, SInt32 MsgType, + : UInt8 *PtSrc, SInt32 BlkSz, UInt32 TotSz ) + : +Goal : Send datas, this is the highest user level function in sender mode. +Inputs : ObjId - the object identifier + : MultiExec - if 0 the function will send all datas and return + : - if 1, it will send one block and return, then you need + : - to call it until it returns 1 + : MsgTYpe - type of message + : PIP_TRANS_MSG_TYPE_COMMAND, + : PIP_TRANS_MSG_TYPE_DATA + : PtSrc - the source datas pointer + : BlkSz - the size in which the datas will be splitted + : TotSz - the total datas size to send + : +Ouputs : 0 if block send ( MultiExec mode - should not happen otherwise ) + : 1 if end of transaction reached with success + : negative value in case of error +Globals : +Remark : BlkSz must be <= SendBuffSz configured in FBegin function, otherwise + : the function will fail, ofcourse it can be less than SendBuffSz. + : If BlkSz < 0 => default value SendBlkSz configured by FBegin is used +Level : This is a user level function. +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FPutDatas ( SInt8 ObjId, SInt8 MultiExec, SInt32 MsgType, UInt8 *PtSrc, SInt32 BlkSz, UInt32 TotSz ) { + + SInt32 VRet; + static SInt32 VCallCnt = 0; + static SInt8 VFirstBlk; + static SInt32 Vi; + static SInt32 VRemSz; + static SInt32 VBlkSz; + PIP_TContext* VPt; + + PIP_CHK_OBJ_ID (ObjId); + + VPt = &PIP_VGContext[ObjId]; + + /* Overwrite BlkSz with default if < 0 - MUST BE DONE HERE & NOT LATER ! */ + + if ( BlkSz < 0 ) { + BlkSz = VPt->SendBlkSz; + } + + VPt->SendMsgType = MsgType; /* Copy of MsgType only for debug ( not usefull ) */ + + /* Initialization on first call */ + + if ( VCallCnt == 0 ) { + Vi = 0; + VFirstBlk = 1; + VRemSz = TotSz; + VBlkSz = BlkSz; + } + + do { + + if ( VRemSz < BlkSz ) { + VBlkSz = VRemSz; + } + + + VRet = PIP_FSendBlk ( ObjId, VFirstBlk /* FirstBlk */ , MsgType, &PtSrc[Vi*BlkSz], VBlkSz, TotSz ); + VFirstBlk = 0; + Vi++; + + VRemSz -= VBlkSz; + + } while ( (VRet == 0) && (MultiExec == 0) ); + + ++VCallCnt; + + if ( VRet == 1 ) { + VCallCnt = 0; + err_retval ( 1, ( ERR_OUT, "Transaction finished - %d bytes sent", VPt->SendDataSzDone ) ); + } + + if ( VRet == 0 ) { + err_retok (( ERR_OUT, "" )); + } + + if ( VRet < 0 ) { + VCallCnt = 0; + err_retfail ( -1, (ERR_OUT,"Send datas fail") ); + } + + return (0); +} + +/******************************************************************************* +Prototype : SInt32 PIP_FGetBlk ( SInt8 ObjId, UInt32 *PtDest, UInt32 MaxDestSz, + : UInt32 *PtGetDataSz ) + : +Goal : Get one block and copy it in memory pointed by PtDest + : +Inputs : ObjId - the object identifier + : PtDest - the destination buffer pointer + : MaxDestSz - the destination buffer size ( to avoid gardening ... ) + : PtGetDataSz - the variable pointed will be set with received block size + : +Ouputs : The function returns + : 0 if one block received + : 1 if transaction if finished ( last block received ) + : -1 => error + : -2 => there is nothing to read ( no block available ) + : + : PtGetDataSz point to received block size +Globals : +Remark : The last block of a transaction can be less than BlockSz, you can + : read it real size with PtGetDataSz. +Level : This is a UNIT PRIVATE level function. +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FGetBlk ( SInt8 ObjId, UInt32 *PtDest, UInt32 MaxDestSz, UInt32 *PtGetDataSz ) { + + SInt32 VRet; + PIP_TContext* VPt; + SInt32 VRecBlkSz; + + PIP_CHK_OBJ_ID (ObjId); + + VPt = &PIP_VGContext[ObjId]; + + if ( VPt->PtGetFunc == NULL ) { + err_retfail ( -1, (ERR_OUT,"No GetFunc connected") ); + } + + VRet = VPt->PtGetFunc ( ObjId, VPt->RecPipeId, -1 /* TransStatus */, NULL /* PtExtParam */, VPt->PtRecBuff, VPt->RecBlkTotSz /* DataSz */, VPt->RecBlkTotSz /* MaxDataSz */ ); + + if ( VRet == -2 ) { + return (-2); + err_warning (( ERR_OUT, "GetFunc fail => because nothing to read" )); + } + + err_retfail ( VRet, (ERR_OUT,"GetFunc fail => return %d", VRet) ); + + if ( VPt->PtRecBuff[PIP_TRANS_TAG_HD_INDEX] == 0 ) { + err_retfail ( -1, (ERR_OUT,"No data available") ); + } + + VPt->RecMsgType = VPt->PtRecBuff[PIP_TRANS_MSG_TYPE_HD_INDEX]; + + /* If this is the first block of a transaction */ + + if ( VPt->PtRecBuff[PIP_TRANS_TAG_HD_INDEX] == PIP_TRANS_TAG_BEGIN ) { + VPt->RecTransSz = VPt->PtRecBuff[PIP_TRANS_TOT_SZ_HD_INDEX]; + VRecBlkSz = VPt->PtRecBuff[PIP_TRANS_BLK_SZ_HD_INDEX]; + VPt->RecBlkIndex = 0; + VPt->RecDataSzDone = 0; + + if ( VRecBlkSz > VPt->RecBlkSz ) { + err_retfail ( -1, (ERR_OUT,"Sender send blocks too bigs=%d bytes > RecBlkSz=%d", VRecBlkSz, VPt->RecBlkSz ) ); + VPt->RecStatus = -1; + } + + VPt->RecStatus = 1; + + } + + /* Else */ + + else { + VRecBlkSz = VPt->PtRecBuff[PIP_TRANS_BLK_SZ_HD_INDEX]; + ++(VPt->RecBlkIndex); + } + + memcpy ( PtDest, &(VPt->PtRecBuff[PIP_DATA_INDEX]), VRecBlkSz ); + + if ( PtGetDataSz != NULL ) { + *PtGetDataSz = VRecBlkSz; + } + + VPt->RecDataSzDone += VRecBlkSz; + + /* If end of transaction => return 1 */ + + if ( VPt->RecDataSzDone >= VPt->RecTransSz ) { + err_retval ( 1, ( ERR_OUT, "Transaction done %d bytes received", VPt->RecTransSz ) ); + } + + /* Else, return */ + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : SInt32 PIP_FGetRecMsgType ( SInt32 ObjId ) + : +Goal : Get message type ( command / data ). This function can be called after + : PIP_FGetDatas BUT NEVER BEFORE ! + : +Inputs : ObjId - the object identifier + : +Ouputs : The message type + : <0 in cas of error + : PIP_TRANS_MSG_TYPE_COMMAND if this a command message + : PIP_TRANS_MSG_TYPE_DATA if this is a data message + : +Globals : +Remark : +Level : This is a user level function. +Date : 13/04/2003 +Doc date : 13/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FGetRecMsgType ( SInt32 ObjId ) { + + PIP_TContext* VPt; + + PIP_CHK_OBJ_ID (ObjId); + + VPt = &PIP_VGContext[ObjId]; + + return ( VPt->RecMsgType ); + +} + +/******************************************************************************* +Prototype : SInt32 PIP_FGetDatas ( SInt8 ObjId, SInt8 MultiExec, UInt8 *PtDest, + : UInt32 MaxDestSz, UInt32 *PtGetTotDataSz ) + : +Goal : Get datas on receiver side, this the highest user level function. + : This function should be called in a polling loop or by an interrupt + : handler, the return value shows the transaction status. + : +Inputs : ObjId - the object identifier + : MultiExec - if 0 the function will read all blocks and return + : - at end of transaction + : - if 1 the function will read one block and return, + : - you will need to call it until it return 1 + : PtDest - the destination buffer pointer + : MaxDestSz - the destination buffer size ( to avoid gardening ... ) + : PtGetTotDataSz - the variable pointed will be set with transaction size + : +Ouputs : The function returns + : 0 if one block received + : 1 if transaction if finished ( last block received ) + : -1 => error + : -2 => there is nothing to read ( no block available ) +Globals : +Remark : +Level : This is a user level function. +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FGetDatas ( SInt8 ObjId, SInt8 MultiExec, UInt8 *PtDest, UInt32 MaxDestSz, UInt32 *PtGetTotDataSz ) { + + SInt32 VRet; + static SInt32 VCallCnt = 0; + static SInt32 Vi; + static SInt32 VBlkSz; + UInt32 VRetBlkSz; + PIP_TContext* VPt; + + PIP_CHK_OBJ_ID (ObjId); + + VPt = &PIP_VGContext[ObjId]; + + + /* Initialization on first call */ + + if ( VCallCnt == 0 ) { + Vi = 0; + VBlkSz = VPt->RecBlkSz; + } + + do { + VRet = PIP_FGetBlk ( ObjId, (UInt32*) &PtDest[Vi*VBlkSz], MaxDestSz, &VRetBlkSz ); + } while ( (VRet == 0) && (MultiExec == 0) ); + + ++VCallCnt; + + /* End of transaction, last block read */ + + if ( VRet == 1 ) { + VCallCnt = 0; + + /* Reset input buffer - should be optimized later => init PIP_TRANS_TAG_HD_INDEX only */ + memset ( VPt->PtRecBuff, 0, VPt->RecBlkTotSz ); + + *PtGetTotDataSz = VPt->RecDataSzDone; + err_retval ( 1, ( ERR_OUT, "End of transaction" ) ); + } + + /* Block read ok, but it's not the last one - MultiExec call */ + + if ( VRet == 0 ) { + Vi++; + VBlkSz = VRetBlkSz; + err_retok (( ERR_OUT, "" )); + } + + /* Error ? */ + + if ( VRet < 0 ) { + + /* It's not a "real error" => there is nothing to read */ + + if ( VRet == -2 ) { + err_trace (( ERR_OUT, "PIP_FGetBlk fail => because nothing to read" )); + return (-2); + } + + /* If it's a real error => reset calls counter */ + + VCallCnt = 0; + + err_retfail ( -1, (ERR_OUT,"Rec datas fail") ); + } + + return (0); +} + +/******************************************************************************* +Prototype : SInt32 PIP_FTestSend ( SInt32 PipeId, SInt32 TransStatus, SInt8* PtExtParam, + : SInt32* PtSrc, SInt32 DataSz, SInt32 MaxDataSz ) + : +Goal : This is the low level send function, which send one block. + : This version use a local memory block to transfer datas ( for demo ). + : +Inputs : PipeId - the sender pipe identifier + : TransStatus - the SendStatus field of object ( transaction status ) + : PtExtParam - a pointer, in case more parameters are needed + : PtSrc - pointer to source datas to send + : DataSz - size of datas to send ( = block size ) + : MaxDataSz - transaction total size ( not used now => set to -1 ) + : +Ouputs : 0 if ok + : negative value in case of error +Globals : +Remark : This function is sender side interface from pipe unit to the hardware. + : It is written by " low level programmer " and called by pipe unit when + : it wants to send a block. + : I provide many parameters from the " high level object ", perhaps some + : are useless. The required parameters are PtSrc, DataSz and TransStatus. + : TransStatus is used to indicate the beginning / end of transaction, it + : can take the following values : PIP_TRANS_STATUS_FIRST_BLK, + : PIP_TRANS_STATUS_RUN, PIP_TRANS_STATUS_LAST_BLK + : + : +Level : This is a UNIT PRIVATE level function. +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FTestSend ( SInt32 PipeId, SInt32 TransStatus, SInt8* PtExtParam, SInt32* PtSrc , SInt32 DataSz, SInt32 MaxDataSz ) { + + memcpy ( PIP_VGDummyPc2UcBuffer, PtSrc, DataSz ); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : SInt32 PIP_FTestGet ( SInt32 PipeId, SInt32 TransStatus, SInt8* PtExtParam, + : SInt32* PtDest, SInt32 DataSz, SInt32 MaxDataSz ) + : +Goal : This is the low level receiver function, which retrieve one block. + : This version use a local memory block to transfer datas ( for demo ). + : +Inputs : PipeId - the sender pipe identifier + : TransStatus - transaction status, not used now ( set to -1 ) + : PtExtParam - a pointer, in case more parameters are needed + : PtDest - pointer to destination buffer + : DataSz - size of datas to send ( = block size ) + : MaxDataSz - transaction total size ( SET TO block size NOW ) + : +Ouputs : 0 if ok + : negative value in case of error +Globals : +Remark : This function is receiver side interface from pipe unit to the hardware. + : It is written by " low level programmer " and called by pipe unit when + : it wants to retrieve a block. + : I provide many parameters from the " high level object ", perhaps some + : are useless. The required parameters are PtSrc, DataSz and TransStatus. + : + : I must point out that DataSz parameter is the total block size ( datas + + : header ) then it's greater than the configured block size on sender side. + : +Level : This is a UNIT PRIVATE level function. +Date : 26/03/2003 +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FTestGet ( SInt32 PipeId, SInt32 TransStatus, SInt8* PtExtParam, SInt32* PtDest, SInt32 DataSz, SInt32 MaxDataSz ) { + + memcpy ( PtDest, PIP_VGDummyPc2UcBuffer, MaxDataSz ); + + err_retok (( ERR_OUT, "" )); +} + + +/* ------------------------------------------------------------------------------------- */ +/* ---- FSend & FGet examples with a directory and files used a data transfert media --- */ +/* ------------------------------------------------------------------------------------- */ + +/* + +How does it works ? + +This is a SIMULATION of a transfer media ( USB, RPC ) using the file system +to build the data pipe. + +Each block to send is written in a file with a name pipe_px_bx where +px is the pipe number ( 1, 2, ... ) and bx the block number ( 0, 1, ... ). +When a new block is ready and written a file pipe_px_w is created, when +the receiver see this file he knows there is a block to read. +Then the receiver delete the file pipe_px_w, therefore the sender knows +he can write the next block. + +The directory where the files are written is set by PIP_FILE_TRF_DIR in pipe.def. + +*/ + + +/******************************************************************************* +Prototype : SInt32 PIP_FFileExists ( char* FilePath ) +Goal : Test if the file exists. +Inputs : The file name ( full path if needed ). +Ouputs : 1 if the file exists, else 0. +Globals : +Remark : The result is not guaranted in case of multi application lock to file. +Level : This is a UNIT PRIVATE level function. +Date : 06/04/2003 +Rev : 09/01/2008 + : - Bug on ROOT environnement ( stacked call => crash ) if fclose is called + : when fopen fails. Now I call it only when fopen success. + : +Doc date : 12/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FFileExists ( char* FilePath ) { + + SInt32 VRet; + FILE* VPf; + + VPf = fopen ( FilePath, "r" ); + + if ( VPf == NULL ) { + VRet = 0; + } + + else { + VRet = 1; + fclose ( VPf ); + } + + return (VRet); +} + + + +SInt32 PIP_FFileSize ( char* FilePath ) { + + FILE* VPf; + SInt32 VFileSz; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + return (-1); + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + return (-1); + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + return (-1); + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + return (-1); + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + return (-1); + } + + if ( fclose (VPf) != 0 ) { + return (-1); + } + + return (VFileSz); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Date : 06/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FDelFile ( char* FilePath ) { + + SInt32 VRet; + + VRet = remove ( FilePath ); + + if ( VRet < 0 ) { + err_warning (( ERR_OUT, "remove file %s fail - %s", FilePath, strerror(errno) )); + return (-1); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : Low level FSend implementation demo. +Inputs : +Ouputs : +Globals : +Remark : +Date : 29/03/2003 +Rev : 16/04/2006 - BUG correction + : - Add a loop on signal file test and creation, because sometimes the + : file creation failed although there is no previous file on disk ! + : The variable VMaxCrSigFileTry sets the maximum number of tentatives. + : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FFileSend ( SInt8 ObjId, SInt32 PipeId, SInt32 TransStatus, SInt8* PtExtParam, SInt32* PtSrc , SInt32 DataSz, SInt32 MaxDataSz ) { + + SInt32 VRet; + static SInt32 VABlkNo[PIP_OBJ_NB]; + SInt32 VSigVal; + FILE* VPf; + char VFilePath[GLB_FILE_PATH_SZ]; + + SInt32 VCrSigFileErrCnt; + SInt32 VMaxCrSigFileTry = 100; + SInt32 VWaitSigFileErrCnt; + SInt32 VMaxWaitSigFileTry = 1000; + + + err_trace (( ERR_OUT, "5" )); + + /* Create data block file */ + + if ( TransStatus == PIP_TRANS_STATUS_FIRST_BLK ) { + VABlkNo[ObjId] = 0; + } + + sprintf ( VFilePath, "%s\\pipe_%d_%d", PIP_FILE_TRF_DIR, PipeId, VABlkNo[ObjId] ); + + VPf = fopen ( VFilePath, "wb" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT,"fopen file %s fail ", VFilePath) ); + } + + if ( fwrite ( PtSrc, DataSz, 1 /* cnt */, VPf ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"fwrite in file %d fail ", VFilePath) ); + } + + fflush ( VPf ); + fclose ( VPf ); + + if ( TransStatus == PIP_TRANS_STATUS_LAST_BLK ) { + VABlkNo[ObjId] = 0; + } + + + /* Wait */ + + sprintf ( VFilePath, "%s\\pipe_%d_w", PIP_FILE_TRF_DIR, PipeId ); + + // 22/01/08 => weak point => lock possible + + VWaitSigFileErrCnt = 0; + + while ( (PIP_FFileExists (VFilePath) == 1) && (VWaitSigFileErrCnt < VMaxWaitSigFileTry) ) { + + #ifdef ROOT_ROOT + gSystem->Sleep (10); + #else + Sleep (10); + #endif + + ++VWaitSigFileErrCnt; + } + + + if ( VWaitSigFileErrCnt >= VMaxWaitSigFileTry ) { + err_retfail ( -1, (ERR_OUT,"Abort => Locked on sigfile present ! %d tests", VWaitSigFileErrCnt ) ); + } + + + err_trace (( ERR_OUT, "8" )); + + /* Create signal file */ + + sprintf ( VFilePath, "%s\\pipe_%d_w", PIP_FILE_TRF_DIR, PipeId ); + + err_trace (( ERR_OUT, "Create signal file begin" )); + + VCrSigFileErrCnt = 0; + + err_trace (( ERR_OUT, "9" )); + + while ( VCrSigFileErrCnt < VMaxCrSigFileTry ) { + + VPf = fopen ( VFilePath, "wb" ); + + if ( VPf == NULL ) { + ++VCrSigFileErrCnt; + + #ifdef ROOT_ROOT + gSystem->Sleep (100); + #else + Sleep (100); + #endif + + continue; + } + + VSigVal = VABlkNo[ObjId]; + + if ( fwrite ( &VSigVal, 4 /* sz */, 1 /* cnt */, VPf ) != 1 ) { + ++VCrSigFileErrCnt; + fclose ( VPf ); + + #ifdef ROOT_ROOT + gSystem->Sleep (100); + #else + Sleep (100); + #endif + + continue; + } + + fflush ( VPf ); + fclose ( VPf ); + + break; + } /* End while */ + + err_trace (( ERR_OUT, "10" )); + + err_trace (( ERR_OUT, "Create signal file end" )); + + if ( VCrSigFileErrCnt > 0 ) { + err_error (( ERR_OUT, "Create signal file errors !!! => Try %d times", VCrSigFileErrCnt )); + } + + if ( VCrSigFileErrCnt >= VMaxCrSigFileTry ) { + err_retfail ( -1, (ERR_OUT,"Create signal file failed after %d try : %s", VCrSigFileErrCnt, strerror(errno) ) ); + } + + ++VABlkNo[ObjId]; + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : Low level FGet implementation demo. +Inputs : +Ouputs : +Globals : +Remark : +Date : 29/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 PIP_FFileGet ( SInt8 ObjId, SInt32 PipeId, SInt32 TransStatus, SInt8* PtExtParam, SInt32* PtDest, SInt32 DataSz, SInt32 MaxDataSz ) { + + SInt32 VRet; + static SInt32 VABlkNo[PIP_OBJ_NB]; + SInt32 VSigVal; + FILE* VPf; + char VFilePath[GLB_FILE_PATH_SZ]; + + SInt32 VRdSigFileErrCnt; + SInt32 VMaxRdSigFileTry = 100; + + SInt32 VLockCnt; + + + /* Check destination buffer */ + + if ( PtDest == NULL ) { + err_retfail ( -1, (ERR_OUT,"Destination buffer pointer is NULL !") ); + } + + /* Is there something to read ? */ + + /* Check signal file */ + + sprintf ( VFilePath, "%s\\pipe_%d_w", PIP_FILE_TRF_DIR, PipeId ); + + err_trace (( ERR_OUT, "Signal file =%s exists ?", VFilePath )); + + if ( PIP_FFileSize (VFilePath) != 4 ) { + err_trace (( ERR_OUT, "Nothing to read")); + return (-2); + } + + + VPf = fopen ( VFilePath, "rb" ); + + if ( VPf == NULL ) { + // fclose ( VPf ); // 21/01/08 => Call to fclose () removed because it's not useful and MAY cause problems + err_warning (( ERR_OUT, "Nothing to read")); + return (-2); + } + + VRdSigFileErrCnt = 0; + + while ( VRdSigFileErrCnt < VMaxRdSigFileTry ) { + + if ( fread ( &VSigVal, 4 /* sz */, 1 /* cnt */, VPf ) != 1 ) { + fclose ( VPf ); + ++VRdSigFileErrCnt; + + #ifdef ROOT_ROOT + gSystem->Sleep (100); + #else + Sleep (100); + #endif + + continue; + // err_retfail ( -1, (ERR_OUT,"Error reading signal file %s", VFilePath ) ); + } + + break; + } /* End while */ + + if ( VRdSigFileErrCnt > 0 ) { + err_error (( ERR_OUT, "Read signal file errors !!! => Try %d times", VRdSigFileErrCnt )); + } + + if ( VRdSigFileErrCnt >= VMaxRdSigFileTry ) { + err_retfail ( -1, (ERR_OUT,"Read signal file failed after %d try : %s", VRdSigFileErrCnt, strerror(errno) ) ); + } + + VABlkNo[ObjId] = VSigVal; /* Now signal file contains the block no */ + + fflush ( VPf ); + fclose ( VPf ); + + err_trace (( ERR_OUT, "Signal file exists - now close it" )); + + /* Read data from block file */ + + sprintf ( VFilePath, "%s\\pipe_%d_%d", PIP_FILE_TRF_DIR, PipeId, VABlkNo[ObjId] ); + + VPf = fopen ( VFilePath, "rb" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT,"Open (for read) data block file %s fail !", VFilePath ) ); + } + + if ( fread ( PtDest, DataSz, 1 /* cnt */, VPf ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Read of %d bytes in %s file fail !", DataSz, VFilePath ) ); + } + + fclose ( VPf ); + + /* Delete the signal file */ + + sprintf ( VFilePath, "%s\\pipe_%d_w", PIP_FILE_TRF_DIR, PipeId ); + + err_trace (( ERR_OUT, "Delete signal file" )); + + + // Code 10/01/2008 => VLockCnt + + VLockCnt = 0; + + while ( PIP_FDelFile (VFilePath) < 0 ) { + + if ( VLockCnt > 1000 ) { + err_retfail ( -1, (ERR_OUT,"Lock on PIP_FDelFile (%s)", VFilePath ) ); + } + + ++VLockCnt; + } + + /* Delete the data file */ + + sprintf ( VFilePath, "%s\\pipe_%d_%d", PIP_FILE_TRF_DIR, PipeId, VABlkNo[ObjId] ); + + // Code 10/01/2008 => VLockCnt + + VLockCnt = 0; + + while ( PIP_FDelFile (VFilePath) < 0 ) { + + if ( VLockCnt > 1000 ) { + err_retfail ( -1, (ERR_OUT,"Lock on PIP_FDelFile (%s)", VFilePath ) ); + } + + ++VLockCnt; + + } + + err_retok (( ERR_OUT, "" )); +} + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/pipe.def b/include/pxi_daq_lib_v.2.1/pipe.def new file mode 100755 index 0000000..2122583 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/pipe.def @@ -0,0 +1,75 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/pipe/ +Goal : Constants ( Macros ) definitions of pipe unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef PIP_DEF +#define PIP_DEF + +#define PIP_OBJ_NB 10 /* Max object number handle by unit */ +#define PIP_OBJ_0 0 /* Default object Id for applications */ + +/* Block buffer size ( max value ) */ + +#define PIP_MAX_SEND_BUFF_SZ (10 * 1024 * 1024) /* Sender side */ +#define PIP_MAX_REC_BUFF_SZ (10 * 1024 * 1024) /* Receive side */ + +/* Header size and field indexs */ + +/* +WARNING => a enumerated type is better to define +this list of fields, more safe, but some compilers +have trouble with them ... +*/ + + +#define PIP_DATA_HEAD_W32SZ 10 /* Header = 10 x W32 words */ + +#define PIP_TRANS_TAG_HD_INDEX 0 /* Used to detect beginning of transaction */ +#define PIP_TRANS_TOT_SZ_HD_INDEX 1 /* Store transaction size */ +#define PIP_TRANS_BLK_SZ_HD_INDEX 2 /* Store block size */ +#define PIP_TRANS_MSG_TYPE_HD_INDEX 3 /* Store message type */ +#define PIP_TRANS_CRC_HD_INDEX 4 /* Store CRC value - not used yet */ +#define PIP_LAST_HD_INDEX 9 /* Must be < PIP_DATA_HEAD_W32SZ */ + +/* Value which identify the beginning of a transaction => PIP_TRANS_TAG_HD_INDEX */ + +#define PIP_TRANS_TAG_BEGIN 0xdeadface /* */ + +/* Messages type */ + +#define PIP_TRANS_MSG_TYPE_COMMAND 1 +#define PIP_TRANS_MSG_TYPE_DATA 2 + + +/* Index of first data W32 word */ + +#define PIP_DATA_INDEX PIP_DATA_HEAD_W32SZ + +/* Sender status - stored in SendStatus object fiedl */ + +#define PIP_TRANS_STATUS_FIRST_BLK 1 /* First block of a transaction */ +#define PIP_TRANS_STATUS_RUN 2 /* Transaction running - First < Block < Last */ +#define PIP_TRANS_STATUS_LAST_BLK 3 /* Last block of a transaction */ + +/* A macro which check the object id and return -1 if it's a bad one */ + +#define PIP_CHK_OBJ_ID(ObjId) { \ + if ( ObjId >= PIP_OBJ_NB ) { \ + err_retfail ( -1, (ERR_OUT,"ObjId=%d >= PIP_OBJ_NB=%d", ObjId, PIP_OBJ_NB ) ); \ + } \ +} + +/* Pipe files directory for the demo which use file system as media */ + +#define PIP_FILE_TRF_DIR "t:\\tmp\\pipes" + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/pipe.h b/include/pxi_daq_lib_v.2.1/pipe.h new file mode 100755 index 0000000..8ebb44d --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/pipe.h @@ -0,0 +1,34 @@ + +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/pipe/ +Goal : Functions prototypes of pipe unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef PIP_H +#define PIP_H + +SInt32 PIP_FBegin ( SInt8 ObjId, + SInt32 SendPipeId, SInt32 SendBuffSz, PIP_TSendFunc PtSendFunc, + SInt32 RecPipeId , SInt32 RecBuffSz , PIP_TGetFunc PtGetFunc ); + +SInt32 PIP_FEnd ( SInt8 ObjId ); + +SInt32 PIP_FPutDatas ( SInt8 ObjId, SInt8 MultiExec, SInt32 MsgType, UInt8 *PtSrc, SInt32 BlkSz, UInt32 TotSz ); +SInt32 PIP_FGetDatas ( SInt8 ObjId, SInt8 MultiExec, UInt8 *PtDest, UInt32 MaxDestSz, UInt32 *PtGetTotDataSz ); + +SInt32 PIP_FSendBlk ( SInt8 ObjId, UInt8 FirstBlk, SInt32 MsgType, UInt32 *PtSrc, UInt32 BlkSz, UInt32 TotSz ); +SInt32 PIP_FGetBlk ( SInt8 ObjId, UInt32 *PtDest, UInt32 MaxDestSz, UInt32 *PtGetDataSz ); + +char* PIP_FStrSendStatus ( SInt8 ObjId ); +char* PIP_FStrGetStatus ( SInt8 ObjId ); + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/pipe.typ b/include/pxi_daq_lib_v.2.1/pipe.typ new file mode 100755 index 0000000..0778f1f --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/pipe.typ @@ -0,0 +1,52 @@ +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/pipe/ +Goal : Types definition of pipe unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef PIP_TYP +#define PIP_TYP + +/* Low level sender / receiver functions */ + +typedef SInt32 (*PIP_TSendFunc) ( SInt8 ObjId, SInt32 PipeId, SInt32 TransStatus, SInt8* PtExtParam, SInt32* PtSrc , SInt32 DataSz, SInt32 MaxDataSz ); +typedef SInt32 (*PIP_TGetFunc ) ( SInt8 ObjId, SInt32 PipeId, SInt32 TransStatus, SInt8* PtExtParam, SInt32* PtDest, SInt32 DataSz, SInt32 MaxDataSz ); + +/* Object context fields */ + +typedef struct PIP_TContext { + + SInt32 *PtSendBuff; /* Pointer to private send buffer */ + SInt32 SendPipeId; /* Sender pipe identifier */ + SInt32 SendStatus; /* Send status flag */ + SInt32 SendMsgType; /* Type of message */ + SInt32 SendBlkIndex; /* Index of current sent buffer */ + SInt32 SendBlkTotSz; /* Bloc size => include header */ + SInt32 SendBlkSz; /* Block size => data only */ + SInt32 SendTransSz; /* Total transaction size ( without headers ) */ + SInt32 SendDataSzDone; /* Current data size sent */ + + PIP_TSendFunc PtSendFunc; + + SInt32 *PtRecBuff; /* Pointer to private rec buffer */ + SInt32 RecPipeId; /* Receiver pipe identifier */ + SInt32 RecStatus; /* Receive status flag */ + SInt32 RecMsgType; /* Type of message */ + SInt32 RecBlkIndex; /* Index of current received buffer */ + SInt32 RecBlkTotSz; /* Bloc size => include header */ + SInt32 RecBlkSz; /* Block size => data only */ + SInt32 RecTransSz; /* Total transaction size ( without headers ) */ + SInt32 RecDataSzDone; /* Current data size received */ + + PIP_TGetFunc PtGetFunc; + +} PIP_TContext; + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/pipe.var b/include/pxi_daq_lib_v.2.1/pipe.var new file mode 100755 index 0000000..eee9e7c --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/pipe.var @@ -0,0 +1,22 @@ +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/pipe/ +Goal : Variables definition of pipe unit. +Prj date : 26/03/2003 +File date : 26/03/2003 +Doc date : 26/03/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef PIP_VAR +#define PIP_VAR + + PIP_TContext PIP_VGContext[PIP_OBJ_NB]; /* Object contexts array */ + + /* Global buffer for demo which use memory as media */ + + static SInt32 PIP_VGDummyPc2UcBuffer[PIP_DATA_HEAD_W32SZ + (PIP_MAX_SEND_BUFF_SZ/4)]; + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/pport.c b/include/pxi_daq_lib_v.2.1/pport.c new file mode 100755 index 0000000..d7b37f6 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/pport.c @@ -0,0 +1,1364 @@ +/******************************************************************************* +File : /dd/sdev_src/c/work/common/units/u/u.c +Goal : Functions definition of +Prj date : 12/01/2004 +File date : //2004 +Versions : //2004 => Creation +Doc date : //2004 +Rev : 30/12/2005 + : - stb lib for DLL building +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef PPORT_C +#define PPORT_C + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : //2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 PPO_FBegin ( SInt8 Enable, char* FilePath ) { + + if ( Enable >= 0 ) { + ERR_FBegin ( Enable, FilePath ); + } + + + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/03/2010 +Doc date : 22/03/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 PPO_FEnableReadDataOutPortBeforeWrite ( SInt8 Id, SInt8 Enable ) { + + if ( PPO_VGNoHwAccess[Id] ) { + err_warning (( ERR_OUT, "Debug mode => No HW access !" )); + return (0); + } + + PPO_VGReadDataOutPortBeforeWrite[Id] = Enable; + + err_retok (( ERR_OUT, "OK" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : //2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 PPO_FEnd () { + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* 12/01/04 */ + + + +SInt32 PPO_FOpen ( UInt32 BaseAdr, SInt8 Id ) { + +#ifdef APP_USING_DLL_FOR_LOW_LEVEL + HWPPO_FOpen( BaseAdr, Id ); + +#else + + + #ifdef CC_APP_WINDOWS + #ifdef CC_APP_SPI_INOUTWRAPPER + + hLib = LoadLibrary("inpout32.dll"); // Charger DLL + if (hLib == NULL) // si erreur de chargement + { // L'indiquer + err_warning ( (ERR_OUT,"Erreur DLL !!" ) ); + return(-1); // Et sortir + } + Out32 = (oupfuncPtr) GetProcAddress(hLib, "Out32"); + if (Out32 == NULL) { + err_warning ( (ERR_OUT,"GetProcAddress for Oup32 Failed.\n")); + return -1; + } + Inp32 = (inpfuncPtr) GetProcAddress(hLib, "Inp32"); + if (Inp32 == NULL) { + err_warning ( (ERR_OUT,"GetProcAddress for Inp32 Failed.\n")); + return -1; + } + #endif + + #else + + if ( ioperm ( BaseAdr, PPO_ADR_BYTES_SPACE, 1 /* Enable */ ) ) { + err_retfail ( -1, (ERR_OUT,"ioperm failed") ); + } + + #endif +#endif + PPO_VGBaseAdr[Id] = BaseAdr; + PPO_VGOutAdr [Id] = BaseAdr; + PPO_VGIn1Adr [Id] = BaseAdr + 1; + PPO_VGCtrlAdr[Id] = BaseAdr + 2; + + PPO_VGPortReady[Id] = 1; + + err_error (( ERR_OUT, "PPO_FOpen /********************WARNING***********************/" )); + err_error (( ERR_OUT, "the signals Strobe, Autofeed and Select in have been inverted" )); + err_error (( ERR_OUT, "because these signals are in negative logic" )); + err_error (( ERR_OUT, "All signal are now in positive logic" )); + err_error (( ERR_OUT, "27/05/2014 - MS" )); + + msg (( MSG_OUT, "PPO_FOpen /********************WARNING***********************/" )); + msg (( MSG_OUT, "the signals Strobe, Autofeed and Select in have been inverted" )); + msg (( MSG_OUT, "because these signals are in negative logic" )); + msg (( MSG_OUT, "All signal are now in positive logic" )); + msg (( MSG_OUT, "27/05/2014 - MS" )); + + + + err_retok (( ERR_OUT, "" )); +} + +SInt32 PPO_FClose ( SInt8 Id ) { +#ifdef APP_USING_DLL_FOR_LOW_LEVEL + HWPPO_FClose( Id ); + +#else + + #ifdef CC_APP_WINDOWS + #ifdef CC_APP_SPI_INOUTWRAPPER + + FreeLibrary(hLib); //Liberer mem ->DLL + #endif + + #else + + if ( ioperm ( PPO_VGBaseAdr[Id], PPO_ADR_BYTES_SPACE, 0 /* Disable */ ) ) { + err_retfail ( -1, (ERR_OUT,"ioperm failed") ); + } + + #endif +#endif + PPO_VGPortReady[Id] = 0; + + return (0); + +} + +/* 11/03/2007 */ + +SInt32 PPO_FDisableHwAccess ( SInt8 Id, SInt8 Disable ) { + + PPO_VGNoHwAccess[Id] = Disable; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 PPO_PRIV_FWinOut( UInt8 Data, UInt16 Adr ) { +// 11/04/2014 - MS added conditionnal compilation to be able to use a DLL for the low level function +// PB compil 31/05/2013 => Missing # before ifdef +#ifdef APP_USING_DLL_FOR_LOW_LEVEL + HWPPO_PRIV_FWinOut( Data, Adr ); + +#else +#ifdef CC_APP_SPI_INOUTWRAPPER + //output32 (Adr,Data); + Out32(Adr,Data); + +#else + asm { + push ax; + push dx; + + mov al, Data; + mov dx, Adr; + out dx, al; + + pop dx; + pop ax; + } + + +#endif +#endif + return (0); +} + +UInt8 PPO_PRIV_FWinIn ( UInt16 Adr ) { +// 11/04/2014 - MS added conditionnal compilation to be able to use a DLL for the low level function + + UInt8 VRet = 0; + //err_warning (( ERR_OUT, "PPO_Priv_FWinIn!" )); + +#ifdef APP_USING_DLL_FOR_LOW_LEVEL + VRet = HWPPO_PRIV_FWinIn( Adr ); + +#else + + + +#ifdef CC_APP_SPI_INOUTWRAPPER +VRet = Inp32(Adr); + //VRet = input32 (Adr); +#else + + asm { + push ax; + push dx; + + mov dx, Adr; + in al, dx; + mov VRet,al; + + pop dx; + pop ax; + } + + + //err_warning (( ERR_OUT, "PPO_Priv_FWinIn, done" )); +#endif +#endif + return ( VRet ); +} + +#endif + +/******************************************************************************/ + + +SInt32 PPO_PRIV_FOut ( SInt8 Id ) { + + SInt32 VRet; + + if ( PPO_VGNoHwAccess[Id] ) { + err_warning (( ERR_OUT, "Debug mode => No HW access !" )); + return (0); + } + + #ifdef CC_APP_WINDOWS + VRet = PPO_PRIV_FWinOut ( PPO_VGOutData[Id], PPO_VGOutAdr [Id] ); + #else + outb ( PPO_VGOutData[Id], PPO_VGOutAdr [Id] ); + VRet = 0; + #endif + + return (VRet); +} + +/* 27/10/2006 */ + +SInt32 PPO_PRIV_FCtrl ( SInt8 Id ) { + + SInt32 VRet; + + if ( PPO_VGNoHwAccess[Id] ) { + err_warning (( ERR_OUT, "Debug mode => No HW access !" )); + return (0); + } + + #ifdef CC_APP_WINDOWS + VRet = PPO_PRIV_FWinOut ( PPO_VGCtrlData[Id], PPO_VGCtrlAdr [Id] ); + #else + outb ( PPO_VGCtrlData[Id], PPO_VGCtrlAdr [Id] ); + VRet = 0; + #endif + + return (VRet); +} + + +/* 22/03/2010 */ + +SInt32 PPO_PRIV_FReadDataOutPortBeforeWrite ( SInt8 Id ) { + + if ( PPO_VGReadDataOutPortBeforeWrite[Id] == 1 ) { + PPO_VGOutData[Id] = PPO_PRIV_FWinIn ( PPO_VGOutAdr[Id] ); + } + + + return (0); +} + + + + +SInt32 PPO_FOut ( SInt8 Id, UInt8 Data ) { + + if ( PPO_VGPortReady[Id] == 0 ) { + err_retfail ( -1, (ERR_OUT,"Port Id=%d not ready", Id ) ); + } + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + PPO_VGOutData[Id] = Data; + + return ( PPO_PRIV_FOut (Id) ); +} + +/* 27/10/2006 */ + +SInt32 PPO_FCtrl ( SInt8 Id, UInt8 Data ) { + + if ( PPO_VGPortReady[Id] == 0 ) { + err_retfail ( -1, (ERR_OUT,"Port Id=%d not ready", Id ) ); + } + + PPO_VGCtrlData[Id] = Data; + + return ( PPO_PRIV_FCtrl (Id) ); +} + + +SInt32 PPO_FIn ( SInt8 Id ) { + + SInt32 VReadVal; + + if ( PPO_VGPortReady[Id] == 0 ) { + err_retfail ( -1, (ERR_OUT,"Port Id=%d not ready", Id ) ); + } + + + if ( PPO_VGNoHwAccess[Id] ) { + err_warning (( ERR_OUT, "Debug mode => No HW access !" )); + return (0); + } + + #ifdef CC_APP_WINDOWS + VReadVal = PPO_PRIV_FWinIn ( PPO_VGIn1Adr [Id] ); + #else + VReadVal = inb ( PPO_VGIn1Adr [Id] ); + #endif + + return (VReadVal); +} + +// 13/10/2011 +// 27/05/2014 - MS bug removed : +// the read back value is the actual physical state of the ctrl register, and Strobe Autofeed and SelectIn signals are in negative logic. +// the negative logic signals had to be inverted + +SInt32 PPO_FReadBackCtrl ( SInt8 Id ) { + + SInt32 VReadVal; + + if ( PPO_VGPortReady[Id] == 0 ) { + err_retfail ( -1, (ERR_OUT,"Port Id=%d not ready", Id ) ); + } + + + if ( PPO_VGNoHwAccess[Id] ) { + err_warning (( ERR_OUT, "Debug mode => No HW access !" )); + return (0); + } + + #ifdef CC_APP_WINDOWS + VReadVal = PPO_PRIV_FWinIn ( PPO_VGCtrlAdr [Id] ); + #else + VReadVal = inb ( PPO_VGCtrlAdr [Id] ); + #endif + + // inversion of the Strobe Autofeed and SelectIn signals + // Strobe neg logic LSB + // Autofeed Neg logic + // Init + // SelectIn neg logic MSB + // 1 0 1 1 = 0xB + // err_warning (( ERR_OUT, "VReadVal (before mask): %X" ,VReadVal)); + + //VReadVal = VReadVal ^ 0xb; + // err_warning (( ERR_OUT, "VReadVal (after mask) : %X" ,VReadVal)); + + return (VReadVal); +} + + + + + + +SInt32 PPO_FOutD0 ( SInt8 Id, UInt8 State ) { + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + if ( State ) { + PPO_VGOutData[Id] = PPO_VGOutData[Id] | 0x01; + } + + else { + PPO_VGOutData[Id] = PPO_VGOutData[Id] & 0xFE; + } + + return ( PPO_PRIV_FOut (Id) ); +} + + +SInt32 PPO_FOutD1 ( SInt8 Id, UInt8 State ) { + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + if ( State ) { + PPO_VGOutData[Id] = PPO_VGOutData[Id] | 0x02; + } + + else { + PPO_VGOutData[Id] = PPO_VGOutData[Id] & 0xFD; + } + + return ( PPO_PRIV_FOut (Id) ); +} + +/* 05/02/2004 */ + +SInt32 PPO_FOutD2 ( SInt8 Id, UInt8 State ) { + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + if ( State ) { + PPO_VGOutData[Id] = PPO_VGOutData[Id] | 0x04; + } + + else { + PPO_VGOutData[Id] = PPO_VGOutData[Id] & 0xFB; + } + + return ( PPO_PRIV_FOut (Id) ); +} + +/* 05/02/2004 */ + +SInt32 PPO_FOutD3 ( SInt8 Id, UInt8 State ) { + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + if ( State ) { + PPO_VGOutData[Id] = PPO_VGOutData[Id] | 0x08; + } + + else { + PPO_VGOutData[Id] = PPO_VGOutData[Id] & 0xF7; + } + + return ( PPO_PRIV_FOut (Id) ); +} + +/* 05/02/2004 */ + +SInt32 PPO_FOutD4 ( SInt8 Id, UInt8 State ) { + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + if ( State ) { + PPO_VGOutData[Id] = PPO_VGOutData[Id] | 0x10; + } + + else { + PPO_VGOutData[Id] = PPO_VGOutData[Id] & 0xEF; + } + + return ( PPO_PRIV_FOut (Id) ); +} + +/* 02/06/2004 */ + +SInt32 PPO_FOutD5 ( SInt8 Id, UInt8 State ) { + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + if ( State ) { + PPO_VGOutData[Id] = PPO_VGOutData[Id] | 0x20; + } + + else { + PPO_VGOutData[Id] = PPO_VGOutData[Id] & 0xDF; + } + + return ( PPO_PRIV_FOut (Id) ); +} + +/* 02/06/2004 */ + +SInt32 PPO_FOutD6 ( SInt8 Id, UInt8 State ) { + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + if ( State ) { + PPO_VGOutData[Id] = PPO_VGOutData[Id] | 0x40; + } + + else { + PPO_VGOutData[Id] = PPO_VGOutData[Id] & 0xBF; + } + + return ( PPO_PRIV_FOut (Id) ); +} + + +/* 05/02/2004 */ + +SInt32 PPO_FOutD7 ( SInt8 Id, UInt8 State ) { + + PPO_PRIV_FReadDataOutPortBeforeWrite ( Id ); + + // msg (( MSG_OUT, "PPO_FOutD7 ( Id=%d, State=%d )", Id, State )); + + if ( State ) { + PPO_VGOutData[Id] = PPO_VGOutData[Id] | 0x80; + } + + else { + PPO_VGOutData[Id] = PPO_VGOutData[Id] & 0x7F; + } + + return ( PPO_PRIV_FOut (Id) ); +} + + +SInt32 PPO_FInAck ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FIn ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x40 ) { + return (1); + } + else { + return (0); + } + +} + +/* 02/07/2005 */ + +SInt32 PPO_FInSel ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FIn ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x10 ) { + return (1); + } + else { + return (0); + } + +} + + +/* 10/02/2007 */ + +SInt32 PPO_FInError ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FIn ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x08 ) { + return (1); + } + else { + return (0); + } + +} + + +/* 10/02/2007 */ + +SInt32 PPO_FInPE ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FIn ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x20 ) { + return (1); + } + else { + return (0); + } + +} + + +/* 10/02/2007 */ + +SInt32 PPO_FInBusy ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FIn ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x80 ) { + return (0); + } + else { + return (1); + } + +} + + +SInt32 PPO_FInAckRisingEdge ( SInt8 Id ) { + + UInt8 VCurState; + static UInt8 VOldState; + static UInt8 VFirstCall = 1; + + if ( VFirstCall ) { + VFirstCall = 0; + VOldState = PPO_FInAck (Id); + + if ( VOldState < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + } + + else { + + VCurState = PPO_FInAck (Id); + + if ( VCurState < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( (VOldState == 0) && (VCurState == 1) ) { + VOldState = VCurState; + return (1); + } + + else { + VOldState = VCurState; + return (0); + } + + } + return(0); + +} + + + + +SInt32 PPO_FInAckFallingEdge ( SInt8 Id ) { + + UInt8 VCurState; + static UInt8 VOldState; + static UInt8 VFirstCall = 1; + + if ( VFirstCall ) { + VFirstCall = 0; + VOldState = PPO_FInAck (Id); + + if ( VOldState < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + } + + else { + + VCurState = PPO_FInAck (Id); + + if ( VCurState < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( (VOldState == 1) && (VCurState == 0) ) { + VOldState = VCurState; + return (1); + } + + else { + VOldState = VCurState; + return (0); + } + + } + return(0); + +} + +/* 02/07/2005 */ + +SInt32 PPO_FInSelRisingEdge ( SInt8 Id ) { + + UInt8 VTryCnt; + UInt8 VCurState; + static UInt8 VOldState; + static UInt8 VFirstCall = 1; + + if ( VFirstCall ) { + VFirstCall = 0; + VOldState = PPO_FInSel (Id); + + if ( VOldState < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + } + + else { + + VCurState = PPO_FInSel (Id); + + /* To avoid glitch => 1 is checked 10 times */ + + if ( VCurState == 1 ) { + + for ( VTryCnt=0; VTryCnt < 10; VTryCnt++ ) { + VCurState = PPO_FInSel (Id); + + if ( VCurState < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VCurState == 0 ) { + break; + } + + } /* End for */ + + } + + if ( (VOldState == 0) && (VCurState == 1) ) { + VOldState = VCurState; + return (1); + } + + else { + VOldState = VCurState; + return (0); + } + + } + return(0); + +} + + + +/* 03/03/2010 */ + +SInt32 PPO_FInPERisingEdge ( SInt8 Id ) { + + UInt8 VTryCnt; + UInt8 VCurState; + static UInt8 VOldState; + static UInt8 VFirstCall = 1; + + if ( VFirstCall ) { + VFirstCall = 0; + VOldState = PPO_FInPE (Id); + + if ( VOldState < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + } + + else { + + VCurState = PPO_FInPE (Id); + + /* To avoid glitch => 1 is checked 10 times */ + + if ( VCurState == 1 ) { + + for ( VTryCnt=0; VTryCnt < 10; VTryCnt++ ) { + VCurState = PPO_FInPE (Id); + + if ( VCurState < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VCurState == 0 ) { + break; + } + + } /* End for */ + + } + + if ( (VOldState == 0) && (VCurState == 1) ) { + VOldState = VCurState; + return (1); + } + + else { + VOldState = VCurState; + return (0); + } + + } + return(0); + +} + + + +/* 10/02/2007 */ + +SInt32 PPO_FGetDataOut ( SInt8 Id ) { + + return ( PPO_VGOutData[Id] ); +} + + +/* 10/02/2007 */ + +SInt32 PPO_FGetCtrlOut ( SInt8 Id ) { + + return ( PPO_VGCtrlData[Id] ); +} + + +/* 10/02/2007 */ +// modified the 27/05/2014 - MS +// inverted the level of the output, because this signal has negative logic + +SInt32 PPO_FCtrlStrobe ( SInt8 Id, UInt8 State ) { + + PPO_VGCtrlData[Id] = PPO_FReadBackCtrl ( Id ); + + if ( State == 0 ) { + PPO_VGCtrlData[Id] = PPO_VGCtrlData[Id] | 0x01; + } + + else { + PPO_VGCtrlData[Id] = PPO_VGCtrlData[Id] & 0xFE; + } + + return ( PPO_PRIV_FCtrl (Id) ); +} + + +/* 10/02/2007 */ +// modified the 27/05/2014 - MS +// inverted the level of the output, because this signal has negative logic + +SInt32 PPO_FCtrlAutoFeed ( SInt8 Id, UInt8 State ) { + + PPO_VGCtrlData[Id] = PPO_FReadBackCtrl ( Id ); + + if ( State == 0 ) { + PPO_VGCtrlData[Id] = PPO_VGCtrlData[Id] | 0x02; + } + + else { + PPO_VGCtrlData[Id] = PPO_VGCtrlData[Id] & 0xFD; + } + + return ( PPO_PRIV_FCtrl (Id) ); +} + + +/* 10/02/2007 */ + +SInt32 PPO_FCtrlInit ( SInt8 Id, UInt8 State ) { + + PPO_VGCtrlData[Id] = PPO_FReadBackCtrl ( Id ); + + if ( State == 1 ) { + PPO_VGCtrlData[Id] = PPO_VGCtrlData[Id] | 0x04; + } + + else { + PPO_VGCtrlData[Id] = PPO_VGCtrlData[Id] & 0xFB; + } + + return ( PPO_PRIV_FCtrl (Id) ); +} + +/* 10/02/2007 */ +// modified the 27/05/2014 - MS +// inverted the level of the output, because this signal has negative logic + +SInt32 PPO_FCtrlSelect ( SInt8 Id, UInt8 State ) { + + PPO_VGCtrlData[Id] = PPO_FReadBackCtrl ( Id ); + + if ( State == 0 ) { + PPO_VGCtrlData[Id] = PPO_VGCtrlData[Id] | 0x08; + } + + else { + PPO_VGCtrlData[Id] = PPO_VGCtrlData[Id] & 0xF7; + } + + return ( PPO_PRIV_FCtrl (Id) ); +} + +// 13/10/2011 + +SInt32 PPO_FReadBackCtrlStrobe ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FReadBackCtrl ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x01 ) { + return (1); + } + else { + return (0); + } + +} + +// 16/10/2011 + +SInt32 PPO_FReadBackCtrlAutoFeed ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FReadBackCtrl ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x02 ) { + return (1); + } + else { + return (0); + } + +} + +// 16/10/2011 + +SInt32 PPO_FReadBackCtrlInit ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FReadBackCtrl ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x04 ) { + return (1); + } + else { + return (0); + } + +} + +// 16/10/2011 + +SInt32 PPO_FReadBackCtrlSelect ( SInt8 Id ) { + + SInt32 VIn; + + VIn = PPO_FReadBackCtrl ( Id ); + + if ( VIn < 0 ) { + err_error (( ERR_OUT, "Port Id=%d is not ready", Id )); + return (0); + } + + if ( VIn & 0x08 ) { + return (1); + } + else { + return (0); + } + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : UInt32 PPO_SPIPol (SInt8 Id, UInt32 Out_Data) + : +Goal : Send and receive one serial data + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 10/06/2008 +Doc date : // +Author : Matthieu SPECHT +E-mail : matthieu.specht@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 PPO_SPIPol (SInt8 Id, UInt32 Out_Data, SInt8* PtDesync, SInt8 SpiEcho ) { + UByte i; + UInt32 Spi_Data; + UInt32 Spi_Mask; + SInt32 VFin; + UInt8 VFout; + + Spi_Mask = 0x80000000; + Spi_Data = 0; + + PPO_FOutD1( Id, 1/* Value */);// Enable Chip Select for the SPI interface : Start of transmission + //PPO_WAIT (PPO_WT); + VFout = PPO_VGOutData[Id]; + for ( i = 1 ; i <= 32 ; i++ ){ + + VFout |= 0x04; /* Data bus : 0 0 0 0 0 1 1 0*/ + /* D7 . . . . D3 = 0*/ + /* D2 = 1 : Rising Edge on SCLK*/ + /* D1 = 1 : Chip Select for the SPI Interface still active */ + /* D0 = 0 */ + if (i > 1 ){ + if (SpiEcho){ + if ((Spi_Data & (Spi_Mask<<1))!=0)/*((Out_Data & Spi_Mask) !=0)*/{ + VFout |= 0x08; + } + else{ + VFout &= 0xF7; + } + } + else{ + if ((Out_Data & Spi_Mask) !=0){ + VFout |= 0x08; + } + else{ + VFout &= 0xF7; + } + } + }/*End if*/ + PPO_FOut (Id, VFout); + PPO_FOutD2 (Id, 0); /* SCLK falling edge : retrieve data from bus*/ + VFin = PPO_FIn (Id); + if (VFin & 0x08) { + Spi_Data += Spi_Mask; + } /* end if */ + Spi_Mask = Spi_Mask >> 1; + } /* End For */ + + + PPO_FOut (Id, VFout & 0xF1); // release the spi interface : reset SCLK, reset SDIN, reset SSEL + + if ( PtDesync != NULL ) { + *PtDesync = (Spi_Data & 1); + } + + return ( (Spi_Data >> 1) & 0x7FFFFFFF); + +}/* End PPO_SPIPol (SInt8 Id, UInt32 Out_Data)*/ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 PPO_TLU_FReadCnt (SInt8 Id, SInt8 TryNb, UInt32 Out_Data, SInt8* PtDesync, SInt8 SpiEcho ) +: +Goal : Send and receive one serial data +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 10/06/2008 +Doc date : // +Author : CLAUS Gilles +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +UInt32 PPO_TLU_FReadCnt (SInt8 PortId, SInt8 TryNb, UInt32 Out_Data, SInt8* PtDesync, SInt8 SpiEcho ) { + + SInt8 Vi; + UInt32 VCnt; + SInt8 VDesync; + + for ( Vi=0; Vi < TryNb; Vi++ ) { + VCnt = PPO_SPIPol ( PortId, Out_Data, &VDesync, SpiEcho ); + + if ( VCnt != 0 ) { + break; + } + } + + if ( Vi > 0 ) { + err_error (( ERR_OUT, "TLU readout error : %d try", Vi )); + } + + if ( VCnt == 0 ) { + err_error (( ERR_OUT, "TLU readout error : Read 0 after %d try !", TryNb )); + } + + if ( VDesync != 0 ) { + err_error (( ERR_OUT, "TLU desync !" )); + } + + if ( PtDesync != NULL ) { + *PtDesync = VDesync; + } + + return (VCnt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : PPO_SPIAutoTrigger (SInt8 Id,SInt8 Count) + : +Goal : Generate Count number of trigger + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : 02/07/2008 +Doc date : // +Author : Matthieu SPECHT +E-mail : matthieu.specht@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +void PPO_SPIAutoTrigger (SInt8 Id,SInt32 Count) { + SInt32 i; + + for (i=0;i FileSize=%d\n", VFileSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + if( VPfDest == NULL ) { + printf( "GetSyncPointer: Source file %s open failed.\n", FilePath ); + return -1; + } + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + printf("SYNC Version is %d\n", ((APP__TSyncIndexRec*)PtDest)->Version); + + if ( VRet != 1 ) { + printf( "GetSyncPointer: Error reading source file %s.\n", FilePath ); + return -1; + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + printf( "GetSyncPointer: Error fclose source file %s.\n", FilePath ); + return -1; + } + + + // Return record nb + + return ( VFileSz / sizeof (APP__TSyncIndexRec) ); + +} + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/sync_index_rec.typ b/include/pxi_daq_lib_v.2.1/sync_index_rec.typ new file mode 100755 index 0000000..bd3bcd8 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/sync_index_rec.typ @@ -0,0 +1,57 @@ +/* ============== */ +/* 10/07/2012 */ +/* -------------- */ +/* Doc 18/07/2012 */ +/* ============== */ + +#ifndef SYNC_INDEX_REC_TYP +#define SYNC_INDEX_REC_TYP + +#define CC_UNIX // Specify operating system +#include "types.typ" + +typedef struct { + + // The fields needed to synchronize DUT & Telescope run are marked with a * + // The other fields are extra information, which may be use to make cross-check + + UInt32 Version; // Record version + + // DUT events information + + UInt32 DutEvId; // * Event identifier from 0 to NbMaxEventsInRun - 1 + UInt32 DutEvTag; // Event tag = Mi26 sync signal pulses count = Mi26 frames counter + UInt32 DutTrigLine; // Line read by DAQ when trigger has occurred + UInt32 DutTrigFrame; // Frame read by DAQ when trigger has occurred + UInt32 DutTrigNbTot; // Total number of triggers seen by DAQ since beginning of run + UInt32 DutTrigNbAccepted; // Number of triggers accepted by DAQ since beginning of run = number of events taken by DAQ + UInt32 DutSpareU32; // Reserved + + // Telescope information + + UInt32 TelBegEvFrId; // * First frame corresponding to DUT event + + // Frame which contains trigger info + // + UInt32 TelTrigFrId; // Frame id since begining of run => 0 .. NbMaxFramesInRun - 1 + UInt32 TelTrigAcqId; // Acquisition id since begining of run + UInt32 TelTrigFrIdInAcq; // Frame id in current acquisition => 0 .. NbMaxFramesPerAcq + UInt32 TelTrigEvTag; // Event tag = Mi26 frames counter + + // Three first triggers of the frame (TelTrigFrId) + // Unit is Mi26 clock TS => divide by 16 to get trigger line + // + UInt32 TelTrig0; // First trigger + UInt32 TelTrig1; // Second trigger + UInt32 TelTrig2; // Third trigger + + UInt32 TelFrTrigNb; // Total number of trigger of the frame (TelTrigFrId) + + UInt32 TelTrigSpareU32; // Reserved + + UInt32 TelEndEvFrId; // * Last frame corresponding to DUT event + +} APP__TSyncIndexRec; + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/system.def b/include/pxi_daq_lib_v.2.1/system.def new file mode 100755 index 0000000..7eaf8a3 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/system.def @@ -0,0 +1,110 @@ + +/************************************************************* +File : /dd/sdev_src/c/work/common/include/system.def +Goal : Old system file keeped for compatibility which + : provides RETURN and PRINT macros. +Prj date : 2000 - 2002 +File date : 18/09/97 +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + + + +#ifndef SYSTEM_H +#define SYSTEM_H + + +/**************************************************************************** +SYSTEME +*****************************************************************************/ + + +#undef UNIX_VXI +#undef OS9_VME +#undef PC_WINDOWS +#define PC_CONSOLE + +#undef I2C_IO_SIROCO +#undef I2C_IO_PC_SERIAL +#undef I2C_IO_PC_PARA + + +/**************************************************************************** +COMPILATION +*****************************************************************************/ + + +#undef IO_SIROCO_LOG_FILE +#undef IO_SIROCO_VECT_FILE +#undef IO_HP82000_VECT_FILE +#undef IO_LOG_FILE +#undef IO_VECT_FILE + + + +/**************************************************************************** +*****************************************************************************/ + + +typedef enum SYS_EOsType {OS_LINUX, OS_LYNX, OS_WINDOWS, OS_MAX } SYS_TOsType; + +#ifdef CREATE_VARIABLES + +char* SYS_StrOs[OS_MAX] = { "OS_LINUX ", + "OS_LYNX ", + "OS_WINDOWS" + }; + +#else + extern char* SYS_StrOs[OS_MAX]; +#endif + + +#ifndef TRUE + #define TRUE true +#endif + +#ifndef FALSE + #define FALSE false +#endif + +typedef unsigned char Boolean; + +#ifndef true + #define true 1 +#endif + +#ifndef false + #define false 0 +#endif + + +/**************************************************************************** +*****************************************************************************/ + +/* + +#ifdef CREATE_VARIABLES + #define EXTERN +#else + #define EXTERN extern +#endif + +#undef EXTERN + +*/ + +#endif + + + diff --git a/include/pxi_daq_lib_v.2.1/time.c b/include/pxi_daq_lib_v.2.1/time.c new file mode 100755 index 0000000..1e98424 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/time.c @@ -0,0 +1,623 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.c +Goal : Functions of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_C +#define TIME_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateL TIME_FConvDateS2DateL ( TIME__TUDateS DateS ) { + + TIME__TUDateL VDateL; + + VDateL.Date.Day = DateS.Date.Day; + VDateL.Date.Month = DateS.Date.Month; + VDateL.Date.Year = 2000 + DateS.Date.Year; + + return (VDateL); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateS TIME_FConvDateL2DateS ( TIME__TUDateL DateL ) { + + TIME__TUDateS VDateS; + + VDateS.Date.Day = DateL.Date.Day; + VDateS.Date.Month = DateL.Date.Month; + VDateS.Date.Year = DateL.Date.Year % 2000; + + return (VDateS); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 23/05/2010 +Doc date : 23/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateS2Str ( TIME__TUDateS Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.2d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( UInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( SInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = (UInt32) Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ + : +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FDateL2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2Str ( TIME__TUDateL Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.4d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 06/03/2010 +Doc date : 06/03/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2StrExt ( TIME__TUDateL Date, char SepChar, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d%c%.2d%c%.4d", Date.Date.Day, SepChar, Date.Date.Month, SepChar, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FConvDateTime2DateL ( TDateTime Src ) { + + TIME__TUDateL VDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + Src.DecodeDate ( &VYear, &VMonth, &VDay ); + + VDate.Date.Year = VYear; + VDate.Date.Month = VMonth; + VDate.Date.Day = VDay; + + return (VDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FGetDateLOfNextDay ( TIME__TUDateL Cur ) { + + TDateTime VCurDate ( Cur.Date.Year, Cur.Date.Month, Cur.Date.Day ); + TIME__TUDateL VNextDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + ++VCurDate; + + VCurDate.DecodeDate ( &VYear, &VMonth, &VDay ); + + VNextDate.Date.Year = VYear; + VNextDate.Date.Month = VMonth; + VNextDate.Date.Day = VDay; + + return (VNextDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +WARNING : If return pointer to list is used, a copy of LIST ( not pointer ) must be done + : after each TIME__FFillListDatesLOfWeek () call otherwise the list content will be + : the one of last call because all pointers will point to last list stored in local + : variable of function. + : + : +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef ROOT_ROOT + +TIME__TListDatesLOfWeek* TIME__FFillListDatesLOfWeek ( TIME__TUDateL MondayDate, TIME__TListDatesLOfWeek* PtList ) { + + static TIME__TListDatesLOfWeek VList; + TIME__TUDateL VDayDate; + SInt8 ViDay; + + + VDayDate = MondayDate; + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + VList.ADates[ViDay] = VDayDate; + VDayDate = TIME__FGetDateLOfNextDay ( VDayDate ); + } + + if ( PtList != NULL ) { + *PtList = VList; + } + + return (&VList); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 TIME__FPrintListDatesLOfWeek ( TIME__TListDatesLOfWeek* PtList ) { + + SInt8 ViDay; + + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + msg (( MSG_OUT, "Date : %s", TIME__FDateL2Str ( PtList->ADates[ViDay], NULL /* PtDestStr */, 0 /* DestStrSz */ ) )); + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +WARNING : A copy of return STRING ( not pointer ) must be done after each TIME_FGetDayName call + : otherwise the string content will be the one of last call because all pointers will + : point to last string stored in local variable of function. +: +Level : +Date : 27/02/2010 +Doc date : 27/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME_FGetDayName ( UInt8 DayIndex, SInt8 Language ) { + + static char* VAStrDayNameFr[8] = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche" }; + static char* VAStrDayNameEn[8] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + + if ( DayIndex > 7 ) { + err_error (( ERR_OUT, "Bad day index = %d out of rnage 0..7", DayIndex )); + return ( "?" ); + } + + switch ( Language ) { + + case TIME__LANG_FRENCH : { + return ( VAStrDayNameFr[DayIndex] ); + break; } + + case TIME__LANG_ENGLISH : { + return ( VAStrDayNameEn[DayIndex] ); + break; } + + + default : { + err_error (( ERR_OUT, "Bad language = %d out of range", Language )); + return ( "?"); + } + + } + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUTime TIME__FConvDateTime2Time ( TDateTime Src ) { + + TIME__TUTime VTime; + unsigned short VHour; + unsigned short VMin; + unsigned short VSec; + unsigned short VMSec; + + Src.DecodeTime ( &VHour, &VMin, &VSec, &VMSec ); + + VTime.Time.Hour = VHour; + VTime.Time.Min = VMin; + VTime.Time.Sec = VSec; + VTime.Time.Cent = VMSec / 10; + + return (VTime); +} + +#endif + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FTime2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FTime2Str ( TIME__TUTime Time, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrTime[TIME__STR_TIME_SZ]; + + sprintf ( VStrTime, "%.2d:%.2d:%.2d|%.2d", Time.Time.Hour, Time.Time.Min, Time.Time.Sec, Time.Time.Cent ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_TIME_SZ) ) { + sprintf ( PtDestStr, "%s", VStrTime ); + } + + return (VStrTime); +} + + +// 23/05/2010 + +char* TIME__FTime2Str ( UInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + +// 23/05/2010 + +char* TIME__FTime2Str ( SInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = (UInt32) Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/time.def b/include/pxi_daq_lib_v.2.1/time.def new file mode 100755 index 0000000..a4ec9f1 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/time.def @@ -0,0 +1,40 @@ + + +/******************************************************************************* +File : x:\lib\com\time\time.def +Goal : Macros definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_DEF +#define TIME_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define TIME__STR_DATE_SZ 11 +#define TIME__STR_TIME_SZ 11 + +#define TIME__LANG_FRENCH 0 +#define TIME__LANG_ENGLISH 1 + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/time.h b/include/pxi_daq_lib_v.2.1/time.h new file mode 100755 index 0000000..5ccbaa4 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/time.h @@ -0,0 +1,39 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.h +Goal : Functions prototypes of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* DIU_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + + + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef TIME_H + #define TIME_H + #endif +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/time.typ b/include/pxi_daq_lib_v.2.1/time.typ new file mode 100755 index 0000000..3d88f0e --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/time.typ @@ -0,0 +1,140 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.typ +Goal : Types definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_TYP +#define TIME_TYP + + +/* =========================== */ +/* Date S => Short date format */ +/* Eg : 01/01/10 */ +/* =========================== */ + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aa in W32 + // B31B24 B23B16 B15B08 B07B00 + // 00 Day Month Year + + SInt8 Year; + SInt8 Month; + SInt8 Day; + SInt8 NotUsed; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateS; + + +typedef union { + + UInt32 W32; + + TIME__TSDateS Date; + +} TIME__TUDateS; + + + +/* ========================== */ +/* Date L => Long date format */ +/* Eg : 01/01/2010 */ +/* ========================== */ + + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aaaa in W32 + // B31B24 B23B16 B15B00 + // Day Month Year + + SInt16 Year; + SInt8 Month; + SInt8 Day; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateL; + + +typedef union { + + UInt32 W32; + + TIME__TSDateL Date; + +} TIME__TUDateL; + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + TIME__TUDateL ADates[7]; + +} TIME__TListDatesLOfWeek; + + +/* =============================== */ +/* Time : Hour - Min - Sec - 1/100 */ +/* Eg : 21/05/2010 */ +/* =============================== */ + + +typedef struct { + + // Fields order MUST be Hour - Min - Sec - 1/100 -> Don't modify it + // B31B24 B23B16 B15B08 B07B00 + // Hour Min Sec Cent + + SInt8 Cent; + SInt8 Sec; + SInt8 Min; + SInt8 Hour; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSTime; + + +typedef union { + + UInt32 W32; + + TIME__TSTime Time; + +} TIME__TUTime; + + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/time.var b/include/pxi_daq_lib_v.2.1/time.var new file mode 100755 index 0000000..3b0fee6 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/time.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.var +Goal : Variables definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_VAR +#define TIME_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN SInt8 TIME_VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/tools.h b/include/pxi_daq_lib_v.2.1/tools.h new file mode 100755 index 0000000..7618a9c --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/tools.h @@ -0,0 +1,47 @@ + +/******************************************************************************* +File : x:\lib\win\tools\tools.h +Goal : Functions prototypes of tools library. +Prj date : 31/07/2007 +File date : 31/07/2007 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef WIN_TOOLS_H + +#include "func_header.def" + + +FHEAD ( int FEdit2DecInt ( TEdit* Ed );) +FHEAD ( int FEdit2HexInt ( TEdit* Ed );) +FHEAD ( float FEdit2Float ( TEdit* Ed );) +FHEAD ( char* FEdit2Char ( TEdit* Ed );) +FHEAD ( void FEdit2CharBuff ( TEdit* Ed, char* PtDest );) +FHEAD ( float FPCh2Float ( char* Str );) +FHEAD ( void FDecInt2Edit ( int Data, TEdit* Ed );) +FHEAD ( void FHexInt2Edit ( int Data, TEdit* Ed );) +FHEAD ( void FFloat2Edit ( float Data, TEdit* Ed );) +FHEAD ( SInt32 FChar2Edit ( char* Text, TEdit* Ed );) +FHEAD ( char* FFloat2PCh ( float Data );) +FHEAD ( char* FStr2PCh ( AnsiString* Str );) +FHEAD ( char* FEdit2PCh ( TEdit* Ed );) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef WIN_TOOLS_H + #define WIN_TOOLS_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/types.def b/include/pxi_daq_lib_v.2.1/types.def new file mode 100755 index 0000000..05619d9 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/types.def @@ -0,0 +1,34 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.def +Goal : Limits of types. + : +Prj date : 2000 - 2002 +File date : +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*************************************************************/ + + +/*H**************************************************************************** +FILE : Types.def +BUT : Define types limts. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_DEF +#define TYPES_DEF + + +#define TYP_MIN_SINT32 0x80000000 +#define TYP_MAX_SINT32 0x7FFFFFFF + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/types.typ b/include/pxi_daq_lib_v.2.1/types.typ new file mode 100755 index 0000000..e92bdb7 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/types.typ @@ -0,0 +1,187 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.typ +Goal : Common basic types definitions. + : I never use default C types names ( char, int ... ) + : i redefined them here ( SInt8, UInt32 ... ). + : + : If something go wong on you'r plateform with C types + : definition you need to update this file. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +/*H**************************************************************************** +FILE : Types.Typ +BUT : Define types. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_TYP +#define TYPES_TYP + + // typedef enum ELang { ELang_FRENCH, ELang_ENGLISH, ELang_GERMAN, ELang_LANG_NB } TLang; + +#ifndef NODEFTYPCHAR + +/* +17/11/04 GC + +BCPPB declares an identfier with the same name " Char " +this problem happens while compiling Mimo* JTAG application (MP). +This Char identifier is used in SpinEdit object. + +MP used conditionnal compilation, i decided to remove this Char +type definition, because i believe i never use it. +Wait and see ... + +*/ + +/* typedef unsigned char Char; */ + +#endif + +#ifndef UInt8 + typedef unsigned char UInt8; +#endif + +#ifndef UByte + typedef UInt8 UByte; +#endif + +#ifndef SInt8 + typedef char SInt8; +#endif + +#ifndef SByte + typedef SInt8 SByte; +#endif + +#ifndef UInt16 + typedef unsigned short UInt16; +#endif + +#ifndef UWord + typedef UInt16 UWord; +#endif + +#ifndef SInt16 + typedef short SInt16; +#endif + +#ifndef SWord + typedef SInt16 SWord; +#endif +#ifndef CC_64B +// 32 bits +#ifndef UInt32 + typedef unsigned long int UInt32; +// typedef unsigned int UInt32; // correction for 64bits, JB 2011/10/28 +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + typedef long int SInt32; +// typedef int SInt32; // correction for 64bits, JB 2014/10/16 +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif +#else +// 64 bits + +#ifndef UInt32 + typedef unsigned int UInt32; +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + typedef int SInt32; +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif +#endif + + +#ifdef CC_UNIX + +#ifndef UInt64 + typedef int64_t UInt64; +#endif + +#ifndef SInt64 + //typedef uint64_t SInt64; + typedef ULong64_t SInt64; +#endif + +#else + +#ifndef UInt64 + typedef unsigned __int64 UInt64; +#endif + +#ifndef SInt64 + typedef __int64 SInt64; +#endif + + +#endif + + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/ult1.c b/include/pxi_daq_lib_v.2.1/ult1.c new file mode 100755 index 0000000..558116a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1.c @@ -0,0 +1,7294 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1.c +Goal : Functions of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_C +#define ULT1_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// $ SInt32 ULT1__FBegin ( SInt8 FileErrLogLvl, char* FileErrFile ) { + +// $ ULT1__VGContext.FileErrLogLvl = FileErrLogLvl; +// $ strcpy ( ULT1__VGContext.FileErrFile, FileErrFile ); + +// $ err_retok (( ERR_OUT, "" )); +// $} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// $SInt32 ULT1__FEnd () { + + +// $ err_retok (( ERR_OUT, "" )); +// $} + + + +/* ------------------------------ */ +/* General functions for MAPS */ +/* ------------------------------ */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__MAPS__FRegDiscriCumulResetHit ( SInt32* PtDestCumul, SInt16 DiscriNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + PtDestCumul[Vi] = 0; + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__MAPS__FRegDiscriCumulAddHit ( SInt8* PtSrcDiscri, SInt32* PtDestCumul, SInt16 DiscriNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + + if ( PtSrcDiscri[Vi] == 1 ) { + ++PtDestCumul[Vi]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 27/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__MAPS__FRegDiscriCumulCalcPercent ( SInt32* PtSrcCumul, float* PtDestPercent, SInt16 DiscriNb, SInt16 EvNb ) { + + SInt16 Vi; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + PtDestPercent[Vi] = 100* ((float) PtSrcCumul[Vi] / (float) EvNb); + } + + err_retok (( ERR_OUT, "" )); +} + + +// 25/02/2009 + +SInt32 ULT1__MAPS__FRegDiscriCumulCountHits ( SInt32* PtSrcCumul, float* PtDestPercent, SInt16 DiscriNb, SInt16 EvNb ) { + + SInt16 Vi; + SInt32 VHiCnt; + + VHiCnt = 0; + + for ( Vi=0; Vi < DiscriNb; Vi++ ) { + VHiCnt = VHiCnt + PtSrcCumul[Vi]; + PtDestPercent[Vi] = PtSrcCumul[Vi]; + } + + // err_retok (( ERR_OUT, "" )); + + return (VHiCnt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Set parameter FirstW16 or LastW16 to -1 to avoid data W16 printing +: +Level : +Date : 16/02/2009 +Rev : 17/06/2009 + : - Print Triger + +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1_FPrintZsFFrameRawHeader ( ULT1__TZsFFrameRaw* Pt ) { + + UInt16 Vi; + + err_retnull ( Pt, (ERR_OUT,"Pt == NULL") ); + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "AsicNo = %4d [D]", Pt->SStatus.AsicNo )); + msg (( MSG_OUT, "AcqNo = %4d [D]", Pt->SStatus.AcqNo )); + msg (( MSG_OUT, "FrameNoInAcq = %4d [D]", Pt->SStatus.FrameNoInAcq )); + msg (( MSG_OUT, "FrameNoInRun = %4d [D]", Pt->SStatus.FrameNoInRun )); + msg (( MSG_OUT, "TrigSignalLine = %4d [D]", Pt->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE] )); + msg (( MSG_OUT, "TrigSignalClk = %4d [D]", Pt->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_CLK] )); + msg (( MSG_OUT, "TrigLine = %4d [D]", Pt->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__LINE] )); + msg (( MSG_OUT, "TotTrigNb = %4d [D]", Pt->SStatus.ATrigRes[ASIC__ULT1_TRIG_TOT_NB] )); + msg (( MSG_OUT, "----------------------------------------" )); + msg (( MSG_OUT, "Header = %4x [H]", Pt->Header )); + msg (( MSG_OUT, "FrameCnt = %4d [D]", Pt->FrameCnt )); + msg (( MSG_OUT, "DataLength = %4x [H]", Pt->DataLength )); + msg (( MSG_OUT, " - DataLength[0] = %4d [D]", (Pt->DataLength) & 0x0000FFFF )); + msg (( MSG_OUT, " - DataLength[1] = %4d [D]", (Pt->DataLength) >> 16 )); + msg (( MSG_OUT, "Trailer = %4x [H]", Pt->Trailer )); + msg (( MSG_OUT, "Zero = %4x [H]", Pt->Zero )); + msg (( MSG_OUT, "Zero2 = %4x [H]", Pt->Zero2 )); + msg (( MSG_OUT, "=======================================" )); + + msg (( MSG_OUT, "" )); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Set parameter FirstW16 or LastW16 to -1 to avoid data W16 printing +: +Level : +Date : 09/12/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1_FPrintZsFFrameRaw ( ULT1__TZsFFrameRaw* Pt, SInt16 FirstW16, SInt16 LastW16 ) { + + UInt16 Vi; + + err_retnull ( Pt, (ERR_OUT,"Pt == NULL") ); + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "Header = %4x [H]", Pt->Header )); + msg (( MSG_OUT, "FrameCnt = %4x [H]", Pt->FrameCnt )); + msg (( MSG_OUT, "DataLength = %4x [H]", Pt->DataLength )); + msg (( MSG_OUT, " - DataLength[0] = %4d [D]", (Pt->DataLength) & 0x0000FFFF )); + msg (( MSG_OUT, " - DataLength[1] = %4d [D]", (Pt->DataLength) >> 16 )); + msg (( MSG_OUT, "Trailer = %4x [H]", Pt->Trailer )); + msg (( MSG_OUT, "Zero = %4x [H]", Pt->Zero )); + msg (( MSG_OUT, "Zero2 = %4x [H]", Pt->Zero2 )); + msg (( MSG_OUT, "=======================================" )); + + if ( (FirstW16 < 0) || (LastW16 < 0) || (LastW16 < FirstW16) ) { + err_retok (( ERR_OUT, "No W16 to print OR bad parameters ? FirstW16=%d - LastW16=%d", FirstW16, LastW16 )); + } + + for ( Vi=FirstW16; Vi <= LastW16; Vi++ ) { + msg (( MSG_OUT, "[W %4d] = %4x [H] - %4d [D]", Vi, Pt->ADataW16[Vi], Pt->ADataW16[Vi] )); + } + + msg (( MSG_OUT, "=======================================" )); + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* ------------------------------ */ +/* Specific functions for ULT1 */ +/* ------------------------------ */ + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FRegDiscriConvBitToW32 ( SInt8* PtSrc, UInt32* PtDest, SInt16 DiscriW32Sz ) { + + + SInt32 ViDiscri; + SInt32 ViDestW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViDestW32=0; ViDestW32 < DiscriW32Sz; ViDestW32++ ) { + + PtDest[ViDestW32] = 0; + VMask = 1; + + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + + if ( PtSrc[ViDiscri] == 1 ) { + PtDest[ViDestW32] = PtDest[ViDestW32] + VMask; + } + + VMask = VMask << 1; + ++ViDiscri; + } + + } + + //err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FRegDiscriConvW32ToBit ( UInt32* PtSrc, SInt8* PtDest, SInt16 DiscriW32Sz ) { + + + SInt32 ViDiscri; + SInt32 ViSrcW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViSrcW32=0; ViSrcW32 < DiscriW32Sz; ViSrcW32++ ) { + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (PtSrc[ViSrcW32] & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + } + + return (0); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FRegDiscriConvW32ToBitAsW32 ( UInt32* PtSrc, SInt32* PtDest, SInt16 DiscriW32Sz ) { + + char VFuncName[] = "ULT1__FRegDiscriConvW32ToBitAsW32"; + + SInt32 ViDiscri; + SInt32 ViSrcW32; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + + for ( ViSrcW32=0; ViSrcW32 < DiscriW32Sz; ViSrcW32++ ) { + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (PtSrc[ViSrcW32] & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + } + + return (0); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FMatDiscriConvW32ToBit ( ULT1__TMatDiscriW32* PtSrc, ULT1__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + ULT1__FRegDiscriConvW32ToBit ( PtSrc->AALineW32[ViLine], PtDest->AALineCol[ViLine], ULT1__REG_DISCRI_W32_SZ ); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FMatDiscriConvW32ToBitAsW32 ( ULT1__TMatDiscriW32* PtSrc, SInt32* PtDest ) { + + char VFuncName[] = "ULT1__FMatDiscriConvW32ToBitAsW32"; + + SInt32 ViLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + ULT1__FRegDiscriConvW32ToBitAsW32 ( PtSrc->AALineW32[ViLine], &PtDest[ViLine * 1152], ULT1__REG_DISCRI_W32_SZ ); + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 07/03/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FQuaterMatDiscriBitAsW32Copy ( SInt32* PtSrc, SInt32* PtDest, SInt8 Matrix ) { + + char VFuncName[] = "ULT1__FQuaterMatDiscriBitAsW32Copy"; + + SInt32 ViLine; + SInt32 ViCol; + SInt32 ViPixSrc; + SInt32 ViPixDest; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + ViPixDest = 0; + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < 288; ViCol++ ) { + ViPixSrc = (ViLine * 1152) + ViCol; + PtDest[ViPixDest] = PtSrc[ViPixSrc]; + ++ViPixDest; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FMatDiscriEmulHit ( ULT1__TMatDiscriBit* PtDest, SInt16 Hit0Line, SInt16 Hit0Col, SInt16 Hit1Line, SInt16 Hit1Col, SInt16 Hit2Line, SInt16 Hit2Col, SInt16 Hits0AllCol, SInt16 Hits1AllCol, SInt16 Hits2AllCol ) { + + SInt32 ViLine; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + // Reset all hits + + memset ( PtDest, 0, sizeof (ULT1__TMatDiscriBit) ); + + // Hit 0 + + if ( (Hit0Line >= 0) && (Hit0Col >= 0) ) { + PtDest->AALineCol[Hit0Line][Hit0Col] = 1; + } + + // Hit 1 + + if ( (Hit1Line >= 0) && (Hit1Col >= 0) ) { + PtDest->AALineCol[Hit1Line][Hit1Col] = 1; + } + + // Hit 2 + + if ( (Hit2Line >= 0) && (Hit2Col >= 0) ) { + PtDest->AALineCol[Hit2Line][Hit2Col] = 1; + } + + // Hits 0 on all lines of one col + + if ( Hits0AllCol >= 0 ) { + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + PtDest->AALineCol[ViLine][Hits0AllCol] = 1; + } + } + + // Hits 1 on all lines of one col + + if ( Hits1AllCol >= 0 ) { + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + PtDest->AALineCol[ViLine][Hits1AllCol] = 1; + } + } + + // Hits 2 on all lines of one col + + if ( Hits2AllCol >= 0 ) { + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + PtDest->AALineCol[ViLine][Hits2AllCol] = 1; + } + } + + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FRegDiscriResetHit ( SInt8* PtDest, SInt16 DiscriBitSz ) { + + SInt16 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // Reset row + + for ( ViCol=0; ViCol < DiscriBitSz; ViCol++ ) { + PtDest[ViCol] = 0; + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 21/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FRegDiscriPrintHit ( SInt8* PtSrc ) { + + SInt16 ViCol; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + + msg (( MSG_OUT, "*************************************" )); + msg (( MSG_OUT, "* Print coordinates pixels with hit *" )); + msg (( MSG_OUT, "*************************************" )); + + // Scan row => Print coordinates if hit + + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc[ViCol] == 1 ) { + msg (( MSG_OUT, "Hit => Col [%.4d]", ViCol )); + } + + } + + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FRegDiscriCompare ( SInt8* PtSrc, SInt8* PtRef, SInt8 PrintErrors ) { + + SInt16 ViCol; + SInt32 VErrCnt; + + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtRef, (ERR_OUT,"PtRef == NULL") ); + + // Scan row => Print if error + + VErrCnt = 0; + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc[ViCol] != PtRef[ViCol] ) { + + ++VErrCnt; + + if ( PrintErrors ) { + msg (( MSG_OUT, "Error => Col [%.4d] Read=%d - Must be=%d", ViCol, PtSrc[ViCol], PtRef[ViCol] )); + } + + } + + } + + + err_retval ( VErrCnt, ( ERR_OUT, "Compare done %d errors found !", VErrCnt ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/03/2011 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FMatDiscriResetHit ( ULT1__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + // Scan matrix => Reset hits + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 0; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FMatDiscriPrintHit ( char* CmtStrTitle, SInt8 CmtSInt8MapsId, ULT1__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + msg (( MSG_OUT, "***************************************************************************" )); + msg (( MSG_OUT, "* Mi28 [%d] %s : Coordinates pixels with hit *", CmtSInt8MapsId, CmtStrTitle )); + msg (( MSG_OUT, "***************************************************************************" )); + + // Scan matrix => Print coordinates if hit + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtDest->AALineCol[ViLine][ViCol] == 1 ) { + msg (( MSG_OUT, "Hit => Line [%.4d] - Col [%.4d]", ViLine, ViCol )); + } + + } + + } + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FMatDiscriCumulResetHit ( ULT1__TMatDiscriCumul* PtDest ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 0; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FMatDiscriCumulAddHit ( ULT1__TMatDiscriBit* PtSrc, ULT1__TMatDiscriCumul* PtDest ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + ++ PtDest->AALineCol[ViLine][ViCol]; + } + + } + + } + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FMatDiscriCumulCalcPercent ( ULT1__TMatDiscriCumul* PtSrc, ULT1__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + PtDest->AALineCol[ViLine][ViCol] = 100 * ( (float) PtSrc->AALineCol[ViLine][ViCol] / (float) EvNb); + } + + } + + err_retok (( ERR_OUT, "" )); +} + +// 06/03/2009 +// Return mean % value of whole matrix +// 23/01/2013 +// - Calculates VMatPerCent on the whole matrix, before it was done on 1/4 matrix assuming +// that Ultimate was tested matrix by matrix = threshold set to 255 on the three matrices not tested + +float ULT1__FExtMatDiscriCumulCalcPercent ( ULT1__TMatDiscriCumul* PtSrc, ULT1__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + float VPixPerCent; + float VSumPerCent; + float VMatPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + VSumPerCent = 0; + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + VPixPerCent = ( (float) PtSrc->AALineCol[ViLine][ViCol] / (float) EvNb); + PtDest->AALineCol[ViLine][ViCol] = 100 * VPixPerCent; + VSumPerCent = VSumPerCent + VPixPerCent; + } + + } + + // 23/01/2013 + + VMatPerCent = 100 * ( (float) VSumPerCent / (float) (ULT1__MAT_DISCRI_COL_NB * ULT1__MAT_DISCRI_USEFUL_LINES_NB) ); + + err_retval ( VMatPerCent, ( ERR_OUT, "Matrix %d [%]", VMatPerCent ) ); +} + + +// 25/02/2009 + +SInt32 ULT1__FMatDiscriCumulCountHits ( ULT1__TMatDiscriCumul* PtSrc, ULT1__TMatDiscriPerCent* PtDest, SInt16 EvNb ) { + + SInt16 ViLine; + SInt16 ViCol; + SInt32 VHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + VHitCnt = 0; + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + VHitCnt = VHitCnt + PtSrc->AALineCol[ViLine][ViCol]; + PtDest->AALineCol[ViLine][ViCol] = PtSrc->AALineCol[ViLine][ViCol]; + } + + } + + // err_retok (( ERR_OUT, "" )); + + // msg (( MSG_OUT, "VHitCnt = %d", VHitCnt )); + + return (VHitCnt); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriCopySubMatBit ( ULT1__TMatDiscriBit* PtSrc, ULT1__TQuaterMatDiscriBit* PtDest, SInt8 SubMatId ) { + + SInt16 ViLine; + SInt16 ViColSrc; + SInt16 ViColDest; + SInt16 VFirstColSrc; + SInt16 VLastColSrc; + SInt16 VSubMatColNb; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + VSubMatColNb = ULT1__REG_DISCRI_BIT_SZ / 4; + + switch ( SubMatId ) { + + case 0 : { + VFirstColSrc = 0; + VLastColSrc = VFirstColSrc + VSubMatColNb - 1; + break; } + + case 1 : { + VFirstColSrc = VSubMatColNb; + VLastColSrc = VFirstColSrc + VSubMatColNb - 1; + break; } + + case 2 : { + VFirstColSrc = 2 * VSubMatColNb; + VLastColSrc = VFirstColSrc + VSubMatColNb - 1; + break; } + + case 3 : { + VFirstColSrc = 3 * VSubMatColNb; + VLastColSrc = VFirstColSrc + VSubMatColNb - 1; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown sub mat id = %d <> 0, 1, 2, 3", SubMatId) ); + break; } + + } /* End switch */ + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + ViColDest = 0; + + for ( ViColSrc=VFirstColSrc; ViColSrc <= VLastColSrc; ViColSrc++) { + + PtDest->AALineCol[ViLine][ViColDest] = PtSrc->AALineCol[ViLine][ViColSrc]; + ++ViColDest; + + } /* End for ViColSrc */ + + + } /* End for ViLine */ + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatConvBitToColState ( ULT1__TMatDiscriBit* PtSrc, ULT1__TMatDiscriColor* PtDest, ULT1__TColor ColorStateZero, ULT1__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ULT1__REG_DISCRI_BIT_SZ - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ULT1__REG_DISCRI_BIT_SZ - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatFullScaleConvCoinBitToColState ( ULT1__TMatDiscriBit* PtSrc, ULT1__TMatDiscriColor* PtDest, ULT1__TColor ColorZeroHit, ULT1__TColor* AColorOneHit, ULT1__TColor ColorMultiHit, SInt8 RevertLineDirection ) { + + UInt16 VMatLineNb = ULT1__MAT_DISCRI_LINES_NB; + UInt16 VMatColNb = ULT1__REG_DISCRI_BIT_SZ; + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPixState; + ULT1__TColor VPixColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + /* --------------------- */ + /* Revert line direction */ + /* --------------------- */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][VMatColNb - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* --------------------------- */ + /* Don't revert line direction */ + /* --------------------------- */ + + else { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatConvCoinBitToColStateHalfScale ( ULT1__TMatDiscriBitHalfScale* PtSrc, ULT1__TMatDiscriColorHalfScale* PtDest, ULT1__TColor ColorZeroHit, ULT1__TColor* AColorOneHit, ULT1__TColor ColorMultiHit, SInt8 RevertLineDirection ) { + + UInt16 VMatLineNb = ULT1__MAT_DISCRI_LINES_NB / 2; + UInt16 VMatColNb = ULT1__REG_DISCRI_BIT_SZ / 2; + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPixState; + ULT1__TColor VPixColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + /* --------------------- */ + /* Revert line direction */ + /* --------------------- */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][VMatColNb - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* --------------------------- */ + /* Don't revert line direction */ + /* --------------------------- */ + + else { + + for ( ViLine=0; ViLine < VMatLineNb; ViLine++ ) { + + for ( ViCol=0; ViCol < VMatColNb; ViCol++ ) { + + VPixState = PtSrc->AALineCol[ViLine][ViCol]; + + while (1) { + + // No hit + + if ( VPixState == 0 ) { + VPixColor = ColorZeroHit; + break; + } + + // One hit => Set color of corresponding plane + + if ( VPixState <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + VPixColor = AColorOneHit[VPixState - 1]; + break; + } + + // Multi hit => Set multi hits color + + VPixColor = ColorMultiHit; + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatConvBitToColStateHalfScale ( ULT1__TMatDiscriBitHalfScale* PtSrc, ULT1__TMatDiscriColorHalfScale* PtDest, ULT1__TColor ColorStateZero, ULT1__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + SInt32 VMaxCol; + SInt32 VMaxLine; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + VMaxCol = ULT1__REG_DISCRI_BIT_SZ / 2; + VMaxLine = ULT1__MAT_DISCRI_LINES_NB / 2; + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < VMaxLine; ViLine++ ) { + + for ( ViCol=0; ViCol < VMaxCol; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][VMaxCol - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][VMaxCol - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < VMaxLine; ViLine++ ) { + + for ( ViCol=0; ViCol < VMaxCol; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 28/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriQuaterMatConvBitToColState ( ULT1__TQuaterMatDiscriBit* PtSrc, ULT1__TQuaterMatDiscriColor* PtDest, ULT1__TColor ColorStateZero, ULT1__TColor ColorStateOne, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ / 4); ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][(ULT1__REG_DISCRI_BIT_SZ / 4) - 1 - ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][(ULT1__REG_DISCRI_BIT_SZ / 4) - 1 - ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ / 4); ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 1 ) { + PtDest->AALineCol[ViLine][ViCol] = ColorStateOne; + } + + else { + PtDest->AALineCol[ViLine][ViCol] = ColorStateZero; + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriCopySubMatPerCent ( ULT1__TMatDiscriPerCent* PtSrc, ULT1__TQuaterMatDiscriPerCent* PtDest, SInt8 SubMatId ) { + + SInt16 ViLine; + SInt16 ViColSrc; + SInt16 ViColDest; + SInt16 VFirstColSrc; + SInt16 VLastColSrc; + SInt16 VSubMatColNb; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + VSubMatColNb = ULT1__REG_DISCRI_BIT_SZ / 4; + + switch ( SubMatId ) { + + case 0 : { + VFirstColSrc = 0; + VLastColSrc = VFirstColSrc + VSubMatColNb - 1; + break; } + + case 1 : { + VFirstColSrc = VSubMatColNb; + VLastColSrc = VFirstColSrc + VSubMatColNb - 1; + break; } + + case 2 : { + VFirstColSrc = 2 * VSubMatColNb; + VLastColSrc = VFirstColSrc + VSubMatColNb - 1; + break; } + + case 3 : { + VFirstColSrc = 3 * VSubMatColNb; + VLastColSrc = VFirstColSrc + VSubMatColNb - 1; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown sub mat id = %d <> 0, 1, 2, 3", SubMatId) ); + break; } + + } /* End switch */ + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + ViColDest = 0; + + for ( ViColSrc=VFirstColSrc; ViColSrc <= VLastColSrc; ViColSrc++) { + + PtDest->AALineCol[ViLine][ViColDest] = PtSrc->AALineCol[ViLine][ViColSrc]; + ++ViColDest; + + } /* End for ViColSrc */ + + + } /* End for ViLine */ + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatConvPerCentToColVal ( ULT1__TMatDiscriPerCent* PtSrc, ULT1__TMatDiscriColor* PtDest, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][ULT1__REG_DISCRI_BIT_SZ - 1 - ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][ULT1__REG_DISCRI_BIT_SZ - 1 - ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatConvCumulToColVal ( ULT1__TMatDiscriCumul* PtSrc, ULT1__TMatDiscriColor* PtDest, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + ULT1__TColor VHitStateColor; + ULT1__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + if ( GrayOrBlueLevels == 0) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][(ULT1__REG_DISCRI_BIT_SZ) - 1 - ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatConvCumulToColValHalfScale ( ULT1__TMatDiscriCumulHalfScale* PtSrc, ULT1__TMatDiscriColorHalfScale* PtDest, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection, SInt8 PrintLvl ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + ULT1__TColor VHitStateColor; + ULT1__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "==============================================" )); + err_error (( ERR_OUT, "= ULT1__FDiscriMatConvCumulToColValHalfScale =" )); + err_error (( ERR_OUT, "==============================================" )); + } + + + if ( GrayOrBlueLevels == 0) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + err_error (( ERR_OUT, "Blue=%d - HitCnt=%d", GrayOrBlueLevels, PlotHitOrHitCnt )); + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][(ULT1__REG_DISCRI_BIT_SZ / 2) - 1 - ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VHitColor = clWhite; + break; + } + + // Hit & Plot state NOT count => Set VHitStateColor if VPixHitCnt > 0 + + if ( PlotHitOrHitCnt == 0) { + VHitColor = VHitStateColor; + break; + } + + // Hit & ovf + // This test MUST be done BEFORE gray / blue level plot + + if ( VPixHitCnt > 255 ) { + VHitColor = clRed; + break; + } + + // Plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VHitColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // Plot count in blue levels + + VHitColor = 0x00FFFF00 + ( (255-VPixHitCnt) << 8 ); // Blue = 255 / Green = 255 / Red = 255 - VPixHitCnt + break; + + } // End while (1) + + PtDest->AALineCol[ViLine][ViCol] = VHitColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + err_error (( ERR_OUT, "==============================================" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatConvCumulCoinOrToColVal ( ULT1__TMatDiscriCumul* PtSrc, ULT1__TMatDiscriColor* PtDest, ULT1__TColor* AColorOneHit, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + ULT1__TColor VPixColor; + ULT1__TColor VHitStateColor; + ULT1__TColor VHitColor; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( GrayOrBlueLevels == 0 ) { + VHitStateColor = clBlack; + } + + else { + VHitStateColor = clBlue; + } + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + PtDest->AALineCol[ViLine][ULT1__REG_DISCRI_BIT_SZ - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 25/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriMatConvCumulCoinOrToColValHalfScale ( ULT1__TMatDiscriCumulHalfScale* PtSrc, ULT1__TMatDiscriColorHalfScale* PtDest, ULT1__TColor* AColorOneHit, SInt8 GrayOrBlueLevels, SInt8 PlotHitOrHitCnt, SInt8 RevertLineDirection, SInt8 PrintLvl ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + UInt16 VFFMinusPixHitCnt; + ULT1__TColor VPixColor; + ULT1__TColor VHitStateColor; + ULT1__TColor VHitColor; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "====================================================" )); + err_error (( ERR_OUT, "= ULT1__FDiscriMatConvCumulCoinOrToColValHalfScale =" )); + err_error (( ERR_OUT, "====================================================" )); + } + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + + PtDest->AALineCol[ViLine][(ULT1__REG_DISCRI_BIT_SZ / 2) - 1 - ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ / 2); ViCol++ ) { + + + while (1) { + + VPixHitCnt = PtSrc->AALineCol[ViLine][ViCol]; + + // No hit + + if ( VPixHitCnt == 0 ) { + VPixColor = clWhite; + break; + } + + // Count only one hit => Set color of plane + + if ( VPixHitCnt <= MAPS__TCDigTelMon_MAX_PLANE_NB) { + VPixColor = AColorOneHit[VPixHitCnt - 1]; + break; + } + + // More than one hit & plot ONLY state, not count + + if ( PlotHitOrHitCnt == 0 ) { + VPixColor = VHitStateColor; + break; + } + + // More than one hit & ovf + // This test MUST be done BEFORE gay / blue levels plot + + if ( VPixHitCnt > 255 ) { + VPixColor = clRed; + break; + } + + // More than one hit & plot count in gray levels + + if ( GrayOrBlueLevels == 0 ) { + VFFMinusPixHitCnt = 255 - VPixHitCnt; + VPixColor = VFFMinusPixHitCnt + (VFFMinusPixHitCnt << 8) + (VFFMinusPixHitCnt << 16); + break; + } + + // More than one hit & plot count in blue levels + + VPixColor = 0x00FF0000 + ((255-VPixHitCnt) << 8); // Blue = 255 + Green = 255 - VPixHitCnt + break; + + } // En while (1) + + + PtDest->AALineCol[ViLine][ViCol] = VPixColor; + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + err_error (( ERR_OUT, "==============================================" )); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FPrintMatDiscriCumul ( ULT1__TMatDiscriCumul* PtSrc ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + + err_error (( ERR_OUT, "===============================" )); + err_error (( ERR_OUT, "= Print ULT1__TMatDiscriCumul =" )); + err_error (( ERR_OUT, "===============================" )); + + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] != 0 ) { + err_error (( ERR_OUT, "Hit cnt [L:%4d][C:%4d] = %4d", ViLine, ViCol, PtSrc->AALineCol[ViLine][ViCol] )); + } + + } + + } + + err_error (( ERR_OUT, "===============================" )); + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FPrintMatDiscriCumulHalfScale ( ULT1__TMatDiscriCumulHalfScale* PtSrc ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt16 VPixHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + + err_error (( ERR_OUT, "========================================" )); + err_error (( ERR_OUT, "= Print ULT1__TMatDiscriCumulHalfScale =" )); + err_error (( ERR_OUT, "========================================" )); + + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB / 2; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ / 2; ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] != 0 ) { + err_error (( ERR_OUT, "Hit cnt [L:%4d][C:%4d] = %4d", ViLine, ViCol, PtSrc->AALineCol[ViLine][ViCol] )); + } + + } + + } + + err_error (( ERR_OUT, "========================================" )); + + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 29/01/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FDiscriQuaterMatConvCumulToColVal ( ULT1__TQuaterMatDiscriPerCent* PtSrc, ULT1__TQuaterMatDiscriColor* PtDest, SInt8 RevertLineDirection ) { + + SInt32 ViLine; + SInt32 ViCol; + UInt8 VPerCent; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc = NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest = NULL") ); + + + + /* Revert line direction */ + + if ( RevertLineDirection == 1 ) { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ / 4); ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][(ULT1__REG_DISCRI_BIT_SZ / 4) - 1 - ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][(ULT1__REG_DISCRI_BIT_SZ / 4) - 1 - ViCol] = (VPerCent << 8) + (VPerCent << 16); + } + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End if RevertLineDirection */ + + /* Don't revert line direction */ + + else { + + for ( ViLine=0; ViLine < ULT1__MAT_DISCRI_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < (ULT1__REG_DISCRI_BIT_SZ / 4); ViCol++ ) { + + if ( PtSrc->AALineCol[ViLine][ViCol] == 0 ) { + PtDest->AALineCol[ViLine][ViCol] = clWhite; + } + + else { + VPerCent = 2 * ((UInt8) PtSrc->AALineCol[ViLine][ViCol]); + PtDest->AALineCol[ViLine][ViCol] = (VPerCent << 8) + (VPerCent << 16);; + } + + + } /* End for ViCol */ + + } /* End for ViLine */ + + } /* End else */ + + + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : convert 32 word of 8 bits to a word of 32 bits +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Mathieu GOFFE +E-mail : mathieu.goffe@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef ULT1__MG_DEV + +SInt32 ULT1__FnameDiscriConvBitToW32 ( UInt8* PtDest, UInt32 word ) { + + + SInt32 ViDiscri; + UInt32 VMask; + SInt8 ViBitInW32; + + err_retnull ( word, (ERR_OUT,"word == NULL") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL") ); + + + ViDiscri = 0; + VMask = 1; + for ( ViBitInW32=0; ViBitInW32 < 32; ViBitInW32++ ) { + PtDest[ViDiscri] = ( (word & VMask) != 0 ); + VMask = VMask << 1; + ++ViDiscri; + } + msg (( MSG_OUT, "valeur du mot de 32 bit = %d", word )); + return (0); +} + +#else + +SInt32 ULT1__FnameDiscriConvBitToW32 ( UInt8* PtDest, UInt32 word ) { + return (0); +} + +#endif + + + + + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 17/03/2009 +Doc date : 17/03/2009 +Rev : 04/05/2009 + : - Add a check of data length, if > 1140, force 1140, done to avoid bad + : data length due to transmission errors. + : + : 05/05/2009 + : - Add handling of odd number of W16 ( ULT1 add one bad W16 in this case ) + : Not done at beginning because ULT1 documentation was not clear enough + : ( bad translation of " impair " in even ! ) and it was not needed for + : tests done with emulated patterns. + : : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__FConvZsFFrameRawToZsFFrame ( ULT1__TZsFFrameRaw* Src, ULT1__TZsFFrame* Dest, SInt8 PrintLvl ) { + + SInt32 VRetW16Length; + SInt32 ViData; + UInt16 VDataW16LengthLow; + UInt16 VDataW16LengthHigh; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt16 ViSrcW16; + + ULT1__TStatesLine VStatesLine; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + SInt16 VPrevLine; + + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Get useful data length + + VDataW16LengthLow = Src->DataLength & 0x0000FFFF; + VDataW16LengthHigh = (Src->DataLength & 0xFFFF0000) >> 16; + VDataW16Length = VDataW16LengthLow + VDataW16LengthHigh; + + VRetW16Length = VDataW16Length; + + if ( (PrintLvl == 5) || (PrintLvl == 6) || (PrintLvl == 7) ) { + msg (( MSG_OUT, "TOTAL frame length : %d W16", VDataW16Length )); + msg (( MSG_OUT, "" )); + } + + // Add a check of data length, if > ULT1__ZS_FFRAME_RAW_MAX_W16, force 0 and continue processing ( no exit on error ) + + if ( VDataW16Length > ULT1__ZS_FFRAME_RAW_MAX_W16 /* 1140 */ ) { + err_error (( ERR_OUT, "Bad data length get from ULT1 = %d W16 => Force 0 W16", VDataW16Length )); + VDataW16Length = 0; + Src->DataLength = 0; + // VRetW16Length = -1; + } + + // Copy information fields + + Dest->SStatus = Src->SStatus; + + Dest->Header = Src->Header; + Dest->FrameCnt = Src->FrameCnt; + Dest->DataLength = Src->DataLength; + Dest->Trailer = Src->Trailer; + Dest->Zero = Src->Zero; + Dest->Zero2 = Src->Zero2; + + Dest->TrigSignalLine = Src->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE]; + Dest->TrigSignalClk = Src->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Src->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__LINE]; + + // Process frame + + ViSrcW16 = 0; + ViStatesLine = 0; + VPrevLine = -1; + + if ( PrintLvl == 4 ) { + msg (( MSG_OUT, "Frame data length = %d [W16]", VDataW16Length )); + msg (( MSG_OUT, "" )); + } + + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, ULT1 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Copy StatesLine field + + VStatesLine.W16 = Src->ADataW16[ViSrcW16]; + Dest->AStatesRec[ViStatesLine].StatesLine = VStatesLine; + VStatesNbPerLine = VStatesLine.F.StateNb; + + if ( (PrintLvl == 5) || (PrintLvl == 7) ) { + + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + + /* Print to show missing handling of odd W16 nb + + if ( VStatesLine.F.LineAddr <= VPrevLine ) { + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ===============> ERROR odd W16 nb NOT HANDLED ! ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + } + + else { + msg (( MSG_OUT, "Line %4d - %d states - %d Ovf ", VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf )); + VPrevLine = VStatesLine.F.LineAddr; + } + + */ + + } + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + Dest->AStatesRec[ViStatesLine].AStates[ViState].W16 = Src->ADataW16[ViSrcW16]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "--> State %d : Col %4d - %2d pixels", ViState, Dest->AStatesRec[ViStatesLine].AStates[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStates[ViState].F.HitNb + 1 )); + ++ViSrcW16; + } + + ++ViStatesLine; + + + // Add on 25/03/2011 during test with random frame size + with all data = 0 + + if ( ViStatesLine >= ULT1__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "Max number of states reached = %d => Abort => Corrupted data !", ULT1__ZS_FFRAME_MAX_STATES_REC )); + break; + } + + } // End while + + } // End if ( VDataW16Length != 0 ) + + Dest->StatesRecNb = ViStatesLine; + + if ( (PrintLvl == 5) || (PrintLvl == 6) || (PrintLvl == 7) ) { + msg (( MSG_OUT, "Conv : %d StatesLines", Dest->StatesRecNb )); + msg (( MSG_OUT, "" )); + } + + return (VRetW16Length); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 14/08/2009 +Doc date : +: +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__FConvZsFFrameRawToZsFFrameHandleTrigger ( SInt8 MapsNb, SInt32 EvNo, SInt32 TotEvNb, ULT1__TZsFFrameRaw* Src, ULT1__TZsFFrame* Dest, SInt8 PrintLvl ) { + + ULT1__TZsFFrameRaw* VPtSrcEv; + SInt32 VTrigPosFromDaq; + SInt32 VTrigLine; + SInt8 VFirstEvent; + static ULT1__TZsFFrame VASrcZsFFrameEv[2]; + SInt32 VLine; + SInt32 ViSrcStateRec; + SInt32 ViDestStateRec; + + // Check parameters + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Four events after this one are required => Abort if it's not the case + + if ( EvNo + 4 >= TotEvNb ) { + err_retfail ( -1, (ERR_OUT,"Processing stop on event %d => Less than 4 events after it !" ,EvNo) ); + } + + + // Trigger position ? + + VTrigPosFromDaq = Src->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE]; + + + if ( (VTrigPosFromDaq < 0) || (VTrigPosFromDaq > 575) ) { + err_retfail ( -1, (ERR_OUT,"Bad trigger pos from DAQ = %d <> [0..575] !", VTrigPosFromDaq) ); + } + + + // Set VPtEv on the first event to process + // - Pos < 572 => Pos correspond to current event + 1 ( next event ) + // - Pos >= 572 => Pos correspond to current event + 2 + +/* ORIGINAL => 1 plane + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 1; + } + + else { + VPtSrcEv = Src + 2; + } + +*/ + +/* 6 planes + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 7; + } + + else { + VPtSrcEv = Src + 8; + } + +*/ + + // N planes + + if ( VTrigPosFromDaq < 572 ) { + VPtSrcEv = Src + 1 + MapsNb; + } + + else { + VPtSrcEv = Src + 2 + MapsNb; + } + + + // Real trigger line = trigger position + 4 modulo 576 + + VTrigLine = (VTrigPosFromDaq + 4) % 576; + + // Debug print + + if ( PrintLvl == 1 ) { + // msg (( MSG_OUT, "=> Trig on Ev=%4d P=%4d L=%4d => Proc Ev=%4d - Ev=%4d", EvNo, VTrigPosFromDaq, VTrigLine, VPtSrcEv[0].SStatus.FrameNoInRun, VPtSrcEv[1].SStatus.FrameNoInRun )); + err_error (( ERR_OUT, "=> Trig on Ev=%4d - P=%4d - L=%4d => Proc Ev=%4d - Ev=%4d", EvNo, VTrigPosFromDaq, VTrigLine, VPtSrcEv[0].SStatus.FrameNoInRun, VPtSrcEv[1].SStatus.FrameNoInRun )); + } + + // Convert each event from ZsFFrameRaw to ZsFFrame + + ULT1__FConvZsFFrameRawToZsFFrame ( VPtSrcEv , VASrcZsFFrameEv , 0 /* PrintLvl */ ); + ULT1__FConvZsFFrameRawToZsFFrame ( VPtSrcEv + 1, VASrcZsFFrameEv + 1, 0 /* PrintLvl */ ); + + // ------------------------- + // Build destination event + // ------------------------- + + // Reset record + + memset ( Dest, 0, sizeof (ULT1__TZsFFrame) ); + + // Copy information fields + + Dest->SStatus = Src->SStatus; + + Dest->Header = Src->Header; + Dest->FrameCnt = Src->FrameCnt; + Dest->DataLength = Src->DataLength; + Dest->Trailer = Src->Trailer; + Dest->Zero = Src->Zero; + Dest->Zero2 = Src->Zero2; + + Dest->TrigSignalLine = Src->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE]; + Dest->TrigSignalClk = Src->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Src->SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__LINE]; + + // Extract lines + + ViDestStateRec = 0; + + // First event => Copy lines >= trigger pos to dest + + for ( ViSrcStateRec=0; ViSrcStateRec < VASrcZsFFrameEv->StatesRecNb; ViSrcStateRec++ ) { + + VLine = VASrcZsFFrameEv->AStatesRec[ViSrcStateRec].StatesLine.F.LineAddr; + + if ( VLine >= VTrigLine ) { + Dest->AStatesRec[ViDestStateRec] = VASrcZsFFrameEv->AStatesRec[ViSrcStateRec]; + ++ViDestStateRec; + } + + } + + if ( VTrigLine == 0 ) { + Dest->StatesRecNb = ViDestStateRec; + return (0); + } + + // Second event => Copy lines < trigger pos to dest + + for ( ViSrcStateRec=0; ViSrcStateRec < VASrcZsFFrameEv[1].StatesRecNb; ViSrcStateRec++ ) { + + VLine = VASrcZsFFrameEv[1].AStatesRec[ViSrcStateRec].StatesLine.F.LineAddr; + + if ( VLine < VTrigLine ) { + Dest->AStatesRec[ViDestStateRec] = VASrcZsFFrameEv[1].AStatesRec[ViSrcStateRec]; + ++ViDestStateRec; + } + + } + + // Update nb of StateRec + + Dest->StatesRecNb = ViDestStateRec; + + return (0); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 17/03/2009 +Rev : 22/07/2009 + : - Return number of hits found +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__FConvZsFFrameToMatDiscriBit ( ULT1__TZsFFrame* PtSrc, ULT1__TMatDiscriBit* PtDest, SInt32* PtOvfCnt, SInt8 PrintLvl ) { + + UInt16 ViLine; + UInt16 VFirstCol; + UInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesRec; + SInt8 ViState; + UInt8 VStatesNb; + SInt32 VHitCnt; + SInt32 VOfvCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (ULT1__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + // StatesRec loop + + VHitCnt = 0; + VOfvCnt = 0; + + if ( PtSrc->StatesRecNb > ULT1__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "StatesRecNb=%d > ULT1__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, ULT1__ZS_FFRAME_MAX_STATES_REC, ULT1__ZS_FFRAME_MAX_STATES_REC )); + err_error (( ERR_OUT, "StatesRecNb=%d > ULT1__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, ULT1__ZS_FFRAME_MAX_STATES_REC, ULT1__ZS_FFRAME_MAX_STATES_REC )); + PtSrc->StatesRecNb = ULT1__ZS_FFRAME_MAX_STATES_REC; + } + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.LineAddr; + + if ( PtSrc->AStatesRec[ViStatesRec].StatesLine.F.Ovf == 1 ) { + ++VOfvCnt; + // err_error (( ERR_OUT, "Ovf ! Count=%d", VOfvCnt )); + } + + // States in one StateRec loop + + // WARNING => Will slow down execution + + if ( VStatesNb > ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC ) { + err_warning (( ERR_OUT, "StatesNb=%d > ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNb, ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC, ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC )); + VStatesNb = ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC; + } + + // WARNING => Will slow down execution + + if ( ViLine >= ULT1__MAT_DISCRI_LINES_NB) { + err_warning (( ERR_OUT, "ViLine=%d >= ULT1__MAT_DISCRI_LINES_NB=%d => Force %d", ViLine, ULT1__MAT_DISCRI_LINES_NB, ULT1__MAT_DISCRI_LINES_NB - 1 )); + ViLine = ULT1__MAT_DISCRI_LINES_NB - 1; + } + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + + // WARNING => Will slow down execution + + if ( VFirstCol >= ULT1__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= ULT1__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, ULT1__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + + // WARNING => Will slow down execution + + if ( VLastCol >= ULT1__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "VLastCol=%d >= ULT1__REG_DISCRI_BIT_SZ=%d => Force 0", VLastCol, ULT1__REG_DISCRI_BIT_SZ )); + VLastCol = 0; + } + + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + if ( PtOvfCnt != NULL ) { + *PtOvfCnt = VOfvCnt; + } + + + // err_error (( ERR_OUT, "TRACE - VHitCnt=%d", VHitCnt )); // 13/02/2013 + + + return (VHitCnt); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : If UpdMatCumul = 0 +: - Don't update cumul matrix +: - BUT count hits => function return Hit nb +Level : +Date : 17/03/2009 +Rev : 22/07/2009 +: - Return number of hits found +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 OLD___ULT1__FConvZsFFrameToMatDiscriBitAndCumul ( ULT1__TZsFFrame* PtSrc, ULT1__TMatDiscriBit* PtDest, SInt8 UpdMatCumul, ULT1__TMatDiscriCumul* PtDestCum, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesRec; + SInt8 ViState; + SInt8 VStatesNb; + SInt32 VHitCnt; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + if ( UpdMatCumul ) { + err_retnull ( PtDestCum, (ERR_OUT,"PtDestCum == NULL") ); + } + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (ULT1__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "---------------------------------" )); + err_error (( ERR_OUT, " Print cumul" )); + err_error (( ERR_OUT, "---------------------------------" )); + } + + // StatesRec loop + + VHitCnt = 0; + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.LineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + PtDest->AALineCol[ViLine][ViCol] = 1; + + if ( UpdMatCumul ) { + ++ PtDestCum->AALineCol[ViLine][ViCol]; + + if ( PrintLvl ) { + err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, ViCol, PtDestCum->AALineCol[ViLine][ViCol] )); + } + + } + + ++VHitCnt; + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "-------------------------------" )); + } + + + + return (VHitCnt); +} + + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : - PtDestFrameBit -> Bit matrix of source frame + : - PtDestCoinBit -> Coin matrix of ONE frame of ALL selected planes + : - PtDestFrameCum -> Cumul matrix of ALL frames of CURRENT plane + : - PtDestCoinCum -> Cumul matrix of ALL frames of ALL selected planes + : +Globals : +Remark : This function is written in a strange way ... code duplication and + : something which looks like a " goto ". This is to avoid to have + : tests excuted in loop and therefore save execution time. + : + : + : +Level : +Date : 17/03/2009 +Rev : 22/07/2009 + : - Return number of hits found + : 25/07/2009 + : - Add Mode parameter => Handling of coincidence modes + : 02/08/2009 + : - Moved in class ULT1__TCTelMon +Doc date : 17/03/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef ROOT_ROOT + +SInt32 ULT1__TCTelMon::PrivFConvZsFFrameToMatDiscriBitAndCumul ( SInt32 DbgEvNo, SInt8 Mode, SInt8 PlaneNo, SInt8 PlaneSelForCoin, SInt8 EvNo, SInt8 EvSelForPlot, ULT1__TZsFFrame* PtSrc, ULT1__TMatDiscriBit* PtDestFrameBit, ULT1__TMatDiscriBit* PtDestCoinBit, ULT1__TMatDiscriCumul* PtDestFrameCum, ULT1__TMatDiscriCumul* PtDestCoinCum, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesRec; + SInt8 ViState; + SInt8 VStatesNb; + SInt32 VHitCnt; + SInt8 VPlaneNoP1; + SInt8 VFlagRevertColDir; + SInt16 VDirRevCol; + SInt32 VEvNoInRun; + + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDestFrameBit, (ERR_OUT,"PtDestFrameBit == NULL") ); + err_retnull ( PtDestCoinBit , (ERR_OUT,"PtDestCoinBit == NULL") ); + err_retnull ( PtDestFrameCum, (ERR_OUT,"PtDestFrameCum == NULL") ); + err_retnull ( PtDestCoinCum , (ERR_OUT,"PtDestCoinCum == NULL") ); + + // Init intermediate variables + + // --------------------------------------------------------------- + // Revert or not X Dir ( columns ) depending of plane parameters + // --------------------------------------------------------------- + + VFlagRevertColDir = ProAPlanePar[PlaneNo].RevertXDir; + + VPlaneNoP1 = PlaneNo + 1; + + VEvNoInRun = PtSrc->SStatus.FrameNoInRun; + + // -------------------------------------------- + // Reset frame bit destination matrix + // -------------------------------------------- + + memset ( PtDestFrameBit, 0, sizeof (ULT1__TMatDiscriBit) ); + + + VHitCnt = 0; + + while (1) { + + //--------------------------------------------------------------- + // Cumul all frames + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL ) { + + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.LineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = 1151 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++PtDestFrameCum->AALineCol[ViLine][VDirRevCol]; + + // err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, VDirRevCol, PtDestFrameCum->AALineCol[ViLine][VDirRevCol] )); + + ++VHitCnt; + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + + } // End MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL + + //--------------------------------------------------------------- + // Plot coincidence of selected planeS of ONE frame ( 6 colors ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS ) { + + if ( (PlaneSelForCoin == 1) && (EvNo == EvSelForPlot) ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.LineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = 1151 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++VHitCnt; + + while (1) { + + // If no hit from other plane => Set Plane Id + 1 (1..6) + + if ( PtDestCoinBit->AALineCol[ViLine][VDirRevCol] == 0 ) { + PtDestCoinBit->AALineCol[ViLine][VDirRevCol] = VPlaneNoP1; + break; + } + + // If already ONE hit from other plane => Set Base + hit count = 10 + 2 = 12 + + if ( PtDestCoinBit->AALineCol[ViLine][VDirRevCol] <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + PtDestCoinBit->AALineCol[ViLine][VDirRevCol] = 12; + break; + } + + // If already > ONE hit from other plane => Increment ( Rq : Hit count = value - 10 ) + + ++PtDestCoinBit->AALineCol[ViLine][VDirRevCol]; + break; + + } // End while (1) + + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + + //--------------------------------------------------------------- + // Plot coincidence cumul of selected planeS of all frames ( 1 color ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR ) { + + if ( PlaneSelForCoin ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.LineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = 1151 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++PtDestFrameCum->AALineCol[ViLine][VDirRevCol]; // Not useful => But keep processing of per plane cumul + // err_error (( ERR_OUT, "AALineCol[L:%4d][C:%4d] = %4d", ViLine, VDirRevCol, PtDestFrameCum->AALineCol[ViLine][VDirRevCol] )); + ++VHitCnt; + ++PtDestCoinCum->AALineCol[ViLine][VDirRevCol]; + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + + //--------------------------------------------------------------- + // Plot coincidence cumul of selected planes of all frames ( 6 colors ) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) { + + if ( PlaneSelForCoin ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.LineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = 1151 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + ++VHitCnt; + + // Res run update + + // err_error (( ERR_OUT, "ProcOnlyFrWithHitOnAllPlanes = %d", ProPar.ProcOnlyFrWithHitOnAllPlanes )); + + if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) && (PrivPtResRun != NULL) ) { + + if ( PrivPtResRun->EvNb < MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB) { + + SInt32 VBHitIndex = PrivPtResRun->ATracks[PrivPtResRun->EvNb].AHitsNbPerPlane[PlaneNo]; + + err_error (( ERR_OUT, "TRACE : Coin - Ev %4d - Fr %4d - Plane %d - StatesNb %d", DbgEvNo, PtSrc->FrameCnt, PlaneNo, VStatesNb )); + + if ( VBHitIndex < MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE ) { + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AAHits[PlaneNo][VBHitIndex].x = VDirRevCol; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AAHits[PlaneNo][VBHitIndex].y = ViLine; + ++VBHitIndex; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].AHitsNbPerPlane[PlaneNo] = VBHitIndex; + PrivPtResRun->ATracks[PrivPtResRun->EvNb].EvNoInRun = VEvNoInRun; + } + + + } + + else { + PrivPtResRun->Full = 1; + } + + } + + + // Res run update END + + while (1) { + + // If no hit from other plane => Set Plane Id + 1 (1..6) + + if ( (PtDestCoinCum->AALineCol[ViLine][VDirRevCol] == 0) || (PtDestCoinCum->AALineCol[ViLine][VDirRevCol] == VPlaneNoP1) ) { + PtDestCoinCum->AALineCol[ViLine][VDirRevCol] = VPlaneNoP1; + break; + } + + // If already ONE hit from other plane / other frame => Set Base + hit count = 10 + 2 = 12 + + if ( PtDestCoinCum->AALineCol[ViLine][VDirRevCol] <= MAPS__TCDigTelMon_MAX_PLANE_NB ) { + PtDestCoinCum->AALineCol[ViLine][VDirRevCol] = 12; + break; + } + + // If already > ONE hit from other plane / other frame => Increment ( Rq : Hit count = value - 10 ) + + ++PtDestCoinCum->AALineCol[ViLine][VDirRevCol]; + break; + + } // End while (1) + + + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + + // If this is last plane selected for coincidence => Update Res run event counter + // Rq : If no plane is selected for coin => ProInf.LastPlaneSelForCoin == -1 therefore above condition is never true + + if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) && (PrivPtResRun != NULL) && (PlaneNo == ProInf.LastPlaneSelForCoin) ) { + ++PrivPtResRun->EvNb; + err_error (( ERR_OUT, "TRACE : Inc Res Run EvNb done => EvNb=%4d - EvNo=%4d - PlaneNo=%d", PrivPtResRun->EvNb, DbgEvNo, PlaneNo )); + } + + + break; + } // End if (PlaneSelForCoin) + + else { + Mode = MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME; // GOTO minimal processing (don't break) => For GUI result fields + } + + } // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + + + //--------------------------------------------------------------- + // Plot only frame + //--------------------------------------------------------------- + // MUST BE LAST ONE OF While (1) + //--------------------------------------------------------------- + + if ( Mode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME ) { + + for ( ViStatesRec=0; ViStatesRec < PtSrc->StatesRecNb; ViStatesRec++ ) { + + VStatesNb = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.StateNb; + ViLine = PtSrc->AStatesRec[ViStatesRec].StatesLine.F.LineAddr; + + // States in one StateRec loop + + for ( ViState=0; ViState < VStatesNb; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.ColAddr; + VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesRec].AStates[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + + // Hits in one State loop + + for ( ViCol=VFirstCol; ViCol <= VLastCol; ViCol++ ) { + + + + if (EvNo == EvSelForPlot) { + + if ( VFlagRevertColDir == 1 ) { + VDirRevCol = 1151 - ViCol; + } + + else { + VDirRevCol = ViCol; + } + + PtDestFrameBit->AALineCol[ViLine][VDirRevCol] = 1; + } + + ++VHitCnt; + } // End hits in one State loop + + } // End States in one StateRec loop + + } // End StatesRec loop + + break; + } // End MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME + + + } // End while (1) + + + if ( PrintLvl ) { + err_error (( ERR_OUT, "-------------------------------" )); + } + + + + return (VHitCnt); +} + + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 23/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__FConvMatDiscriBitToMatDiscriBitHalfScale ( ULT1__TMatDiscriBit* PtSrc, ULT1__TMatDiscriBitHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = ULT1__REG_DISCRI_BIT_SZ / 2; + VyDestMax = ULT1__MAT_DISCRI_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] || PtSrc->AALineCol[V2yDest][V2xDestP1] || PtSrc->AALineCol[V2yDestP1][V2xDest] || PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 26/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__FConvMatDiscriBitCoinToMatDiscriBitCoinHalfScale ( ULT1__TMatDiscriBit* PtSrc, ULT1__TMatDiscriBitHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + UInt8 VPixState0; + UInt8 VPixState1; + UInt8 VPixState2; + UInt8 VPixState3; + + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = ULT1__REG_DISCRI_BIT_SZ / 2; + VyDestMax = ULT1__MAT_DISCRI_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + VPixState0 = (PtSrc->AALineCol[V2yDest ][V2xDest ] != 0); + VPixState1 = (PtSrc->AALineCol[V2yDest ][V2xDestP1] != 0); + VPixState2 = (PtSrc->AALineCol[V2yDestP1][V2xDest ] != 0); + VPixState3 = (PtSrc->AALineCol[V2yDestP1][V2xDestP1] != 0); + + + while (1) { + + // If no pixel at 1 => set 0 + + if ( (VPixState0 | VPixState1 | VPixState2 | VPixState3) == 0 ) { + PtDest->AALineCol[VyDest][VxDest] = 0; + break; + } + + // If one pixel at 1 and ONLY one => Make or of values = or of PlaneID + 1 + + if ( (VPixState0 ^ VPixState1 ^ VPixState2 ^ VPixState3) == 1 ) { + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] | PtSrc->AALineCol[V2yDest][V2xDestP1] | PtSrc->AALineCol[V2yDestP1][V2xDest] | PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + break; + } + + // If more than one pixel at 1 => Base + Sum pixels states = 10 + Sum + + PtDest->AALineCol[VyDest][VxDest] = 10 + (VPixState0 + VPixState1 + VPixState2 + VPixState3); + break; + + } // End while (1) + + } // End for ( VxDest ... ) + + } // End for ( VyDest ... ) + + err_retok (( ERR_OUT, "" )); +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 23/07/2009 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__FConvMatDiscriCumToMatDiscriCumHalfScale ( ULT1__TMatDiscriCumul* PtSrc, ULT1__TMatDiscriCumulHalfScale* PtDest ) { + + SInt32 VxDest; + SInt32 VyDest; + SInt32 VxDestMax; + SInt32 VyDestMax; + SInt32 V2xDest; + SInt32 V2xDestP1; + SInt32 V2yDest; + SInt32 V2yDestP1; + + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + VxDestMax = ULT1__REG_DISCRI_BIT_SZ / 2; + VyDestMax = ULT1__MAT_DISCRI_LINES_NB / 2; + + for ( VyDest=0; VyDest < VyDestMax; VyDest++ ) { + + for ( VxDest=0; VxDest < VxDestMax; VxDest++ ) { + + V2xDest = 2 * VxDest; + V2xDestP1 = V2xDest + 1; + V2yDest = 2 * VyDest; + V2yDestP1 = V2yDest + 1; + + PtDest->AALineCol[VyDest][VxDest] = PtSrc->AALineCol[V2yDest][V2xDest] + PtSrc->AALineCol[V2yDest][V2xDestP1] + PtSrc->AALineCol[V2yDestP1][V2xDest] + PtSrc->AALineCol[V2yDestP1][V2xDestP1]; + } + + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 30/04/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 ULT1__FBuildMatDiscriW32FromLinePatReg ( ULT1__TRegDiscriW32* PtLinePatReg0, ULT1__TRegDiscriW32* PtLinePatReg1, ULT1__TMatDiscriW32* PtDest ) { + + SInt16 ViLine; + + err_retnull ( PtLinePatReg0, (ERR_OUT,"PtLinePatReg0 == NULL !") ); + err_retnull ( PtLinePatReg1, (ERR_OUT,"PtLinePatReg1 == NULL !") ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL !") ); + + ViLine= 0; + + do { + + memcpy ( PtDest->AALineW32[ViLine], PtLinePatReg0, ULT1__REG_DISCRI_W32_SZ * 4 ); + ++ViLine; + memcpy ( PtDest->AALineW32[ViLine], PtLinePatReg1, ULT1__REG_DISCRI_W32_SZ * 4 ); + ++ViLine; + + } while ( ViLine < ULT1__MAT_DISCRI_LINES_NB); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/05/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FCompareMatDiscriBit__org ( SInt16 LineNbToCompare, ULT1__TMatDiscriBit* PtMat, ULT1__TMatDiscriBit* PtMatRef, SInt8 PrintLvl, SInt8 PrintMimosaId, SInt32 PrintAcqId, SInt16 PrintFrameId ) { + + SInt32 ViLine; + SInt32 ViCol; + SInt8 VPixState; + SInt8 VRefPixState; + SInt32 VErrCnt; + SInt32 VTimeBegMs; + SInt32 VTimeEndMs; + SInt32 VTimeExecMs; + + + if ( (LineNbToCompare <= 0) || (LineNbToCompare > ULT1__MAT_DISCRI_LINES_NB) ) { + err_error (( ERR_OUT, "Bad line nb to compare = %d MUST be 1..%d", LineNbToCompare, ULT1__MAT_DISCRI_LINES_NB )); + return (0); + } + + // VTimeBegMs = GetTickCount (); + + VErrCnt = 0; + + for ( ViLine=0; ViLine < LineNbToCompare; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ /* 580 for Test LP003 */; ViCol++ ) { + + /* + VPixState = PtMat->AALineCol[ViLine][ViCol]; + VRefPixState = PtMatRef->AALineCol[ViLine][ViCol]; + + if ( VPixState != VRefPixState ) { + ++VErrCnt; + if ( PrintLvl == 2 ) msg (( MSG_OUT, "Error => ULT1[%d] Line %4d - Col %4d : Pixel = %d <> Expected = %d", PrintMimosaId, ViLine, ViCol, VPixState, VRefPixState )); + } + */ + + } // End for ViCol + + } // End for ViLine + + if ( (PrintLvl >= 1) && (VErrCnt != 0) ) msg (( MSG_OUT, "For this event Acq[%3d] Frame [%6d] %d errors on Mimosa [%d]", PrintAcqId, PrintFrameId, VErrCnt, PrintMimosaId )); + + // VTimeEndMs = GetTickCount (); + // VTimeExecMs = VTimeEndMs - VTimeBegMs; + + // msg (( MSG_OUT, "$$$$$ Compare matrix exec time = %d [ms] - LineNbToCompare=%d - PrintAcqId=%d - PrintFrameId=%d", VTimeExecMs, LineNbToCompare, PrintAcqId, PrintFrameId )); + + return ( VErrCnt ); +} + +// XX/01/14 +// Optimized version : fast processing with memcmp, followed by bad pixels test & log (slow) if needed + +SInt32 ULT1__FCompareMatDiscriBit ( SInt16 LineNbToCompare, ULT1__TMatDiscriBit* PtMat, ULT1__TMatDiscriBit* PtMatRef, SInt8 PrintLvl, SInt8 PrintMimosaId, SInt32 PrintAcqId, SInt16 PrintFrameId ) { + + SInt32 ViLine; + SInt32 ViCol; + SInt8 VPixState; + SInt8 VRefPixState; + SInt32 VErrCnt; + SInt32 VTimeBegMs; + SInt32 VTimeEndMs; + SInt32 VTimeExecMs; + SInt8 VErrInMatrix; + TDateTime VCDateTime; + TIME__TUDateL VDate; + TIME__TUTime VTime; + + + if ( (LineNbToCompare <= 0) || (LineNbToCompare > ULT1__MAT_DISCRI_LINES_NB) ) { + err_error (( ERR_OUT, "Bad line nb to compare = %d MUST be 1..%d", LineNbToCompare, ULT1__MAT_DISCRI_LINES_NB )); + return (0); + } + + + // VTimeBegMs = GetTickCount (); + + VErrCnt = 0; + + // Fast compare Matrix from DAQ / Reference matrix built from JTAG line patten registers + + VErrInMatrix = memcmp ( PtMat, PtMatRef, LineNbToCompare * ULT1__REG_DISCRI_BIT_SZ ); + +// err_error (( ERR_OUT, "VErrInMatrix=%d - PrintLvl=%d", VErrInMatrix, PrintLvl )); + + // Matrix from DAQ = Matrix from JTAG => Exit, ret 0 error + + if ( VErrInMatrix == 0 ) { + return (0); + } + + // Matrix from DAQ <> Matrix from JTAG => Compare and list errors (very slow processing) + + for ( ViLine=0; ViLine < LineNbToCompare; ViLine++ ) { + + for ( ViCol=0; ViCol < ULT1__REG_DISCRI_BIT_SZ /* 580 for Test LP003 */; ViCol++ ) { + + VPixState = PtMat->AALineCol[ViLine][ViCol]; + VRefPixState = PtMatRef->AALineCol[ViLine][ViCol]; + + if ( VPixState != VRefPixState ) { + ++VErrCnt; + if ( PrintLvl == 2 ) msg (( MSG_OUT, "Error => ULT1[%d] Line %4d - Col %4d : Pixel = %d <> Expected = %d", PrintMimosaId, ViLine, ViCol, VPixState, VRefPixState )); + } + + } // End for ViCol + + } // End for ViLine + + if ( (PrintLvl >= 1) && (VErrCnt != 0) ) { + VCDateTime = VCDateTime.CurrentDateTime (); + VDate = TIME__FConvDateTime2DateL ( VCDateTime ); + VTime = TIME__FConvDateTime2Time ( VCDateTime ); + + msg (( MSG_OUT, "Data errors event %s - %s : Acq[%3d] Frame [%6d] %d errors on Mimosa [%d]", TIME__FDateL2Str ( VDate, NULL, 0 ), TIME__FTime2Str ( VTime, NULL, 0 ), PrintAcqId, PrintFrameId, VErrCnt, PrintMimosaId )); + } + + // VTimeEndMs = GetTickCount (); + // VTimeExecMs = VTimeEndMs - VTimeBegMs; + + // msg (( MSG_OUT, "$$$$$ Compare matrix exec time = %d [ms] - LineNbToCompare=%d - PrintAcqId=%d - PrintFrameId=%d", VTimeExecMs, LineNbToCompare, PrintAcqId, PrintFrameId )); + + return ( VErrCnt ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +ULT1__TCDiscriFile :: ULT1__TCDiscriFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) : FIL__TCBinFile ( ErrLogFile, EnableErrLog, ErrLogLvl ) { + + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFSetFileName ( char* DataFile ) { + + return ( FIL__TCBinFile :: PubFSetFileName (DataFile) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + return ( FIL__TCBinFile :: PubFSetFlushMode (FlushAfterWrite) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +ULT1__TCDiscriFile :: ~ULT1__TCDiscriFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFConf ( char* DataFile, SInt8 WriteRead, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt32 VRet; + SInt32 VRWBMode; + SInt32 VMaxBlocSz; + SInt32 VBlocSz; + + switch ( WriteRead ) { + + case 0 : { + VRWBMode = FIL__TCBinFile_RWB_MODE_WRITE; + break; } + + case 1 : { + VRWBMode = FIL__TCBinFile_RWB_MODE_READ; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Bad WriteRead param = %d <> 0..1", WriteRead ) ); + break; } + + } + + VMaxBlocSz = VBlocSz = sizeof (ULT1__TMatDiscriW32); + + VRet = FIL__TCBinFile::PubFConf ( DataFile, VRWBMode, VMaxBlocSz, VBlocSz, FlushAfterWrite, MeasTime ); + + // msg (( MSG_OUT, "PubFConf => FlushAfterWrite=%d", FlushAfterWrite )); + + return (VRet); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFGetFileSz () { + return ( FIL__TCBinFile::PubFGetFileSz () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFGetEvNb () { + return ( FIL__TCBinFile::PubFGetBlocNb () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFCreate () { + return ( FIL__TCBinFile::PubFCreate () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFOpen () { + return ( FIL__TCBinFile::PubFOpen () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFWriteEv ( ULT1__TMatDiscriW32* PtSrcMat ) { + + SInt32 VRet; +// SInt32 VRet; // modif 2009_03_04 MG + + VRet = PubFSeqWrite ( (void*) PtSrcMat, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Write event failed !") ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFReadNextEv ( ULT1__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( (void*) PtDestMat, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read event failed !") ); + err_retok (( ERR_OUT, "" )); + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +ULT1__TMatDiscriW32* ULT1__TCDiscriFile :: PubFReadNextEv () { + + ULT1__TMatDiscriW32* VPtEv; + + VPtEv = (ULT1__TMatDiscriW32*) PubFSeqRead ( ProParBlocSz ); + + if ( VPtEv == NULL ) { + err_error (( ERR_OUT, "Read event failed !" )); + } + + err_retval ( VPtEv, ( ERR_OUT, "" ) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFGotoEv ( SInt32 EvNo ) { + + SInt32 VRet; + + VRet = PubFGotoBloc ( EvNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto event [%d] failed !", EvNo ) ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFReadEv ( SInt32 EvNo, ULT1__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ) { + + SInt32 VRet; + + VRet = PubFBlocRead ( EvNo, PtDestMat, MaxDestSz ); + + err_retfail ( VRet, (ERR_OUT,"Read event [%d] failed !", EvNo ) ); + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +ULT1__TMatDiscriW32* ULT1__TCDiscriFile :: PubFReadEv ( SInt32 EvNo ) { + + ULT1__TMatDiscriW32* VPtEv; + + + VPtEv = (ULT1__TMatDiscriW32*) PubFBlocRead ( EvNo ); + + if ( VPtEv == NULL ) { + err_error (( ERR_OUT, "Read event [%d] failed !", EvNo )); + } + + err_retval ( VPtEv, ( ERR_OUT, "" ) ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFFlush () { + return ( FIL__TCBinFile::PubFFlush () ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCDiscriFile :: PubFClose () { + return ( FIL__TCBinFile::PubFClose () ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FWriteZSRunCnf ( char* FileName, ULT1__TZSRunCnf* PtSrc ) { + + SInt32 VRecSz; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (ULT1__TZSRunCnf); + + err_retfail ( FIL_FWriteRecord ( FileName, PtSrc, VRecSz ), (ERR_OUT,"Write failed !") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FReadZSRunCnf ( char* FileName, ULT1__TZSRunCnf* PtDest ) { + + SInt32 VRecSz; + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (ULT1__TZSRunCnf); + + err_retfail ( FIL_FReadRecord ( FileName, PtDest, VRecSz ) , (ERR_OUT,"Read failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FPrintZSRunCnf ( ULT1__TZSRunCnf* PtSrc ) { + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + msg (( MSG_OUT, "================================================" )); + msg (( MSG_OUT, "RunNo %6d", PtSrc->RunNo )); + msg (( MSG_OUT, "RunSave %6d", PtSrc->RunSave )); + msg (( MSG_OUT, "RunSaveMode %6d", PtSrc->RunSaveMode )); + msg (( MSG_OUT, "RunEvNb %6d", PtSrc->RunEvNb )); + msg (( MSG_OUT, "RunFileEvNb %6d", PtSrc->RunFileEvNb )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "StartDate %s", TIME__FDateS2Str ( PtSrc->StartDate, NULL, 0 ) )); + msg (( MSG_OUT, "StartTime %s", TIME__FTime2Str ( PtSrc->StartTime, NULL, 0 ) )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "AsicName %6d", PtSrc->AsicName )); + msg (( MSG_OUT, "AsicNb %6d", PtSrc->AsicNb )); + msg (( MSG_OUT, "------------------------------------------------" )); + msg (( MSG_OUT, "SwTrigEnabled %6d", PtSrc->SwTrigEnabled )); + msg (( MSG_OUT, "HwTrigModeSavedData %6d", PtSrc->HwTrigModeSavedData )); + msg (( MSG_OUT, "HwTrigPar[DPXI__HW_TRIG_PAR__OFFSET] %6d", PtSrc->HwTrigPar[DPXI__HW_TRIG_PAR__OFFSET] )); + msg (( MSG_OUT, "HwTrigPar[DPXI__HW_TRIG_PAR__WINDOW] %6d", PtSrc->HwTrigPar[DPXI__HW_TRIG_PAR__WINDOW] )); + msg (( MSG_OUT, "================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FWriteZSRunRes ( char* FileName, ULT1__TZSRunRes* PtSrc ) { + + SInt32 VRecSz; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (ULT1__TZSRunRes); + + err_retfail ( FIL_FWriteRecord ( FileName, PtSrc, VRecSz ), (ERR_OUT,"Write failed !") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FReadZSRunRes ( char* FileName, ULT1__TZSRunRes* PtDest ) { + + SInt32 VRecSz; + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRecSz = sizeof (ULT1__TZSRunRes); + + err_retfail ( FIL_FReadRecord ( FileName, PtDest, VRecSz ) , (ERR_OUT,"Read failed !") ); + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FPrintZSRunRes ( ULT1__TZSRunRes* PtSrc ) { + + SInt32 Vi; + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + + msg (( MSG_OUT, "================================================" )); + msg (( MSG_OUT, "StopDate %s", TIME__FDateS2Str ( PtSrc->StopDate, NULL, 0 ) )); + msg (( MSG_OUT, "StopTime %s", TIME__FTime2Str ( PtSrc->StopTime, NULL, 0 ) )); + msg (( MSG_OUT, "EvNbTaken %6d", PtSrc->EvNbTaken )); + msg (( MSG_OUT, "RejAcqNb %6d", PtSrc->RejAcqNb )); + msg (( MSG_OUT, "================================================" )); + + for ( Vi=0; Vi < PtSrc->RejAcqNb; Vi++ ) { + msg (( MSG_OUT, "Acq [%6d] rejected !", PtSrc->ARejAcqList[Vi] )); + } + + msg (( MSG_OUT, "================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +ULT1__TCZsRunRW :: ULT1__TCZsRunRW () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +ULT1__TCZsRunRW :: ~ULT1__TCZsRunRW () { + + delete ProPtBinFile; + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : All fields BUT NOT + : - errors handling and log file + : - messages and event header print flags +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PrivFInitForNewRunLoading () { + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + + // Parameters from conf + + sprintf ( ProParRunDir, "" ); + ProParRunNo = 0; + ProParCurULT1No = 0; + ProParCurEvNo = 0; + + // Informations + + ProInfRunULT1Nb = 0; + ProInfRunEvNb = 0; + ProInfRunFileSz = 0; + ProInfRunEvNbPerFile = 0; + ProInfRunBlocNbPerFile = 0; + + // Variables for internal processing + + ProLastEvAccessDoneInOneULT1Mode = 1; + + ProCurBlocNoInRun = 0; + ProCurFileNo = 0; + ProCurBlocNoInFile = 0; + sprintf ( ProCurFileName, "" ); + + ProPtFFrameRaw = NULL; + + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + + // Conf done & errors log + // Parameters from constructor + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // Frame size + + ProInfZsFFrameRawSz = sizeof (ULT1__TZsFFrameRaw); + + // Print ctrl fields + + ProParMeasTime = 0; + ProParPrintMsg = 0; + ProParPrintEvHeader = 0; + + + PrivFInitForNewRunLoading (); + + // Res + + // TCBinFile + + ProPtBinFile = new FIL__TCBinFile ( "x:\\log\\err_TCBinFile.txt", 0 /* EnableErrLog */, ERR_LOG_LVL_NONE ); + + err_retnull ( ProPtBinFile, (ERR_OUT,"Allocation of ProPtBinFile failed !!! => Abort") ); + + ProPtBinFile->PubFConf ( "", FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFSetMeasTime ( SInt8 Yes ) { + ProParMeasTime = Yes; + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFSetPrintMsg ( SInt8 Print ) { + ProParPrintMsg = Print; + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFSetPrintEvHeader ( SInt8 Print ) { + ProParPrintEvHeader = Print; + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFGetMeasTime () { + return (ProParMeasTime); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFGetPrintMsg () { + return ( ProParPrintMsg ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFGetPrintEvHeader () { + return ( ProParPrintEvHeader ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFGetULT1Nb () { + return ( ProInfRunULT1Nb ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFGetEvNb () { + return ( ProInfRunEvNb ); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 29/07/2009 +Doc date : 29/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFGetEvNbPerFile () { + return ( ProInfRunEvNbPerFile ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Rev : 29/07/2009 + : - Two kinds of events handling : OneULT1 / AllULT1 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFLoadRun ( char* RunDir, UInt32 RunNo ) { + + SInt32 VRet; + + ULT1__TCZsRunRW__CHK_INIT (); + + err_retnull ( RunDir, (ERR_OUT,"RunDir == NULL !") ); + + + // Set run dir and run no + + sprintf ( ProParRunDir, "%s", RunDir ); + + ProParRunNo = RunNo; + + // Load and print run conf + // Must be loaded here because fiels of VRunCnfFile are used later + + sprintf ( ProRunCnfFile, "%s\\run_%.4d_cnf.bin", ProParRunDir, ProParRunNo ); + + ULT1__FReadZSRunCnf ( ProRunCnfFile, &ProRecZSRunCnf ); + ULT1__FPrintZSRunCnf ( &ProRecZSRunCnf ); + + // Load and print run res + + sprintf ( ProRunResFile, "%s\\run_%.4d_res.bin", ProParRunDir, ProParRunNo ); + + ULT1__FReadZSRunRes ( ProRunResFile, &ProRecZSRunRes ); + ULT1__FPrintZSRunRes ( &ProRecZSRunRes ); + + // Update information fields + + ProInfRunULT1Nb = ProRecZSRunCnf.AsicNb; + ProInfRunEvNb = ProRecZSRunCnf.RunEvNb; + ProInfRunEvNbPerFile = ProRecZSRunCnf.RunFileEvNb; + + // ---------------------------------- + // WARNING - Upgrade on 29/07/2009 + // ---------------------------------- + // - Now class can provide two kinds of events pointer via PubFGotoEvOneULT1 / PubFGotoEvAllULT1 + // -> PubFGotoEvOneULT1 : Pointer to ONE plane of ULT1 telescope + // -> PubFGotoEvAllULT1 : Pointer to ALL planes of ULT1 telescope + // + // => ProInfRunBlocNbPerFile depend on which kind off event we want to access + // Therefore ProInfRunBlocNbPerFile is ovewritten in PubFGotoEvOneULT1 / PubFGotoEvAllULT1 + // By default it is set HERE for "PubFGotoEvOneULT1" kind of events + // + // The first call to ProPtBinFile->PubFConf done at the end of this function also configure + // buffer size for "PubFGotoEvOneULT1" kind of events. + + ProInfRunBlocNbPerFile = ProInfRunULT1Nb * ProInfRunEvNbPerFile; + + // Set flag to memorize last ev access mode + + ProLastEvAccessDoneInOneULT1Mode = 1; + + // Set cur event to first one, first ULT1 + + ProParCurULT1No = 0; + ProParCurEvNo = 0; + + // Open file for first event + + ProCurBlocNoInRun = 0; + ProCurFileNo = 0; + ProCurBlocNoInFile = 0; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Load run try to open first file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + + // Try to open file + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + + + if ( VRet < 0 ) { + ProInfRunFileSz = 0; + err_retfail ( -1, (ERR_OUT,"Open file %s for event %d failed !", ProCurFileName, ProParCurEvNo ) ); + } + + ProInfRunFileSz = ProPtBinFile->PubFGetFileSz (); + + + err_retok (( ERR_OUT, "Open file %s done :-)", ProCurFileName )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +ULT1__TZsFFrameRaw* ULT1__TCZsRunRW :: PubFGotoEvOneULT1 ( SInt8 ULT1No, SInt32 EvNo ) { + + SInt32 VRet = 0; + SInt32 VNewFileNo; + + ProParCurULT1No = ULT1No; + ProParCurEvNo = EvNo; + + // Calculate Nb of bloc per file ( Rq : value is different for PubFGotoEvAllULT1 ) + + ProInfRunBlocNbPerFile = ProInfRunULT1Nb * ProInfRunEvNbPerFile; + + // Calculate bloc no and file to access + + ProCurBlocNoInRun = ( ProParCurEvNo * ProInfRunULT1Nb ) + ProParCurULT1No; + VNewFileNo = ProCurBlocNoInRun / ProInfRunBlocNbPerFile; + ProCurBlocNoInFile = ProCurBlocNoInRun % ProInfRunBlocNbPerFile; + + // If last ev acces done in AllULT1 mode ( -> TCBin file MUST be reconfigured ) + // If event is not in current file + // => close current file & open new one + + if ( (ProLastEvAccessDoneInOneULT1Mode == 0) || (VNewFileNo != ProCurFileNo) ) { + + ProLastEvAccessDoneInOneULT1Mode = 1; + + // Close current file + + ProPtBinFile->PubFClose (); + + // Open new file + + ProCurFileNo = VNewFileNo; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d - ULT1No=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProParCurULT1No, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "Try to open file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, ProInfZsFFrameRawSz /* Max bloc sz */ , ProInfZsFFrameRawSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + err_retfailnull ( VRet, (ERR_OUT,"Open file %s failed !", ProCurFileName) ); + } + + else { + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d - ULT1No=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProParCurULT1No, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + } + + // Try to read event + + ProPtFFrameRaw = (ULT1__TZsFFrameRaw*) ProPtBinFile->PubFBlocRead ( ProCurBlocNoInFile ); + + if ( ProParPrintEvHeader ) { + ULT1_FPrintZsFFrameRawHeader ( ProPtFFrameRaw ); + } + + return ( ProPtFFrameRaw ); +} + + + + +/******************************************************************************* +Prototype : +Goal : Retun pointeur to first plane of Telescope => size = Nb plane * ProInfZsFFrameRawSz +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 28/07/2009 +Doc date : 28/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +ULT1__TZsFFrameRaw* ULT1__TCZsRunRW :: PubFGotoEvAllULT1 ( SInt32 EvNo ) { + + SInt32 VRet = 0; + SInt32 VNewFileNo; + SInt32 VEventSz; + SInt32 Vi; + + + ProParCurEvNo = EvNo; + VEventSz = ProInfRunULT1Nb * ProInfZsFFrameRawSz; + + // Calculate Nb of bloc per file ( Rq : value is different for PubFGotoEvOneULT1 ) + + ProInfRunBlocNbPerFile = ProInfRunEvNbPerFile; + + // Calculate bloc no and file to access + + ProCurBlocNoInRun = ProParCurEvNo; // * ProInfRunULT1Nb; + VNewFileNo = ProCurBlocNoInRun / ProInfRunBlocNbPerFile; + ProCurBlocNoInFile = ProCurBlocNoInRun % ProInfRunBlocNbPerFile; + + // If last ev acces done in OneULT1 mode ( -> TCBin file MUST be reconfigured ) + // If event is not in current file + // => close current file & open new one + + if ( (ProLastEvAccessDoneInOneULT1Mode == 1) || (VNewFileNo != ProCurFileNo) ) { + + ProLastEvAccessDoneInOneULT1Mode = 0; + + // Close current file + + ProPtBinFile->PubFClose (); + + // Open new file + + ProCurFileNo = VNewFileNo; + + sprintf ( ProCurFileName, "%srun_%.4d_%.4d", ProParRunDir, ProParRunNo, ProCurFileNo ); + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "Try to open file = %s", ProCurFileName )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + ProPtBinFile->PubFConf ( ProCurFileName, FIL__TCBinFile_RWB_MODE_READ, VEventSz /* Max bloc sz */ , VEventSz /* Bloc sz */ , 0 /* FlushAfterWrite */, ProParMeasTime /* MeasTime */ ); + VRet = ProPtBinFile->PubFOpen (); + + err_retfailnull ( VRet, (ERR_OUT,"Open file %s failed !", ProCurFileName) ); + } + + else { + + if ( ProParPrintMsg ) { + msg (( MSG_OUT, "-------------------------------------------------" )); + msg (( MSG_OUT, "Read event=%d => BlocNoInRun=%d - FileNo=%d - BlocNoInFile=%d", ProParCurEvNo, ProCurBlocNoInRun, ProCurFileNo, ProCurBlocNoInFile )); + msg (( MSG_OUT, "-------------------------------------------------" )); + } + + } + + // Try to read event + + ProPtFFrameRaw = (ULT1__TZsFFrameRaw*) ProPtBinFile->PubFBlocRead ( ProCurBlocNoInFile ); + + if ( ProParPrintEvHeader ) { + + for ( Vi=0; Vi < ProInfRunULT1Nb; Vi++ ) { + ULT1_FPrintZsFFrameRawHeader ( &ProPtFFrameRaw[Vi] ); + } + + } + + return ( ProPtFFrameRaw ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 ULT1__TCZsRunRW :: PubFCloseRun () { + + ProPtBinFile->PubFClose (); + PrivFInitForNewRunLoading (); + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 09/07/2009 +Doc date : 09/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + + + + +// ************************************* +// ************************************* +// ULT1__TCTelMon +// ************************************* +// ************************************* + + +#ifndef ROOT_ROOT + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PrivFInit () { + + SInt32 Vi; + + + // Plane & MAPS settings for ULT1 + + ProPar.PlaneNb = 6; + + MAPS__TCDigTelMon_CHK_PLANE_NB (ProPar.PlaneNb); + + + ProPar.MapsName = ASIC__ULT1; + ProPar.MapsNb = 6; + + // Planes conf + // - Id = Index of plane : seem's to be strange and redundant => can be useful later + // - plot color + // - revert or not X direction + + ProAPlanePar[0].MapsId = 0; + ProAPlanePar[0].PlotColor = ULT1__TCTelMon__COL_PLANE_0; + ProAPlanePar[0].RevertXDir = 1; + + ProAPlanePar[1].MapsId = 1; + ProAPlanePar[1].PlotColor = ULT1__TCTelMon__COL_PLANE_1; + ProAPlanePar[1].RevertXDir = 0; + + ProAPlanePar[2].MapsId = 2; + ProAPlanePar[2].PlotColor = ULT1__TCTelMon__COL_PLANE_2; + ProAPlanePar[2].RevertXDir = 1; + + ProAPlanePar[3].MapsId = 3; + ProAPlanePar[3].PlotColor = ULT1__TCTelMon__COL_PLANE_3; + ProAPlanePar[3].RevertXDir = 0; + + ProAPlanePar[4].MapsId = 4; + ProAPlanePar[4].PlotColor = ULT1__TCTelMon__COL_PLANE_4; + ProAPlanePar[4].RevertXDir = 1; + + ProAPlanePar[5].MapsId = 5; + ProAPlanePar[5].PlotColor = ULT1__TCTelMon__COL_PLANE_5; + ProAPlanePar[5].RevertXDir = 0; + + + for ( Vi=0; Vi < MAPS__TCDigTelMon_MAX_PLANE_NB; Vi++ ) { + PrivAPlanePlotColor[Vi] = ProAPlanePar[Vi].PlotColor; + } + + + + + // Frames record reset + + memset ( &PrivZsFFrame , 0, sizeof (ULT1__TZsFFrame) ); + + memset ( &PrivMatDiscriCoin , 0, sizeof (ULT1__TMatDiscriBit) ); + memset ( &PrivMatDiscriCoinCum , 0, sizeof (ULT1__TMatDiscriCumul) ); + memset ( &PrivMatDispColor , 0, sizeof (ULT1__TMatDiscriColor) ); + + memset ( &PrivMatDiscriBitHalfScale, 0, sizeof (ULT1__TMatDiscriBitHalfScale) ); + memset ( &PrivMatDiscriCumHalfScale, 0, sizeof (ULT1__TMatDiscriCumulHalfScale) ); + memset ( &PrivMatDispColorHalfScale, 0, sizeof (ULT1__TMatDiscriColorHalfScale) ); + + + // Events list allocation & reset + + PriEnListEvWitHitUpdate = 1; + PriEnListEvWithTrigUpdate = 1; + + // Allocation & reset + + for ( Vi=0; Vi < ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB; Vi++ ) { + + PrivAAListEvWithTrig[Vi] = (ASIC__TFrameStatus*) malloc ( ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + err_retnull ( PrivAAListEvWithTrig[Vi], (ERR_OUT,"Allocation of trigger list elt=%d failed !", Vi) ); + + memset ( PrivAAListEvWithTrig[Vi], 0, ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + + + PrivAAListEvWithHit[Vi] = (ASIC__TFrameStatus*) malloc ( ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + err_retnull ( PrivAAListEvWithHit[Vi], (ERR_OUT,"Allocation of hit list elt=%d failed !", Vi) ); + + memset ( PrivAAListEvWithHit[Vi], 0, ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + + } + + PrivAListEvWithHitAllPlanes = (ULT1__TCTelMon_TEltListEvWithHitAllPlanes*) malloc ( ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ULT1__TCTelMon_TEltListEvWithHitAllPlanes) ); + + err_retnull ( PrivAListEvWithHitAllPlanes, (ERR_OUT,"Allocation of hit all planes failed !") ); + + memset ( PrivAListEvWithHitAllPlanes, 0, ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ULT1__TCTelMon_TEltListEvWithHitAllPlanes) ); + + + // Reset + + PrivListEvWithTrigIndex = 0; + PrivListEvWithTrigFull = 0; + + PrivListEvWithHitIndex = 0; + PrivListEvWithHitFull = 0; + + PrivListEvWithHitAllPlanesIndex = 0; + PrivListEvWithHitAllPlanesFull = 0; + + // Variables reset + + PrivPtAcqData = NULL; + PrivAcqEvNb = 0; + + PrivPtResRun = NULL; + + PubAcqOffLineProcOrRunOffLineProc = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Rev : 31/07/2009 + : - Add multi planes handling +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PrivFAddEvInListEvWithTrig ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt ) { + + err_retnull ( PtFrStatus, (ERR_OUT,"PtFrStatus == NULL") ); + + if ( PriEnListEvWithTrigUpdate == 0 ) { + return (0); + } + + if ( PrivListEvWithTrigIndex < ULT1__TCTelMon__EV_LIST_MAX_ELT_NB ) { + PtFrStatus->HitCnt = HitCnt; + PrivAAListEvWithTrig[PlaneNo][PrivListEvWithTrigIndex] = *PtFrStatus; + ++PrivListEvWithTrigIndex; + } + + else { + PrivListEvWithTrigFull = 1; + err_retfail (-1, (ERR_OUT,"List full %d elt", PrivListEvWithTrigIndex ) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : This function MUST always be called one time / ev with PlaneNo = ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL + : because list index is ONLY updated when PlaneNo = ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL + : +Date : 26/07/2009 +Rev : 31/07/2009 + : - Add multi planes handling +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PrivFAddEvInListEvWithHit ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt, SInt8 HitOnAllPlanes, SInt8 SingleHitOnEachPlane ) { + + err_retnull ( PtFrStatus, (ERR_OUT,"PtFrStatus == NULL") ); + + if ( PriEnListEvWitHitUpdate == 0 ) { + return (0); + } + + // Check PlaneNo + + if ( (PlaneNo < 0) || (PlaneNo > ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB) ) { + err_retfail ( -1, (ERR_OUT,"Bad Plane No = %d MUST be [0..%d]", PlaneNo, ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL ) ); + } + + // Update hit count field of FrStatus which already contains information about acq no, ev no, ULT1 no etc ... + + PtFrStatus->HitCnt = HitCnt; + + // Copy FrStatus in plane array + + PrivAAListEvWithHit[PlaneNo][PrivListEvWithHitIndex] = *PtFrStatus; + + // Update list index ONLY if PlaneNo == ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL + + if ( PlaneNo == ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL ) { + + // Update hit on all planes list + + // Rq : Decision to add event in list or not is done in two steps ( two tests ) and not by a single test in order to save execution time + // -> First test ( HitOnAllPlanes == 1 ) cost less => Is there hits on all planes ? Yes / No ? + // -> Second test cost much and therefore is only done if first one has passed + + if ( HitOnAllPlanes == 1 ) { + + // Add or not event in list depending of list mode + // -> List events with hit(s) ( at least one per plane ) on all planes => Yes + // -> List events with single hit in each plane => Yes if SingleHitOnEachPlane parameter is set / otherwise No + + if ( (ProPar.ListHitAllPlanesMode == MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES ) || ( (ProPar.ListHitAllPlanesMode == MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE) && (SingleHitOnEachPlane == 1) ) ) { + + PrivAListEvWithHitAllPlanes[PrivListEvWithHitAllPlanesIndex].FrStatus = *PtFrStatus; + PrivAListEvWithHitAllPlanes[PrivListEvWithHitAllPlanesIndex].IndexInEvWithHitList = PrivListEvWithHitIndex; // Store ev with trig list index + + if ( PrivListEvWithHitAllPlanesIndex < ULT1__TCTelMon__EV_LIST_MAX_ELT_NB ) { + ++PrivListEvWithHitAllPlanesIndex; + } + + else { + PrivListEvWithHitAllPlanesFull = 1; + } + } + + + } // End if ( HitOnAllPlanes == 1 ) + + // Update PrivListEvWithHitIndex + + if ( PrivListEvWithHitIndex < ULT1__TCTelMon__EV_LIST_MAX_ELT_NB ) { + ++PrivListEvWithHitIndex; + } + + else { + PrivListEvWithHitFull = 1; + err_retfail (-1, (ERR_OUT,"List full %d elt", PrivListEvWithHitIndex ) ); + } + + + + } + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : Hit count +Remark : +Date : 22/07/2009 +Rev : 20/05/2010 + : - Add CumTotTrigNb & CumFrameTrigNb handling + : +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::ProFProcessPlane ( SInt32 DbgEvNo, SInt8 Id, ULT1__TZsFFrameRaw* PtSrc ) { + + ULT1__TMatDiscriBit* VPtFrMatDiscriBit; + ULT1__TMatDiscriCumul* VPtFrMatCumTotHitCnt; + SInt32 VHitCnt; + SInt8 VUpdateMatCumul; + SInt8 VRequestPlot; + SInt8 VGoodFrame; + + // Check plane id + + MAPS__TCDigTelMon_CHK_PLANE_ID (Id); + + + VRequestPlot = 0; // Used to store plot request and move it at END of function AFTER ALL processings + + // Init pointers + + VPtFrMatDiscriBit = (ULT1__TMatDiscriBit*) ProAPlaneRes[Id].PtMatDiscriBit; + VPtFrMatCumTotHitCnt = (ULT1__TMatDiscriCumul*) ProAPlaneRes[Id].PtMatCumTotHitCnt; + + // If first event of analysis + // -> Reset all results of plane + + if ( ProInf.CurEvToProc == 0 ) { + ProAPlaneRes[Id].FrameNbWithTrig = 0; + ProAPlaneRes[Id].FramePCentWithTrig = 0; + ProAPlaneRes[Id].CumTotTrigNb = 0; + ProAPlaneRes[Id].CumFrameTrigNb = 0; + + ProAPlaneRes[Id].FrameNbWithHit = 0; + ProAPlaneRes[Id].FramePCentWithHit = 0; + ProAPlaneRes[Id].CumTotHitNb = 0; + ProAPlaneRes[Id].CumFrHitNb = 0; + ULT1__FMatDiscriCumulResetHit ( VPtFrMatCumTotHitCnt ); + + msg (( MSG_OUT, "----------> ProFProcessPlane => Reset - Plane %d", Id )); + } + + VGoodFrame = 1; + + // Convert ZsFFrameRaw to ZsFFrame and store result in class tmp var PrivZsFFrame + + if ( ProPar.HandleTrigPos == 0 ) { + ULT1__FConvZsFFrameRawToZsFFrame ( PtSrc, &PrivZsFFrame, 0 /* DbgPrintLvl */ ); + } + + // Trigger pos handling + + else { + if ( ULT1__FConvZsFFrameRawToZsFFrameHandleTrigger ( ProPar.MapsNb, DbgEvNo, PrivAcqEvNb, PtSrc, &PrivZsFFrame, 1 /* DbgPrintLvl */ ) < 0 ) { +// msg (( MSG_OUT, "***********************************************************************************" )); +// msg (( MSG_OUT, "=> Event %4d has no trigger => Abort ! Plot may be false ! ( it's previous event ) ", DbgEvNo )); +// msg (( MSG_OUT, "**********************************************************************************" )); + +// return (0); + + VGoodFrame = 0; + } + } + + // Convert ZsFFrameRaw to Pixels matrix AND Process cumul AT THE SAME TIME + + VUpdateMatCumul = ProAPlanePar[Id].PlotCum || ProAPlanePar[Id].PlotCoin; + + // ****************************************************************************************************** + // WARNING !!! TODAY 25/07/2009 Update matrix cumul is ALWAYS done => flag VUpdateMatCumul IS NOT used + // => Use flag later AND check ! + // ****************************************************************************************************** + +if ( VGoodFrame == 1 ) { + + VHitCnt = PrivFConvZsFFrameToMatDiscriBitAndCumul ( + DbgEvNo, + ProPar.ProcMode /* Mode */, + Id /* PlaneNo */, + ProAPlanePar[Id].PlotCoin /* PlaneSelForCoin */, + ProInf.CurEvToProc /* EvNo */, + ProPar.GotoRawFrNo /* EvSelForPlot */, + &PrivZsFFrame /* PtSrc */, + VPtFrMatDiscriBit /* PtDestFrameBit */, // Plane pixel matrix as "bit = state" + &PrivMatDiscriCoin /* PtDestCoinBit */, // Common coincidence pixel matrix as "bit = state" + VPtFrMatCumTotHitCnt /* PtDestFrameCum */, // Plane pixel cumul matrix as "count" + &PrivMatDiscriCoinCum /* PtDestCoinCum */, // Common coincidence cumul matrix as "count" + 0 /* PrintLvl */ ); + + // Increment counter of frames with trigger + + if ( PrivZsFFrame.TrigSignalLine >= 0 ) { + ++ProAPlaneRes[Id].FrameNbWithTrig; + } + + // Increment counter of triggers + + if ( PrivZsFFrame.SStatus.ATrigRes[ASIC__ULT1_TRIG_TOT_NB] > 0 ) { + ProAPlaneRes[Id].CumTotTrigNb += PrivZsFFrame.SStatus.ATrigRes[ASIC__ULT1_TRIG_TOT_NB]; + } + + + // Increment counter of frames with hits + + if ( VHitCnt > 0 ) { + ++ProAPlaneRes[Id].FrameNbWithHit; + ProAPlaneRes[Id].CumTotHitNb += VHitCnt; + } + + +} // End if ( VGoodFrame == 1 ) + + + // ------------------------------------------------ + // Plot frame + // ------------------------------------------------ + + if ( (ProAPlanePar[Id].PlotFrame ) && (ProPar.GotoRawFrNo >= 0) && (ProPar.GotoRawFrNo == ProInf.CurEvToProc) ) { + + if ( ProPar.DispFullMatrix ) { + ULT1__FDiscriMatConvBitToColState ( VPtFrMatDiscriBit, &PrivMatDispColor, clWhite /* ColorStateZero */, ProAPlanePar[Id].PlotColor, 0 /* RevertLineDirection */ ); + } + + else { + ULT1__FConvMatDiscriBitToMatDiscriBitHalfScale ( VPtFrMatDiscriBit, &PrivMatDiscriBitHalfScale ); + ULT1__FDiscriMatConvBitToColStateHalfScale ( &PrivMatDiscriBitHalfScale, &PrivMatDispColorHalfScale, clWhite /* ColorStateZero */, ProAPlanePar[Id].PlotColor, 0 /* RevertLineDirection */ ); + + ULT1_FPrintZsFFrameRawHeader ( PtSrc ); + ULT1__FMatDiscriPrintHit ( "Plane", Id, VPtFrMatDiscriBit ); + + // err_error (( ERR_OUT, "---> ---> Plot frame request 1/2 matrix - Plane %d", Id )); + } + + VRequestPlot = 1; // PLot request will be done at end of function + + } // End if Plot frame + + + + // Copy to buffer if required + + if ( ProPar.StoreEvents == 1 ) { + + err_error (( ERR_OUT, "Copy of event to buffer NOT IMPLEMENTED" )); + + } // Enf if copy to buffer + + + // ================================================ + // Last event => calculate results & display + // ================================================ + + if ( (PrivStopProc == 1) || (ProInf.CurEvToProc >= (ProInf.LastEvToProc) ) ) { + + msg (( MSG_OUT, "----------> ProFProcessPlane => Last event => Calc" )); + + err_error (( ERR_OUT, "----------> ProFProcessPlane => Last event => Calc" )); + + ProAPlaneRes[Id].FramePCentWithTrig = ( (float) ProAPlaneRes[Id].FrameNbWithTrig / (float) ProInf.EvNbToProc ) * 100; + + ProAPlaneRes[Id].FramePCentWithHit = ( (float) ProAPlaneRes[Id].FrameNbWithHit / (float) ProInf.EvNbToProc ) * 100; + + if ( ProAPlaneRes[Id].FrameNbWithTrig != 0 ) { + ProAPlaneRes[Id].CumFrameTrigNb = (float) ProAPlaneRes[Id].CumTotTrigNb / (float) ProAPlaneRes[Id].FrameNbWithTrig; + } + + else { + ProAPlaneRes[Id].CumFrameTrigNb = 0; + } + + + if ( ProAPlaneRes[Id].FrameNbWithHit != 0 ) { + ProAPlaneRes[Id].CumFrHitNb = ( (float) ProAPlaneRes[Id].CumTotHitNb / (float) ProAPlaneRes[Id].FrameNbWithHit ); + } + + else { + ProAPlaneRes[Id].CumFrHitNb = 0; + } + + + PubFPrintPlaneRes (Id); + + while (1) { + + // ------------------------------------------------ + // Plot cumul + // ------------------------------------------------ + + if ( ProAPlanePar[Id].PlotCum ) { + + // ULT1__FPrintMatDiscriCumul ( VPtFrMatCumTotHitCnt ); + + if ( ProPar.DispFullMatrix ) { + ULT1__FDiscriMatConvCumulToColVal ( VPtFrMatCumTotHitCnt, &PrivMatDispColor, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + err_error (( ERR_OUT, "---> Plot cumul request FULL matrix - Plane %d", Id )); + } + + else { + ULT1__FConvMatDiscriCumToMatDiscriCumHalfScale ( VPtFrMatCumTotHitCnt, &PrivMatDiscriCumHalfScale ); + + // ULT1__FPrintMatDiscriCumulHalfScale ( &PrivMatDiscriCumHalfScale ); + + ULT1__FDiscriMatConvCumulToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + err_error (( ERR_OUT, "---> Plot cumul request 1/2 matrix - Plane %d", Id )); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCum) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS) ) { + + if ( ProPar.DispFullMatrix ) { + ULT1__FDiscriMatFullScaleConvCoinBitToColState ( &PrivMatDiscriCoin, &PrivMatDispColor, clWhite /* ColorZeroHit */, PrivAPlanePlotColor /* AColorOneHit */, clBlack /* ColorMultiHit */, 0 /* RevertLineDirection */ ); + } + + else { + ULT1__FConvMatDiscriBitCoinToMatDiscriBitCoinHalfScale ( &PrivMatDiscriCoin, &PrivMatDiscriBitHalfScale ); + ULT1__FDiscriMatConvCoinBitToColStateHalfScale ( &PrivMatDiscriBitHalfScale, &PrivMatDispColorHalfScale, clWhite /* ColorZeroHit */, PrivAPlanePlotColor /* AColorOneHit */, clBlack /* ColorMultiHit */, 0 /* RevertLineDirection */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR) ) { + + if ( ProPar.DispFullMatrix ) { + ULT1__FDiscriMatConvCumulToColVal ( &PrivMatDiscriCoinCum, &PrivMatDispColor, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + } + + else { + ULT1__FConvMatDiscriCumToMatDiscriCumHalfScale ( &PrivMatDiscriCoinCum, &PrivMatDiscriCumHalfScale ); + ULT1__FDiscriMatConvCumulToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR) + + // ----------------------------------------------------------------------------------- + // Plot coincidence & Mode MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + // ----------------------------------------------------------------------------------- + + if ( ProAPlanePar[Id].PlotCoin && (ProPar.ProcMode == MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) ) { + + if ( ProPar.DispFullMatrix ) { + ULT1__FDiscriMatConvCumulCoinOrToColVal ( &PrivMatDiscriCoinCum, &PrivMatDispColor, PrivAPlanePlotColor /* AColorOneHit */, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */ ); + } + + else { + ULT1__FConvMatDiscriCumToMatDiscriCumHalfScale ( &PrivMatDiscriCoinCum, &PrivMatDiscriCumHalfScale ); + ULT1__FDiscriMatConvCumulCoinOrToColValHalfScale ( &PrivMatDiscriCumHalfScale, &PrivMatDispColorHalfScale, PrivAPlanePlotColor /* AColorOneHit */, ProPar.CumPlotGrayOrBlueLevels, ProPar.CumPlotHitOrHitCnt, 0 /* RevertLineDirection */, 0 /* PrintLvl */ ); + } + + VRequestPlot = 1; // PLot request will be done at end of function + break; + + } // End if (PlotCoin && MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS ) + + + break; + } // End while (1) + + + } // End if Last event + + + // ------------------ + // Plot request + // ------------------ + + if ( VRequestPlot ) { + + if ( ProRequestPlot == 0 ) { + ProRequestPlot = 1; + } + + } + + + return (VHitCnt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +ULT1__TCTelMon::ULT1__TCTelMon () : MAPS__TCDigTelMon () { + + err_error (( ERR_OUT, "TRACE - ProPar.PlaneNb=%d", ProPar.PlaneNb )); + + PrivFInit (); + + err_error (( ERR_OUT, "TRACE - ProPar.PlaneNb=%d", ProPar.PlaneNb )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +ULT1__TCTelMon::~ULT1__TCTelMon () { + + SInt32 Vi; + + // Free + + for ( Vi=0; Vi < ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB; Vi++ ) { + free ( PrivAAListEvWithTrig[Vi] ); + free ( PrivAAListEvWithHit[Vi] ); + } + + free ( PrivAListEvWithHitAllPlanes ); + + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 17/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 MaxBuffEvNb ) { + + if ( MaxBuffEvNb > MAPS__TCDigTelMon_MAX_EV_NB ) { + err_retfail ( -1, (ERR_OUT,"MaxBuffEvNb=%d > MAPS__TCDigTelMon_MAX_EV_NB=%d", MaxBuffEvNb, MAPS__TCDigTelMon_MAX_EV_NB ) ); + } + + ProPar.MaxBuffEvNb = MaxBuffEvNb; + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 23/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFConnectGui () { + + MAPS__TCDigTelMon::PubFConnectGui (); + + PubPt_ALbPlane[0]->Font->Color = ULT1__TCTelMon__COL_PLANE_0; + PubPt_ALbPlane[1]->Font->Color = ULT1__TCTelMon__COL_PLANE_1; + PubPt_ALbPlane[2]->Font->Color = ULT1__TCTelMon__COL_PLANE_2; + PubPt_ALbPlane[3]->Font->Color = ULT1__TCTelMon__COL_PLANE_3; + PubPt_ALbPlane[4]->Font->Color = ULT1__TCTelMon__COL_PLANE_4; + PubPt_ALbPlane[5]->Font->Color = ULT1__TCTelMon__COL_PLANE_5; + + PubPt_GrpTelMon->Color = clSilver; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFGetGuiPar () { + + // -------------------------- + // Get parameters from GUI + // -------------------------- + + MAPS__TCDigTelMon::PubFGetGuiPar (); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 ULT1__TCTelMon::PubFStartRun ( SInt8 MapsNb) { + + SInt8 ViPlane; + SInt32 ViEv; + void* VPtMat; + + + // --------------------- + // Run in progress + // --------------------- + + ProInf.RunInProgress = 1; + + // --------------------- + // Set MAPS nb + // --------------------- + + ProPar.MapsNb = MapsNb; + + // --------------------- + // Reset Ev No to process + // --------------------- + + ProInf.CurEvToProc = 0; + + // --------------------- + // Allocate memory + // --------------------- + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + // Intermediate buffers + + ProAPlaneRes[ViPlane].PtMatDiscriBit = malloc ( sizeof (ULT1__TMatDiscriBit) ); + err_retnull ( ProAPlaneRes[ViPlane].PtMatDiscriBit, (ERR_OUT,"Allocation of PtMatDiscriBit plane [%d] failed !", ViPlane) ); + + ProAPlaneRes[ViPlane].PtMatCumTotHitCnt = malloc ( sizeof (ULT1__TMatDiscriCumul)); + err_retnull ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt, (ERR_OUT,"Allocation of PtMatCumTotHitCnt plane [%d] failed !", ViPlane) ); + + // Events + + if ( ProPar.StoreEvents == 1 ) { + + for ( ViEv=0; ViEv < ProPar.MaxBuffEvNb; ViEv++ ) { + VPtMat = malloc ( sizeof (ULT1__TMatDiscriBit) ); + + if ( VPtMat = NULL) { + err_retfail ( -1, (ERR_OUT,"Allocation of plane[%d] event[%d] failed !",ViPlane, ViEv) ); + } + + ProAPlaneData[ViPlane].AEvPt[ViEv] = VPtMat; + + } // End for ViEv + + } // End if StoreEvents + + } // End for + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFStopRun () { + + SInt8 ViPlane; + SInt32 ViEv; + + // --------------------- + // Run stopped + // --------------------- + + ProInf.RunInProgress = 0; + + // --------------------- + // DeAllocate memory + // --------------------- + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + // Intermediate buffers + + if ( ProAPlaneRes[ViPlane].PtMatDiscriBit != NULL ) free ( ProAPlaneRes[ViPlane].PtMatDiscriBit ); + if ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt != NULL ) free ( ProAPlaneRes[ViPlane].PtMatCumTotHitCnt ); + + // Events + + for ( ViEv=0; ViEv < MAPS__TCDigTelMon_MAX_EV_NB; ViEv++ ) { + if ( ProAPlaneData[ViPlane].AEvPt != NULL ) { + free ( ProAPlaneData[ViPlane].AEvPt ); + } + } + + } // End for + + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFStartMon () { + + ProPar.MonEnabled = 1; + + PubFSetGuiPar (); + + PubPt_GrpTelMon->Color = clBtnFace; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFStopMon () { + + ProPar.MonEnabled = 0; + + PubFSetGuiPar (); + + PubPt_GrpTelMon->Color = clSilver; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ) { + + ProPar.ProcOnlyFrWithHitOnAllPlanes = Yes; + PriEnListEvWitHitUpdate = !Yes; + PriEnListEvWithTrigUpdate = !Yes; + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 22/07/2009 - 06/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt32 EvNb, ULT1__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ) { + + SInt8 ViPlane; + SInt32 ViFramePlane0ofEvent; + SInt32 ViFrame; + SInt32 ViEvInAcq; + SInt32 VTrigSigLine; + SInt32 VEvHitCnt; + SInt32 VPlaneHitCnt; + SInt8 VFlgHitOnAllPlane; + SInt8 VFlgSingleHitOnEachPlane; + SInt32 VLocalCpySz; + ASIC__TFrameStatus* VPtEvStatus; + static UInt32 VTimeBeg; + static UInt32 VTimeEnd; + + SInt8 ViDbgMaps; + UInt16 VDbgTrigNb; + UInt16 VADbgTrigVal[3]; + UInt16 VADbgTrigLine[3]; + UInt16 VADbgTrigClock[3]; + + err_error (( ERR_OUT, "MapsName=%d - MapsNb=%d - EvNb=%d", MapsName, MapsNb, EvNb )); + err_error (( ERR_OUT, "" )); + + for ( ViDbgMaps=0; ViDbgMaps < MapsNb; ViDbgMaps++ ) { + + VDbgTrigNb = (PtSrc[ViDbgMaps].Zero & 0xFFFF0000) >> 16; + VADbgTrigVal[0] = (PtSrc[ViDbgMaps].Zero & 0x0000FFFF); + VADbgTrigVal[1] = (PtSrc[ViDbgMaps].Zero2 & 0xFFFF0000) >> 16; + VADbgTrigVal[2] = (PtSrc[ViDbgMaps].Zero2 & 0x0000FFFF); + + VADbgTrigLine[0] = VADbgTrigVal[0] / 16; + VADbgTrigLine[1] = VADbgTrigVal[1] / 16; + VADbgTrigLine[2] = VADbgTrigVal[2] / 16; + + VADbgTrigClock[0] = VADbgTrigVal[0] % 16; + VADbgTrigClock[1] = VADbgTrigVal[1] % 16; + VADbgTrigClock[2] = VADbgTrigVal[2] % 16; + + err_error (( ERR_OUT, "=======================================================================================" )); + err_error (( ERR_OUT, "ViDbgMaps=%d : AsicNo=%d - AcqNo=%d - Header=%x", ViDbgMaps, PtSrc[ViDbgMaps].SStatus.AsicNo, PtSrc[ViDbgMaps].SStatus.AcqNo, PtSrc[ViDbgMaps].Header )); +// err_error (( ERR_OUT, "--> Trailer=%x", PtSrc[ViDbgMaps].Trailer )); +// err_error (( ERR_OUT, "--> Zero H=%d - Zero L=%d", (PtSrc[ViDbgMaps].Zero & 0xFFFF0000) >> 16, (PtSrc[ViDbgMaps].Zero & 0x0000FFFF) )); +// err_error (( ERR_OUT, "--> Zero2 H=%d - Zero2 L=%d", (PtSrc[ViDbgMaps].Zero2 & 0xFFFF0000) >> 16, (PtSrc[ViDbgMaps].Zero2 & 0x0000FFFF) )); + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "--> Trig Nb = %d", VDbgTrigNb )); + err_error (( ERR_OUT, "--> Trig [0] : Line %4d - clock %4d", VADbgTrigLine[0], VADbgTrigClock[0] )); + err_error (( ERR_OUT, "--> Trig [1] : Line %4d - clock %4d", VADbgTrigLine[1], VADbgTrigClock[1] )); + err_error (( ERR_OUT, "--> Trig [2] : Line %4d - clock %4d", VADbgTrigLine[2], VADbgTrigClock[2] )); + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); + err_error (( ERR_OUT, "Info Trigger : Line %4d - clock %4d", PtSrc[ViDbgMaps].SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE], PtSrc[ViDbgMaps].SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_CLK] )); + err_error (( ERR_OUT, "---------------------------------------------------------------------------------------" )); + + } + + err_error (( ERR_OUT, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$" )); + + if ( (ProPar.MonEnabled == 0) && (OffLineCall == 0) ) { + return (0); + } + + // Check parameters + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc = NULL") ); + + if ( MapsName != ProPar.MapsName ) { + err_retfail ( -1, (ERR_OUT,"Bad MapsName=%d <> ProPar.MapsName=%d", MapsName, ProPar.MapsName ) ); + } + + if ( MapsNb != ProPar.MapsNb ) { + err_retfail ( -1, (ERR_OUT,"Bad MapsNb=%d <> ProPar.MapsNb=%d", MapsNb, ProPar.MapsNb ) ); + } + + // make a copy of Acq event nb, for off-line processing call of this function + + PrivAcqEvNb = EvNb; + + // Make a local copy if required + + if ( MakeLocalCpy ) { + + if ( PrivPtAcqData != NULL ) { + free ( PrivPtAcqData ); + } + + VLocalCpySz = MapsNb * EvNb * sizeof (ULT1__TZsFFrameRaw); + + PrivPtAcqData = (ULT1__TZsFFrameRaw*) malloc ( VLocalCpySz ); + + if ( PrivPtAcqData == NULL ) { + err_error (( ERR_OUT, "Allocation of buffer for local copy of %d bytes ... failed !", VLocalCpySz )); + } + + else { + memcpy ( PrivPtAcqData, PtSrc, VLocalCpySz ); + msg (( MSG_OUT, "Allocation of buffer AND local copy of %d Kbytes done :-)", VLocalCpySz / 1024 )); + err_error (( ERR_OUT, "Allocation of buffer for local copy of %d Kbytes done :-)", VLocalCpySz / 1024 )); + } + + } + + // Read GUI parameters + + PubFGetGuiPar (); + + + // Update processing mode flags + + PrivListEvWithHitAllPlanesCurProcMode = ProPar.ListHitAllPlanesMode; + + // ---------------------------------------- + // If beginning of processing + // ---------------------------------------- + + + if ( ProInf.CurEvToProc == 0 ) { + + PrivStopProc = 0; + + VTimeBeg = GetTickCount (); // Get time of beginning of processing + + msg (( MSG_OUT, "----------> PubFAddEvents => Reset all results" )); + + // Reset all coin destination matrices ( common for all planes ) + + memset ( &PrivMatDiscriCoin , 0, sizeof (ULT1__TMatDiscriBit) ); + memset ( &PrivMatDiscriCoinCum, 0, sizeof (ULT1__TMatDiscriCumul) ); + + // Reset list & list index & full flag + // + // -> Must be done HERE + // -> MUST NOT be done at end of this function when ProInf.EvNbToProc is reached + // because user will want to plot theses results at end of processing + + if ( PriEnListEvWithTrigUpdate == 1 ) { + + for ( ViPlane=0; ViPlane < ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB; ViPlane++ ) { + memset ( PrivAAListEvWithTrig[ViPlane], 0, ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + } + + PrivListEvWithTrigIndex = 0; + PrivListEvWithTrigFull = 0; + } // End if ( PriEnListUpdate == 1 ) + + if ( PriEnListEvWitHitUpdate == 1 ) { + + for ( ViPlane=0; ViPlane < ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB; ViPlane++ ) { + memset ( PrivAAListEvWithHit[ViPlane], 0, ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ASIC__TFrameStatus) ); + } + + memset ( PrivAListEvWithHitAllPlanes, 0, ULT1__TCTelMon__EV_LIST_MAX_ELT_NB * sizeof (ULT1__TCTelMon_TEltListEvWithHitAllPlanes) ); + + PrivListEvWithHitIndex = 0; + PrivListEvWithHitFull = 0; + + PrivListEvWithHitAllPlanesIndex = 0; + PrivListEvWithHitAllPlanesFull = 0; + + } // End if ( PriEnListUpdate == 1 ) + + + } + + // Results set + + ProRes.AcqFrNb = EvNb; + + // Processing mode selection + // - One acq => number of events received by server + // - Events number from GUI => can be less or more than one Acq + + if ( ProPar.ProcOneAcq ) { + ProInf.EvNbToProc = EvNb; + } + + else { + ProInf.EvNbToProc = ProPar.ProcEvNb; + } + + ProInf.LastEvToProc = ProInf.EvNbToProc - 1; + + msg (( MSG_OUT, "PubFAddEvents => MapsName=%d - MapsNb=%d - EvNb=%d (DAQ) - ProcOneAcq=%d - EvNbToProc=%d", MapsName, MapsNb, EvNb, ProPar.ProcOneAcq, ProInf.EvNbToProc )); + + // Process events + + + for ( ViEvInAcq=0; ViEvInAcq < EvNb; ViEvInAcq++ ) { + + if ( ProPar.ProcOnlyFrWithHitOnAllPlanes == 1) { + PrivStopProc = PubFIsEvLastOfListEvWithHitOnAllPlanes ( ViEvInAcq ); + } + + else { + PrivStopProc = 0; + } + + + VFlgHitOnAllPlane = 1; + VFlgSingleHitOnEachPlane = 1; + + if ( ProInf.CurEvToProc < ProInf.EvNbToProc ) { + + if ( ViEvInAcq % 100 == 0 ) { + FDecInt2Edit ( ViEvInAcq, PubPt_DispCurProcFr ); + Application->ProcessMessages (); + } + + ViFramePlane0ofEvent = MapsNb * ViEvInAcq; + VTrigSigLine = PtSrc[ViFramePlane0ofEvent].SStatus.ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE]; + VPtEvStatus = &PtSrc[ViFramePlane0ofEvent].SStatus; + + // If Process all frames OR Process frame with trigger AND there is a Trigger on this frame + + // if ( (ProPar.ProcOnlyFrWithTrig == 0) || (VTrigSigLine >= 0) ) { + // if ( (ProPar.ProcOnlyFrWithHitOnAllPlanes == 0) || (PubFIsEvInListEvWithHitOnAllPlanes (ViEvInAcq) == 1) ) { + + if ( ((ProPar.ProcOnlyFrWithTrig == 0) || (VTrigSigLine >= 0)) && ((ProPar.ProcOnlyFrWithHitOnAllPlanes == 0) || (PubFIsEvInListEvWithHitOnAllPlanes (ViEvInAcq) == 1)) ) { + + // Reset event hits counter + + VEvHitCnt = 0; + + // Loop on all selected planes + + for ( ViPlane=0; ViPlane < ProPar.PlaneNb; ViPlane++) { + + if ( ProAPlanePar[ViPlane].Process == 1 ) { + + ViFrame = ViFramePlane0ofEvent + ViPlane; + VPlaneHitCnt = ProFProcessPlane ( ViEvInAcq, ViPlane, &PtSrc[ViFrame] ); + VEvHitCnt += VPlaneHitCnt; + + if ( VPlaneHitCnt != 1 ) { + VFlgSingleHitOnEachPlane = 0; + } + + if ( VPlaneHitCnt > 0 ) { + PrivFAddEvInListEvWithHit ( ViPlane, VPtEvStatus, VPlaneHitCnt, 0 /* HitOnAllPlanes */, 0 /* SingleHitOnEachPlane */ ); + } + + else { + VFlgHitOnAllPlane = 0; // Reset flag in at least one plane is without hit + } + + } + } + + // If trigger ( -1 => no trigger ) => store in list + + if ( VTrigSigLine >= 0 ) { + PrivFAddEvInListEvWithTrig ( ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL, VPtEvStatus, VEvHitCnt ); + } + + // If hits => store in list + + if ( VEvHitCnt > 0 ) { + PrivFAddEvInListEvWithHit ( ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL, VPtEvStatus, VEvHitCnt, VFlgHitOnAllPlane, VFlgSingleHitOnEachPlane ); + } + + // Results + + ProRes.ProFrNo = ProInf.CurEvToProc; + + ++ProInf.CurEvToProc; + + } + + + } + + else { + break; // End of processing => We can reach ProInf.EvNbToProc while all events of current Acq are not needed for processing + } + + } // End for + + // If end of processing => Reset event index + + if ( ProInf.CurEvToProc >= ProInf.EvNbToProc ) { + + msg (( MSG_OUT, "----------> PubFAddEvents => Print results" )); + + ProInf.CurEvToProc = 0; + + // Get time of end of processing + + VTimeEnd = GetTickCount (); + ProRes.ProTimeMs = VTimeEnd - VTimeBeg; + + // Display results + + PubFSetGuiRes (); + + // Stop monitoring if required + + if ( ProPar.StopAtEndOfProc ) { + PubFStopMon (); + } + + } + + // Display status + + PubFSetGuiStatus (); + + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFProcessOffLineCurAcq () { + + + // Stop on-line monitoring + + PubFStopMon (); + + // Get GUI parameters => In order to get user choices + + PubFGetGuiPar (); + + // Force mode to "Process one Acq" AND update GUI fields + + ProPar.ProcOneAcq = 1; + + PubFSetGuiPar (); + + // Don't update list if processing of ONLY events with trigger + + if ( ProPar.ProcOnlyFrWithTrig == 1 ) { + PriEnListEvWithTrigUpdate = 0; + } + + else { + PriEnListEvWithTrigUpdate = 1; + } + + // Check buffer of current acq data + + err_retnull ( PrivPtAcqData, (ERR_OUT,"No data in buffer => PrivPtAcqData == NULL !") ); + + // ---------------------------------------------------------------------------------------------------------------------- + // Reset Ev No to process + // ---------------------------------------------------------------------------------------------------------------------- + // Because on some processing it may not be reset at end of processing, in case event nb to process has not been reached + // for example : processing of only events with trigger + // ---------------------------------------------------------------------------------------------------------------------- + // + // WARNING => IT MUST BE CHECKED if this init DONE HERE IS compatible WITH ALL sw operating modes !!! + // => It may CAUSE BUGS in other operating modes !!! + // + // 15/08/09 + // ---------------------------------------------------------------------------------------------------------------------- + + ProInf.CurEvToProc = 0; + + + // Execute PubFAddEvents (...) in off-line mode + + PubFAddEvents ( ProPar.MapsName, ProPar.MapsNb, PrivAcqEvNb, PrivPtAcqData/* PtSrc */, 0 /* MakeLocalCpy */, 1 /* OffLineCall */ ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFProcessOffLineCurAcq2 () { + + // Stop on-line monitoring + + PubFStopMon (); + + // Force mode to "Process one Acq" AND update GUI fields + + ProPar.ProcOneAcq = 1; + + // Execute PubFAddEvents (...) in off-line mode + + PubFAddEvents ( ProPar.MapsName, ProPar.MapsNb, PrivAcqEvNb, PrivPtAcqData/* PtSrc */, 0 /* MakeLocalCpy */, 1 /* OffLineCall */ ); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFGotoFirstFrame () { + + ProPar.GotoRawFrNo = 0; + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFGotoPrevFrame () { + + if ( ProPar.GotoRawFrNo > 0 ) { + --ProPar.GotoRawFrNo; + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFGotoNextFrame () { + + if ( ProPar.GotoRawFrNo < PrivAcqEvNb ) { + ++ProPar.GotoRawFrNo; + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFGotoLastFrame () { + + if ( PrivAcqEvNb > 0 ) { + ProPar.GotoRawFrNo = PrivAcqEvNb-1; + } + + else { + ProPar.GotoRawFrNo = -1; // No frame available, < 0 tested when we try to access data + } + + PubFSetGuiParGotoFr (); + + if ( ProPar.MonEnabled == 0 ) PubFProcessOffLineCurAcq (); + +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubPrintListEvWithTrig ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPt; + + + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "- Print events with trigger -" )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithTrigIndex, PrivListEvWithTrigFull )); + msg (( MSG_OUT, "-----------------------------" )); + + VPt = PrivAAListEvWithTrig[ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL]; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithTrigIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithTrigIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - TSigLine=%4d - HitCnt=%4d", Vi, VPt->FrameNoInRun, VPt->ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 26/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubPrintListEvWithHit ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPtPlane0; + ASIC__TFrameStatus* VPtPlane1; + ASIC__TFrameStatus* VPt; + + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, "- Print events with hit -" )); + msg (( MSG_OUT, "-----------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithHitIndex, PrivListEvWithHitFull )); + msg (( MSG_OUT, "-----------------------------" )); + + + VPtPlane0 = PrivAAListEvWithHit[0]; + VPtPlane1 = PrivAAListEvWithHit[1]; + VPt = PrivAAListEvWithHit[ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL]; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithHitIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt[C]=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPt; + ++VPtPlane0; + ++VPtPlane1; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithHitIndex; Vi++ ) { + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - TSigLine=%4d - HitCnt [0]=%4d / [1]=%4d / [C]=%4d", Vi, VPt->FrameNoInRun, VPt->ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE], VPtPlane0->HitCnt, VPtPlane1->HitCnt, VPt->HitCnt )); + ++VPt; + ++VPtPlane0; + ++VPtPlane1; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubPrintListEvWithHitOnAllPlanes ( SInt8 Verbose ) { + + SInt32 Vi; + ASIC__TFrameStatus* VPtP0; + ASIC__TFrameStatus* VPtP1; + ASIC__TFrameStatus* VPt; + ULT1__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + if ( ProPar.ListHitAllPlanesMode != PrivListEvWithHitAllPlanesCurProcMode ) { + msg (( MSG_OUT, "----------------------------------------------------------" )); + msg (( MSG_OUT, "- Please process data before with button -" )); + msg (( MSG_OUT, "----------------------------------------------------------" )); + err_retok (( ERR_OUT, "" )); + } + + + msg (( MSG_OUT, "--------------------------------------" )); + + + switch ( ProPar.ListHitAllPlanesMode ) { + + case MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES : { + msg (( MSG_OUT, "- Print events with hit on ALL planes -" )); + break; } + + case MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE : { + msg (( MSG_OUT, "- Print events with single hit on EACH plane -" )); + break; } + + default : { + msg (( MSG_OUT, "- Error => Unknown list mode = %d -", ProPar.ListHitAllPlanesMode )); + break; } + + } + + msg (( MSG_OUT, "------------------------------------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivListEvWithHitAllPlanesIndex, PrivListEvWithHitAllPlanesFull )); + msg (( MSG_OUT, "------------------------------------------------------" )); + + + VPtRec = PrivAListEvWithHitAllPlanes; + + if ( Verbose ) { + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + VPt = &VPtRec->FrStatus; + msg (( MSG_OUT, "[%4d] : EvInRun=%4d - Acq=%4d - EvInAcq=%4d - TSigLine=%4d - HitCnt[C]=%4d", Vi, VPt->FrameNoInRun, VPt->AcqNo, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE], VPt->HitCnt )); + ++VPtRec; + } + } + + else { + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + VPt = &VPtRec->FrStatus; + + if ( (VPtRec->IndexInEvWithHitList >=0) && (VPtRec->IndexInEvWithHitList < PrivListEvWithHitIndex) ) { + VPtP0 = &PrivAAListEvWithHit[0][VPtRec->IndexInEvWithHitList]; + VPtP1 = &PrivAAListEvWithHit[1][VPtRec->IndexInEvWithHitList]; + msg (( MSG_OUT, "[%4d] : EvInAcq=%4d - TSigLine=%4d - HitCnt [0]=%4d / [1]=%4d / [C]=%4d", Vi, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE], VPtP0->HitCnt, VPtP1->HitCnt, VPt->HitCnt )); + } + + else { + msg (( MSG_OUT, "[%4d] : EvInAcq=%4d - TSigLine=%4d - HitCnt [0]=! / [1]=! / [C]=%4d", Vi, VPt->FrameNoInAcq, VPt->ATrigRes[ASIC__ULT1_TRIG_RES__SIG_LINE], VPt->HitCnt )); + } + + ++VPtRec; + } + } + + + msg (( MSG_OUT, "-----------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 04/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubAllocResRun () { + + // Res run alloc / free handling + + if ( PrivPtResRun != NULL ) { + free ( PrivPtResRun ); + } + + + PrivPtResRun = (ULT1__TCTelMon_TResRun*) malloc ( sizeof (ULT1__TCTelMon_TResRun) ); + + if ( PrivPtResRun == NULL ) { + err_error (( ERR_OUT, "Allocation of result run failed !" )); + } + + else { + + memset ( PrivPtResRun, 0, sizeof (ULT1__TCTelMon_TResRun) ); + + PrivPtResRun->EvNb = 0; + PrivPtResRun->PlaneNb = 2; + } + + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 06/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFreeResRun () { + + if ( PrivPtResRun != NULL ) { + free ( PrivPtResRun ); + } + + + PrivPtResRun = NULL; + + return (0); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubPrintResRun () { + + SInt32 ViEv; + SInt32 ViHit; + ULT1__TCTelMon_TTrack* VPt; + + if ( PrivPtResRun == NULL ) { + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "- ERROR => Res run is NOT allocated - " )); + msg (( MSG_OUT, "-------------------------------------" )); + err_retfail ( -1, (ERR_OUT,"PrivPtResRun == NULL") ); + } + + msg (( MSG_OUT, "--------------------------------------" )); + msg (( MSG_OUT, "- Result run -" )); + msg (( MSG_OUT, "--------------------------------------" )); + msg (( MSG_OUT, " %d events - List full ? %d ", PrivPtResRun->EvNb, PrivPtResRun->Full )); + msg (( MSG_OUT, "--------------------------------------" )); + + + for ( ViEv=0; ViEv < PrivPtResRun->EvNb; ViEv++) { + + VPt = &PrivPtResRun->ATracks[ViEv]; + + if ( VPt->AHitsNbPerPlane[0] != VPt->AHitsNbPerPlane[1] ) { + msg (( MSG_OUT, "WARNING : Hit nb P0 = %d <> Hit nb P1 = %d => Use P0 for print", VPt->AHitsNbPerPlane[0], VPt->AHitsNbPerPlane[1] )); + } + + msg (( MSG_OUT, "=================================================================" )); + + for ( ViHit=0; ViHit < VPt->AHitsNbPerPlane[0]; ViHit++) { + msg (( MSG_OUT, "Ev %4d - EvInRun %4d - Hit %4d : P0 [x=%4d, y=%4d] - P1[x=%4d, y=%4d]", ViEv, VPt->EvNoInRun, ViHit, VPt->AAHits[0][ViHit].x, VPt->AAHits[0][ViHit].y, VPt->AAHits[1][ViHit].x, VPt->AAHits[1][ViHit].y )); + } + + } + + + msg (( MSG_OUT, "-----------------------------" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubSaveResRun ( char* FileName ) { + + SInt32 VTotResRecordSz; + + if ( PrivPtResRun == NULL ) { + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "- ERROR => Res run is NOT allocated - " )); + msg (( MSG_OUT, "-------------------------------------" )); + err_retfail ( -1, (ERR_OUT,"PrivPtResRun == NULL") ); + } + + FIL__TCBinFile VResFile ( "x:\\log\\err_TCBinFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_WARNINGS_ERRORS ); + + err_retnull ( FileName, (ERR_OUT,"FileName == NULL") ); + + VTotResRecordSz = sizeof (ULT1__TCTelMon_TResRun); + + VResFile.PubFConf ( FileName, 0 /* WriteRead => 0=Write 1=Read */ , VTotResRecordSz /* MaxBlocSz */, VTotResRecordSz /* BlocSz */, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VResFile.PubFCreate (); + VResFile.PubFSeqWrite ( PrivPtResRun, VTotResRecordSz ); + + VResFile.PubFClose (); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFIsEvInListEvWithHitOnAllPlanes ( SInt32 EvNo ) { + + SInt8 VFound; + SInt32 Vi; + ULT1__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + VPtRec = PrivAListEvWithHitAllPlanes; + + VFound = 0; + + // Acq processing + + if ( PubAcqOffLineProcOrRunOffLineProc == 0 ) { + + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + if ( EvNo == VPtRec->FrStatus.FrameNoInRun ) { + err_error (( ERR_OUT, "TRACE : EltNo %4d - EvNo %4d - FrNoInAcq %4d => Hit on all planes", Vi, VPtRec->FrStatus.FrameNoInRun, VPtRec->FrStatus.FrameNoInAcq )); + VFound = 1; + break; + } + ++VPtRec; + } + + } + + // Run processing via N Acq processing + + else { + + for ( Vi=0; Vi < PrivListEvWithHitAllPlanesIndex; Vi++ ) { + + if ( EvNo == VPtRec->FrStatus.FrameNoInAcq ) { + err_error (( ERR_OUT, "TRACE : EltNo %4d - EvNo %4d - FrNoInAcq %4d => Hit on all planes", Vi, VPtRec->FrStatus.FrameNoInRun, VPtRec->FrStatus.FrameNoInAcq )); + VFound = 1; + break; + } + ++VPtRec; + } + + } + + + return (VFound); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 01/08/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__TCTelMon::PubFIsEvLastOfListEvWithHitOnAllPlanes ( SInt32 EvNo ) { + + SInt32 Vi; + ULT1__TCTelMon_TEltListEvWithHitAllPlanes* VPtRec; + + + VPtRec = PrivAListEvWithHitAllPlanes; + + if ( EvNo == VPtRec[PrivListEvWithHitAllPlanesIndex - 1].FrStatus.FrameNoInRun ) { + return (1); + } + + return (0); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt8* ULT1__TCTelMon::PubFGetPtDispFullMatrix () { + return ( &ProPar.DispFullMatrix ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +ULT1__TMatDiscriColor* ULT1__TCTelMon::PubFGetPtFullMatCol () { + return ( &PrivMatDispColor ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 24/07/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +ULT1__TMatDiscriColorHalfScale* ULT1__TCTelMon::PubFGetPtHalfMatCol () { + return ( &PrivMatDispColorHalfScale ); +} + +#endif + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/ult1.def b/include/pxi_daq_lib_v.2.1/ult1.def new file mode 100755 index 0000000..f6d4cfb --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1.def @@ -0,0 +1,221 @@ +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_DEF +#define ULT1_DEF + + +#ifdef ULT1__APP_DLL_TEST_MI26 + #include "ult1_test_mi26.def" +#else + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define ULT1__REG_DISCRI_BIT_SZ 960 // Mi26 = 1152 +#define ULT1__REG_DISCRI_W32_SZ 30 // Mi26 = 36 + + +#ifdef ULT1__APP_DLL_TEST_WITH_PATTERN_GENERATOR + + // Size in CLK unit of the frame which contains the readout of ONE line + + #define ULT1__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 1858 // Single line = nop scanning mode + #define ULT1__DISCRI_RO_SCAN_FRAME_CLK_NB 1858 // Scanning mode + +#else + + // Size in CLK unit of the frame which contains the readout of ONE line + + #define ULT1__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 1856 // Single line = nop scanning mode + #define ULT1__DISCRI_RO_SCAN_FRAME_CLK_NB 1858 // Scanning mode + +#endif + + + + +// This register is not implemented on Ultimate +// +// #define ULT1__REG_AFTER_ZS_BIT_SZ 160 +// #define ULT1__REG_AFTER_ZS_W32_SZ 5 + +#define ULT1__REG_AFTER_MUX_BIT_SZ 160 // Mi26 = 160 +#define ULT1__REG_AFTER_MUX_W32_SZ 5 // Mi26 = 5 + +#define ULT1__MAT_DISCRI_COL_NB 960 // 23/01/2013 +#define ULT1__MAT_DISCRI_LINES_NB 930 +#define ULT1__MAT_DISCRI_USEFUL_LINES_NB 928 // 23/01/2013 - Without the two markers lines + +#define ULT1__ZS_FFRAME_RAW_MAX_W16 3700 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define ULT1__ZS_FFRAME_RAW_MAX_W32 1850 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 +#define ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 1856 // Total frame size ( sum of 2 links ) in W32 - Mi26 = 576 + +// 11/09/2014 GC - Removed because defined in ult1_usr.def +// +// #define ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +// #define ULT1__ZS_FFRAME_MAX_STATES_REC 928 // Mi26 = 576 - one per line + + +#define ULT1__ZS_FFRAME_MODE0_1X80MHZ 0 +#define ULT1__ZS_FFRAME_MODE1_2X80MHZ 1 +#define ULT1__ZS_FFRAME_MODE2_1X160MHZ 2 +#define ULT1__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 14848 // 928 W16 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 14848 // 928 W16 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 29696 // 1856 W16 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 29696 // 1856 W16 + +// $ #define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 928 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 928 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 1856 // Mi26 = 576 +// #define ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 1856 // Mi26 = 576 => Moved in ult1_usr.def + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 464 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 464 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 928 // Mi26 = 144 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 928 // Mi26 = 288 + + +// Id to select ULT1 register + +#define ULT1__REG_DISCRI 0 +// #define ULT1__REG_AFTER_ZS 1 -> Not implemented on Ultimate +#define ULT1__REG_AFTER_MUX 1 +#define ULT1__REG_DISCRI_SCAN 2 + +#define ULT1__REG_DISCRI_SCAN__SRC_CLK_160MHZ 3 // 23/06/2010 + +// ====================================== +// For ULT1 discri analysis tools +// ====================================== + +// Submatrices number + +#define ULT1__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define ULT1__REG_BIAS_NB 19 + +// $ #define ULT1__REG_BIAS_ICLPDISC 0 +// $ #define ULT1__REG_BIAS_IPWRSW 1 +// $ #define ULT1__REG_BIAS_IBUF 2 +// $ #define ULT1__REG_BIAS_ID1PWRS 3 +// $ #define ULT1__REG_BIAS_ID2PWRS 4 +// $ #define ULT1__REG_BIAS_ILVDSTX 5 +// $ #define ULT1__REG_BIAS_ILVDSRX 6 +// $ #define ULT1__REG_BIAS_IVTST1 7 +// $ #define ULT1__REG_BIAS_IVTST2 8 +// $ #define ULT1__REG_BIAS_IANABUF 9 +// $ #define ULT1__REG_BIAS_IVDREF1D 10 +// $ #define ULT1__REG_BIAS_IVDREF1C 11 +// $ #define ULT1__REG_BIAS_IVDREF1B 12 +// $ #define ULT1__REG_BIAS_IVDREF1A 13 +// $ #define ULT1__REG_BIAS_IVDREF2 14 +// $ #define ULT1__REG_BIAS_IDIS1 15 +// $ #define ULT1__REG_BIAS_IDIS2 16 +// $ #define ULT1__REG_BIAS_IPXI 17 +// $ #define ULT1__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define ULT1__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define ULT1__DIS_MEAS_STEP_PAR_FIRST 0 +#define ULT1__DIS_MEAS_STEP_PAR_LAST (ULT1__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define ULT1__DIS_TEST_MAX_STEP_NB 50 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define ULT1__NB_MAX_ULT1_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define ULT1__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define ULT1__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define ULT1__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// ULT1__TCTelMon +// -------------------- + +#define ULT1__COLOR_BROWN 0x000066CC +#define ULT1__COLOR_ORANGE 0x0000A5FF +#define ULT1__COLOR_YELLOW 0x0000FFFF +#define ULT1__COLOR_GREEN 0x0000FF00 +#define ULT1__COLOR_BLUE 0x00FF0000 +#define ULT1__COLOR_VIOLET 0x00990066 + +#define ULT1__TCTelMon__COL_PLANE_0 (TColor) ULT1__COLOR_ORANGE +#define ULT1__TCTelMon__COL_PLANE_1 (TColor) ULT1__COLOR_BLUE +#define ULT1__TCTelMon__COL_PLANE_2 (TColor) ULT1__COLOR_BROWN +#define ULT1__TCTelMon__COL_PLANE_3 (TColor) ULT1__COLOR_YELLOW +#define ULT1__TCTelMon__COL_PLANE_4 (TColor) ULT1__COLOR_GREEN +#define ULT1__TCTelMon__COL_PLANE_5 (TColor) ULT1__COLOR_VIOLET + + +#define ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define ULT1__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.2.1/ult1.h b/include/pxi_daq_lib_v.2.1/ult1.h new file mode 100755 index 0000000..0d331b3 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1.h @@ -0,0 +1,53 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1.h +Goal : Functions prototypes of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* ULT1_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + + + +// $ FHEAD ( SInt32 ULT1_FBegin ( SInt8 FileErrLogLvl, char* FileErrFile );) +// $ FHEAD ( SInt32 ULT1_FEnd ();) + +FHEAD ( SInt32 ULT1__FRegDiscriConvW32ToBit ( UInt32* PtSrc, UInt8* PtDest);) +FHEAD ( SInt32 ULT1__FRegDiscriConvBitToW32 ( UInt8* PtSrc, UInt32* PtDest );) +FHEAD ( SInt32 ULT1__FDiscriMatConvW32ToBit ( ULT1__TMatDiscriW32* PtSrc, ULT1__TMatDiscriBit* PtDest );) +FHEAD ( SInt32 ULT1__FDiscriMatConvBitToW32 ( ULT1__TMatDiscriBit* PtSrc, ULT1__TMatDiscriW32* PtDest );) + +FHEAD ( SInt32 ULT1__FDiscriMatPrintHit ( ULT1__TMatDiscriBit* PtMat, UInt32 Line, UInt32 FirstCol, UInt32 LastCol );) +FHEAD ( SInt32 ULT1__FDiscriEmulHit ( ULT1__TMatDiscriBit* PtMat, UInt16 Hit0Line, UInt16 Hit0Col, UInt16 Hit1Line, UInt16 Hit1Col, UInt16 Hit2Line, UInt16 Hit2Col );) + +FHEAD ( SInt32 ULT1__FMatDiscriPrintHit ( char* CmtStrTitle, SInt8 CmtSInt8MapsId, ULT1__TMatDiscriBit* PtDest );) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef ULT1_H + #define ULT1_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/ult1.typ b/include/pxi_daq_lib_v.2.1/ult1.typ new file mode 100755 index 0000000..9016166 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1.typ @@ -0,0 +1,1223 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_TYP +#define ULT1_TYP + +#ifdef ROOT_ROOT + typedef UInt32 ULT1__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor ULT1__TColor; +#endif + + + + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +// $ typedef struct { +// $ +// $ SInt8 FileErrLogLvl; +// $ char FileErrFile[GLB_FILE_PATH_SZ]; +// $ +// $} ULT1__TContext; + +/* ============================================================================ */ +/* Discri register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[ULT1__REG_DISCRI_W32_SZ]; + SInt8 ADataBit[ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TRegDiscri; + +/* ============================================================================ */ +/* Discri register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[ULT1__REG_DISCRI_W32_SZ]; + +} ULT1__TRegDiscriW32; + + +/* ============================================================================ */ +/* Discri register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TRegDiscriBit; + + +/* ============================================================================ */ +/* Discri matrix dual view : W32 or Bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + ULT1__TRegDiscri ALine[ULT1__MAT_DISCRI_LINES_NB]; + +} ULT1__TMatDiscri; + +/* ============================================================================ */ +/* Discri matrix view as W32 array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AALineW32[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_W32_SZ]; + +} ULT1__TMatDiscriW32; + +/* ============================================================================ */ +/* Discri matrix view as bit array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriBit; + + +typedef struct { + + float AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriBitf; + + +/* ============================================================================ */ +/* Discri matrix view as bit array - BUT scale 1/4 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 23/07/2009 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[ULT1__MAT_DISCRI_LINES_NB / 2][ULT1__REG_DISCRI_BIT_SZ / 2]; + +} ULT1__TMatDiscriBitHalfScale; + + + +/* ============================================================================ */ +/* After Zero Sup register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + UInt32 ADataW32[ULT1__REG_AFTER_ZS_W32_SZ]; + SInt8 ADataBit[ULT1__REG_AFTER_ZS_BIT_SZ]; + +} ULT1__TRegAfterZs; +*/ + +/* ============================================================================ */ +/* After Zero Sup register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + UInt32 AW32[ULT1__REG_AFTER_ZS_W32_SZ]; + +} ULT1__TRegAfterZsW32; +*/ + +/* ============================================================================ */ +/* After Zero Sup register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + SInt8 ABit[ULT1__REG_AFTER_ZS_BIT_SZ]; + +} ULT1__TRegAfterZsBit; +*/ + +/* ============================================================================ */ +/* After Mux register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[ULT1__REG_AFTER_MUX_W32_SZ]; + SInt8 ADataBit[ULT1__REG_AFTER_MUX_BIT_SZ]; + +} ULT1__TRegAfterMux; + +/* ============================================================================ */ +/* After Mux register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[ULT1__REG_AFTER_MUX_W32_SZ]; + +} ULT1__TRegAfterMuxW32; + + +/* ============================================================================ */ +/* After Mux register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[ULT1__REG_AFTER_MUX_BIT_SZ]; + +} ULT1__TRegAfterMuxBit; + + + +/* ======================================================= */ +/* Frame provided by ULT1 DAQ, it's independent of output */ +/* mode BUT data are not organized as in ULT1__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by ULT1__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + + typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + + + UInt16 ADataW16[ULT1__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + + } xxx__TZsFFrameRaw; + + + + + + //typedef struct { + // + // ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + // UInt32 Header; // Header of Mimosa 26 frame + // UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + // UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + // UInt32 Trailer; // Trailer of Mimosa 26 frame + + // UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + // UInt16 ADataW16[ULT1__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + //} ULT1__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + + //typedef union { + + // UInt16 W16; + + // struct { + + // UInt16 StateNb : 4; + // UInt16 LineAddr : 11; + // UInt16 Ovf : 1; + + // } F; + + //} ULT1__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +// typedef union { + +// UInt16 W16; + +// struct { + +// UInt16 HitNb : 2; +// UInt16 ColAddr : 11; +// UInt16 NotUsed : 3; + +// } F; + +// } ULT1__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max ULT1__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +// typedef struct { + +// ULT1__TStatesLine StatesLine; +// ULT1__TState AStates[ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +// } ULT1__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by ULT1, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max ULT1__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +//typedef struct { + +//ASIC__TFrameStatus SStatus; + +//UInt32 Header; +//UInt32 FrameCnt; +//UInt32 DataLength; +// SInt16 TrigSignalLine; +//SInt8 TrigSignalClk; +// SInt16 TrigLine; + +// UInt32 StatesRecNb; // It's NOT a ULT1 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + +// ULT1__TZsFStatesRec AStatesRec[ULT1__ZS_FFRAME_MAX_STATES_REC]; + +// UInt32 Trailer; +// UInt32 Zero; +// UInt32 Zero2; + +// } ULT1__TZsFFrame; // F in FFrame means Fixed size frame + + + + +#ifndef APP__RMV_ULT1__TCDiscriFile +#ifndef APP__RMV_CLASSES + +// 31/01/2009 + +class ULT1__TCDiscriFile : public FIL__TCBinFile { + + + private : + + protected : + + + public : + + ULT1__TCDiscriFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~ULT1__TCDiscriFile (); + + SInt32 PubFConf ( char* DataFile, SInt8 WriteRead, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetEvNb (); + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + SInt32 PubFWriteEv ( ULT1__TMatDiscriW32* PtSrcMat ); + SInt32 PubFReadNextEv ( ULT1__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + ULT1__TMatDiscriW32* PubFReadNextEv (); + SInt32 PubFGotoEv ( SInt32 EvNo ); + SInt32 PubFReadEv ( SInt32 EvNo, ULT1__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + ULT1__TMatDiscriW32* PubFReadEv ( SInt32 EvNo ); + + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + +#endif +#endif + +/* ==================================================== */ +/* Discriminators test information file record */ +/* */ +/* - Test no */ +/* - Chip no / comment */ +/* - Number of steps */ +/* - Events nb / step */ +/* - Run no associated to each step */ +/* - Bias used for each step */ +/* - User defined parameters for each step */ +/* The can be used to convert udac / mv etc ... */ +/* */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.cnf contains the structure */ +/* ULT1__TDisTestCnfFile */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + +// A copy of bias used for the current run +// 10/02/2009 + +typedef struct { + + UInt8 ABias[ULT1__REG_BIAS_NB]; + +} ULT1__TBiasCnf; + + +// All information about current discri measurement step +// 10/02/2009 + +typedef struct { + + SInt32 RunNo; + ULT1__TBiasCnf Bias; + float APar[ULT1__DIS_MEAS_STEP_MAX_PAR_NB]; + +} ULT1__TDisMeasStep; + + +// Format of file discri_test_NNNN.cnf +// 10/02/2009 + +/*typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to ULT1__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + +} ULT1__TDisMeasHeader; + +typedef struct { + ULT1__TDisMeasHeader Head; + ULT1__TDisMeasStep AStep[ULT1__DIS_TEST_MAX_STEP_NB]; +}ULT1__TDisTestCnfFile;*/ + + +typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to ULT1__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + + ULT1__TDisMeasStep AStep[ULT1__DIS_TEST_MAX_STEP_NB]; + + +} ULT1__TDisTestCnfFile; + + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in sub matrices view mode => sub A, B, C, D */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 3D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED per submatrix. */ +/* => Header.SubMatView = 1 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* ULT1__TDisHitCntAllSubMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of ULT1__TDisHitCntAllSubMatStepData */ +/* - init a ULT1__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + SInt32 TestNo; + SInt8 SubMatView; // 0 => whole matrix as single data piece + // 1 => submatrices A, B, C, D + SInt32 StepNb; + char CnfFileName[GLB_FILE_PATH_SZ]; + + +} ULT1__TDisHitCntHeader; + + +typedef struct { + + float AAASubMat[ULT1__SUB_MAT_NB][ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ / 4]; + +} ULT1__TDisHitCntAllSubMatStepData; + +typedef struct { + + float AAAASubMat [ULT1__DIS_TEST_MAX_STEP_NB][ULT1__SUB_MAT_NB][ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ / 4]; + +} ULT1__TDisHitCntAllSubMatStepDataMG; + +typedef struct { + + ULT1__TDisHitCntHeader Header; + ULT1__TDisHitCntAllSubMatStepData FirstStepData; + +} ULT1__TDisHitCntAllSubMatFile; + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in whole matrix view mode */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 2D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED as ONE matrix. */ +/* => Header.SubMatView = 0 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* ULT1__TDisHitCntMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of ULT1__TDisHitCntMatStepData */ +/* - init a ULT1__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + float AAMat[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TDisHitCntMatStepData; + + +typedef struct { + + ULT1__TDisHitCntHeader Header; + ULT1__TDisHitCntMatStepData FirstStepData; + +} ULT1__TDisHitCntMatFile; + + + +typedef struct { + + SInt8 AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ / 4]; + +} ULT1__TQuaterMatDiscriBit; + +typedef struct { + + ULT1__TColor AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriColor; + + +typedef struct { + + ULT1__TColor AALineCol[ULT1__MAT_DISCRI_LINES_NB / 2][ULT1__REG_DISCRI_BIT_SZ / 2]; + +} ULT1__TMatDiscriColorHalfScale; + + +typedef struct { + + ULT1__TColor AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ / 4]; + +} ULT1__TQuaterMatDiscriColor; + + +// To store "1" count on each discri for N events + +typedef struct { + + SInt32 ABit[ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TRegDiscriCumul; + + +// To store % of "1" on each discri for N events + +typedef struct { + + float ABit[ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TRegDiscriPerCent; + +// To store "1" count on whole matrix for N events + +typedef struct { + + UInt16 AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriCumul; + + +typedef struct { + + UInt16 AALineCol[ULT1__MAT_DISCRI_LINES_NB / 2][ULT1__REG_DISCRI_BIT_SZ / 2]; + +} ULT1__TMatDiscriCumulHalfScale; + + +// To store % of "1" on whole matrix for N events + +typedef struct { + + float AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriPerCent; + + +typedef struct { + + float AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TQuaterMatDiscriPerCent; + + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + + +// DPXI__ULT1_NB_MAX_ULT1_PER_DAQ + +typedef ULT1__TZsFFrame ULT1__TAZsFFrame[ULT1__NB_MAX_ULT1_PER_DAQ]; + + + +typedef struct { + + // Date & Time + + UInt32 StartDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StartTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Asic conf + + UInt8 AsicName; // Value of enumerated ASIC__TEAsicName defined in asic.def + SInt8 AsicNb; // Number of Asic read by DAQ + + // Trigger mode + + SInt8 SwTrigEnabled; // Enable automatic start of acquisition on first trigger of a spill + // - 0 => Board starts upon acquisition request command, don't care about trigger + // - 1 => After acquisition request command, board wait on first trigger to start + // Trigger detection is done by sw, therefore it has a latency of N x 15 ms + + SInt8 HwTrigModeSavedData; // Trigger mode + // - 0 => Run contains all frames : with OR without trigger + // - 1 => Run contains ONLY frames with a trigger + // - More trigger modes may be defined later + + SInt32 HwTrigPar[ULT1__TZSRunCnf__HW_TRIG_PAR_NB]; // Parameter about trigger handling -> enumerated DPXI__TEHwTrigPar in daq_pix.def + // - DPXI__HW_TRIG_PAR__OFFSET -> Offset which must be added to trigger position to get real position + // - DPXI__HW_TRIG_PAR__WINDOW -> Number of frame acquired after trigger + // - DPXI__HW_TRIG_PAR_NB -> Max parameters number + + + // Run parameters + + SInt32 RunNo; // Run number + SInt8 RunSave; // Save (1) or Not (0) data + SInt8 RunSaveMode; // Save mode -> Reserved for future use + SInt32 RunEvNb; // Event number in run + SInt32 RunFileEvNb; // Event number per file + +} ULT1__TZSRunCnf; + + +typedef struct { + + // Date & Time + + UInt32 StopDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StopTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Status + + SInt32 EvNbTaken; // Real number of events taken must be <= ULT1__TZSRunCnf.RunEvNb + SInt32 RejAcqNb; // Number of acquistion rejected in case of Mimosa 26 data error ( bad header, trailer etc ... ) + + SInt32 ARejAcqList[ULT1__TZSRunRes__MAX_ACQ_REJ_NB]; // List of rejected acquisition + +} ULT1__TZSRunRes; + + +// 09/07/2009 + +#ifndef APP__RMV_CLASSES + +class ULT1__TCZsRunRW { + + private: + + SInt32 PrivFInitForNewRunLoading (); + + // Object + + FIL__TCBinFile* ProPtBinFile; + + protected: + + // Parameters + + char ProParRunDir[GLB_FILE_PATH_SZ]; + SInt32 ProParRunNo; + SInt32 ProParCurULT1No; + SInt32 ProParCurEvNo; + + SInt8 ProParMeasTime; + SInt8 ProParPrintMsg; + SInt8 ProParPrintEvHeader; + + // Informations from run conf file OR calculated + + char ProRunCnfFile[GLB_FILE_PATH_SZ]; + char ProRunResFile[GLB_FILE_PATH_SZ]; + + ULT1__TZSRunCnf ProRecZSRunCnf; + ULT1__TZSRunRes ProRecZSRunRes; + + SInt32 ProInfRunULT1Nb; + SInt32 ProInfRunEvNb; + SInt32 ProInfRunFileSz; + SInt32 ProInfRunEvNbPerFile; + SInt32 ProInfRunBlocNbPerFile; + SInt32 ProInfZsFFrameRawSz; + + // Intermediate variables for processing + + SInt8 ProConfDone; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + + + SInt8 ProLastEvAccessDoneInOneULT1Mode; + SInt32 ProCurBlocNoInRun; + SInt32 ProCurFileNo; + SInt32 ProCurBlocNoInFile; + char ProCurFileName[GLB_FILE_PATH_SZ]; + + ULT1__TZsFFrameRaw* ProPtFFrameRaw; + + + public: + + ULT1__TCZsRunRW (); + ~ULT1__TCZsRunRW (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + SInt32 PubFSetMeasTime ( SInt8 Yes ); + SInt32 PubFSetPrintMsg ( SInt8 Print ); + SInt32 PubFSetPrintEvHeader ( SInt8 Print ); + + SInt32 PubFGetMeasTime (); + SInt32 PubFGetPrintMsg (); + SInt32 PubFGetPrintEvHeader (); + + SInt32 PubFGetULT1Nb (); + SInt32 PubFGetEvNb (); + SInt32 PubFGetEvNbPerFile (); + + SInt32 PubFLoadRun ( char* RunDir, UInt32 RunNo ); + + ULT1__TZsFFrameRaw* PubFGotoEvOneULT1 ( SInt8 ULT1No, SInt32 EvNo ); + ULT1__TZsFFrameRaw* PubFGotoEvAllULT1 ( SInt32 EvNo ); + + SInt32 PubFCloseRun (); + +}; + +#endif + +// 01/08/09 + +typedef struct { + + UInt32 IndexInEvWithHitList; + ASIC__TFrameStatus FrStatus; + +} ULT1__TCTelMon_TEltListEvWithHitAllPlanes; + + +// 02/08/09 + +typedef struct { + + SInt16 x; + SInt16 y; + +} ULT1__TCTelMon_THit; + +// 02/08/09 + +typedef struct { + + ULT1__TCTelMon_THit AAHits[MAPS__TCDigTelMon_MAX_PLANE_NB][MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE]; + SInt32 AHitsNbPerPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + SInt32 EvNoInRun; + +} ULT1__TCTelMon_TTrack; + +// 02/08/09 + +typedef struct { + + SInt8 Full; + SInt8 PlaneNb; + SInt32 EvNb; + ULT1__TCTelMon_TTrack ATracks[MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB]; + + +} ULT1__TCTelMon_TResRun; + + +// 17/07/09 + +#ifndef ROOT_ROOT + +#ifndef APP__RMV_CLASSES + +class ULT1__TCTelMon : public MAPS__TCDigTelMon { + + private: + + SInt8 PrivStopProc; + + // ------------------------------------------- + // Plot colors of planes for coincidence mode + // ------------------------------------------- + + ULT1__TColor PrivAPlanePlotColor[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // ------------------------------------------------------ + // Variables to store frames : pixel, cumul, plot color + // ------------------------------------------------------ + + ULT1__TZsFFrameRaw* PrivPtAcqData; // Copy of Acq data, enabled if MakeLocalCpy parameter of PubFAddEvents (...) is set + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, ULT1__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + SInt32 PrivAcqEvNb; // Event nb of current Acq = parameter EvNb of last PubFAddEvents (...) call + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, ULT1__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + + ULT1__TZsFFrame PrivZsFFrame; // Tmp var to store ZsFFrameRaw converted to ZsFFrame + // Used for each frame converted + + ULT1__TMatDiscriBit PrivMatDiscriCoin; // Result for planeS coin plot AS PIXELS full scale matrix + ULT1__TMatDiscriCumul PrivMatDiscriCoinCum; // Result for planeS coin cumul plot AS COUNT full scale matrix + + ULT1__TMatDiscriBitHalfScale PrivMatDiscriBitHalfScale; // Result for planeS coin plot AS PIXELS 1/2 scale matrix + ULT1__TMatDiscriCumulHalfScale PrivMatDiscriCumHalfScale; // Result for planeS coin cumul plot AS COUNT 1/2 scale matrix + + ULT1__TMatDiscriColor PrivMatDispColor; // Result in matrix color data for ALL KINDS of plots + ULT1__TMatDiscriColorHalfScale PrivMatDispColorHalfScale; // Result in 1/2 scale matrix color data for ALL KINDS of plots + + // ===================================================================== + // Lists to store informations results of events processing + // ===================================================================== + + // Flag to enable / disable list update + // It's useful to disable list update for data re-processing ( off-line ) with information of list + // because list informations should not been updates while using them for current data processing ... + // + // The following methods set this flag to one + // - PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ) + + SInt8 PriEnListEvWitHitUpdate; + SInt8 PriEnListEvWithTrigUpdate; + + // --------------------------- + // List of events with trigger + // --------------------------- + + SInt32 PrivListEvWithTrigIndex; // Current elt index + SInt8 PrivListEvWithTrigFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithTrig[ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB]; + + // --------------------------- + // List of events with hit(s) + // --------------------------- + + SInt32 PrivListEvWithHitIndex; // Current elt index + SInt8 PrivListEvWithHitFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithHit[ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB]; // List + + // ----------------------------------------- + // List of events with hit(s) on all planes + // ----------------------------------------- + + SInt32 PrivListEvWithHitAllPlanesIndex; // Currenr elt index + SInt8 PrivListEvWithHitAllPlanesFull; // Full flag + SInt8 PrivListEvWithHitAllPlanesCurProcMode; // Current processing mode + // Uses to know if data must be reprocessed in cas user + // has changed list mode via ProPar.ListHitAllPlanesMode + + // The list array ( dynamic allocation ) + + ULT1__TCTelMon_TEltListEvWithHitAllPlanes* PrivAListEvWithHitAllPlanes; + + // --------------------------------------------------------------------- + // Result run after data processing + // --------------------------------------------------------------------- + + ULT1__TCTelMon_TResRun* PrivPtResRun; + + // --------------------------------------------------------------------- + // General init function : reset all variables, called by constructor + // --------------------------------------------------------------------- + + SInt32 PrivFInit (); + + // --------------------------------------------------------------------- + // Processing function + // --------------------------------------------------------------------- + + SInt32 PrivFConvZsFFrameToMatDiscriBitAndCumul ( SInt32 DbgEvNo, SInt8 Mode, SInt8 PlaneNo, SInt8 PlaneSelForCoin, SInt8 EvNo, SInt8 EvSelForPlot, ULT1__TZsFFrame* PtSrc, ULT1__TMatDiscriBit* PtDestFrameBit, ULT1__TMatDiscriBit* PtDestCoinBit, ULT1__TMatDiscriCumul* PtDestFrameCum, ULT1__TMatDiscriCumul* PtDestCoinCum, SInt8 PrintLvl ); + + + // --------------------------------------------------------------------- + // Lists ( events with trigger / hit ) add events functions + // --------------------------------------------------------------------- + + SInt32 PrivFAddEvInListEvWithTrig ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt ); + SInt32 PrivFAddEvInListEvWithHit ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt, SInt8 HitOnAllPlanes, SInt8 SingleHitOnEachPlane ); + + protected: + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Process one frame = one event of plane specified by Id (0..5) + + SInt32 ProFProcessPlane ( SInt32 DbdEvNo, SInt8 Id, ULT1__TZsFFrameRaw* PtSrc ); + + + + public: + + // -------------------------------------------------------------------------- + // Flag to select one Acq off-line processing / full RUN off-line processing + // -------------------------------------------------------------------------- + // Will be done via a method later + // 06/08/2009 + // -------------------------------------------------------------------------- + + SInt8 PubAcqOffLineProcOrRunOffLineProc; + + // ------------------------------------------- + // Constructor & Destructor + // ------------------------------------------- + + ULT1__TCTelMon (); + ~ULT1__TCTelMon (); + + // ------------------------------------------------------------ + // Begin method => MUST be called before ANY other function ! + // ------------------------------------------------------------ + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 MaxBuffEvNb ); + + // ------------------------------------------- + // GUI handling methods + // ------------------------------------------- + + #ifndef ROOT_ROOT + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGetGuiPar (); + + #endif + + // ------------------------------------------- + // Run control methods + // ------------------------------------------- + // Allocate / free buffers + // ------------------------------------------- + + SInt32 PubFStartRun ( SInt8 MapsNb ); + SInt32 PubFStopRun (); + + // ------------------------------------------- + // Monitoring control methods + // ------------------------------------------- + + SInt32 PubFStartMon (); + SInt32 PubFStopMon (); + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Add events in on-line monitoring mode and call data processing methods ( protected ) + + SInt32 PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt32 EvNb, ULT1__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + // Off-line processing of data + // WARNING : NOW - 26/07/2009 - IT'S ONLY data of LAST acquisition ( data provided by last call to PubFAddEvents ) + // => Uses as events number the one of last acq + // => Force mode to "Process one Acq" AND update GUI parameters + + SInt32 PubFProcessOffLineCurAcq (); + SInt32 PubFProcessOffLineCurAcq2 (); + + // Select frame to plot + + SInt32 PubFGotoFirstFrame (); + SInt32 PubFGotoPrevFrame (); + SInt32 PubFGotoNextFrame (); + SInt32 PubFGotoLastFrame (); + + // ------------------------------------------- + // Results print methods + // ------------------------------------------- + + // Print list of events with a trigger detected => print SStatus record + + SInt32 PubPrintListEvWithTrig ( SInt8 Verbose ); + + // Print list of events with at least one hit in one plane => print SStatus record + + SInt32 PubPrintListEvWithHit ( SInt8 Verbose ); + + // Print list of events with hit on ALL planes => print SStatus record + + SInt32 PubPrintListEvWithHitOnAllPlanes ( SInt8 Verbose ); + + // Print res run + + SInt32 PubAllocResRun (); + SInt32 PubFreeResRun (); + SInt32 PubPrintResRun (); + SInt32 PubSaveResRun ( char* FileName ); + + + SInt32 PubFIsEvInListEvWithHitOnAllPlanes ( SInt32 EvNo ); + SInt32 PubFIsEvLastOfListEvWithHitOnAllPlanes ( SInt32 EvNo ); + + SInt32 PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ); + + + // ------------------------------------------- + // Results plot methods + // ------------------------------------------- + + // There is NO plot method in class. + // + // Because a call of a plot function ( from plot lib ) in DAQ supervisor thread doesn't work + // - nothing is displayed ! + // - this may crash the application + // I don't know why and have no time to study and understand this bug. I have found a workarround + // by calling the plot function in an application timer. + // + // The class request plot by setting the flag ProRequestPlot to 1 + // plot is done by "plot timer" callback in application which + // reset the flag ProRequestPlot after plot. + + // The application "plot timer" must know : + // - when he must plot --> Test variable pointed by PubFGetPtPlotRq () + // - the matrix to plot : full / half scale --> Test variable pointed by PubFGetPtDispFullMatrix () + // - the data to plot --> Read via pointer given by PubFGetPtFullMatCol () / PubFGetPtHalfMatCol () + // + // Polling of plot request and access to data is NOT DONE via method calls because + // - calling class methods in timer while other methods may be called in DAQ supervisor thread MAY cause problems => No detailed understanding, no time ... + // - it will save execution time by avoiding function call + + SInt8* PubFGetPtDispFullMatrix (); + ULT1__TMatDiscriColor* PubFGetPtFullMatCol (); + ULT1__TMatDiscriColorHalfScale* PubFGetPtHalfMatCol (); + + +}; + +#endif + + +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/ult1.var b/include/pxi_daq_lib_v.2.1/ult1.var new file mode 100755 index 0000000..09ddf06 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1.var @@ -0,0 +1,33 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1.var +Goal : Variables definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_VAR +#define ULT1_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +// $ EXTERN VAR_STATIC ULT1__TContext ULT1__VGContext; + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/ult1_test_mi26.def b/include/pxi_daq_lib_v.2.1/ult1_test_mi26.def new file mode 100755 index 0000000..1cd7556 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1_test_mi26.def @@ -0,0 +1,191 @@ +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_test_mi26.def +Goal : Macros definition of Ultimate 1 library => for lib test with Mi26. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 01/03/2011 +File date : 01/03/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_TEST_MI26_DEF +#define ULT1_TEST_MI26_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define ULT1__REG_DISCRI_BIT_SZ 1152 // Mi26 = 1152 +#define ULT1__REG_DISCRI_W32_SZ 36 // Mi26 = 36 + +// This register is not implemented on Ultimate +// +// #define ULT1__REG_AFTER_ZS_BIT_SZ 160 +// #define ULT1__REG_AFTER_ZS_W32_SZ 5 + +#define ULT1__REG_AFTER_MUX_BIT_SZ 160 // Mi26 = 160 +#define ULT1__REG_AFTER_MUX_W32_SZ 5 // Mi26 = 5 + +#define ULT1__MAT_DISCRI_LINES_NB 578 // 578 + +#define ULT1__ZS_FFRAME_RAW_MAX_W16 1140 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define ULT1__ZS_FFRAME_RAW_MAX_W32 570 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 +#define ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 // Total frame size ( sum of 2 links ) in W32 - Mi26 = 576 + +#define ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define ULT1__ZS_FFRAME_MAX_STATES_REC 576 // Mi26 = 576 - one per line + +#define ULT1__ZS_FFRAME_MODE0_1X80MHZ 0 +#define ULT1__ZS_FFRAME_MODE1_2X80MHZ 1 +#define ULT1__ZS_FFRAME_MODE2_1X160MHZ 2 +#define ULT1__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 0 // 0 => Not used for this test +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 0 // 0 => Not used for this test +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 0 // 0 => Not used for this test +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 9216 // = Mi26 2 x 80 MHz + +// $ #define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 288 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 576 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 576 // Mi26 = 576 + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 288 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 288 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 144 // Mi26 = 144 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 288 // Mi26 = 288 + + +// Id to select ULT1 register + +#define ULT1__REG_DISCRI 0 +// #define ULT1__REG_AFTER_ZS 1 -> Not implemented on Ultimate +#define ULT1__REG_AFTER_MUX 1 +#define ULT1__REG_DISCRI_SCAN 2 + +#define ULT1__REG_DISCRI_SCAN__SRC_CLK_160MHZ 3 // 23/06/2010 + +// ====================================== +// For ULT1 discri analysis tools +// ====================================== + +// Submatrices number + +#define ULT1__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define ULT1__REG_BIAS_NB 19 + +// $ #define ULT1__REG_BIAS_ICLPDISC 0 +// $ #define ULT1__REG_BIAS_IPWRSW 1 +// $ #define ULT1__REG_BIAS_IBUF 2 +// $ #define ULT1__REG_BIAS_ID1PWRS 3 +// $ #define ULT1__REG_BIAS_ID2PWRS 4 +// $ #define ULT1__REG_BIAS_ILVDSTX 5 +// $ #define ULT1__REG_BIAS_ILVDSRX 6 +// $ #define ULT1__REG_BIAS_IVTST1 7 +// $ #define ULT1__REG_BIAS_IVTST2 8 +// $ #define ULT1__REG_BIAS_IANABUF 9 +// $ #define ULT1__REG_BIAS_IVDREF1D 10 +// $ #define ULT1__REG_BIAS_IVDREF1C 11 +// $ #define ULT1__REG_BIAS_IVDREF1B 12 +// $ #define ULT1__REG_BIAS_IVDREF1A 13 +// $ #define ULT1__REG_BIAS_IVDREF2 14 +// $ #define ULT1__REG_BIAS_IDIS1 15 +// $ #define ULT1__REG_BIAS_IDIS2 16 +// $ #define ULT1__REG_BIAS_IPXI 17 +// $ #define ULT1__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define ULT1__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define ULT1__DIS_MEAS_STEP_PAR_FIRST 0 +#define ULT1__DIS_MEAS_STEP_PAR_LAST (ULT1__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define ULT1__DIS_TEST_MAX_STEP_NB 30 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define ULT1__NB_MAX_ULT1_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define ULT1__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define ULT1__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define ULT1__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// ULT1__TCTelMon +// -------------------- + +#define ULT1__COLOR_BROWN 0x000066CC +#define ULT1__COLOR_ORANGE 0x0000A5FF +#define ULT1__COLOR_YELLOW 0x0000FFFF +#define ULT1__COLOR_GREEN 0x0000FF00 +#define ULT1__COLOR_BLUE 0x00FF0000 +#define ULT1__COLOR_VIOLET 0x00990066 + +#define ULT1__TCTelMon__COL_PLANE_0 (TColor) ULT1__COLOR_ORANGE +#define ULT1__TCTelMon__COL_PLANE_1 (TColor) ULT1__COLOR_BLUE +#define ULT1__TCTelMon__COL_PLANE_2 (TColor) ULT1__COLOR_BROWN +#define ULT1__TCTelMon__COL_PLANE_3 (TColor) ULT1__COLOR_YELLOW +#define ULT1__TCTelMon__COL_PLANE_4 (TColor) ULT1__COLOR_GREEN +#define ULT1__TCTelMon__COL_PLANE_5 (TColor) ULT1__COLOR_VIOLET + + +#define ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define ULT1__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/ult1_usr.c b/include/pxi_daq_lib_v.2.1/ult1_usr.c new file mode 100755 index 0000000..94b08c0 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1_usr.c @@ -0,0 +1,115 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.c +Goal : Functions of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_C +#define ULT1_USR_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FBegin ( SInt8 FileErrLogLvl, char* FileErrFile ) { + + ULT1__VGContext.FileErrLogLvl = FileErrLogLvl; + strcpy ( ULT1__VGContext.FileErrFile, FileErrFile ); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 24/11/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 ULT1__FEnd () { + + + err_retok (( ERR_OUT, "" )); +} + + + + +#endif + + diff --git a/include/pxi_daq_lib_v.2.1/ult1_usr.def b/include/pxi_daq_lib_v.2.1/ult1_usr.def new file mode 100755 index 0000000..20ecdd7 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1_usr.def @@ -0,0 +1,86 @@ +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_DEF +#define ULT1_USR_DEF + +#ifdef ULT1__APP_DLL_TEST_MI26 + #include "ult1_usr_test_mi26.def" +#else + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 1856 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 3712 // + + +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 1850 // Add on 11/05/2011 - value per link +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 3700 // Add on 11/05/2011 - value per link + +#define ULT1__ZS_FFRAME_RAW_MAX_W8 7400 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 +#define ULT1__ZS_FFRAME_RAW_MAX_W16 3700 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define ULT1__ZS_FFRAME_RAW_MAX_W32 1850 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 + +#define ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 1856 // Mi26 = 576 + + +#define ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define ULT1__ZS_FFRAME_MAX_STATES_REC 828 // Mi26 = 576 - one per line + +// ====================================== +// For ULT1 discri analysis tools +// ====================================== + +// Submatrices number + +#define ULT1__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define ULT1__REG_BIAS_NB 19 + +#define ULT1__REG_BIAS_ICLPDISC 0 +#define ULT1__REG_BIAS_IPWRSW 1 +#define ULT1__REG_BIAS_IBUF 2 +#define ULT1__REG_BIAS_ID1PWRS 3 +#define ULT1__REG_BIAS_ID2PWRS 4 +#define ULT1__REG_BIAS_ILVDSTX 5 +#define ULT1__REG_BIAS_ILVDSRX 6 +#define ULT1__REG_BIAS_IVTST1 7 +#define ULT1__REG_BIAS_IVTST2 8 +#define ULT1__REG_BIAS_IANABUF 9 +#define ULT1__REG_BIAS_IVDREF1D 10 +#define ULT1__REG_BIAS_IVDREF1C 11 +#define ULT1__REG_BIAS_IVDREF1B 12 +#define ULT1__REG_BIAS_IVDREF1A 13 +#define ULT1__REG_BIAS_IVDREF2 14 +#define ULT1__REG_BIAS_IDIS1 15 +#define ULT1__REG_BIAS_IDIS2 16 +#define ULT1__REG_BIAS_IPXI 17 +#define ULT1__REG_BIAS_VPIXCLP 18 + + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.2.1/ult1_usr.h b/include/pxi_daq_lib_v.2.1/ult1_usr.h new file mode 100755 index 0000000..ba81b65 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1_usr.h @@ -0,0 +1,41 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.h +Goal : Functions prototypes of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_H + +#include "func_header.def" + + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, char* ULT1_FGetVersion ();) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, ;) +// FHEAD ( SInt32 REF_FHello ();) + +FHEAD ( SInt32 ULT1_FBegin ( SInt8 FileErrLogLvl, char* FileErrFile );) +FHEAD ( SInt32 ULT1_FEnd ();) + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef ULT1_USR_H + #define ULT1_USR_H + #endif +#endif + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/ult1_usr.typ b/include/pxi_daq_lib_v.2.1/ult1_usr.typ new file mode 100755 index 0000000..04f1914 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1_usr.typ @@ -0,0 +1,193 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_TYP +#define ULT1_USR_TYP + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} ULT1__TContext; + + +/* ======================================================= */ +/* Frame provided by ULT1 DAQ, it's independent of output */ +/* mode BUT data are not organized as in ULT1__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by ULT1__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + UInt32 Header; // Header of Mimosa 26 frame + UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 Trailer; // Trailer of Mimosa 26 frame + + UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + UInt16 ADataW16[ULT1__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} ULT1__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} ULT1__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} ULT1__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max ULT1__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + ULT1__TStatesLine StatesLine; + ULT1__TState AStates[ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} ULT1__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by ULT1, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max ULT1__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a ULT1 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + ULT1__TZsFStatesRec AStatesRec[ULT1__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} ULT1__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/ult1_usr.var b/include/pxi_daq_lib_v.2.1/ult1_usr.var new file mode 100755 index 0000000..42b7cdb --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1_usr.var @@ -0,0 +1,33 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.var +Goal : Variables definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_VAR +#define ULT1_USR_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC ULT1__TContext ULT1__VGContext; + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/ult1_usr_test_mi26.def b/include/pxi_daq_lib_v.2.1/ult1_usr_test_mi26.def new file mode 100755 index 0000000..310b227 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/ult1_usr_test_mi26.def @@ -0,0 +1,76 @@ +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.def +Goal : Macros definition of Ultimate 1 library => for lib test with Mi26. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 01/03/2011 +File date : 01/03/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_TEST_MI26_DEF +#define ULT1_USR_TEST_MI26_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W8_SZ 1152 // Mi26 = 1152 + +#define ULT1__ZS_FFRAME_RAW_MAX_W8 2280 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 +#define ULT1__ZS_FFRAME_RAW_MAX_W16 1140 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define ULT1__ZS_FFRAME_RAW_MAX_W32 570 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 + +#define ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 // Mi26 = 576 + + +#define ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define ULT1__ZS_FFRAME_MAX_STATES_REC 576 // Mi26 = 576 - one per line + +// ====================================== +// For ULT1 discri analysis tools +// ====================================== + +// Submatrices number + +#define ULT1__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define ULT1__REG_BIAS_NB 19 + +#define ULT1__REG_BIAS_ICLPDISC 0 +#define ULT1__REG_BIAS_IPWRSW 1 +#define ULT1__REG_BIAS_IBUF 2 +#define ULT1__REG_BIAS_ID1PWRS 3 +#define ULT1__REG_BIAS_ID2PWRS 4 +#define ULT1__REG_BIAS_ILVDSTX 5 +#define ULT1__REG_BIAS_ILVDSRX 6 +#define ULT1__REG_BIAS_IVTST1 7 +#define ULT1__REG_BIAS_IVTST2 8 +#define ULT1__REG_BIAS_IANABUF 9 +#define ULT1__REG_BIAS_IVDREF1D 10 +#define ULT1__REG_BIAS_IVDREF1C 11 +#define ULT1__REG_BIAS_IVDREF1B 12 +#define ULT1__REG_BIAS_IVDREF1A 13 +#define ULT1__REG_BIAS_IVDREF2 14 +#define ULT1__REG_BIAS_IDIS1 15 +#define ULT1__REG_BIAS_IDIS2 16 +#define ULT1__REG_BIAS_IPXI 17 +#define ULT1__REG_BIAS_VPIXCLP 18 + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/vme_stat.h b/include/pxi_daq_lib_v.2.1/vme_stat.h new file mode 100755 index 0000000..c6d9179 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/vme_stat.h @@ -0,0 +1,19 @@ + +/****************************************************************/ +/* */ +/* vme_stat.h defines constants for the static vme windows */ +/* defined in /sys/devices/vme_cesinfo.c. */ +/* */ +/* 07.Feb.96 MAJO created */ +/* 22 Nov 96 JDB A32 size 0x0e000000, not 0x0d000000 */ +/* */ +/****************************************************************/ + +#define VMEA32_BASE 0xd0000000 +#define VMEA24_BASE 0xde000000 +#define VMEA16_BASE 0xdffe0000 + +#define VMEA32_SIZE 0x0e000000 +#define VMEA24_SIZE 0x01000000 +#define VMEA16_SIZE 0x00010000 + diff --git a/include/pxi_daq_lib_v.2.1/win_files.c b/include/pxi_daq_lib_v.2.1/win_files.c new file mode 100755 index 0000000..3adcb84 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/win_files.c @@ -0,0 +1,3387 @@ + +#ifndef FIL_C +#define FIL_C + +/******************************************************************************* +Prototype : SInt32 FIL_FFileExists ( char* FilePath ) +Goal : Test if the file exists. +Inputs : The file name ( full path if needed ). +Ouputs : 1 if the file exists, else 0. +Globals : +Remark : The result is not guaranted in case of multi application lock to file. +Level : This is a user level function. +Date : 17/04/2003 +Doc date : 17/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FFileExists ( char* FilePath ) { + + SInt32 VRet; + FILE* VPf; + + VPf = fopen ( FilePath, "r" ); + + if ( VPf == NULL ) { + VRet = 0; + } + + else { + fclose ( VPf ); + VRet = 1; + } + + + return (VRet); +} + +/* 13/10/2004 */ + +SInt32 FIL_FFileSize ( char* FilePath ) { + + FILE* VPf; + SInt32 VFileSz; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fopen fail !" ) )); + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fclose (VPf) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fclose fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "%d Bytes", VFileSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FCpyFile ( char* Src, char* Dest ) + : +Goal : Copy SrcFile to DestFile. + : +Inputs : Src - Source file + : Dest - Destination file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - fonction moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FCpyFile ( char* Src, char* Dest ) { + + FILE* VPfSrc; + FILE* VPfDest; + SInt8 VBuffer[512]; // Debug 02/06/2007 move storage class static to auto + SInt32 VReadBytesCnt; + SInt32 VTotBytesCnt; + SInt32 VRet; + + VPfSrc = fopen ( Src, "rb" ); + + err_retnull ( VPfSrc, (ERR_OUT,"Source file %d open failed", Src ) ); + + VPfDest = fopen ( Dest, "wb" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", VPfDest ) ); + + VTotBytesCnt = 0; + + while ( ( VReadBytesCnt = fread ( VBuffer, 1 /* byte size */ , 512 /* bytes number */, VPfSrc ) ) > 0 ) { + fwrite ( VBuffer, 1 /* byte size */, VReadBytesCnt, VPfDest ); + VTotBytesCnt += VReadBytesCnt; + } + + fclose (VPfSrc); + fclose (VPfDest); + + err_retok (( ERR_OUT, "file %s copied in %s => %d bytes", Src, Dest, VTotBytesCnt )); +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FRemoveFile ( char* FilePath ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FRemoveFile ( char* FilePath ) { + + SInt32 VRet; + char* VStrError; + + VRet = remove ( FilePath ); + + err_retfail ( VRet, (ERR_OUT,"Remove file=%s failed => %s", FilePath, _strerror ("")) ); + err_retok (( ERR_OUT, "")); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) + : +Goal : List the directory SrcDir and write the result in DestDirFile. + : +Inputs : SrcDir - The directory to list + : DestDirFile - The result file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - Function moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + + VPf = fopen ( DestDirFile, "wt" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT, "Dir file %s creation failed ", DestDirFile ) ); + } + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + ++VItemCnt; + fprintf( VPf, "%s\n", VFileInfo.ff_name); + VRet = findnext(&VFileInfo); + } + + fclose ( VPf ); + + return (0); +} + + +#endif + + +SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosDirOutFile ( SrcDir, DestDirFile ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FDosDelDir ( char* SrcDir ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : Compiled only if CC_APP_WINDOWS is defined +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + +#ifdef CC_APP_WINDOWS + + +SInt32 FIL_FDosRmDirFiles ( char* SrcDir ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + char VFileToDelete[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + SInt32 VRetRemove; + SInt32 VFuncRet; + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VFuncRet = 0; + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + sprintf ( VFileToDelete, "%s\\%s", SrcDir, VFileInfo.ff_name ); + VRetRemove = FIL_FRemoveFile ( VFileToDelete ); + + if ( VRetRemove < 0 ) { + VFuncRet = -1; + err_error (( ERR_OUT, "Remove file=%s failed => %s", VFileToDelete, _strerror ("") )); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + + return (VFuncRet); +} + +#endif + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDirFiles ( char* SrcDir ) +Goal : Remove all the files in directory SrcDir but let the direcory +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDirFiles ( char* SrcDir ) { + +#ifdef CC_APP_WINDOWS + return ( FIL_FDosRmDirFiles (SrcDir) ); + +#else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available !", SrcDir) ); +#endif + + +} + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDir ( char* SrcDir ) +Goal : Remove the directory SrcDir if empty +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDir ( char* SrcDir ) { + + SInt32 VRet; + +#ifdef CC_APP_WINDOWS + + // VRet = _rtl_chmod( SrcDir, 1 , FA_NORMAL ); + // err_retfail ( VRet, (ERR_OUT,"Chmod failed on directory=%s", SrcDir) ); + + VRet = rmdir ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"Remove directory=%s failed => %s ", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + +#else + err_retfail ( -1, (ERR_OUT,"Function handled only under Windows") ); +#endif + +} + +/******************************************************************************* +Prototype : +Goal : Delete direcory files and directory itself +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelDir ( char* SrcDir ) { + + SInt32 VRet; + char VNewName[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + + sprintf ( VNewName, "%s.old", SrcDir ); + + VRet = rename ( SrcDir, VNewName ); + + err_retfail ( VRet, (ERR_OUT,"Rename Dir=%s to %s failed !", SrcDir, VNewName ) ); + + err_warning (( ERR_OUT, "Directory %s renamed in %s because delete is impossible !", SrcDir, VNewName )); + + err_retok (( ERR_OUT, "" )); + +/* + VRet = FIL_FRmDirFiles ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDirFiles (%s) failed ", SrcDir) ); + + VRet = FIL_FRmDir ( VNewName ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDir (%s) failed ", SrcDir) ); + + err_retok (( ERR_OUT, "" )); +*/ + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FMkDir ( char* SrcDir ) { + + SInt32 VRet; + char VStrCmd[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + #ifdef APP_DAQ + + err_retfail ( -1, (ERR_OUT,"Function NOT available under LynxOS !") ); + + #endif + + #ifdef CC_APP_LINUX + sprintf ( VStrCmd, "mkdir %s", SrcDir ); + system ( VStrCmd ); + #endif + + + #ifdef CC_APP_WINDOWS + VRet = mkdir ( SrcDir ); + + err_retfail ( VRet, (ERR_OUT,"Creation of directory=%s failed => %s", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FMkDir (SrcDir=%s) IS NOT available !", SrcDir) ); + #endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in + : the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT + : are not written in list. +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in +: the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT +: are not written in list. +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +SInt32 FIL_FExtDosListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\%s", SrcDir, Joker ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIl_FDosListDirFiles ( SrcDir, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + return ( FIL_FExtDosListDirFiles ( SrcDir, Joker, PtList ) ); +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList ) { + + SInt32 VRet; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + VFilesCnt = FIl_FListDirFiles ( VRmpDirPath, PtList ); + + return ( VFilesCnt ); +} + + + +#ifndef APP_DAQ + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Extended version which handles conf extension i,j,k +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtDelRmpFiles ( char* RmpDataPath, char ConfExt, SInt32 RunNo, SInt32 MaxFileCnt ) { + + SInt32 VRet; + SInt32 ViFile; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VInfoFilePath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VData0Filepath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + FIL_TDirFilesList VFilesList; // Debug 02/06/2007 move storage class static to auto + + + char VFileToDelete[GLB_FILE_PATH_SZ]; + + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + sprintf ( VInfoFilePath , "RUN_%d_%c.rz", RunNo, ConfExt ); + sprintf ( VData0Filepath, "RUN_%d_0.rz" , RunNo ); + + VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &VFilesList ); + + /* !!! DESY 20/09/05 !!! MUST BE CHECKED ! */ + /* previous line replaced by this one in order to be able to compile boards_db_man */ + /* VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &(VPtAFilesPath) ); */ + + err_retfail ( VFilesCnt, (ERR_OUT,"FIL_FCntRmpFiles (%s) failed Ret=%d", RmpDataPath, VFilesCnt ) ); + + if ( VFilesCnt < MaxFileCnt ) { + err_retok (( ERR_OUT, "Nothing to do VFilesCnt=%d < MaxFileCnt=%d", VFilesCnt, MaxFileCnt )); + } + + err_warning (( ERR_OUT, "%d RMP files are not deleted by monitoring => I will remove them", VFilesCnt )); + + for ( ViFile = 0; ViFile < VFilesCnt; ViFile++ ) { + + if ( strcmp ( VFilesList.AList[ViFile], VInfoFilePath ) == 0 ) { + continue; + } + + if ( strcmp ( VFilesList.AList[ViFile], VData0Filepath ) == 0 ) { + continue; + } + + sprintf ( VFileToDelete, "%s\\%s", VRmpDirPath, VFilesList.AList[ViFile] ); + + err_warning (( ERR_OUT, "FIL_FDelRmpFilesv => File = %s", VFileToDelete )); + + FIL_FRemoveFile ( VFileToDelete ); + + } + + return (0); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Creation of FIL_FExtDelRmpFiles to replace FIL_FDelRmpFiles + : - FIL_FDelRmpFiles call FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt ) { + return ( FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) ); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FFloatVectorsToTextFile ( float** SrcVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** VectorsNames, char DataSep, char* DestFile ) { + + char VFuncName[] = "FIL_FFloatVectorsToTextFile"; + + FILE* VPfDest; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + + + VPfDest = fopen ( DestFile, "wt" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", DestFile ) ); + + + if ( HeaderLine != NULL ) { + VRet = fprintf ( VPfDest, "%s \n", HeaderLine ); + } + + else { + VRet = fprintf ( VPfDest, "No header line \n", HeaderLine ); + } + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing Header line file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + + if ( VectorsNames != NULL ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + VRet = fprintf ( VPfDest, "%-21s", VectorsNames[ViVector]); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing vectors names line - Vector=%d file=%s => %s", ViVector, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + VRet = fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + } + + else { + fprintf ( VPfDest, "No vectors names line \n", HeaderLine ); + } + + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + VRet = fprintf ( VPfDest, "%.6f%c", SrcVectors[ViVector][ViLine], DataSep); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing line=%d in file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR line=%d file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + fflush (VPfDest); + fclose (VPfDest); + + err_retok (( ERR_OUT, "%d line written in file", EltNbPerVector, DestFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FTextFileToFloatVectors ( char* SrcFile, char DataSep, float** DestVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** AVectorsNames, char* StrVectorsNames ) { + + char VFuncName[] = "FIL_FTextFileToFloatVectors"; + + FILE* VPf; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + char VStrCR[2]; + char VDataSep; + + /* Check parameters */ + + err_retnull ( SrcFile , (ERR_OUT,"SrcFile == NULL" ) ); + err_retnull ( DestVectors , (ERR_OUT,"DestVectors == NULL" ) ); + err_retnull ( HeaderLine , (ERR_OUT,"HeaderLine == NULL" ) ); + err_retnull ( AVectorsNames , (ERR_OUT,"AVectorsNames == NULL" ) ); + err_retnull ( StrVectorsNames , (ERR_OUT,"StrVectorsNames == NULL" ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 1" )); + + /* Try to open file */ + + VPf = fopen ( SrcFile, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFile ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read header line */ + + VRet = (SInt32) fgets( HeaderLine, 255, VPf ); + + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read header line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + /* Read vectors names line */ + + + VRet = (SInt32) fgets( StrVectorsNames, 255, VPf ); + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read vectors names line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + sprintf ( AVectorsNames[ViVector], "" ); + }; + + + /* Read vectors */ + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + if ( ViVector == VectorsNb-1 ) { + VRet = fscanf ( VPf, "%f%c", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + else { + VRet = fscanf ( VPf, "%f%c\n", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + + if ( VRet != 2 ) { + fflush (VPf); + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s", ViLine, SrcFile, VRet, _strerror ( "System says :" ) ) ); + } + + } + + } + + + fflush (VPf); + fclose (VPf); + + err_retok (( ERR_OUT, "%d line Read in file", EltNbPerVector, SrcFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef CC_APP_WINDOWS + + SInt32 FIL_FGetAppRunDir ( char* StrRunDir, TApplication* PtApp ) { + + char* VPtStrExeName; + AnsiString VAStrExeName; + char VExeDriveLetter; + char VExeDriveId; /* 0 = default, 1 = A, 2 = B ... */ + char VStrCurDir[GLB_FILE_PATH_SZ]; + char VStrCurDirPath[GLB_FILE_PATH_SZ]; + + err_retfailnull ( StrRunDir, (ERR_OUT,"StrRunDir == NULL") ); + + VPtStrExeName = FStr2PCh ( &(PtApp->ExeName) ); + + VExeDriveLetter = toupper ( VPtStrExeName[0] ); + + switch ( VExeDriveLetter ) { + + case 'A' : { + VExeDriveId = 1; + break; } + + case 'B' : { + VExeDriveId = 2; + break; } + + case 'C' : { + VExeDriveId = 3; + break; } + + case 'D' : { + VExeDriveId = 4; + break; } + + case 'E' : { + VExeDriveId = 5; + break; } + + case 'F' : { + VExeDriveId = 6; + break; } + + case 'G' : { + VExeDriveId = 7; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown drive id=%d", VExeDriveId) ); + VExeDriveId = 0; + } + + } + + getcurdir( VExeDriveId, VStrCurDir ); + + sprintf ( VStrCurDirPath, "%c:\\%s", VExeDriveLetter, VStrCurDir ); + sprintf ( StrRunDir, "%s", VStrCurDirPath ); + + // msg (( MSG_OUT, "VStrCurDirPath = %s", VStrCurDirPath )); + + err_retok (( ERR_OUT, "" )); + } + +#else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retfailnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: ~FIL__TCBinFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + + // Variables for internal processing + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdEltId = 0; + ProCurRdSz = 0; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProPtFile = NULL; + + err_trace (( ERR_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + ProParRWBMode = RWBMode; + ProParMaxBlocSz = MaxBlocSz; + ProParBlocSz = BlocSz; + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + ProConfDone = 1; + + + // Allocate memory buffer for data read from file + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = MaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCBinFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProPtFile == NULL ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + + // Store current ( initial ) position in file + + if ( (VCurPos = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Goto end of file + + if ( fseek ( ProPtFile, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + // Get current position = END in file => it's file size + + if ( (VFileSz = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Restor initial position in file + + if ( fseek ( ProPtFile, VCurPos, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + + } // End file is already open + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFCreate () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProPtFile = fopen ( ProParDataFile, "wb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFOpen () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + ProPtFile = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz ) { + SInt8 VBlocNbWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can write to a file when RWB mode IS NOT Write !") ); + } + + ProCurWrSz = DataSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbWritten = fwrite ( PtrData, DataSz /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbWritten != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc write failed ! => System : %s", _strerror ("") ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + fflush ( ProPtFile ); + } + + ++ProCurWrEltId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", DataSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + if ( DataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > MaxDestSz=%d", DataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( DestPtr, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc read failed ! => System : %s", _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + if ( DataSzToRead > ProParMaxBlocSz ) { + err_retfailnull ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > ProParMaxBlocSz=%d", DataSzToRead, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( ProPtrBuffRdData, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Bloc read failed ! => System : %s", _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGotoBloc ( SInt32 BlocNo ) { + + SInt32 VOffset; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + VOffset = BlocNo * ProParBlocSz; + + if ( fseek ( ProPtFile, VOffset, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Goto bloc %d => %d bytes from beginning failed !", BlocNo ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ) { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFFlush () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + fflush ( ProPtFile ); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFClose () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + fflush ( ProPtFile ); + } + + fclose ( ProPtFile ); + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + ProConfDone = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_WRITE, RecSz, RecSz, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFCreate (); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqWrite ( PtSrc, RecSz ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_READ, RecSz, RecSz, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFOpen(); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqRead ( PtDest, RecSz /* MaxDestSz */, RecSz /* DataSzToRead */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + + +// msg (( MSG_OUT, "Msg" )); + + + +// **************************** +// FIL__TCStreamFile +// **************************** + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl, DiskBlocSz ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: ~FIL__TCStreamFile () { + + // Free info record + + if ( ProPtRecInfFile != NULL ) { + free ( ProPtRecInfFile ); + } + + TerminateThread ( ProThreadHnd , 0 /* Thread exit code */ ); + + DeleteCriticalSection ( &ProCsPrintMsg ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : 05/11/2010 + : - Error handling on disk access is not properly done, a message is printed + : but the error is not propagated => MUST be done. +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ) { + + FIL__TCStreamFile* VPtObj = (FIL__TCStreamFile*) lpParam; + + SInt32 VRet; + DWORD VBuffFull; + UInt32 VNbBytesToWrite; + UInt32 VNbBytesWritten; + char VStrMsg[GLB_CMT_SZ]; + + + while (1) { + + // Wait on buffer to read + + VBuffFull = WaitForSingleObject ( VPtObj->ProSemRdBuffHnd, INFINITE ); + + switch ( VBuffFull ) { + + case WAIT_OBJECT_0 : { + + + VNbBytesToWrite = VPtObj->ProParBlocSz; + + WriteFile( + VPtObj->ProFileHnd, // handle to file to write to + VPtObj->ProABuff[VPtObj->ProIndexRdBuff], // pointer to data to write to file + VNbBytesToWrite, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != VNbBytesToWrite ) { + sprintf ( VStrMsg, "ThreadDisk => Writing buff %d error !", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + else { + sprintf ( VStrMsg, "ThreadDisk => Buffer %d save to disk", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg ); + } + + if ( VPtObj->ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( VPtObj->ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + ++VPtObj->ProIndexRdBuff; + + err_retfail ( VPtObj->ProIndexRdBuff, (ERR_OUT,"Bad variable size => ProIndexRdBuff=%d < 0", VPtObj->ProIndexRdBuff) ); + + if ( VPtObj->ProIndexRdBuff >= FIL__TCStreamFile_MAX_BUFF_NB ) { + VPtObj->ProIndexRdBuff = 0; + } + + ReleaseSemaphore ( VPtObj->ProSemWrBuffHnd, 1, NULL ); + + + break; } + + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFull )); + break; } + + } + + + + } // End while (1) + + return 0; +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 05/11/2010 +Doc date : 05/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFCalcProParBlocSz ( SInt32 DataSz ) { + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VRecInfSz; + + VNotIntegerDiskBlocNb = DataSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (DataSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = DataSz; + } + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + SInt8 ViBuff; + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + ProParDiskBlocSz = DiskBlocSz; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + sprintf ( ProInfFileName, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + ProParFixedBlocSzMode = 1; + + // Variables for internal processing + + ProUseThread = 0; + + ProFileHnd = INVALID_HANDLE_VALUE; + ProPtInfFile = NULL; + + InitializeCriticalSection ( &ProCsPrintMsg ); + + + ProThreadHnd = INVALID_HANDLE_VALUE; + ProThreadId = 0; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProABuff[ViBuff] = NULL; + } + + ProSemWrBuffHnd = INVALID_HANDLE_VALUE; + ProSemRdBuffHnd = INVALID_HANDLE_VALUE; + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + ProBuffSz = 0; + + ProPtRecInfFile = NULL; + ProRecInfSz = 0; + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdBlocId = 0; + ProCurRdSz = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void FIL__TCStreamFile :: PubFPrintMsg ( char* Msg ) { + + EnterCriticalSection( &ProCsPrintMsg ); + + err_trace (( ERR_OUT, "%s", Msg )); + + LeaveCriticalSection( &ProCsPrintMsg ); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt8 ViBuff; + SInt32 VNotIntegerDiskBlocNb; + TDateTime VODateTime; + + + + + // ------------------------------------------------------- + // Set class parameters from PubFConf parameters list + // ------------------------------------------------------- + + err_retnull ( PtMyself, (ERR_OUT,"PtMyself == NULL") ); + + PriPtMyself = PtMyself; + + ProUseThread = UseThread; + + sprintf ( ProParDataFile, "%s", DataFile ); + + sprintf ( ProInfFileName, "%s.inf", ProParDataFile ); + + ProParRWBMode = RWBMode; + + ProParFixedBlocSzMode = FixedBlocSzMode; + + ProParRequestedBlocSz = BlocSz; + + VNotIntegerDiskBlocNb = ProParRequestedBlocSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (ProParRequestedBlocSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = ProParRequestedBlocSz; + } + + err_trace (( ERR_OUT, "RequestedBlocSz=%d - BlocSz=%d", ProParRequestedBlocSz, ProParBlocSz )); + + + ProParRequestedMaxBlocSz = MaxBlocSz; + + if ( ProParRequestedMaxBlocSz >= ProParBlocSz ) { + ProParMaxBlocSz = ProParRequestedMaxBlocSz; + } + + else { + err_warning (( ERR_OUT, "ProParMaxBlocSz=%d must be adjusted -> Set to ProParBlocSz=%d", ProParMaxBlocSz, ProParBlocSz )); + ProParMaxBlocSz = ProParBlocSz; + } + + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + // ------------------------------------------------------- + // Alloc information file record + // ------------------------------------------------------- + + if ( ProParFixedBlocSzMode == 1 ) { + ProRecInfSz = sizeof (FIL__TCStreamFile_Old_TRecInfFile); + } + + else { + ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (UInt64) ); + } + + ProPtRecInfFile = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFile, (ERR_OUT,"Allocation of info record failed !") ); + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // ------------------------------------------------------- + // Create or open information file + // ------------------------------------------------------- + + // Write mode => Create info file + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProPtRecInfFile->Version = 1; + ProPtRecInfFile->FixedBlocSz = ProParFixedBlocSzMode; + ProPtRecInfFile->MaxBlocSz = ProParMaxBlocSz; + ProPtRecInfFile->BlocSz = ProParBlocSz; + ProPtRecInfFile->BlocNb = 0; + ProPtRecInfFile->ABlocInf[0].Offset = 0; + ProPtRecInfFile->ABlocInf[0].Sz = 0; + + VODateTime = VODateTime.CurrentDateTime (); + + ProPtRecInfFile->DateCreate = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeCreate = TIME__FConvDateTime2Time ( VODateTime ); + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Creation of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + err_trace (( ERR_OUT, "Info file=%s created", ProInfFileName )); + } + + // Read mode => Open info file + + else { + + ProPtInfFile = fopen ( ProInfFileName, "rb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Open info file %s failed => system : %s", ProInfFileName, _strerror ( "" ) )); + err_trace (( ERR_OUT, "Info file=%s read", ProInfFileName )); + + if ( fread ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Read info file %s failed => system : %s", ProInfFileName, _strerror ( "" )) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + // Print info file + + PubFPrintInfFile (); + + // Set bloc size + + ProParBlocSz = ProPtRecInfFile->BlocSz; + + if ( ProParRequestedBlocSz != ProParBlocSz ) { + err_warning (( ERR_OUT, "Requested bloc sz=%d <> Info file bloc sz=%d => Use Info file bloc sz", ProParRequestedBlocSz, ProParBlocSz )); + } + + } + + + // ------------------------------------------------------------- + // Write mode => Allocate buffers, create semaphores and thread + // ------------------------------------------------------------- + + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + if ( FIL__TCStreamFile_MAX_BUFF_NB > 4 ) { + err_retfail ( -1, (ERR_OUT,"FIL__TCStreamFile_MAX_BUFF_NB = %d ! Handling of more than 4 buffers is NOT implemented !", FIL__TCStreamFile_MAX_BUFF_NB) ); + } + + // Allocate buffers + + ProBuffSz = ProParMaxBlocSz; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + // If already allocated => Free + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + } + + // Allocate + + ProABuff[ViBuff] = (UInt8*) malloc ( ProBuffSz ); + + err_retnull ( ProABuff[ViBuff], (ERR_OUT,"Allocation buffer[%d] of %d bytes failed !", ViBuff, ProBuffSz ) ); + err_trace (( ERR_OUT, "Buffer[%d] of %d bytes allocated", ViBuff, ProBuffSz )); + + // Reset content with $FF + + memset ( ProABuff[ViBuff], 0xFF, ProBuffSz ); + } + + // Create & init semaphores + + ProSemWrBuffHnd = CreateSemaphore( NULL, FIL__TCStreamFile_MAX_BUFF_NB, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = Max = Max buff nb + + err_retnull ( ProSemWrBuffHnd, (ERR_OUT,"Create SemWrBuff failed ! - LastError=%d", GetLastError ()) ); + + ProSemRdBuffHnd = CreateSemaphore( NULL, 0, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = 0, Max = Max buff nb + + err_retnull ( ProSemRdBuffHnd, (ERR_OUT,"Create SemRdBuff failed ! - LastError=%d", GetLastError ()) ); + + // Init buffers index + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + // Create thread + + ProThreadHnd = CreateThread ( NULL, 0, FIL__TCStreamFile_FThread, (void*) PriPtMyself /* Param */ , 0, &ProThreadId ); + + err_retnull ( ProThreadHnd, (ERR_OUT,"Thread creation failed ! LastError=%d", GetLastError ()) ); + + } + + // ------------------------------------------------------------- + // Read mode => Allocate memory buffer for data read from file + // ------------------------------------------------------------- + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = ProParMaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 20/05/2010 +Doc date : 20/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFile () { + + SInt32 ViBloc; + + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record " )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Version = %d", ProPtRecInfFile->Version )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Date create = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateCreate, NULL, 0 ) )); + msg (( MSG_OUT, "Time create = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeCreate, NULL, 0 ) )); + msg (( MSG_OUT, "Date close = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateClose , NULL, 0 ) )); + msg (( MSG_OUT, "Time close = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeClose , NULL, 0 ) )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "FixedBlocSz = %d", ProPtRecInfFile->FixedBlocSz )); + msg (( MSG_OUT, "MaxBlocSz = %d", ProPtRecInfFile->MaxBlocSz )); + msg (( MSG_OUT, "BlocSz = %d", ProPtRecInfFile->BlocSz )); + msg (( MSG_OUT, "BlocNb = %d", ProPtRecInfFile->BlocNb )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "ABlocInf[0].Offset = %Lu", ProPtRecInfFile->ABlocInf[0].Offset )); + msg (( MSG_OUT, "ABlocInf[0].Sz = %d ", ProPtRecInfFile->ABlocInf[0].Sz )); + msg (( MSG_OUT, "ABlocInf[0].SpareW32Info = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32Info )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "ABlocInf[1].Offset = %Lu", ProPtRecInfFile->ABlocInf[1].Offset )); + msg (( MSG_OUT, "ABlocInf[1].Sz = %d ", ProPtRecInfFile->ABlocInf[1].Sz )); + msg (( MSG_OUT, "ABlocInf[1].SpareW32Info = %d ", ProPtRecInfFile->ABlocInf[1].SpareW32Info )); + msg (( MSG_OUT, "-------------------------" )); + + if ( ProPtRecInfFile->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < ProPtRecInfFile->BlocNb; ViBloc++ ) { + msg (( MSG_OUT, "Bloc[%.4d] : Offset=%.12Lu - Sz=%d [Bytes]", ViBloc, ProPtRecInfFile->ABlocInf[ViBloc].Offset, ProPtRecInfFile->ABlocInf[ViBloc].Sz )); + } + + } + + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + err_retfail ( -1, (ERR_OUT,"File is opened => Get file size not coded in this state (TOB ...)") ); + } + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 + : - Calculation => file size / block size +Rev : 20/05/2010 + : - Read from info file field BlocNb + : +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + +/* Before 20/05/2010 + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + +*/ + + VBlocNb = ProPtRecInfFile->BlocNb; + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFCreate () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_WRITE | GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFOpen () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 SpareW32Info ) { + + SInt32 VRet; + DWORD VBuffFree; + UInt32 VNbBytesWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Cant write to a file when RWB mode IS NOT Write !") ); + } + + // If variable bloc sz mode => Test max nb of blocs allowed & Adjust ProParBlocSz + + if ( ProParFixedBlocSzMode == 0 ) { + + if ( ProPtRecInfFile->BlocNb >= FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE ) { + err_retfail ( -1, (ERR_OUT,"Max bloc nb = %d reached in variable bloc sz mode !", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE) ); + } + + ProFCalcProParBlocSz ( DataSz ); + } + + // err_error (( ERR_OUT, "DataSz=%d - ProParBlocSz=%d bytes", DataSz, ProParBlocSz )); + + ProCurWrSz = ProParBlocSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + // Let thread write data to disk in background task + + if ( ProUseThread == 1 ) { + + // Wait on buffer to write + + VBuffFree = WaitForSingleObject ( ProSemWrBuffHnd, 1 /* ms */ ); + + switch ( VBuffFree ) { + + case WAIT_TIMEOUT : { + ++ProResWrBlocFailCnt; + err_retfail ( -1, (ERR_OUT,"Write failed for the %d time -> No buffer available for event %d!", ProResWrBlocFailCnt, SpareW32Info ) ); + break; } + + case WAIT_OBJECT_0 : { + + memcpy ( ProABuff[ProIndexWrBuff], PtrData, DataSz ); + + // PubFPrintMsg ( "Thread => Buffer %d filled", ProIndexWrBuff ); + err_trace (( ERR_OUT, "Thread => Buffer %d filled with Event %d", ProIndexWrBuff, SpareW32Info )); + + ++ProIndexWrBuff; + + err_retfail ( ProIndexWrBuff, (ERR_OUT,"Bad variable size => ProIndexWrBuff=%d < 0", ProIndexWrBuff) ); + + if ( ProIndexWrBuff >= FIL__TCStreamFile_MAX_BUFF_NB) { + ProIndexWrBuff = 0; + } + + ReleaseSemaphore ( ProSemRdBuffHnd, 1, NULL ); + break; } + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFree )); + break; } + + } + + } + + // Write NOW data to disk + + else { + + // Copy to buffer -> "Automatically" add padding bytes + + memcpy ( ProABuff[0], PtrData, DataSz ); + + // Warning => Write ProParBlocSz bytes AND NOT the value passed via parameter DataSz + // because non buffered I/O functions MUST write multiple of DISK bloc size + + WriteFile( + ProFileHnd, // handle to file to write to + ProABuff[0], // pointer to data to write to file + ProParBlocSz, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != ProParBlocSz ) { + err_retfail ( VRet, (ERR_OUT,"Writing block %d failed %d bytes written - %d bytes requested ! - %s", ProCurWrBlocId, VNbBytesWritten, ProParBlocSz, strerror ( errno ) ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + } + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32Info = SpareW32Info; + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + + if ( ProUseThread == 1 ) { + err_trace (( ERR_OUT, "Copy bloc of %d bytes done in %d [ms]", DataSz, ProTimeExec )); + } + + else { + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", VNbBytesWritten, ProTimeExec )); + } + + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + UInt32 VNbBytesRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + ReadFile( + ProFileHnd, // handle of file to read + DestPtr, // address of buffer that receives data + VDataSzToRead, // number of bytes to read + &VNbBytesRead, // address of number of bytes read + NULL // address of structure for data + ); + + if ( VNbBytesRead != VDataSzToRead ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed : %d bytes read - %d bytes requested ! - %s", ProCurRdBlocId, VNbBytesRead, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( ProPtrBuffRdData, ProSzBuffRdData, DataSzToRead ); + + err_retfailnull ( VRet, (ERR_OUT,"PubFSeqRead failed !") ); + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : Limited to 4 GB files + : +Rev : 09/05/2010 + : - Use W64 offset => Not limited to 4 GB file +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGotoBloc ( SInt32 BlocNo ) { + + UInt32 VRet; + UInt64 VOffsetW64; + SInt32* VPtOffsetLow32; + SInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((SInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((SInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = SetFilePointer ( + ProFileHnd, // handle of file + *VPtOffsetLow32, // number of bytes to move file pointer + // (SInt32*) VPtOffsetHigh32, // address of high-order word of distance to move + VPtOffsetHigh32, // address of high-order word of distance to move + // lpDistanceToMoveHigh = 0 => Limited to 4 GB + FILE_BEGIN // how to move + ); + + + if ( VRet == 0xFFFFFFFF ) { + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &VMsgBuf, + 0, + NULL + ); + + err_retfail ( -1, (ERR_OUT,"Goto bloc %d failed => %s", BlocNo, VMsgBuf ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32Info ) { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + + if ( PtSpareW32Info != NULL ) { + *PtSpareW32Info = ProPtRecInfFile->ABlocInf[BlocNo].SpareW32Info; + } + } + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + return (ProParBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + } + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFFlush () { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFClose () { + + SInt32 VRet; + SInt8 ViBuff; + TDateTime VODateTime; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + PubFFlush (); + } + + ProConfDone = 0; + + CloseHandle ( ProFileHnd ); + + // Free read buffers + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + // Free write buffers + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + ProABuff[ViBuff] = NULL; + } + + } + + + // Get close date & time + + VODateTime = VODateTime.CurrentDateTime (); + + ProPtRecInfFile->DateClose = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeClose = TIME__FConvDateTime2Time ( VODateTime ); + + // Overwrite info file with update close time & date + bloc nb + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Overwrite of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file failed => System : %s", strerror ( errno ) ) ); + } + + err_retok (( ERR_OUT, "" )); +} + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/win_files.def b/include/pxi_daq_lib_v.2.1/win_files.def new file mode 100755 index 0000000..91f6f5a --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/win_files.def @@ -0,0 +1,29 @@ +/* 24/02/05 */ + + +#ifndef FIL_DEF +#define FIL_DEF + +#define FIL_DIR_FILES_LIST_MAX_CNT 100 + +#define FIL__TCBinFile_MEAS_TIME +#define FIL__TCStreamFile_MEAS_TIME + +#define FIL__TCBinFile_RWB_MODE_WRITE 0 +#define FIL__TCBinFile_RWB_MODE_READ 1 +#define FIL__TCBinFile_RWB_MODE_BOTH 2 + +// 07/03/2009 +// Macro removed because they are not supported under ROOT ... +// => Macro "calls" had been replaced by the macro code below in files.c +// => For new implementations : a copy paste of the macro code below must be done for each "flag test" +// +// #define FIL__TCBinFile_CHK_CONF_DONE {err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_WR {err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_RD {err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );} + + +#define FIL__TCStreamFile_MAX_BUFF_NB 4 +#define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 // Maximum number of blocs in variable bloc size mode + +#endif diff --git a/include/pxi_daq_lib_v.2.1/win_files.h b/include/pxi_daq_lib_v.2.1/win_files.h new file mode 100755 index 0000000..6e01073 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/win_files.h @@ -0,0 +1,51 @@ +/* 24/02/05 */ + + +#ifndef FIL_H + +#include "func_header.def" + +#include "files.def" +#include "files.typ" + + +FHEAD ( SInt32 FIL_FFileExists ( char* FilePath );) +FHEAD ( SInt32 FIL_FFileSize ( char* FilePath );) + +FHEAD ( SInt32 FIL_FCpyFile ( char* Src, char* Dest );) +FHEAD ( SInt32 FIL_FRemoveFile ( char* FilePath );) +FHEAD ( SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile );) +FHEAD ( SInt32 FIL_FRmDirFiles ( char* SrcDir );) +FHEAD ( SInt32 FIL_FRmDir ( char* SrcDir );) +FHEAD ( SInt32 FIL_FDelDir ( char* SrcDir );) +FHEAD ( SInt32 FIL_FMkDir ( char* SrcDir );) +FHEAD ( SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList );) +FHEAD ( SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList );) +FHEAD ( SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz );) +FHEAD ( SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz );) + +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz );) +// FHEAD_DLL_IE (APP_DLL_IMPORT_EXPORT, SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz );) + + +#ifdef CC_APP_WINDOWS + FHEAD ( SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile );) + FHEAD ( SInt32 FIL_FDosRmDirFiles ( char* SrcDir );) + FHEAD ( SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList );) +#endif + + +#ifndef APP_DAQ + FHEAD ( SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt );) +#endif + + +#ifndef APP_DLL_IMPORT_EXPORT + #ifndef FIL_H + #define FIL_H + #endif +#endif + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/win_files.typ b/include/pxi_daq_lib_v.2.1/win_files.typ new file mode 100755 index 0000000..6122ac7 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/win_files.typ @@ -0,0 +1,261 @@ +/* 24/02/05 */ + + +#ifndef FIL_TYP +#define FIL_TYP + +/* char FIL_TADirFilesList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; */ + + +typedef struct { + char AList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; +} FIL_TDirFilesList; + + +// 30/01/2009 + +class FIL__TCBinFile { + + + private : + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + // Parameters from conf + + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParMaxBlocSz; + SInt32 ProParBlocSz; + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + + SInt32 ProCurRdEltId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrEltId; + UInt64 ProCurWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + UInt64 ProTotWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + FILE* ProPtFile; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + + + public : + + FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~FIL__TCBinFile (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + SInt32 PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz ); + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + +// 01/05/2010 + +typedef struct { + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + UInt32 ABlocSz[1]; + +} FIL__TCStreamFile_Old_TRecInfFile; + +// 05/11/10 + +typedef struct { + + UInt64 Offset; + UInt32 Sz; + SInt32 SpareW32Info; + +} FIL__TCStreamFile_TBlocInf; + + +// 05/11/10 + +typedef struct { + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + FIL__TCStreamFile_TBlocInf ABlocInf[1]; + +} FIL__TCStreamFile_TRecInfFile; + + +class FIL__TCStreamFile { + + + private : + + FIL__TCStreamFile* PriPtMyself; + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + SInt32 ProParDiskBlocSz; + SInt8 ProParFixedBlocSzMode; + + // Parameters from conf + + SInt8 ProUseThread; + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParRequestedMaxBlocSz; // Bloc size value asked by user + SInt32 ProParMaxBlocSz; // Adjusted depending on ProParBlocSz + + SInt32 ProParRequestedBlocSz; // Bloc size value asked by user + SInt32 ProParBlocSz; // Bloc size value used ( multiple of disk bloc size ) + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + HANDLE ProFileHnd; + + char ProInfFileName[GLB_FILE_PATH_SZ]; + FILE* ProPtInfFile; + + FIL__TCStreamFile_TRecInfFile* ProPtRecInfFile; + SInt32 ProRecInfSz; + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + +#ifndef CC_UNIX + CRITICAL_SECTION ProCsPrintMsg; +#endif + + HANDLE ProThreadHnd; + DWORD ProThreadId; + + HANDLE ProSemWrBuffHnd; + HANDLE ProSemRdBuffHnd; + + SInt16 ProIndexWrBuff; + SInt16 ProIndexRdBuff; + + UInt8* ProABuff[FIL__TCStreamFile_MAX_BUFF_NB]; + SInt32 ProBuffSz; + + + SInt32 ProCurRdBlocId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrBlocId; + SInt32 ProCurWrSz; + + // SInt32 ProTotWrSz; + + SInt64 ProTotWrSz; + + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + // Results + + SInt32 ProResWrBlocFailCnt; + + SInt32 ProFCalcProParBlocSz ( SInt32 DataSz ); + + public : + + FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + ~FIL__TCStreamFile (); + + friend DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + void PubFPrintMsg ( char* Msg ); + SInt32 PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFPrintInfFile (); + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 SpareInfo ); + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32Info ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + + + +#endif + diff --git a/include/pxi_daq_lib_v.2.1/win_files.var b/include/pxi_daq_lib_v.2.1/win_files.var new file mode 100755 index 0000000..84c5111 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/win_files.var @@ -0,0 +1,16 @@ +/* 24/02/05 */ + + +#ifndef FIL_VAR +#define FIL_VAR + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +// Examples +// +// VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +// VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/win_globals.def b/include/pxi_daq_lib_v.2.1/win_globals.def new file mode 100755 index 0000000..62296d3 --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/win_globals.def @@ -0,0 +1,37 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_DEF +#define GLOBALS_DEF + +#include "globals_root.def" + +#ifndef ROOT_ROOT + #define GLB_READ_CR { while ( getchar () != '\n' ); }; +#endif + + +#ifndef ROOT_ROOT + #define GLB_KEYB_CR { while ( getchar () != '\n' ); } +#endif + + + +#endif diff --git a/include/pxi_daq_lib_v.2.1/win_time.c b/include/pxi_daq_lib_v.2.1/win_time.c new file mode 100755 index 0000000..93737eb --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/win_time.c @@ -0,0 +1,622 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.c +Goal : Functions of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_C +#define TIME_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateL TIME_FConvDateS2DateL ( TIME__TUDateS DateS ) { + + TIME__TUDateL VDateL; + + VDateL.Date.Day = DateS.Date.Day; + VDateL.Date.Month = DateS.Date.Month; + VDateL.Date.Year = 2000 + DateS.Date.Year; + + return (VDateL); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateS TIME_FConvDateL2DateS ( TIME__TUDateL DateL ) { + + TIME__TUDateS VDateS; + + VDateS.Date.Day = DateL.Date.Day; + VDateS.Date.Month = DateL.Date.Month; + VDateS.Date.Year = DateL.Date.Year % 2000; + + return (VDateS); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 23/05/2010 +Doc date : 23/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateS2Str ( TIME__TUDateS Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.2d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( UInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( SInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = (UInt32) Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ + : +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FDateL2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2Str ( TIME__TUDateL Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.4d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 06/03/2010 +Doc date : 06/03/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2StrExt ( TIME__TUDateL Date, char SepChar, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d%c%.2d%c%.4d", Date.Date.Day, SepChar, Date.Date.Month, SepChar, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FConvDateTime2DateL ( TDateTime Src ) { + + TIME__TUDateL VDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + Src.DecodeDate ( &VYear, &VMonth, &VDay ); + + VDate.Date.Year = VYear; + VDate.Date.Month = VMonth; + VDate.Date.Day = VDay; + + return (VDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FGetDateLOfNextDay ( TIME__TUDateL Cur ) { + + TDateTime VCurDate ( Cur.Date.Year, Cur.Date.Month, Cur.Date.Day ); + TIME__TUDateL VNextDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + ++VCurDate; + + VCurDate.DecodeDate ( &VYear, &VMonth, &VDay ); + + VNextDate.Date.Year = VYear; + VNextDate.Date.Month = VMonth; + VNextDate.Date.Day = VDay; + + return (VNextDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +WARNING : If return pointer to list is used, a copy of LIST ( not pointer ) must be done + : after each TIME__FFillListDatesLOfWeek () call otherwise the list content will be + : the one of last call because all pointers will point to last list stored in local + : variable of function. + : + : +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef ROOT_ROOT + +TIME__TListDatesLOfWeek* TIME__FFillListDatesLOfWeek ( TIME__TUDateL MondayDate, TIME__TListDatesLOfWeek* PtList ) { + + static TIME__TListDatesLOfWeek VList; + TIME__TUDateL VDayDate; + SInt8 ViDay; + + + VDayDate = MondayDate; + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + VList.ADates[ViDay] = VDayDate; + VDayDate = TIME__FGetDateLOfNextDay ( VDayDate ); + } + + if ( PtList != NULL ) { + *PtList = VList; + } + + return (&VList); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 TIME__FPrintListDatesLOfWeek ( TIME__TListDatesLOfWeek* PtList ) { + + SInt8 ViDay; + + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + msg (( MSG_OUT, "Date : %s", TIME__FDateL2Str ( PtList->ADates[ViDay], NULL /* PtDestStr */, 0 /* DestStrSz */ ) )); + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +WARNING : A copy of return STRING ( not pointer ) must be done after each TIME_FGetDayName call + : otherwise the string content will be the one of last call because all pointers will + : point to last string stored in local variable of function. +: +Level : +Date : 27/02/2010 +Doc date : 27/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME_FGetDayName ( UInt8 DayIndex, SInt8 Language ) { + + static char* VAStrDayNameFr[8] = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche" }; + static char* VAStrDayNameEn[8] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + + if ( (DayIndex < 0) || (DayIndex > 7) ) { + err_error (( ERR_OUT, "Bad day index = %d out of rnage 0..7", DayIndex )); + return ( "?" ); + } + + switch ( Language ) { + + case TIME__LANG_FRENCH : { + return ( VAStrDayNameFr[DayIndex] ); + break; } + + case TIME__LANG_ENGLISH : { + return ( VAStrDayNameEn[DayIndex] ); + break; } + + + default : { + err_error (( ERR_OUT, "Bad language = %d out of range", Language )); + return ( "?"); + } + + } + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUTime TIME__FConvDateTime2Time ( TDateTime Src ) { + + TIME__TUTime VTime; + unsigned short VHour; + unsigned short VMin; + unsigned short VSec; + unsigned short VMSec; + + Src.DecodeTime ( &VHour, &VMin, &VSec, &VMSec ); + + VTime.Time.Hour = VHour; + VTime.Time.Min = VMin; + VTime.Time.Sec = VSec; + VTime.Time.Cent = VMSec / 10; + + return (VTime); +} + +#endif + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FTime2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FTime2Str ( TIME__TUTime Time, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrTime[TIME__STR_TIME_SZ]; + + sprintf ( VStrTime, "%.2d:%.2d:%.2d|%.2d", Time.Time.Hour, Time.Time.Min, Time.Time.Sec, Time.Time.Cent ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_TIME_SZ) ) { + sprintf ( PtDestStr, "%s", VStrTime ); + } + + return (VStrTime); +} + + +// 23/05/2010 + +char* TIME__FTime2Str ( UInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + +// 23/05/2010 + +char* TIME__FTime2Str ( SInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = (UInt32) Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.2.1/win_types.typ b/include/pxi_daq_lib_v.2.1/win_types.typ new file mode 100755 index 0000000..0d38fdf --- /dev/null +++ b/include/pxi_daq_lib_v.2.1/win_types.typ @@ -0,0 +1,148 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.typ +Goal : Common basic types definitions. + : I never use default C types names ( char, int ... ) + : i redefined them here ( SInt8, UInt32 ... ). + : + : If something go wong on you'r plateform with C types + : definition you need to update this file. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +/*H**************************************************************************** +FILE : Types.Typ +BUT : Define types. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_TYP +#define TYPES_TYP + + // typedef enum ELang { ELang_FRENCH, ELang_ENGLISH, ELang_GERMAN, ELang_LANG_NB } TLang; + +#ifndef NODEFTYPCHAR + +/* +17/11/04 GC + +BCPPB declares an identfier with the same name " Char " +this problem happens while compiling Mimo* JTAG application (MP). +This Char identifier is used in SpinEdit object. + +MP used conditionnal compilation, i decided to remove this Char +type definition, because i believe i never use it. +Wait and see ... + +*/ + +/* typedef unsigned char Char; */ + +#endif + +#ifndef UInt8 + typedef unsigned char UInt8; +#endif + +#ifndef UByte + typedef UInt8 UByte; +#endif + +#ifndef SInt8 + typedef char SInt8; +#endif + +#ifndef SByte + typedef SInt8 SByte; +#endif + +#ifndef UInt16 + typedef unsigned short UInt16; +#endif + +#ifndef UWord + typedef UInt16 UWord; +#endif + +#ifndef SInt16 + typedef short SInt16; +#endif + +#ifndef SWord + typedef SInt16 SWord; +#endif + +#ifndef UInt32 + typedef unsigned long int UInt32; +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + typedef long int SInt32; +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif + + +#ifndef UInt64 + typedef unsigned __int64 UInt64; +#endif + +#ifndef SInt64 + typedef __int64 SInt64; +#endif + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/asic.def b/include/pxi_daq_lib_v.3.1/asic.def new file mode 100755 index 0000000..9ebc738 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/asic.def @@ -0,0 +1,238 @@ + + +/******************************************************************************* +File : x:\lib\com\asic\asic.def +Goal : Macros definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_DEF +#define ASIC_DEF + + + + +/* ============== */ +/* */ +/* ============== */ +// 30/04/2014 - MS - upg FSBB0 + +typedef enum { + + ASIC__NONE, // 0 + ASIC__MI26, // 1 + ASIC__ULT1, // 2 + ASIC__SUZE02, // 3 + ASIC__FSBB0, // 4 + ASIC__NB + +} ASIC__TEAsicName; + + +/* ============== */ +/* */ +/* ============== */ + +// 12/12/13 GC - Upg AROM1D : +// ASIC_ARM_... => ARM stand for Asic & Read Mode +// 05/05/2014 - MS - Upg FSBB0 : +// added ASIC__ARM_FSBB0_A_416 , ASIC__ARM_FSBB0_A_420 , ASIC__ARM_FSBB_M0_D_416L , ASIC__ARM_FSBB0_D_420 , // + +typedef enum { + + ASIC__ARM_NONE, // 0 + ASIC__ARM_SIS_REF, // Silicon Strip Reference detectors + ASIC__ARM_MI1, // + ASIC__ARM_MI2, // + ASIC__ARM_MI3, // + ASIC__ARM_MI4 , // + ASIC__ARM_MI5 , // + ASIC__ARM_MI6A , // + ASIC__ARM_MI6D , // + ASIC__ARM_MI7A , // + ASIC__ARM_MI7D , // + ASIC__ARM_MI8A , // + ASIC__ARM_MI8D , // + ASIC__ARM_MI9 , // + ASIC__ARM_MI10 , // + ASIC__ARM_MI11 , // + ASIC__ARM_MI12 , // + ASIC__ARM_MI13 , // + ASIC__ARM_MI14 , // + ASIC__ARM_MI15 , // + ASIC__ARM_MI16 , // + ASIC__ARM_MI17 , // + ASIC__ARM_MI18, // + ASIC__ARM_MI19 , // + + // ASIC__ARM_MI20_PH1_A_640L , // + // ASIC__ARM_MI20_PH1_A_642L , // + // ASIC__ARM_MI20_PH1_D_640L , // + // ASIC__ARM_MI20_PH1_D_642L , // + + ASIC__ARM_MI20_MSTAR3_A_320L , // + ASIC__ARM_MI20_MSTAR3_D_320L , // + + + ASIC__ARM_MI21 , // + + ASIC__ARM_MI22_A_576L , // + ASIC__ARM_MI22_A_578L , // + ASIC__ARM_MI22_D_576L , // + ASIC__ARM_MI22_D_578L , // + + ASIC__ARM_MI22_THRA_A_320L , // + ASIC__ARM_MI22_THRA_A_322L , // + ASIC__ARM_MI22_THRA_D_320L , // + ASIC__ARM_MI22_THRA_D_322L , // + + ASIC__ARM_MI22_THRB_A_64L , // + ASIC__ARM_MI22_THRB_A_66L , // + ASIC__ARM_MI22_THRB_D_64L , // + ASIC__ARM_MI22_THRB_D_66L , // + + ASIC__ARM_MI23_PH1_A_640L , // + ASIC__ARM_MI23_PH1_A_642L , // + ASIC__ARM_MI23_PH1_D_640L , // + ASIC__ARM_MI23_PH1_D_642L , // + + ASIC__ARM_MI24 , // + ASIC__ARM_MI25 , // + + ASIC__ARM_MI26_A_576L , // + ASIC__ARM_MI26_A_578L , // + ASIC__ARM_MI26_D_576L , // + ASIC__ARM_MI26_D_578L , // + + ASIC__MI27 , // + + ASIC__ARM_MI28_A_928L , // + ASIC__ARM_MI28_A_930L , // + ASIC__ARM_MI28_D_928L , // + ASIC__ARM_MI28_D_930L , // + + ASIC__MI29, // + + ASIC__ARM_MI30S_A_256L , // + ASIC__ARM_MI30S_A_258L , // + ASIC__ARM_MI30S_D_256L , // + ASIC__ARM_MI30S_D_258L , // + + ASIC__ARM_MI30E_A_64L , // + ASIC__ARM_MI30E_A_66L , // + ASIC__ARM_MI30E_D_64L , // + ASIC__ARM_MI30E_D_66L , // + + ASIC__ARM_MI31 , // + ASIC__ARM_MI32_A , // + ASIC__ARM_MI32_D , // + ASIC__ARM_MI33 , // + ASIC__ARM_MI34 , // + ASIC__ARM_AROM0 , // + + ASIC__ARM_AROM1_A_64L , // + ASIC__ARM_AROM1_A_68L , // + ASIC__ARM_AROM1_D_64L , // + ASIC__ARM_AROM1_D_68L , // + + ASIC__ARM_SUZE02, // + + ASIC__ARM_FSBB_M0_A_416L , // + ASIC__ARM_FSBB_M0_A_420L , // + ASIC__ARM_FSBB_M0_D_416L , // + ASIC__ARM_FSBB_M0_D_420L , // + + ASIC__ARM_FSBB_A0_A_416L , // + ASIC__ARM_FSBB_A0_A_420L , // + ASIC__ARM_FSBB_A0_D_416L , // + ASIC__ARM_FSBB_A0_D_420L , // + + ASIC__ARM_NB // + +} ASIC__TEAsicReadMode; + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__MI26_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__MI26_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__MI26_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__MI26_TRIG_TOT_NB // Total number of triggers + +} ASIC__MI26_TETrigRes; + + + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__ULT1_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__ULT1_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__ULT1_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__ULT1_TRIG_TOT_NB // Total number of triggers + +} ASIC__ULT1_TETrigRes; + +/* ============== */ +/* */ +/* ============== */ + +typedef enum { + + // Position of trigger AS it is registered by acquisition board + // It means : during this frame a trigger pulse has been detected while reading + // - this line + // - at this clock position during this line + + // Remember that this information concern NOT current frame BUT next one because Mimosa 26 + // has a pipeline of one frame + + ASIC__FSBB0_TRIG_RES__SIG_LINE, // Index of Mimosa 26 line read when trigger occurs ( As is => without correction ) + ASIC__FSBB0_TRIG_RES__SIG_CLK, // Index of clock cycle <0..15> ( 16 clock / line ) when trigger occurs ( As is => without correction ) + + ASIC__FSBB0_TRIG_RES__LINE, // Index of Mimosa 26 line read when trigger occurs AFTER correction + ASIC__FSBB0_TRIG_TOT_NB // Total number of triggers + +} ASIC__FSBB0_TETrigRes; +#define ASIC__ENUM_TRIG_RES_NB 4 + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/asic.typ b/include/pxi_daq_lib_v.3.1/asic.typ new file mode 100755 index 0000000..51d7703 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/asic.typ @@ -0,0 +1,51 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.typ +Goal : Types definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_TYP +#define ASIC_TYP + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + SInt8 AsicNo; // Index of Asic <0..N-1> in case more than one is acquired + SInt32 AcqNo; // Index of current acquisition + SInt32 FrameNoInAcq; // Index of frame in acquisition <0..AcqFrameNb-1> + SInt32 FrameNoInRun; // Index of frame in run <0..TotEventNb-1> + + SInt32 HitCnt; // Counter of hits in frame + // Used for monitoring, may be not set, therefore HitCnt = -1 + + + SInt32 ATrigRes[ASIC__ENUM_TRIG_RES_NB]; // Information about trigger, see ASIC__MI26_TETrigRes in asic.def + // Parameters list index is + // ASIC__MI26_TRIG_RES__SIG_LINE + // ASIC__MI26_TRIG_RES__SIG_CLK + // ASIC__MI26_TRIG_RES__LINE + // ASIC__MI26_TRIG_TOT_NB + +} ASIC__TFrameStatus; + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/asic.var b/include/pxi_daq_lib_v.3.1/asic.var new file mode 100755 index 0000000..452512e --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/asic.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\asic\asic.var +Goal : Variables definition of ASIC common constants / strcutures librairy +Prj date : 29/06/2009 +File date : 29/06/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ASIC_VAR +#define ASIC_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN VAR_STATIC SInt8 ASIC__VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/daq_lib.c b/include/pxi_daq_lib_v.3.1/daq_lib.c new file mode 100755 index 0000000..1ba13ec --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/daq_lib.c @@ -0,0 +1,1306 @@ +// Include file for linking the whole daq library to PXIeBoardReader +// It is enough to include this file in PXIeBoardReader.c +// along with +// +// Originally written by Gille Claus +// Few additions: +// 2014/10/15, JB: Conditional directives on LIB CONFIGURATIO +// 2014/10/15, JB: addition of global var: VAcqNo, VFrNo, VPtFrame +// 2015/07/21, JB: cleaning of definitions for DATA_FORMAT_CC1 & CC2 + +/******************************************************************************* +File : X:\prj\unix\read_daq_files\flex_rio_2011\main.c +Goal : Demonstration program for Mi26 Flex RIO DAQ run file loading under Linux +Prj date : 19/02/2011 +File date : 19/02/2011 +Doc date : 19/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + +#pragma GCC diagnostic ignored "-Wwrite-strings" + +/* ======================= */ +/* Standard C header files */ +/* ======================= */ + + +#define _FILE_OFFSET_BITS 64 // Mandatory for large files ( > 2 GB ) handling + // MUST be set before standard C header files + +#include +#include +#include // types +#include +#include +#include + +/* ========================================= */ +/* Conditional compilation for DAQ sources */ +/* ========================================= */ + +#define ROOT_ROOT // Disable code parts which can't compile under ROOT +#define CC_UNIX // Specify operating system + +#define CC_64B // Mandatory for 64bits machine + +#define INT_MAX 128 + +#define APP_NEW_BUFFER_ALLOC + +//********************************** +// LIB CONFIGURATION +//********************************** +// Made in the "pxi_daq_lib_config.h" file +//********************************** +// JB 2014/10/15 +// The following include replaces definitions originally done here +#include "pxi_daq_lib_config.h" + +// test to check if configuration in "pxi_daq_lib_config.h" is well done +// (is one of the APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1 variable defined ?) +#ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + #error in pxi_daq_lib_v.1.2 (daq_lib.h) : bad configuration for DATA_FORMAT_CC1 in file include/pxi_daq_lib_config.h + #endif + #endif +#endif + +#ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + #ifndef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + #error in pxi_daq_lib_v.1.2 (daq_lib.h) : bad configuration for DATA_FORMAT_CC2 in file include/pxi_daq_lib_config.h + #endif +#endif + +/* ========================================= */ +/* DAQ commun files -> types & constants */ +/* ========================================= */ + + +#include "globals.def" +#include "globals_root.def" +#include "types.def" +#include "types.typ" + +/* ================================================================ */ +/* Definition of WIndows types & constant not available under Linux */ +/* ---------------------------------------------------------------- */ +/* Work like this now = allow to compile program, but should be */ +/* done in a better way later !!!!!!!!! */ +/* ================================================================ */ + +#define HANDLE UInt32 +#define DWORD UInt32 +#define WINAPI +#define LPVOID void* +#define INVALID_HANDLE_VALUE 0xFFFFFFFF + + +/* ========================================= */ +/* Macros needed to compile DAQ sources */ +/* ========================================= */ + +#define EXTERN +#define VAR_STATIC +#define VAR_INIT(x) =x +#define VAR_INIT_A2(x,y) ={x,y} +#define VAR_DCL(Extern,Static,Var) Extern Static Var; +#define VAR_DCL_INIT(Extern,Static,Var,Init) Extern Static Var VAR_INIT (Init); +#define VAR_DCL_INIT_A2(Extern,Static,Var,Init0,Init1) Extern Static Var VAR_INIT_A2 (Init0,Init1); + + +/* ========================================= */ +/* Includes DAQ source files */ +/* ========================================= */ + +// Errors messages logging library interface + +#include "errors.def" +#include "errors.typ" +#include "errors.var" + +// General messages logging library interface + +#include "msg.def" +#include "msg.typ" +#include "msg.var" + +// ASIC library interface + +#include "asic.def" +#include "asic.typ" +#include "asic.var" + +// MAPS library interface + +#include "maps.def" +#include "maps.typ" +#include "maps.var" + +// Time library interface + +#include "time.def" +#include "time.typ" +#include "time.var" + + +// Files library interface + +#include "files.def" +#include "files.typ" +#include "files.var" + + +// Math library interface + +#include "math.def" +#include "math.typ" +#include "math.var" + + + +// Mimosa 26 library interface + +#include "mi26_usr.def" +#include "mi26_usr.typ" + +// Ultimate 1 library interface + +#include "ult1_usr.def" +#include "ult1.def" +#include "ult1_usr.typ" +#include "ult1.typ" + +// FSBB 0 library interface + +#include "fsbb0_usr.def" +#include "fsbb0.def" +#include "fsbb0_usr.typ" +#include "fsbb0.typ" + + +// Eudet flex rio DAQ library interface + +#include "eudet_frio.def" +#include "eudet_frio.typ" +#include "eudet_frio.var" +#include "eudet_frio_usr.def" +#include "eudet_frio_usr.typ" +#include "eudet_frio_usr.var" + +// Libraries C source files + +#include "errors.c" +#include "msg.c" +#include "time.c" +#include "math.c" +#include "files.c" +#include "math.c" + + +#include "eudet_frio_fsbb0.c" +#include "eudet_frio_print.c" + + + +/* ========================== */ +/* Application constants */ +/* ========================== */ + +#define APP_ERR_LOG_FILE "./Results/errors.txt" +#define APP_MSG_LOG_FILE "./Results/msg.txt" + +/* ========================== */ +/* Application macros */ +/* ========================== */ + +#define APP__READ_CR { while ( getchar () != '\n' ); }; + + +/* ============================= */ +/* Application context type */ +/* ============================= */ + + +typedef struct { + + // Parameters + + char ParRunDir[GLB_FILE_PATH_SZ]; // Run directory + char ParFileNamePrefix[20]; // Run file prefix, eg : RUN_666 => RUN_ is the prefix + SInt32 ParRunNo; + + SInt32 ParFrameNbPerAcq; // Nb of frame in the acquisition ( get from run file ) + SInt32 ParAcqNo; // Index of acquisition to select ( get from GUI ) + SInt32 ParFrameNo; // Index of frame to get + + // Intermediate variables + + char InfRunParFile[GLB_FILE_PATH_SZ]; // File which contains run parameters *.par + char InfRunDataFile[GLB_FILE_PATH_SZ]; // File which contains run data *.bin + SInt32 InfMaxFrameSz; // Maximal size of one frame = total size for N Mimosa 26 + + // Results + + SInt8 ResRunLoaded; // Flag indicates run state : -1 not loaded, +1 loaded + + EFRIO__TRunCont ResRunCont; // Run context record = run parameter + additional info + // Loaded from file RUN*.par + + EFRIO__TFrameList ResFramesList; // List of frames + +} APP__TContext; + + +/* ============================= */ +/* Application global variables */ +/* ============================= */ + + +// Error messages logging level ( file errors.txt ) , can be +// - ERR_LOG_LVL_NONE +// - ERR_LOG_LVL_ALL +// - ERR_LOG_LVL_WARNINGS_ERRORS +// - ERR_LOG_LVL_ERRORS + + +SInt32 APP_VGErrFileLogLvl = ERR_LOG_LVL_ALL; // Log level for log file +SInt32 APP_VGErrUserLogLvl = ERR_LOG_LVL_ALL; // Log level for user print function => not used + +// General messages logging level ( file msg.txt ), 127 => log all messages + +SInt32 APP_VGMsgFileLogLvl = 127; // Log level for log file +SInt32 APP_VGMsgUserLogLvl = 127; // Log level for user print function => not used + +// Class to read run file +// - APP__VGRunConfFile for run conf file = RUN*.par +// - APP__VGRunDataFile for run data file = RUN*.bin (data) and RUN*.bin.inf (index file) + +FIL__TCBinFile APP__VGRunConfFile ( "./err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); +FIL__TCStreamFile APP__VGRunDataFile ( "./err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); + + +// Application context record +// - Contains all global variables needed => easier to move to an object +// - Should also include errors and messages log variables ( APP_VGErrFileLogLvl, etc ... ), not done now + +APP__TContext APP__VGContext; + +// Addition for PXIeBoardReader, JB 2014/10/15 +SInt32 VAcqNo; // current acquisition number +SInt32 VFrNo; // current frame number +EFRIO__TFrame* VPtFrame; // pointer to the current frame + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 19/02/2011 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FIsLittleEndian () + : +Goal : Test is CPU is little endian, return 1 in this case, 0 otherwise. + : +Inputs : None + : +Ouputs : The function returns + : 0 - CPU is not little endian + : 1 - CPU is little endian + : +Globals : None + : +Remark : One + : +Level : +Date : 19/02/2011 +Doc date : 19/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FIsLittleEndian () { + + SInt32 VTest = 0x11223344; + char* VPt; + + VPt = (char*) &VTest; + + if ( (VPt[0] == 0x11) && (VPt[1] == 0x22) && (VPt[2] == 0x33) && (VPt[3] == 0x44) ) { + return (0); + } + + else { + return (1); + } + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 19/02/2011 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FPrintRecSzChkAlign ( char* Os ) { + + // In the logfile + // Change Antonin Maire, based on an idea by Gilles Claus, Alejandro Perez (16 oct 2014) + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "= Print records size for alignment checking Windows / Unix =" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "= System = %s ", Os )); +#ifdef CC_64B + msg (( MSG_OUT, "= Compiled for 64 bits system" )); +#else + msg (( MSG_OUT, "= Compiled for 32 bits system" )); +#endif + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "sizeof(int*) = %d", sizeof(int*) )); + msg (( MSG_OUT, "sizeof(int) = %d", sizeof(int) )); + msg (( MSG_OUT, "sizeof(unsigned) = %d", sizeof(unsigned) )); + msg (( MSG_OUT, "sizeof(unsigned int) = %d", sizeof(unsigned int) )); + msg (( MSG_OUT, "sizeof(unsigned long int) = %d", sizeof(unsigned long int) )); + msg (( MSG_OUT, "sizeof(unsigned long) = %d", sizeof(unsigned long) )); + msg (( MSG_OUT, "sizeof(unsigned short) = %d", sizeof(unsigned short) )); + msg (( MSG_OUT, "sizeof(long int) = %d", sizeof(long int) )); + msg (( MSG_OUT, "sizeof(size_t) = %d", sizeof(size_t) )); + msg (( MSG_OUT, "sizeof(uint32_t) = %d", sizeof(uint32_t) )); + msg (( MSG_OUT, "sizeof(uint64_t) = %d", sizeof(uint64_t) )); + msg (( MSG_OUT, "sizeof(int64_t) = %d", sizeof(int64_t) )); + + msg (( MSG_OUT, "sizeof(float) = %d", sizeof(float) )); + msg (( MSG_OUT, "sizeof(double) = %d", sizeof(double) )); + msg (( MSG_OUT, "============================================================\n" )); + msg (( MSG_OUT, "" )); + + msg (( MSG_OUT, "FIL__TCStreamFile_TBlocInf = %d ", sizeof (FIL__TCStreamFile_TBlocInf) )); + msg (( MSG_OUT, "FIL__TCStreamFile_TRecInfFile = %d ", sizeof (FIL__TCStreamFile_TRecInfFile) )); + msg (( MSG_OUT, "EFRIO__TRunCont = %d ", sizeof (EFRIO__TRunCont) )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EFRIO__TFrame = %d ", sizeof (EFRIO__TFrame) )); + msg (( MSG_OUT, "EFRIO__TFrameHeader = %d ", sizeof (EFRIO__TFrameHeader) )); + msg (( MSG_OUT, "EFRIO__TFrameData = %d ", sizeof (EFRIO__TFrameData) )); + msg (( MSG_OUT, "EFRIO__TTriggerRec = %d ", sizeof (EFRIO__TTriggerRec) )); + + msg (( MSG_OUT, "" )); + + // On stdout. + // Change Antonin Maire, based on an idea by Gilles Claus, Alejandro Perez (16 oct 2014) + // Check the size in terms of bytes of the different type on the current system. + // Very important to know, in order to read properly the words of the C struct of the written frame. + // Very likely the writing is done under a Windows 32 bits system, + // while the analysis treatment is done under Mac/Linux 64 bits. + printf("============================================================\n" ); + printf("= Print records size for alignment checking Windows / Unix =\n" ); + printf("------------------------------------------------------------\n" ); + printf("= System = %s ", Os ); + printf("-------------------------------\n" ); + printf("sizeof(int*) = %d \n", sizeof(int*) ); + printf("sizeof(int) = %d \n", sizeof(int) ); + printf("sizeof(unsigned) = %d \n", sizeof(unsigned) ); + printf("sizeof(unsigned int) = %d \n", sizeof(unsigned int) ); + printf("sizeof(unsigned long int) = %d \n", sizeof(unsigned long int) ); + printf("sizeof(unsigned long) = %d \n", sizeof(unsigned long) ); + printf("sizeof(unsigned short) = %d \n", sizeof(unsigned short) ); + printf("sizeof(long int) = %d \n", sizeof(long int) ); + printf("sizeof(size_t) = %d \n", sizeof(size_t) ); + printf("sizeof(uint32_t) = %d \n", sizeof(uint32_t) ); + printf("sizeof(uint64_t) = %d \n", sizeof(uint64_t) ); + printf("sizeof(int64_t) = %d \n", sizeof(int64_t) ); + + printf("sizeof(float) = %d \n", sizeof(float) ); + printf("sizeof(double) = %d \n", sizeof(double) ); + printf("============================================================\n" ); + printf(" "); + + printf("FIL__TCStreamFile_TBlocInf = %d \n", sizeof (FIL__TCStreamFile_TBlocInf) ); + printf("FIL__TCStreamFile_TRecInfFile = %d \n", sizeof (FIL__TCStreamFile_TRecInfFile) ); + printf("EFRIO__TRunCont = %d \n", sizeof (EFRIO__TRunCont) ); + printf("------------------------------------------------------------\n" ); + printf("EFRIO__TFrame = %d \n", sizeof (EFRIO__TFrame) ); + printf("EFRIO__TFrameHeader = %d \n", sizeof (EFRIO__TFrameHeader) ); + printf("EFRIO__TFrameData = %d \n", sizeof (EFRIO__TFrameData) ); + printf("EFRIO__TTriggerRec = %d \n", sizeof (EFRIO__TTriggerRec) ); + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) + : +Goal : Load a run file = configure lib for this run but the run is not loaded + : in memory. + : +Inputs : RunDir - Run directory without \ at end + : RunPrefix - Run file prefix, eg : "RUN_" + : RunNo - Run no + : +Ouputs : The function returns + : Number of acquisitions in run file + : -1 if an error occurs + : +Globals : Update APP__VGContext fields + : +Remark : None + : +Level : +Date : 19/02/2011 +Rev : 06/07/2011 + : - Bug fix => VRet is used via a "OR" to cumlate errors and was not set to 0 ! +Doc date : 19/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FLoadRun ( char* RunDir, char* RunPrefix, SInt32 RunNo ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqNb; + SInt32 VRet = 0; + + + // ----------------------------- + // Reset run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = -1; + + // ----------------------------- + // Set run parameters + // ----------------------------- + + sprintf ( VPtCont->ParRunDir , "%s", RunDir ); + sprintf ( VPtCont->ParFileNamePrefix, "%s", RunPrefix ); + + VPtCont->ParRunNo = RunNo; + + // Calculate run par file & run data file names + + sprintf ( VPtCont->InfRunDataFile, "%s/%s%d.bin", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + sprintf ( VPtCont->InfRunParFile , "%s/%s%d.par", VPtCont->ParRunDir, VPtCont->ParFileNamePrefix, VPtCont->ParRunNo ); + + // Print run par file & run data file names for debugging + + msg (( MSG_OUT, "Run data file name = %s", VPtCont->InfRunDataFile )); + msg (( MSG_OUT, "Run par file name = %s", VPtCont->InfRunParFile )); + msg (( MSG_OUT, "sizeof (EFRIO__TRunCont) = %d", sizeof (EFRIO__TRunCont) )); + + // ----------------------------- + // Read run param file + // ----------------------------- + + // Init & conf TCBinFile class to do the job +#ifdef CC_64B + VRet = VRet | APP__VGRunConfFile.PubFConf ( VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, 1628/*sizeof (EFRIO__TRunCont)*/,1628/* sizeof (EFRIO__TRunCont)*/, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunConfFile.PubFOpen (); + VRet = VRet | APP__VGRunConfFile.PubFSeqRead ( &VPtCont->ResRunCont,1628/* sizeof (EFRIO__TRunCont)*/, 1628/*sizeof (EFRIO__TRunCont)*/ ); +#else + VRet = VRet | APP__VGRunConfFile.PubFConf ( VPtCont->InfRunParFile, FIL__TCBinFile_RWB_MODE_READ, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont), 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunConfFile.PubFOpen (); + VRet = VRet | APP__VGRunConfFile.PubFSeqRead ( &VPtCont->ResRunCont, sizeof (EFRIO__TRunCont), sizeof (EFRIO__TRunCont) ); +#endif + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Load run parameter file = %s failed !", VPtCont->InfRunParFile ) ); + + // ----------------------------- + // Open run data file + // ----------------------------- + + // Init & conf TCStreamFile class to do the job + + VRet = VRet | APP__VGRunDataFile.PubFConf ( &APP__VGRunDataFile, 0 /* UseThread */, VPtCont->InfRunDataFile, FIL__TCBinFile_RWB_MODE_READ, 0 /* FixedBlocSzMode */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Max */, EFRIO__MAX_DATA_FILE_BLOC_SZ /* Bloc */, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + VRet = VRet | APP__VGRunDataFile.PubFOpen (); + + // Exit if error + + err_retfail ( VRet, (ERR_OUT,"Open run data file %s failed !", VPtCont->InfRunDataFile ) ); + + + // ----------------------------- + // Set run loaded flag + // ----------------------------- + + VPtCont->ResRunLoaded = 1; + + // ----------------------------- + // Return number of acq in file + // ----------------------------- + + VAcqNb = APP__VGRunDataFile.PubFGetBlocNb (); + + err_retval ( VAcqNb, ( ERR_OUT, "Run %d loaded => Contains %d acquistions", RunNo, VAcqNb ) ); +} + + +#ifdef APP_NEW_BUFFER_ALLOC + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FAllocAcqBuffer (SInt8 MapsName ) + : +Goal : Allocates the buffer for one acqusition. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Read informations from APP__VGContext and set pointer to buffer. + : +Remark : None + : +Level : +Date : 19/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FAllocAcqBuffer (SInt8 MapsName) { + + APP__TContext* VPtCont = &APP__VGContext; + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + + // ---------------------- + // Calculates sizes + // ---------------------- + switch (MapsName){ + case ASIC__MI26:{ + printf("ASIC__MI26\n"); + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + printf("VPtCont->InfMaxFrameSz = %d\n",VPtCont->InfMaxFrameSz); + printf("sizeof ( EFRIO__TFrame ) = %d\n",sizeof ( EFRIO__TFrame )); + printf("VPtCont->ResRunCont.ParMi26Nb = %d\n",VPtCont->ResRunCont.ParMi26Nb); + printf("MI26__ZS_FFRAME_RAW_MAX_W8 = %d\n",MI26__ZS_FFRAME_RAW_MAX_W8); + printf("sizeof ( EFRIO__TTriggerRec ) = %d\n",sizeof ( EFRIO__TTriggerRec )); + printf("EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB = %d\n",EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB); + printf("EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ = %d\n",EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + break; + } + case ASIC__ULT1:{ + printf("ASIC__ULT1\n"); + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + printf("VPtCont->InfMaxFrameSz = %d\n",VPtCont->InfMaxFrameSz); + printf("sizeof ( EFRIO__TFrame ) = %d\n",sizeof ( EFRIO__TFrame )); + printf("VPtCont->ResRunCont.ParMi26Nb = %d\n",VPtCont->ResRunCont.ParMi26Nb); + printf("ULT1__ZS_FFRAME_RAW_MAX_W8 = %d\n",ULT1__ZS_FFRAME_RAW_MAX_W8); + printf("sizeof ( EFRIO__TTriggerRec ) = %d\n",sizeof ( EFRIO__TTriggerRec )); + printf("EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB = %d\n",EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB); + printf("EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ = %d\n",EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + break; + } + case ASIC__FSBB0:{ + printf("ASIC__FSBB0\n"); + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + printf("VPtCont->InfMaxFrameSz = %d\n",VPtCont->InfMaxFrameSz); + printf("sizeof ( EFRIO__TFrame ) = %d\n",sizeof ( EFRIO__TFrame )); + printf("VPtCont->ResRunCont.ParMi26Nb = %d\n",VPtCont->ResRunCont.ParMi26Nb); + printf("ULT1__ZS_FFRAME_RAW_MAX_W8 = %d\n",ULT1__ZS_FFRAME_RAW_MAX_W8); + printf("sizeof ( EFRIO__TTriggerRec ) = %d\n",sizeof ( EFRIO__TTriggerRec )); + printf("EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB = %d\n",EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB); + printf("EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ = %d\n",EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + break; + } + default:{ + printf("DEFAULT\n"); + err_retfail ( -1, (ERR_OUT,"Abort : unknown asic n :%d !", MapsName) ); + + } + } // end switch MapsName + VPtCont->ResRunCont.InfFrameBuffSz = VPtCont->ResRunCont.ParFrameNbPerAcq * VPtCont->InfMaxFrameSz; + + // ---------------------- + // Print results + // ---------------------- + + msg (( MSG_OUT, "==========================================" )); + msg (( MSG_OUT, "InfMaxFrameSz = %d", VPtCont->InfMaxFrameSz )); + msg (( MSG_OUT, "ResRunCont.InfFrameBuffSz = %d", VPtCont->ResRunCont.InfFrameBuffSz )); + msg (( MSG_OUT, "EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB = %d", EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + msg (( MSG_OUT, "EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ = %d", EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ )); + msg (( MSG_OUT, "==========================================" )); + + + // ---------------------- + // Allocate acq buffer + // ---------------------- + + // Free if already allocated + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + } + + // Try to allocate + + VPtCont->ResRunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->ResRunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->ResRunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->ResRunCont.ParFrameNbPerAcq) ); + + err_retok (( ERR_OUT, "" )); +} + + + +#else +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FAllocAcqBuffer ( ) + : +Goal : Allocates the buffer for one acqusition. + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Read informations from APP__VGContext and set pointer to buffer. + : +Remark : None + : +Level : +Date : 19/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FAllocAcqBuffer () { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + + // ---------------------- + // Calculates sizes + // ---------------------- + // 19 11 14 - MS changed MI26__ZS_FFRAME_RAW_MAX_W8 to ULT1__ZS_FFRAME_RAW_MAX_W8 because the size of the allocated buffer was too small for 14 chips + VPtCont->InfMaxFrameSz = ( sizeof ( EFRIO__TFrame ) + ( VPtCont->ResRunCont.ParMi26Nb * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + VPtCont->ResRunCont.InfFrameBuffSz = VPtCont->ResRunCont.ParFrameNbPerAcq * VPtCont->InfMaxFrameSz; + + // ---------------------- + // Print results + // ---------------------- + + msg (( MSG_OUT, "==========================================" )); + msg (( MSG_OUT, "InfMaxFrameSz = %d", VPtCont->InfMaxFrameSz )); + msg (( MSG_OUT, "ResRunCont.InfFrameBuffSz = %d", VPtCont->ResRunCont.InfFrameBuffSz )); + msg (( MSG_OUT, "EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB = %d", EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + msg (( MSG_OUT, "EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ = %d", EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ )); + msg (( MSG_OUT, "==========================================" )); + + + // ---------------------- + // Allocate acq buffer + // ---------------------- + + // Free if already allocated + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + } + + // Try to allocate + + VPtCont->ResRunCont.PtFrame = (EFRIO__TFrame*) malloc ( VPtCont->ResRunCont.InfFrameBuffSz ); + + err_retnull ( VPtCont->ResRunCont.PtFrame, (ERR_OUT,"Allocation of EUDET buffer for %d frames failed !", VPtCont->ResRunCont.ParFrameNbPerAcq) ); + + err_retok (( ERR_OUT, "" )); +} +#endif + + + + + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FFreeAcqBuffer () + : +Goal : Free acquisition buffer + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Read informations from APP__VGContext and set buffer pointer to NULL. + : +Remark : None + : +Level : +Date : 19/02/2011 +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FFreeAcqBuffer ( ) { + + APP__TContext* VPtCont = &APP__VGContext; + + + // ------------------------------- + // Free buffer + // ------------------------------- + + if ( VPtCont->ResRunCont.PtFrame != NULL ) { + free ( VPtCont->ResRunCont.PtFrame ); + VPtCont->ResRunCont.PtFrame = NULL; + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) + : +Goal : Build the frame list for one acquisition + : +Inputs : FrameNb - The number of frames in the acquisition + : PtAcqData - A pointer to source data = all frames of one acquisition + : PtList - A pointer to the frame list to build + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : This function is the copy of EFRIO__FBuildFrameListFromAcq for application + : program demo. + : + : This function is called to build the frame list ( eg : AAcqFrameList field + : of lib context record ) while reading data from run file. + : + : For more information, read comments on EFRIO__TFrameList record in *.typ file + : +Level : +Date : 06/11/2010 +Rev : 19/02/2011 + : - Moved from eudet_fio.c + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 APP__FBuildFrameListFromAcq ( SInt32 FrameNb, void* PtAcqData, EFRIO__TFrameList* PtList ) { + + SInt32 ViFrame; + EFRIO__TFrame* VPtFirstFr; + EFRIO__TFrame* VPtNextFr; + + // -------------- + // Check param + // -------------- + + if ( (FrameNb <= 0) || (FrameNb > EFRIO__MAX_FRAME_NB_PER_ACQ) ) { + err_retfail ( -1, (ERR_OUT,"FrameNB=%d out of range 1..%d", FrameNb, EFRIO__MAX_FRAME_NB_PER_ACQ ) ); + } + + err_retnull ( PtAcqData, (ERR_OUT,"PtAcqData == NULL") ); + err_retnull ( PtList , (ERR_OUT,"PtList == NULL ") ); + + // -------------- + // Reset list + // -------------- + + memset ( PtList,0 , sizeof (EFRIO__TFrameList) ); + + + // -------------- + // Build frames list + // -------------- + + PtList->TotFrameNb = FrameNb; + + // Set frame pointer on first frame + + VPtFirstFr = (EFRIO__TFrame*) PtAcqData; + + // Fill first elt + + PtList->AFrameSz[0] = VPtFirstFr->TotSz; + PtList->AFramePtr[0] = VPtFirstFr; + + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtFirstFr) + VPtFirstFr->TotSz ); + + // Fill following elt + + for ( ViFrame=1; ViFrame < FrameNb; ViFrame++ ) { + PtList->AFrameSz[ViFrame] = VPtNextFr->TotSz; + PtList->AFramePtr[ViFrame] = VPtNextFr; + VPtNextFr = (EFRIO__TFrame*) ( ((UInt8*) VPtNextFr) + VPtNextFr->TotSz ); + } + + err_retok (( ERR_OUT, "" )); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) + : +Goal : Load AcqNo in memory + : +Inputs : AcqNo - No of acquisition to load + : PtFrameNb - Pointer to a variable which will be set with frames nb in AcqNo + : - Set it to NULL if you don't need it + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : Read information from APP__VGContext. + : +Remark : None. + : +Level : +Date : 19/02/2011 +Rev : 07/03/2011 + : - New " spare W32 info " format +Doc date : /2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ + +SInt32 APP__FGotoAcq ( SInt32 AcqNo, SInt32* PtFrameNb ) { + + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VAcqInfFormat; + EFRIO__TFileSpareW32Info VAcqInf; + SInt32 VRet; + + // ------------------------------- + // Exit if there is no run loaded + // ------------------------------- + + err_retfail ( VPtCont->ResRunLoaded, (ERR_OUT,"Abort => NO run loaded" ) ); + + // ----------------------------------- + // Load acquisition in memory + // ----------------------------------- + + // Load from run file + + // Before 07/03/2011 + // VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VFrameNb ); + + VRet = APP__VGRunDataFile.PubFBlocRead ( AcqNo, VPtCont->ResRunCont.PtFrame, VPtCont->ResRunCont.InfFrameBuffSz /* Max dest size */, &VAcqInfFormat, sizeof (VAcqInf) / 4 /* MaxSpareW32InfoNb */, (SInt32*) &VAcqInf ); + + err_retfail ( VRet, (ERR_OUT, "Goto acquisition No %d failed !", AcqNo ) ); + + // Build frame list = array of pointer to access frames one by one + + VRet = APP__FBuildFrameListFromAcq ( VAcqInf.TotFrameNb, VPtCont->ResRunCont.PtFrame, &VPtCont->ResFramesList ); + + err_retfail ( VRet, (ERR_OUT,"Build frames list for acquisition No %d failed !", AcqNo ) ); + + // ----------------------------------- + // Update frame nb parameter + // ----------------------------------- + + if ( PtFrameNb != NULL ) { + *PtFrameNb = VAcqInf.TotFrameNb; + } + + err_retok (( ERR_OUT, "Acquisiton No %d loaded in memory - Contains %d frames", AcqNo, VAcqInf.TotFrameNb )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) + : +Goal : Return a pointer to one frame of the acquisition which is loaded in memory. + : +Inputs : FrameIdInAcq - The no of the frame + : +Ouputs : The function returns + : A valid pointer to the frame + : A NULL pointer if the operation failed + : +Globals : Read information from APP__VGContext. + : +Remark : None + : +Level : +Date : 19/02/2011 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +EFRIO__TFrame* APP__FGetFramePt ( SInt32 FrameIdInAcq ) { + + APP__TContext* VPtCont = &APP__VGContext; + EFRIO__TRunCont* VPtRunCont = &VPtCont->ResRunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->ResFramesList; + + + + if ( (FrameIdInAcq < 0) || (FrameIdInAcq >= VPtRunCont->ParFrameNbPerAcq) ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Bad FrameId=%d out of range [0..%d]", FrameIdInAcq, VPtRunCont->ParFrameNbPerAcq-1 ) ); + } + + if ( VPtFrList->AFramePtr[FrameIdInAcq] == NULL ) { + err_retfailnull ( -1, (ERR_OUT,"No frame=%d in list => Pointer NULL", FrameIdInAcq) ); + } + + return ( VPtFrList->AFramePtr[FrameIdInAcq] ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : int main () +: +Goal : Demonstration function + : - read run + : - move between acquisitions and frames + : - print frames information ( header, data, trigger ) in messages file + : +Inputs : None + : +Ouputs : Always 0 + : +Globals : All + : +Remark : None + : +Level : +Date : 19/02/2011 +Rev : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +int main () +{ + APP__TContext* VPtCont = &APP__VGContext; + SInt32 VMyVar = 10; + SInt32 VRet = 0; // Variable to store error code of functions called + EFRIO__TFrame* VPtFrame; + SInt32 VAcqNo; + SInt32 VFrNo; + + + /* ----------------------------------------- */ + /* Init application errors messages handling */ + /* ----------------------------------------- */ + + ERR_FBegin ( ( APP_VGErrFileLogLvl != 0 ) /* Enable */, APP_ERR_LOG_FILE ); + ERR_FSetFileLogLevel ( APP_VGErrFileLogLvl ); + ERR_FSetUserLogLevel ( APP_VGErrUserLogLvl ); + // ERR_FSetUserErrorFunc ( APP_FUserErrorFunc ); + + /* ------------------------------------------ */ + /* Init application general messages handling */ + /* ------------------------------------------ */ + + MSG_FBegin ( (APP_VGMsgFileLogLvl != 0) /* Enable */, APP_MSG_LOG_FILE ); + MSG_FSetFileLogLevel ( APP_VGMsgFileLogLvl ); + MSG_FSetUserLogLevel ( APP_VGMsgUserLogLvl ); + // MSG_FSetUserMsgFunc ( APP_FUserMsgFunc ); + + + /* ------------------------------------------ */ + /* Print records sise */ + /* ------------------------------------------ */ + + APP__FPrintRecSzChkAlign ( "Linux" ); + + + /* ------------------------------------------ */ + /* print std sizes */ + /* ------------------------------------------ */ + + msg (( MSG_OUT, "sizeof (char) = %d", sizeof (char) )); + msg (( MSG_OUT, "sizeof (SInt8) = %d", sizeof (SInt8) )); + msg (( MSG_OUT, "sizeof (UInt8) = %d", sizeof (UInt8) )); + msg (( MSG_OUT, "sizeof (SInt16) = %d", sizeof (SInt16) )); + msg (( MSG_OUT, "sizeof (UInt16) = %d", sizeof (UInt16) )); + msg (( MSG_OUT, "sizeof (SInt32) = %d", sizeof (SInt32) )); + msg (( MSG_OUT, "sizeof (UInt32) = %d", sizeof (UInt32) )); + msg (( MSG_OUT, "sizeof (UInt64) = %d", sizeof (UInt64) )); + msg (( MSG_OUT, "sizeof (int) = %d", sizeof (int) )); + msg (( MSG_OUT, "sizeof (long) = %d", sizeof (long) )); + msg (( MSG_OUT, "sizeof (float) = %d", sizeof (float) )); + msg (( MSG_OUT, "sizeof (EFRIO__TFrame) = %d", sizeof (EFRIO__TFrame) )); + msg (( MSG_OUT, "sizeof (MI26__TZsFFrameRaw) = %d", sizeof (MI26__TZsFFrameRaw) )); + msg (( MSG_OUT, "sizeof (EFRIO__TFrame*) = %d", sizeof (EFRIO__TFrame*) )); + msg (( MSG_OUT, "sizeof (MI26__TZsFFrameRaw*) = %d", sizeof (MI26__TZsFFrameRaw*) )); + msg (( MSG_OUT, "sizeof (EFRIO__TFrame*) = %d", sizeof (EFRIO__TFrame*) )); + msg (( MSG_OUT, "sizeof (EFRIO__TFrameHeader*) = %d", sizeof (EFRIO__TFrameHeader*) )); + msg (( MSG_OUT, "sizeof (EFRIO__TFrameData*) = %d", sizeof (EFRIO__TFrameData*) )); + msg (( MSG_OUT, "sizeof (EFRIO__TFrameHeader) = %d", sizeof (EFRIO__TFrameHeader) )); + msg (( MSG_OUT, "sizeof (EFRIO__TFrameData) = %d", sizeof (EFRIO__TFrameData) )); + + msg (( MSG_OUT, " EFRIO__MAX_DATA_FILE_BLOC_SZ = %d", EFRIO__MAX_DATA_FILE_BLOC_SZ )); + + + + + //msg (( MSG_OUT, "sizeof (u32) = %d", sizeof (u32) )); + + + + + + + /* ------------------------------------------ */ + /* Reset application context record */ + /* ------------------------------------------ */ + + memset ( VPtCont, 0, sizeof (APP__TContext) ); + + VPtCont->ResRunLoaded = -1; // No run loaded + + + /* ------------------------------------------ */ + /* Test if CPU is little / big endian */ + /* ------------------------------------------ */ + + printf ( "========================================================= \n" ); + printf ( "Little endian = %d \n", APP__FIsLittleEndian () ); + printf ( "========================================================= \n" ); + + /* ------------------------------------------ */ + /* Error logging macros demo */ + /* ------------------------------------------ */ + + err_trace (( ERR_OUT, "This is a trace message - VMyVar=%d", VMyVar )); + err_warning (( ERR_OUT, "This is a warning message - VMyVar=%d", VMyVar )); + err_error (( ERR_OUT, "This is an error message - VMyVar=%d", VMyVar )); + + /* ------------------------------------------ */ + /* Messages logging macros demo */ + /* ------------------------------------------ */ + + msg (( MSG_OUT, "This is a general message - with default LogLvl = 1 - VMyVar=%d", VMyVar )); + msg (( MSG_OUT, "sizeof (EFRIO__TRunCont) = %d", sizeof (EFRIO__TRunCont) )); + + + // -------------------------------------------------------------- + // Printf records size for alignment checking Unix / Windows + // -------------------------------------------------------------- + + // APP__FPrintRecSzChkAlign ( "Linux" ); + + // ----------------------------- + // Load run + // ----------------------------- + + printf ( "Try to load run \n" ); + + + +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/286000" /* RunDir */, "RUN_" /* RunPrefix */, 286000 /* RunNo */ ); +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/288000" /* RunDir */, "RUN_" /* RunPrefix */, 288000 /* RunNo */ ); +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/286001" /* RunDir */, "RUN_" /* RunPrefix */, 286001 /* RunNo */ ); +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/288001" /* RunDir */, "RUN_" /* RunPrefix */, 288001 /* RunNo */ ); + +// VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/mi28_bt_run_file_format_var_length_040214__template_run/288001" /* RunDir */, "RUN_" /* RunPrefix */, 288001 /* RunNo */ ); + //VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/fsbb0_lab_test_runs/35402" /* RunDir */, "RUN_" /* RunPrefix */, 35402 /* RunNo */ ); + //VRet = APP__FLoadRun ( "/Projets/Caract_test/tmp/Desy_salat_11_2014/28011" /* RunDir */, "RUN_" /* RunPrefix */, 28011 /* RunNo */ ); + VRet = APP__FLoadRun ( "/Users/jeromeb/Data/cmos/fsbb/35400" /* RunDir */, "RUN_" /* RunPrefix */, 35400 /* RunNo */ ); + + printf ( "Run loaded => Contains %d acquistions \n", VRet ); + + // -------------------------------------------------------------- + // Printf run context record = run paramters from file RUN*.par + // -------------------------------------------------------------- + + EFRIO__FPrintRunContRec ( &VPtCont->ResRunCont ); + + + // ----------------------------- + // Allocate acquisition buffer + // ----------------------------- +#ifdef APP_NEW_BUFFER_ALLOC + APP__FAllocAcqBuffer (ASIC__ULT1); +#else + APP__FAllocAcqBuffer (); +#endif + + + EFRIO__FPrintRunContRec ( &VPtCont->ResRunCont ); // DBG 07/02/14 + + + // ----------------------------- + // Goto acq & print frame record + // ----------------------------- + + VAcqNo = 0; + + while ( VAcqNo >= 0 ) { + + // Print " menu " + + printf ( "\n" ); + printf ( "-------------------------------------------------------------------------- \n" ); + printf ( "Goto acquisition No, Frame No => print record in messages logfile \n" ); + printf ( "Set Acq No & Frame No to -1 in order to exit \n" ); + printf ( "Acquisition No ? " ); + scanf ( "%d", &VAcqNo ); + APP__READ_CR; + printf ( "Frame No ? " ); + scanf ( "%d", &VFrNo ); + APP__READ_CR; + + // User wants to stop frames scanning + + if ( VAcqNo == -1 ) { + break; + } + + // Load acquisition in memory and get pointer on frame + + VRet = APP__FGotoAcq ( VAcqNo /* AcqNo */, NULL /* PtFrameNb */ ); + + VPtFrame = APP__FGetFramePt ( VFrNo /* FrameIdInAcq */ ); + + // Check if frame is available => Jump to menu in case of error + + if ( (VRet < 0) || (VPtFrame == NULL) ) { + printf ( "Goto acquistion %d frame %d failed ! \n", VAcqNo, VFrNo ); + printf ( "VRet :%d VPtFrame %d \n", VRet, VPtFrame ); + continue; + } + + // Acquistion loaded and frame found + + printf ( "Goto acquisition %d frame %d done => Result in messages logfile \n", VAcqNo, VFrNo ); + + // Print frame record, information type depend on PrintLevel parameter + // You can look at EFRIO__FPrintFrameRec to see how to access to all frame fields + + // PrintLevel - 0 -> Print nothing + // - 1 -> Print AcqId & FrId + // - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + // - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + // - 4 -> Print trigger list + + + EFRIO__FPrintFrameRec( VPtFrame, 3 /* PrintLevel */ ); + + } // End while (1) + + + // ----------------------------- + // Close run class + // ----------------------------- + + APP__VGRunDataFile.PubFClose (); + APP__VGRunConfFile.PubFClose (); + + + // ----------------------------- + // Free acquisition buffer + // ----------------------------- + + APP__FFreeAcqBuffer (); + + return 0; +} + + + +//--------------------------------------------------------------------------- diff --git a/include/pxi_daq_lib_v.3.1/errors.c b/include/pxi_daq_lib_v.3.1/errors.c new file mode 100755 index 0000000..d3aff27 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/errors.c @@ -0,0 +1,360 @@ + +/******************************************************************************* +File : x:\lib\com\errors\errors.c +Goal : Implement errors messages print ( screen ) or log ( file ) functions. + : Each function use " errors macros " to log errors and return code. + : +Remark : The way it works is controlled by 3 globals variables + : ERR_VGLogClosed = 0 ( disable ) / 1 ( enable ) errors messages + : ERR_VGLogPath = '/tmp/errors.txt' = path of error logfile + : ERR_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_C +#define ERRORS_C + + +#ifdef CC_APP_OS9 + +char* strerror ( SInt32 errno ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + sprintf ( VMsgStr, "Not avalibale under OS9" ); + + return (VMsgStr); +} + +#endif + +#ifndef CC_APP_WINDOWS + + +char *_strerror ( char* UsrStr ) { + + static char VMsgStr[ERR_TOT_MSG_SZ+1]; + + #ifdef APP_ROOT + sprintf ( VMsgStr, "%s : No errno str because not supported by ROOT", UsrStr ); + #else + strncpy ( VMsgStr, UsrStr, ERR_USR_MSG_SZ-10 ); + strcat ( VMsgStr, " : " ); + strncat ( VMsgStr, strerror ( errno ), ERR_SYS_MSG_SZ-10 ); + #endif + + + return (VMsgStr); +} + + +#endif + +SInt32 ERR_FEnableLog ( SInt8 Enable ) { + + ERR_VGLogClosed = Enable; + ERR_VGFileLogEnable = Enable; + ERR_VGUserLogEnable = Enable; + + return (0); +} + +SInt32 ERR_EnableLog ( SInt8 Enable ) { + return ( ERR_FEnableLog ( Enable) ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetFileLogEnabled () { + return ( ERR_VGFileLogEnable ); +} + +/* 07/04/2007 */ + +SInt32 ERR_FGetUserLogEnabled () { + return ( ERR_VGUserLogEnable ); +} + + +SInt32 ERR_FSetLogFilePath ( char* LogFilePath ) { + sprintf ( ERR_VGLogPath, "%s", LogFilePath ); + return (0); +} + +char* ERR_FGetLogFilePath () { + return ( ERR_VGLogPath ); +} + +SInt32 ERR_FBegin ( SInt8 Enable, char* FilePath ) { + ERR_FEnableLog ( Enable ); + ERR_FSetLogFilePath ( FilePath ); + + return (0); +} + + +SInt32 ERR_FEnd () { + return (0); +} + + +SInt32 ERR_FStopLog ( SInt8 Stop ) { + ERR_VGFileDontLog = Stop; + return (0); +} + +/* 11/06/2005 */ + +SInt32 ERR_FSetFileLogLevel ( SInt8 LogLevel ) { + ERR_VGFileLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetFileLogLevel () { + return ( ERR_VGFileLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FLogLevel2Str ( SInt8 Lvl ) { + + static char VStr[GLB_CMT_SZ+1]; + + switch ( Lvl ) { + + case ERR_LOG_LVL_NONE : { + sprintf ( VStr, "ERR_LOG_LVL_NONE" ); + break; } + + case ERR_LOG_LVL_ALL : { + sprintf ( VStr, "ERR_LOG_LVL_ALL" ); + break; } + + case ERR_LOG_LVL_WARINGS_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_WARINGS_ERRORS" ); + break; } + + case ERR_LOG_LVL_ERRORS : { + sprintf ( VStr, "ERR_LOG_LVL_ERRORS" ); + break; } + + default : { + sprintf ( VStr, "Unknow error level = %d", Lvl ); + break; } + + } + + return ( VStr ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetFileLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGFileLogLevel ) ); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FSetUserLogLevel ( SInt8 LogLevel ) { + ERR_VGUserLogLevel = LogLevel; + return (0); +} + +/* 07/04/2007 */ + +SInt8 ERR_FGetUserLogLevel () { + return ( ERR_VGUserLogLevel ); +} + +/* 07/04/2007 */ + +char* ERR_FGetUserLogLevelStr () { + + return ( ERR_FLogLevel2Str ( ERR_VGUserLogLevel ) ); +} + + +/* 07/04/2007 */ + +char* ERR_FGetErrLogConfStr () { + + static char VStr[GLB_CMT_SZ+1]; + + sprintf ( VStr, "Error log configuration \n\n - File log enabled = %d \n - File log level = %s \n - File stop log =%d \n - Log file name = %s \n - User log enabled = %d \n - User log level = %s \n - User stop log =%d \n\n", ERR_VGFileLogEnable, ERR_FGetFileLogLevelStr (), ERR_VGFileDontLog, ERR_VGLogPath, ERR_VGUserLogEnable, ERR_FGetUserLogLevelStr (), ERR_VGUserDontLog ); + + return (VStr); +} + + +/* 11/06/2005 */ + +SInt32 ERR_FUserStopLog ( SInt8 Stop ) { + ERR_VGUserDontLog = Stop; + return (0); +} + +/* 10/06/2005 */ + +SInt32 ERR_FSetUserErrorFunc ( ERR_TUserErrorFunc Func ) { + + ERR_VGUserErrorFunc = Func; + + return (0); +} + +SInt32 ERR_FGenError ( char MsgType ) { + + static char VErrMsg[ERR_TOT_MSG_SZ]; + + ERR_VGLastErrMsg = VErrMsg; + + /* ERR_VGLogLevel */ + /* == ERR_LOG_LVL_NONE => No log */ + /* == ERR_LOG_LVL_ALL => Log 'T', 'W', 'E' */ + /* == ERR_LOG_LVL_WARINGS_ERRORS => Log 'W', 'E' */ + /* == ERR_LOG_LVL_ERRORS => Log 'E' */ + + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_NONE) && (ERR_VGUserLogLevel == ERR_LOG_LVL_NONE) ) { + return (0); + } + + sprintf ( VErrMsg, "%s%s \n", ERR_VGStrLocationMsg , ERR_OUT ); + + /* File log handling */ + + while (1) { + + if ( ERR_VGFileLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGFileLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Write error message to file */ + + if ( ERR_VGLogClosed && (ERR_VGLogFile != stdout) && (ERR_VGLogFile != stderr) ) { + ERR_VGLogClosed = 0; + + // + // 29/10/10 => Don't open log file in append mode but overwrite it + // + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + + // 02/06/12 => Enable again open in append mode for strip analysis LIB / DLL debug + // if (( ERR_VGLogFile = fopen ( ERR_VGLogPath, "a" ) ) == NULL ) { ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); } + + + ERR_VGLogFile = fopen ( ERR_VGLogPath, "w" ); + } + + if ( (ERR_VGFileDontLog == 0) && (ERR_VGLogFile != NULL) ) { + fprintf ( ERR_VGLogFile, VErrMsg ); + fflush ( ERR_VGLogFile ); + } + + break; + } + + /* User log handling */ + + while (1) { + + if ( ERR_VGUserLogLevel == ERR_LOG_LVL_NONE ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_ERRORS) && (MsgType != 'E') ) { + break; + } + + if ( (ERR_VGUserLogLevel == ERR_LOG_LVL_WARINGS_ERRORS) && (MsgType == 'T') ) { + break; + } + + /* Call user error function */ + + if ( (ERR_VGUserDontLog == 0) && (ERR_VGUserErrorFunc != NULL) ) { + ERR_VGUserErrorFunc ( MsgType, ERR_VGStrLocationMsg , ERR_OUT, VErrMsg ); + } + + break; + } + + + + + + + return (0); +} + + + +char* ERR_FGetLastErrMsg () { + + return (ERR_VGLastErrMsg); + +} + + + +void FPrint ( void ) +{ + printf ( "%s \n", VGOut ); +} + + +// 01/03/2012 + +SInt32 ERR_FGetEnumSz () { + + SInt32 VSz; + + typedef enum EEnumTest { FIRST, PREC, NEXT, LAST } TEnumTest; + + VSz = sizeof ( TEnumTest ); + + err_trace (( ERR_OUT, "Enum size = %d Bytes", VSz )); + + return (VSz); +} + + + +//========================================================================================= + + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.3.1/errors.def b/include/pxi_daq_lib_v.3.1/errors.def new file mode 100755 index 0000000..40969a2 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/errors.def @@ -0,0 +1,153 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.def +Goal : Macros definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef ERRORS_DEF +#define ERRORS_DEF + +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 + + + +#ifdef CC_APP_WINDOWS + + #ifndef __FUNCTION__ + + #ifdef CC_COMPILER_CPPB_4 + #define __FUNCTION__ "? Not available" + #endif + + #ifdef CC_COMPILER_CPPB_6 + #define __FUNCTION__ __FUNC__ + #endif + + #endif + +#endif +// ms 24 11 2009 changed size from 100 to 256 +#define ERR_USR_MSG_SZ 256 +#define ERR_SYS_MSG_SZ 256 +#define ERR_TOT_MSG_SZ (ERR_USR_MSG_SZ + ERR_SYS_MSG_SZ) + + +/* 07/04/2007 ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ +/* #define ERR_OUT ERR_VGStrUserMsg */ + + +/* 07/04/2007 - Use a local variable in each function because __FUNCTION__ IS NOT handled by CNT ... */ +/* __LINE__ is replaced by 0 because __LINE__ because ... __LINE__ is not handled file by file ... */ + +#ifdef APP_ROOT + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,VFuncName, 0 /* __LINE__ */ );} +#else + #define ERR_LOCATION(MsgType) {sprintf ( ERR_VGStrLocationMsg, "%.4d #%c - %-35s - %-25s - %.4d = ", ERR_VGMsgCnt++, MsgType, __FILE__,__FUNCTION__,__LINE__ );} +#endif + + + +#define ERR_WARNING(Msg) { sprintf Msg; ERR_LOCATION ('W'); ERR_FGenError ('W'); } + +#define ERR_ERROR(Msg) { sprintf Msg; ERR_LOCATION ('E'); ERR_FGenError ('E'); } + +#define ERR_TRACE(Msg) { sprintf Msg; ERR_LOCATION ('T'); ERR_FGenError ('T'); } + + +#define ERR_RET(Code,MsgOk,MsgFail) { \ + if ((Code)<0) ERR_ERROR (MsgFail) \ + else ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_RET_FAIL(Code,MsgFail) { \ + if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (Code); } \ + } + + + +#define ERR_RET_FAIL_NULL(Code,MsgFail) { \ +if ((SInt32)(Code)<0) { ERR_ERROR (MsgFail) return (NULL); } \ + } + + + +#define ERR_RET_NULL(Ptr,MsgFail) { \ +if ((void*)(Ptr)==NULL) { ERR_ERROR (MsgFail) return (-1); } \ + } + + + +#define ERR_RET_OK(MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (0); \ + } + + + +#define ERR_RET_VAL(Code,MsgOk) { \ +ERR_TRACE (MsgOk) \ + return (Code); \ + } + + +#define ERR_TYPE_ID(Id) ( 0x5A00 | Id ) + +#define ERR_TYPE_CHK(Pt,TypeId) { \ +if ( *( (UInt16*) (Pt) ) != ERR_TYPE_ID(TypeId) ) { \ + err_retfail ( -1, (ERR_OUT,"Bad type used Type Id = %x MUST be %x => Check the function call parameters in your source code", *( (UInt8*) (Pt) ) , TypeId ) ); \ + } \ + } + + +#define err_trace(Msg) ERR_TRACE(Msg) +#define err_tracel(Lvl,Msg) ERR_TRACE(Msg) +#define err_warning(Msg) ERR_WARNING(Msg) +#define err_error(Msg) ERR_ERROR(Msg) + +#define err_ret(Code,MsgOk,MsgFail) ERR_RET(Code,MsgOk,MsgFail) +#define err_retok(MsgOk) ERR_RET_OK(MsgOk) +#define err_retval(Code,MsgOk) ERR_RET_VAL(Code,MsgOk) +#define err_retfail(Code,MsgFail) ERR_RET_FAIL(Code,MsgFail) +#define err_retfailnull(Code,MsgFail) ERR_RET_FAIL_NULL(Code,MsgFail) +#define err_retnull(Ptr,MsgFail) ERR_RET_NULL(Ptr,MsgFail) + +#define err_typechk(Pt,TypeId) ERR_TYPE_CHK(Pt,TypeId) + +#define PRINT(msg) { sprintf (VGOut, "%s",msg); FPrint (); } +#define RETURN_ERROR(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (FALSE); } +#define RETURN_ERROR_2(msg1,msg2) { sprintf (VGOut, "%s %s",msg1,msg2); FPrint (); return (FALSE); } + +#define RETURN_ERROR_NULL(msg) { sprintf (VGOut, "%s",msg); FPrint (); return (NULL); } +#define RETURN_OK { return (TRUE);} + + + + +#endif + + +// trace (( ERR_OUT, "", par )); +// retfail ( Code, (ERR_OUT,"MsgFail",par) ); +// retnull ( Code, (ERR_OUT,"MsgFail",par) ); // Pointer == NULL => Ret -1 +// error (( ERR_OUT, "", par )); + + diff --git a/include/pxi_daq_lib_v.3.1/errors.typ b/include/pxi_daq_lib_v.3.1/errors.typ new file mode 100755 index 0000000..983ef79 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/errors.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.typ +Goal : Types definition if error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_TYP +#define ERRORS_TYP + +typedef SInt32 (*ERR_TUserErrorFunc) ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ); + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/errors.var b/include/pxi_daq_lib_v.3.1/errors.var new file mode 100755 index 0000000..a0d8944 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/errors.var @@ -0,0 +1,79 @@ +/******************************************************************************* +File : x:\lib\com\errors\errors.var +Goal : Variables definition of error messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef ERRORS_VAR +#define ERRORS_VAR + + +/* + +EXTERN VAR_STATIC SInt8 ERR_VGLogClosed VAR_INIT (0); // Set to 1 to allow error loggin +EXTERN VAR_STATIC SInt8 ERR_VGFileDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserDontLog VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogEnable VAR_INIT (0); +EXTERN VAR_STATIC SInt8 ERR_VGFileLogLevel VAR_INIT (ERR_LOG_LVL_ALL); +EXTERN VAR_STATIC SInt8 ERR_VGUserLogLevel VAR_INIT (ERR_LOG_LVL_ALL); + +EXTERN VAR_STATIC char ERR_VGLogPath[GLB_FILE_PATH_SZ] VAR_INIT ("/dd/tmp/pc/errors.txt"); +EXTERN VAR_STATIC FILE *ERR_VGLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC FILE *ERR_VGTmpLogFile VAR_INIT (NULL); +EXTERN VAR_STATIC SInt32 ERR_VGMsgCnt VAR_INIT (0); +EXTERN VAR_STATIC ERR_TUserErrorFunc ERR_VGUserErrorFunc VAR_INIT (NULL); +EXTERN VAR_STATIC char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ]; +EXTERN VAR_STATIC char ERR_VGStrUserMsg[ERR_TOT_MSG_SZ]; + +EXTERN VAR_STATIC char VGOut[255]; + +*/ + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserDontLog , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogEnable , 1); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogEnable , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGFileLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGUserLogLevel , ERR_LOG_LVL_ALL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char ERR_VGLogPath[GLB_FILE_PATH_SZ] , "c:\\tmp\\errors.txt"); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, FILE *ERR_VGTmpLogFile , NULL); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt32 ERR_VGMsgCnt , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, ERR_TUserErrorFunc ERR_VGUserErrorFunc , NULL); +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_VGStrLocationMsg[ERR_TOT_MSG_SZ] ); + +/* 07/04/2007 - ERR_VGStrUserMsg identifier replaced by ERR_OUT because of ROOT CINT macros limitations */ + +VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + +VAR_DCL ( EXTERN, VAR_STATIC, char VGOut[255] ); + +// 21/12/2010 + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char *ERR_VGLastErrMsg, "NULL"); + + + +#endif + + + diff --git a/include/pxi_daq_lib_v.3.1/eudet_frio.def b/include/pxi_daq_lib_v.3.1/eudet_frio.def new file mode 100755 index 0000000..848d53f --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/eudet_frio.def @@ -0,0 +1,271 @@ + + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.def +Goal : Macros definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_DEF +#define EUDET_FRIO_DEF + + +/* ======================= */ +/* Conditional compilation */ +/* ======================= */ + +// Enable EFRIO__FRAME_TAGS_ENABLE to add tags at beginning of EFRIO__TFrame record and sub-records +// +// Each sub-record has it own tag, see list of constants at end of file +// +// EFRIO__TFrame -> EFRIO__FRAME_TAG +// EFRIO__TFrameHeader -> EFRIO__FRAME_TAG_HEADER +// EFRIO__TFrameData -> EFRIO__FRAME_TAG_DATA +// EFRIO__TTriggerRec -> EFRIO__FRAME_TAG_TRIG + +#define EFRIO__FRAME_TAGS_ENABLE + + + + +// Enable / Disable demultiplexing of Mimosa 26 data part +// +// It has NO effect if running with a single Mimosa 26 +// +// In case of multiple Mimosa 26 acquisition, Flex RIO provides multiplexed data +// +// W32[0] Mi26 No 0 , W32[0] Mi26 No 1 ... W32[0] Mi26 No 5 +// W32[1] Mi26 No 0 , W32[1] Mi26 No 1 ... W32[1] Mi26 No 5 +// W32[2] Mi26 No 0 , W32[2] Mi26 No 1 ... W32[2] Mi26 No 5 +// W32[3] Mi26 No 0 , W32[3] Mi26 No 1 ... W32[3] Mi26 No 5 +// +// Data are demultiplexed if this directive is enabled +// This processing will cost CPU time -> it may be done on EUDET SW side if needed +// that's why this processing can be disabled + + +// #define NO_MI26 + +#define EFRIO__DEMUX_MI26_DATA_PART +#define EFRIO__DEMUX_ULT1_DATA_PART + + +// Enable / Disable Mi28 FlexRIO trig fw bug work arround + +#define EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + +/* ================= */ +/* Macro */ +/* ================= */ + + +// Test if board Id is valid, if not return (-1) and lof error message + +#define EFRIO__CHK_BOARD_ID(BoardId) { if ( (BoardId < 0) || (BoardId > EFRIO__MAX_BOARDS_NB) ) err_retfail ( -1, (ERR_OUT,"Abort : Bad board Id=%d out of range [0..%d]", BoardId, EFRIO__MAX_BOARDS_NB-1 ) ); } + + +/* ================= */ +/* Constants */ +/* ================= */ + + +// Maximum board number handle by the lib ( define arrays size ) + +#define EFRIO__MAX_BOARDS_NB 2 + +// Maximum ASIC nb handle by the lib ( define arrays size ) + +// #define EFRIO__MAX_ASIC_NB 6 before 21/02/2011 + +#define EFRIO__MAX_ASIC_NB 16 // Set to 16 on 21/02/2011 + +#define EFRIO__MAX_ASIC_NB_FOR_DMA 14 // 25/05/2011 + // 8 Used to calculate DmaHostSz because Labview can't allocate memory for EFRIO__MAX_ASIC_NB = 16 + // 12 before 30/10/14 + +// Maximum number of frames per acquisition ( define arrays size ) +// - One frame = one readout of MAPS +// - One acquisition = N consecutives frames acquired in one call of board readout function + +#define EFRIO__MAX_FRAME_NB_PER_ACQ 1800 + + +// ************************************************************************************************************* +// Data transfer modes +// ************************************************************************************************************* +// Few information about how the Flex RIO board acquired Mimosa 26 +// +// - Flex RIO board can acquire the data of up to 6 Mimosa 26 and deserialize them +// Each Mimosa 26 is seen as an "acquisition channel", because fw is organized / Mimosa 26 +// +// - Now the fw doesn't care about trigger to select which frame to acquire, all frames are stored and the selection +// is done on-line by DAQ sw. Because it will be more flexible to adjust & modify trigger handling by sw rather than +// by fw and for 6 Mimosa 26 it seems possible to do it on execution time point of view. +// Later, this processing will be moved in fw, for AIDA but for EUDET it should work fine by sw. +// +// - The fw counts triggers and store it's own trigger information "Mimosa 26 trigger" ( the Mimosa 26 line read when trigger occurs ) +// This trigger information is written in the zero fields of Mimosa 26 ( by overwritting them ) +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 +// +// - An extra acquisition channel can be enabled to store trigger from TLU ( it has the same size as a Mimosa 26 channel = 2304 W8 ) +// It will store two W32 informations for each trigger +// - The trigger TLU -> See record EFRIO__TTluTrigger +// - The trigger from Flex RIO ( Mimosa 26 line + frame ) -> See record EFRIO__TFlexRioTimeStamp1 +// The extra channel can store up to 288 triggers ( 288 * W32 * 2 = 2304 ) +// +// We have decided to implement 4 data transfert mode, the difference is on trigger handling and only the last one will +// be useful for EUDET => EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// +// * EFRIO__TRF_MODE_IPHC +// +// Keep compatibility with IPHC DAQ -> limited to 3 triggers + data demultiplex which cost CPU time +// +// * EFRIO__TRF_MODE_EUDET__NO_TRG_CHAN, +// +// Send all frames, store 3 first "Mimosa 26 trigger", don't store TLU trigger +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_ALL_FRAMES, +// +// Send all frames, store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// +// * EFRIO__TRF_MODE_EUDET__TRG_CHAN__SEND_FRAMES_WITH_TRIG +// +// Send only frame with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG +// store 3 first "Mimosa 26 trigger", store TLU trigger + Flex RIO trigegr in extra channel = trigger channel +// + + +typedef enum EFRIO__TRF_MODE { + EFRIO__TRF_MODE_IPHC, + EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, + EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, + EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + +} EFRIO__TTrfMode; + + +// We use the two "zero fields" of each 32 bits at the end of Mimosa 26 data stream to store first three triggers +// It's not trigger from TLU but the trigger we used in our first BT with flex RIO = Mimosa 26 line index when trigger occurs +// +// This is the field Mi26Line of the record EFRIO__TFlexRioTimeStamp1 x 16 because unit is Mimosa 26 clock cycle +// Up to 3 triggers can be stored +// Field Zero1 => B31B16 = trigger nb - B15B00 = Trigger No 0 +// Field Zero2 => B31B16 = Trigger No 1 - B15B00 = Trigger No 2 + + +#define EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA 3 // CAN'T be higher than 3 !!!!!!!!!! + + +// The current frame - with trigger - is not enough to build the physics event +// due to internal MAPS logic ( double memory, pipelines etc ... ) following frames must be also used +// => This is the number of frames to read after the one which contains trigger to build physics event + +#define EFRIO__FRAME_NB_TO_READ_AFTER_TRIG 3 // For Mimosa 26 it's 3 + +// Constants to define extra channel size -> Hard coded ( don't use sizeof ( xyz) ) in order to reduce execution time +// The extra channel is a MAPS acquisition channel ( it has he same size ) but used to store trigger information +// It can store up to 288 triggers / MAPS frame +// +// Now 28/10/2010 +// - Each trigger info stored in extra channel contain two fields, each one is a W32, in the following order +// -- EFRIO__TTluTrigger +// -- EFRIO__TFlexRioTimeStamp1 +// --> Total trigger info size is 2 x W32 = 8 bytes +// - The extral channel has the same size of one Mi26 frame = 2304 W8 +// --> Maximum number of trigger info which can be stored = 2304 / 8 = 288 +// --> It means one trigger each two lines of Mimosa 26 readout ... ;-) + +// ------------------------------------------------------------------------------------------------- +// WARNING - 20/05/2011 => Solve bug of 19/05 = memory crash at second run ( first one ok ) ) +// ------------------------------------------------------------------------------------------------- +// - Ultimate allows 928 triggers / frame - Mi26 was limited to 288 +// - The test on max allowed trig number was not done in data processing loop => to save exec time +// but after the loop when padding zero part of frame is processed to find triggers +// - A test was done in this part, but only a warning was generated and waring messages were disabled ... +// ------------------------------------------------------------------------------------------------- +// Now ( 20/05/2011 ) +// - The size of temporary record used to stored trigger info has been increased to fit with Ultimate +// -- EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 288 +// -- EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 576 +// +// - But, in order to KEEP COMPATIBILIY with Mi26, the number of trigger copied to frame record has +// been limited to EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 = 288 +// +// - This may be increased LATER because frame record has variable size ( also for triggers part ) +// BUT now I DON'T KNOW if there are limitations somewhere else in sources ( run readout lib ? ) +// therefore I prefer to keep Mimosa 26 " triggers number limitation " +// ------------------------------------------------------------------------------------------------- + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 928 // Maximum number of trigger info = pair of W32 fields TLU Trig + Felx RIO TS +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 1856 // Maximum number of W32 fields + +#define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 288 + +// #define EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB 288 // Maximum number of trigger info = pair of W32 fields TLU Trig + Felx RIO TS +// #define EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB 576 // Maximum number of W32 fields + + +#define EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ 8 // Size of the trigger info = pair of W32 fields TLU Trig + Flex RIO TS + +#define EFRIO__EXTRA_CHAN__TRIGGER_FIELD_SZ 4 // Size of one W32 field + + +// Maximum number of messages / board -> define array in EFRIO__TBoardStatus + +#define EFRIO__ERROR_MSG_LIST_MAX_NB 100 + + +// Maximum number of triggers in DAQ emulation configurable by GUI +// We can emulate more triggers than EFRIO__MAX_GUI_TRIG_NB but their value is hard coded in emulation function to 0 +// +// Only the first three triggers and the last one ( if EFRIO__MAX_GUI_TRIG_NB = 4 ) are configurable from GUI + +// #define EFRIO__MAX_GUI_TRIG_NB 4 // WARNING => Redined (with same value) in C++ Builder emulation application ! + +#define EFRIO__MAX_EMUL_GUI_TRIG_NB 4 // WARNING => Redefined (with same value) in C++ Builder emulaion application ! + + +// Tags values to be added at beginning of each EFRIO__TFrame sub-record + +#define EFRIO__FRAME_TAG 0x55550000 +#define EFRIO__FRAME_TAG_HEADER 0x00000001 +#define EFRIO__FRAME_TAG_DATA 0x00000002 +#define EFRIO__FRAME_TAG_TRIG 0x00000003 + +// Maximum size of one acquisition store to disk => Used by FIL__TCStreamFile class +// 20/05/2011 => Calculated for Ultimate + +// #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * MI26__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) + + +#ifdef CC_UNIX + #define ULT1__ZS_FFRAME_RAW_MAX_W8 7400 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 + #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +#else + #define EFRIO__MAX_DATA_FILE_BLOC_SZ ( EFRIO__MAX_FRAME_NB_PER_ACQ * ( sizeof ( EFRIO__TFrame ) + ( EFRIO__MAX_ASIC_NB * ULT1__ZS_FFRAME_RAW_MAX_W8 ) + sizeof ( EFRIO__TTriggerRec ) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ) ) +#endif + + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/eudet_frio.typ b/include/pxi_daq_lib_v.3.1/eudet_frio.typ new file mode 100755 index 0000000..ff52bd3 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/eudet_frio.typ @@ -0,0 +1,996 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.typ +Goal : Types definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_TYP +#define EUDET_FRIO_TYP + + + +/* ============================================== */ +/* Board parameters configuration record */ +/* ---------------------------------------------- */ +/* Can be use to build a boards database */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// Remark for EUDET concerning trigger handling +// +// Most of the following trigger options will be useless for EUDET +// The operating mode for EUDET is : +// - The board takes data all the time regardless of trigger state +// - The fw store all triggers from TLU ( up to 288 / Mimsoa 26 frame ) are stored +// - The sw extract frames with trigger + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames after trigger + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + + char AsicName[GLB_CMT_SZ]; // The ASIC read by the board + + SInt32 AsicNb; // The number of ASICs read by the board + + SInt32 ReadoutMode; // The readout mode -> Future use + + SInt8 EmuleChannels; // Copy data of first MAPS in all channels, useful for test & debugging + // because it allows to run with one ASIC only but get data of all + + float DataClkFrequency; // Frequency of clock -> Future use, only useful in case board provide clock + + UInt32 DmaHostSz; // DMA size reserved on host CPU, must be >= size of one acquisition + + SInt32 FrameNbPerAcq; // Consecutives frames number stored during one acquisition + + SInt8 EnableExtraChannel; // Enable one more channel ( default is one channel per ASIC ) + // which can be used to store extra information -> eg : TLU trigger + + SInt32 AcqNbPerTrig; // TO BE CHECKED ! Number of consecutive acquisitions taken upon trigger detection by board + + SInt8 TriggerMode; // Trigger operating mode + + UInt32 TriggerDetectTimeWindow; // Time window during which we count triggers and decide to start acquisition if >= TriggerDetectOccurNb + + UInt32 TriggerDetectOccurNb; // Minimum trigger number during TriggerDetectTimeWindow to decide to start acquisition + + UInt32 TimeStampRes; // Resolution of time stamp + + SInt8 EnableTimeStamping; // Enable time stamping mode + + SInt8 EnableTrigCnt; // Enable trigger counter + + SInt8 TagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ ( HW line indicates that DUT has saved event ) + + UInt32 ReadTluTrigCntEachNTrig; // Period of reading TLU trigger + + +} EFRIO__TBoardConf; + + +/* ============================================== */ +/* Board status record */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 BoardId; // The board identifier = a number associated to each board 0,1 ... + SInt8 BoardPresent; // Board present => 1, otherwise 0 + SInt8 FwLoaded; // Firmware has been loaded in board + SInt8 ConfDone; // The board has been configured by sw + + SInt32 StatusCode; // Current board status code + + char StatusStr[GLB_CMT_SZ]; // Status message associated to StatusCode + + // List of errors and last error + + char* ErrorMsgList[EFRIO__ERROR_MSG_LIST_MAX_NB]; + char LastErrorMsg[GLB_CMT_SZ]; + + // Registers read from board + + UInt32 RegDmaHostSz; // DMA host size in bytes + SInt32 RegFrameNbPerAcq; // Number of frames / acq + SInt8 RegEnableExtraChannel; // Extral channel state = enabled or not + SInt32 RegAcqNbPerTrig; // Consecutive acquisition nb per trigger + + SInt8 RegTriggerMode; // Trigger mode + UInt32 RegTriggerDetectTimeWindow; // Trigger detection window + UInt32 RegTriggerDetectOccurNb; // Number of triggers required during window to start acquisition + + UInt32 RegTimeStampRes; // Resolution of time stamp -> Check with CS if implemented ! + SInt8 RegEnableTimeStamping; // Enable time stamping mode -> Check with CS if implemented ! + + SInt8 RegEnableTrigCnt; // Enable trigger counter -> Check with CS if implemented ! + + SInt8 RegTagEventsStoredByDUT; // Tag in Flex RIO data stream the events stored by DUT DAQ -> Check with CS if implemented ! + UInt32 RegReadTluTrigCntEachNTrig; // Period of reading TLU trigger -> Check with CS if implemented ! + + UInt64 RegTimeStamp; // Time stamp value + UInt32 RegTrigCnt; // Flex RIO rigger value + UInt32 RegTluTrigCnt; // TLU trigger value + +} EFRIO__TBoardStatus; + + + + +/* ============================================== */ +/* TLU trigger record */ +/* ---------------------------------------------- */ +/* Contains TLU trigger -> field TrigCnt */ +/* plus additional information */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 TrigCnt : 16; // Trigger counter read from TLU + UInt32 FrameIdInAcq : 11; // Index of frame in current acquisition during which trigger occurs ( 0 - 2407 ) + UInt32 EventTakenByDut : 1; // For future use : Flag at 1 if DUT has taken the event + UInt32 Reserved : 3; + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TTluTrigger; + + +/* ============================================== */ +/* Flex RIO time stamp 1 record */ +/* ---------------------------------------------- */ +/* This is the Flex RIO trigger, called */ +/* "time stamp" to avoid confusion / TLU */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Mi26Line : 10; // Line of Mi26 read during which trigger occurs + UInt32 Mi26Frame : 21; // Frame of Mi26 ( = frame counter field ) read during which trigger occurs + UInt32 InvalidInfo : 1; // If 1 this field is not valid + + } F; + +} EFRIO__TFlexRioTimeStamp1; + + +/* ============================================== */ +/* Frame header */ +/* ---------------------------------------------- */ +/* Each frame starts with a header which contains */ +/* - DAQ system info */ +/* - Mimosa 26 relevant fields */ +/* ---------------------------------------------- */ +/* Date : 22/10/2010 */ +/* Rev : 23/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_HEADER +#endif + + // New fields AcqStatus & TrigStatus 23/02/2011 + // + SInt32 AcqStatus; // Status of acquistion board for this acquisition + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + // + SInt32 TrigStatus; // No meaning now = reserved for future use + + UInt16 AcqId; // Index of acquisition containing this frame + UInt16 FrameIdInAcq; // Index of frame IN the CURRENT acquisition + + UInt16 MapsName; // MAPS name as a 16 bits code + UInt16 MapsNb; // Total number of MAPS in data + + UInt32 AMapsHeader[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 AMapsFrameCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 AMapsDataLength[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 AMapsTrailer[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + SInt16 TriggerNb; // Total triggers number during this frame + + UInt16 AMapsTrigInfo[EFRIO__MAX_TRIGGER_NB_STORED_IN_FRAME_DATA]; // First 3 "Mi26 trigger info" -> Line of Mi26 read during which trigger occurs + // if more than 3 trigger => look in trigger info block where all trigger are stored + +} EFRIO__TFrameHeader; + + +/* ============================================== */ +/* Frame data */ +/* ---------------------------------------------- */ +/* Each frame has a data part with variable size */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_DATA +#endif + UInt32 TotSz; // Total size of data bloc + UInt32 OneMapsSz; // Size of data of one MAPS + + UInt32 ADataW32[0]; // Beginning of data space + +} EFRIO__TFrameData; + + +/* ============================================== */ +/* Frame triggers list */ +/* ---------------------------------------------- */ +/* Each frame has a triggers list, up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB fields */ +/* which means up to */ +/* EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB */ +/* trigger info */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG_TRIG +#endif + UInt32 TotSz; // Total size of trigger info bloc + UInt16 TrigNb; // Total trigger nb + UInt16 TrigType; // Type of trigger info stored + + UInt32 ATrig[0]; // Beginning off triggers list + +} EFRIO__TTriggerRec; + + +/* ============================================== */ +/* Frame record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Data handling fields ( size etc ) */ +/* - The frame header */ +/* - The frame data part ( variable length ) */ +/* - Followed by the triggers info part */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new field DaqVersion */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + +#ifdef EFRIO__FRAME_TAGS_ENABLE + UInt32 Tag; // EFRIO__FRAME_TAG +#endif + SInt32 DaqVersion; // Version of DAQ - New field 21/02/2011 + SInt32 TotSz; // Total size of this frame + SInt32 TrigRecOffset; // Offset ( in bytes ) from beginning of frame to trigger info part + EFRIO__TFrameHeader Header; // Frame header + EFRIO__TFrameData Data; // Beginning of data part + + // The field EFRIO__TTriggerInfo is not defined here because "Data" has variable length + // the field BegData of Data field is used a pointer to beginning of data part + // The trigger info will be added at the end of this part but position is calculated dynamically + +} EFRIO__TFrame; + + +/* ============================================== */ +/* List of frames currently stored by lib */ +/* ---------------------------------------------- */ +/* This record stores frames list corresponding */ +/* to one acquisition */ +/* */ +/* It can be : */ +/* - frames acquired by DAQ */ +/* - frames loaded from a run file */ +/* ---------------------------------------------- */ +/* Date : 25/10/2010 */ +/* Rev : */ +/* : 24/02/2011 */ +/* : - Add fields AcqStatus, TrigStatus */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +// More information about frames storage in memory +// +// A buffer IS NOT allocated for EACH frame, a single bloc of memory is allocated for all frames of one acquisition. +// This will avoid copy frame by frame before sending them to Ethernet lib or saving them to disk. A single access +// can be done with a pointer on beginning of buffer and data size. +// +// But to process frames it's handly to have an array of pointers, each array item pointing on next frame, +// this is the goal of this list which provides : +// - The total number of frames in list +// - An array of pointers, eg : AFramePtr[2] points on third frame of acquisition +// - An array with the total size ( in bytes ) of each frame +// +// This list is built on-line while DAQ is running, or off-line via EFRIO__FBuildFrameListFromAcq (...) from +// the data of one acquisition stored in a run file. + +typedef struct { + + // New fields AcqStatus & TrigStatus 24/02/2011 + // + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + EFRIO__TFrame* AFramePtr[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of pointers on each frame + UInt32 AFrameSz[EFRIO__MAX_FRAME_NB_PER_ACQ]; // Array of frames size + +} EFRIO__TFrameList; + + +/* ============================================== */ +/* Run configuration record */ +/* ---------------------------------------------- */ +/* Contains : */ +/* - Run parameters -> Par... */ +/* - Informations built from Par etc -> Inf... */ +/* - Acquisition results ( ev cnt etc ) -> Res... */ +/* - Pointers to frames buffers */ +/* ---------------------------------------------- */ +/* This record is filled by EFRIO__FConfRun (...) */ +/* call with run parameters from GUI or Ethernet */ +/* ---------------------------------------------- */ +/* This record can be saved to disk as run config */ +/* file, but it can't be ONLY loaded from file ! */ +/* A call to EFRIO__FConfRun (...) must be done */ +/* because it allocates mem and do other tasks */ +/* -> load record from file */ +/* -> call EFRIO__FConfRun with record fields as */ +/* parameters, it will overwrite itself and all */ +/* " other tasks " will also be done */ +/* ---------------------------------------------- */ +/* Date : 05/08/2010 */ +/* Rev : 21/02/2011 */ +/* : - Add new fields */ +/* : ParDaqVersion, ParMapsName */ +/* : - Change type of ParMi26Nb to S16 */ +/* : */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_... directive at a time ! + #endif + +#endif + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_SINCE_JULY_2012 + +typedef struct { + + SInt32 ParDaqVersion; // Version of DAQ system - New field 21/02/2011 + UInt16 ParMapsName; // Name of MAPS - New field 21/02/2011 + + UInt16 ParMi26Nb; // Mimosa 26 number - Moved from SInt8 to UInt16 on 21/02/2011 + SInt32 ParFrameNbPerAcq; // Frames number per acquisition + + SInt32 ParRunNo; // Run no + SInt32 ParTotEvNb; // Total event number of run + SInt32 ParEvNbPerFile; // Event number per file + char ParDestDir[GLB_FILE_PATH_SZ]; // Run file destination directory + char ParFileNamePrefix[GLB_FILE_PATH_SZ]; // Prefix of run file name, eg : RUN_666 => "RUN" is the prefix + + char ParJtagFileName[GLB_FILE_PATH_SZ]; // JTAG configuration file (*.mcf) -> New field 03/02/2011 + + SInt8 ParDataTransferMode; // Transfer mode see enum EFRIO__TRF_MODE in *.def file + + SInt8 ParTrigMode; // Trigger mode -> Future use + SInt8 ParSaveOnDisk; // Save data on disk + SInt8 ParSendOnEth; // Send data on Ethernet + SInt8 ParSendOnEthPCent; // % of data sent on Ethernet + + SInt8 ParMeasDataRate; // Enable data rate measurement, hard coded in EFRIO__FConfRun (...) + SInt8 ParAcqNbToMeasDataRate; // Acq number used to measure data rate, hard coded in EFRIO__FConfRun (...) + + // SInt32 InfMi26FrameSzFromFlexRio; // Not used now + + SInt32 InfZsFFrameRawBuffSz; // If data ParDataTransferMode = IPHC => Size of acquisition frames buffer + SInt32 InfFrameBuffSz; // If data ParDataTransferMode = EUDET 1,2,3 => Size of acquisition frames buffer + + char InfConfFileName[GLB_FILE_PATH_SZ]; // Run configuration file ( save EFRIO__TRunCont to disk ) name built form ParRunNo, ParDestDir + char InfDataFileName[GLB_FILE_PATH_SZ]; // Run data file name built from ParRunNo, ParFileNamePrefix, ParDestDir + char InfIndexFileName[GLB_FILE_PATH_SZ]; // Run index file name built from ParRunNo, ParFileNamePrefix, ParDestDir - 10/07/2012 + + // Variables to measure data rate -> average over ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasTotalSz; // Total size acquired during ParAcqNbToMeasDataRate acquisitions + SInt32 InfDataRateMeasStartTimeMs; // Start time of measurement + SInt32 InfDataRateMeasStopTimeMs; // Stop time of measurement + SInt32 InfDataRateMeasTotalTimeMs; // Total time of measurement + + SInt8 InfSaveDataOnDiskRunning; // Add on 15/02/2011 + // Because for run ctrl via Eth, stop run cmd will be seen on DLL + // side before Labview side, which may cause trouble because saving + // function are called on both sides => a lock must be implemented + // + // Indicates that data are saved on disk + // Set to 1 by EFRIO__FStartSavingOnFile () call + // Set to 0 by EFRIO__FStopSavingOnFile () call + // Tested by EFRIO__FSaveAcqOnFile () => exit if at 0 + + SInt32 CmdRun; // Add on 21/12/2010 for interface / EUDET DAQ + // Field used to control Labview application "acquisition engine" from DLL + // Set to 1 to take data, to 0 to stop taking data by EFRIO_FSetCmdRun ( 0/1 ) + // State tested from Labview by a call to EFRIO_FGetCmdRun () + + SInt32 ResAcqFunctRetCode; // Return code of Acq function + // - < 0 => Acquisition error + // - = 0 => No data available + // > 0 = Total acquisition size ( in bytes ) + // = size of data bloc after data processing ( for example : extraction of frames with trigger ) + // This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + + + SInt32 ResAcqCnt; // Acquisitions counter + SInt32 ResFrameCnt; // Frames counter + SInt32 ResEventCnt; // Events counter -> By default events counter = frames counter + // but they may be different as more than one frame is needed to build a physics event + + float ResDataRateMBytesPerSec; + + + // Buffer for frames + // Only one of the two is allocated depending on ParDataTransferMode = IPHC / EUDET + + MI26__TZsFFrameRaw* PtZsFFrameRaw; // If data ParDataTransferMode = IPHC => Acquisition frames buffer + EFRIO__TFrame* PtFrame; // If data ParDataTransferMode = EUDET 1,2,3 => Acquisition frames buffer + +} EFRIO__TRunCont; + + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_BEFORE_JULY_2012 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC2_... directive at a time ! + #endif + +#endif + + + + + + +/* ============================================== */ +/* Acquisition emulation record */ +/* ---------------------------------------------- */ +/* This record contains context of DAQ emulator */ +/* application, it means : */ +/* - Parameters -> Par... */ +/* - Information, calculated from Par -> Inf... */ +/* - Results -> Res... */ +/* ---------------------------------------------- */ +/* All emulation functions are implemented in the */ +/* lib, therefore application task is only GUI. */ +/* That's why emulation context is defined here */ +/* ---------------------------------------------- */ +/* All run param for emulation are taken from */ +/* run config record -> EFRIO__TRunCont */ +/* ---------------------------------------------- */ +/* Date : 30/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqCycleMs; // Delai between two acquisitions + + SInt32 ParEmuleDRamReadMs; // Delai added to PC DRAM access to emulate Flex RIO DRAM access time + + SInt32 ParEmuleFunctNo; // Select emulation function to call -> Future use = not implemented now + + SInt8 ParRandomDataSz; // Enables random generation of data size per Mimosa 26 + // By default data size is fixed in emulation function + // Used to check if variabl length records are properly handled + + SInt8 ParSetMaxDataSzOnOneMaps; // Set maximum possible data sze on first Mi26, overwrite value set by emulation + // function, but next Mi26 keep the data size value from emulation function + // Used to check if DAQ loose frames while Mi26 provides full frames + + + UInt32 ParAHeader[EFRIO__MAX_ASIC_NB]; // Emulated header of each Mi26 + + UInt32 ParATrailer[EFRIO__MAX_ASIC_NB]; // Emulated trailer of each Mi26 + + SInt32 ParTrigNbPerFrame; // Number of trigger per frame, set the part trigger nb (B31B16) of Mi26 Zero1 field + + // In data transfer modes EUDET 2 & 3 a more complex trigger emulation is done + // We don't emulate ParTrigNbPerFrame on each frame but on N consecutives frames + // each M frames + // + SInt32 ParTrigOnOneFrameOverN; // Start emulate ParTrigNbPerFrame on one frame over M = ParTrigOnOneFrameOverN + SInt32 ParTrigOnNConsecutiveFrames; // Emulates on N consecutive frames = ParTrigOnNConsecutiveFrames + + // TLU trigger & Flex RIO trigger emulation + // Up to 288 couples TLU & Flex RIO triggers can be emulated but only EFRIO__MAX_EMUL_GUI_TRIG_NB + // are configurabbles from GUI, now EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + // - First three are configurable from GUI + // - The last one is configurable from GUI + // - Others are configured in emulation function and set to 0 + // + SInt32 ParATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated TLU trigger + SInt32 ParATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Emulated Flex RIO trigger, called "Time stamp 1" + + // DRAM info to emulate Flex RIO readout ( we need a PC RAM bloc of same size as the board one ) + // + SInt32 InfDRamSzMb; // DRAM size in MB + SInt32 InfDRamSz; // DRAM size in bytes + UInt32* InfDRamPtr; // DRAM pointer + + SInt8 InfExtraChan; // Extra channel status ( enabled or not ) depends on data transfer mode ( -> run config ) + + char InfEmuleFuncCmt[GLB_CMT_SZ]; // A comment set by emulation function selected by ParEmuleFunctNo + // -> Future use = not implemented now + + // DAQ emulation results + // + SInt32 ResAcqCnt; // Acquisition counter + SInt32 ResEvCnt; // Events counter + // + SInt32 ResAcqFunctRetCode; // Error code returned by acquisition function + +} EFRIO__TAcqEmul; + + +/* ============================================== */ +/* Frames check record */ +/* ---------------------------------------------- */ +/* This is context of frames check functions */ +/* - EFRIO__MI26_FChkAcqIphcMode (...) */ +/* - EFRIO__MI26_FChkAcqEudetMode (...) */ +/* */ +/* They check frames integrity, can be used in */ +/* normal DAQ mode or emulation */ +/* ---------------------------------------------- */ +/* Date : 31/10/2010 */ +/* Doc date : 07/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParAcqNo; // Acquisition index + + SInt32 ParFrNo; // Frame index + + SInt8 ParChkMode; // Check mode -> Allows to define a level of test + + SInt8 ParChkVerbose; // Verbose mode or not + + SInt8 ParFrPrintLevel; // Define the frame information printed in log file + // 0 -> No print + // 1 -> Print general info ( AcqId, FrameId, TrigNb ... ) + Mi26 header, frame cnt, trailer + // 2 -> Print also triggers list + + SInt8 InfMi26Nb; // Mi26 number runnig in the system + + // Values provided by DAQ to check + // They are compared to the " same fields " of EFRIO_TAcqEmul + // + UInt32 ResAHeader[EFRIO__MAX_ASIC_NB]; // Mi26 header + UInt32 ResATrailer[EFRIO__MAX_ASIC_NB]; // Mi26 trailer + UInt32 ResAFrameCnt[EFRIO__MAX_ASIC_NB]; // Mi26 frames counter + UInt32 ResADataLenght[EFRIO__MAX_ASIC_NB]; // Mi26 data part length ( in W8 not in W16 as in DataLength fields of Mi26 data stream ) + // + SInt32 ResTrigNb; // Trigger info ( couple TLU & Flex RIO trigger ) number UNDER GUI control => limited to EFRIO__MAX_EMUL_GUI_TRIG_NB = 4 + SInt32 ResATrig[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // TLU triggers list + SInt32 ResATS[EFRIO__MAX_EMUL_GUI_TRIG_NB]; // Flex RIO trigegrs list + + SInt32 ResErrCnt; // Total errors counter => Information provide by DAQ <> value set in EFRIO_TAcqEmul + + +} EFRIO__TFrCheck; + +/* ============================================== */ +/* Board check record */ +/* ---------------------------------------------- */ +/* This is context of board check Vi */ +/* The board test is done by a Vi on Labview side */ +/* this record pass the parameters to the Vi */ +/* */ +/* Parameters are set via call to functions */ +/* EFRIO__FSetBoardChk... */ +/* */ +/* Parameters are read via call to functions */ +/* EFRIO__FGetBoardChk... */ +/* Theses functions are encapsulated in Vi */ +/* ---------------------------------------------- */ +/* */ +/* The test results are written in board status */ +/* record ABoardsStatus [BoardId] */ +/* */ +/* Test results are set or read functions */ +/* EFRIO__FSetBoardStatus... */ +/* EFRIO__FGetBoardStatus... */ +/* ---------------------------------------------- */ +/* Date : 22/12/2010 */ +/* Doc date : 22/12/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 ParBoardId; // Board to test + + SInt8 ParDoTheTest; // Set to 1 to request the test + // Reset once test has been started + + SInt32 ParTestId; // Identifier to select different tests + + SInt8 ResTestDone; // Set to 1 when test is finished + + SInt32 ResTestResult; // Test result + // < 0 => Test has failed + // = 0 => Test OK + +} EFRIO__TBoardCheck; + + +/* ============================================== */ +/* Spare W32 bloc of index file */ +/* ---------------------------------------------- */ +/* This record contains spare info for index file */ +/* ---------------------------------------------- */ +/* Date : 24/02/2011 */ +/* Doc date : 24/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 AcqStatus; // Status of acquistion board for this acquisition + + // 0 = OK + // > 0 = frame nb lost + // < 0 = hardware error + + SInt32 TrigStatus; // No meaning now = reserved for future use + + + SInt32 TotFrameNb; // Total frames nb in list + + SInt32 DiskSectorSz; // Size of disk sector + +} EFRIO__TFileSpareW32Info; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains monitoring via Eth conf */ +/* ---------------------------------------------- */ +/* Date : 15/02/2011 */ +/* Doc date : 15/02/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + SInt32 InfFrameNbToSend; // Frame nb to send on Eth = " Frame nb per acq * % monitoring " + SInt32 InfSzToSend; // Size corresponding to InfFrameNbToSend + +} EFRIO__TMon; + + +/* ============================================== */ +/* Monitoring record */ +/* ---------------------------------------------- */ +/* This record contains tests on data conf / res */ +/* ---------------------------------------------- */ +/* Date : 29/04/2011 */ +/* Doc date : 29/04/2011 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + +typedef struct { + + // Control + + SInt8 ParTestType; // + SInt8 ParModeEnable; // Enable test + SInt8 ParResetCnt; // Reset all error counters + SInt8 ParPrintLvl; // Errors print level + SInt8 ParMapsNb; // Nb of MAPS configured in JTAG + SInt8 ParMapsNbToTest; // Number of MAPS on which the test is performed + // MAPS no 0 to ParMapsNbToTest - 1 + + // Reference / expected values + + UInt32 ParAMapsHeaderRef[EFRIO__MAX_ASIC_NB]; // Mimosa 26/28 header field + UInt32 ParAMapsTrailerRef[EFRIO__MAX_ASIC_NB]; // Mimosa 26/28 trailer field + + ULT1__TRegDiscriW32 ParUlt1ALinePat0[EFRIO__MAX_ASIC_NB]; // Mimosa 28 line patten + ULT1__TRegDiscriW32 ParUlt1ALinePat1[EFRIO__MAX_ASIC_NB]; + + SInt16 ParAMatPatternLineNb [EFRIO__MAX_ASIC_NB]; // Mimosa 26/28 Max line number in emulated matrix + + + UInt32 InfMapsFrameCntRef; // Mimosa 26 frame counter field + + ULT1__TMatDiscriBit InfUlt1AMatBitFromJtag[EFRIO__MAX_ASIC_NB]; + ULT1__TMatDiscriW32 InfUlt1TmpMatW32; + + // Current values get from DAQ + + UInt32 ResAMapsHeaderVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + UInt32 ResAMapsFrameCntVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + UInt16 ResAMapsDataLengthVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + UInt32 ResAMapsTrailerVal[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + + ULT1__TZsFFrame ResUlt1AZsFFrame[EFRIO__MAX_ASIC_NB]; + + ULT1__TMatDiscriBit ResUlt1AMatBitFromDaq[EFRIO__MAX_ASIC_NB]; // Mimosa 28 matrix from DAQ + + + // Errors counters + + SInt32 ResAMapsErrCnt[EFRIO__MAX_ASIC_NB]; // Err counter / MAPS = sum errors on header, fc, trailer + + SInt32 ResAMapsHeaderErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 header field + SInt32 ResAMapsFrameCntErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 frame counter field + SInt32 ResAMapsDataLengthErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 data length in BYTES -> It's final result NOT the DataLength FIELD from data stream + SInt32 ResAMapsTrailerErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 trailer field + SInt32 ResAMapsMatrixErrCnt[EFRIO__MAX_ASIC_NB]; // Mimosa 26 matrix + + + SInt32 ResTotErrCnt; // Total errors counter = sum of N MAPS + SInt32 ResFrameNbWithErr; // Number of frames with at least one error + SInt8 ResErrOnCurrentAcq; // Indicates errors on current acq - 25/04/2013 + // 0 => None + // 1 => Errors + + SInt32 ResAMapsMatrixHitCnt[EFRIO__MAX_ASIC_NB]; // 06/02/14 - Mimosa 28 hits cnt + + +} EFRIO__TTestOnDataCont; + + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : 07/08/2010 */ +/* Doc date : 06/11/2010 */ +/* Author : Gilles CLAUS */ +/* E-mail : gilles.claus@ires.in2p3.fr */ +/* Labo : DRS - IPHC */ +/* ============================================== */ + + +typedef struct { + +#ifndef EFRIO__V10 + + // Add on 11/05/2011 + // Lib version, eg : 1.2 + SInt8 VersionMajor; // Lib version major : version 1.2 => 1 + SInt8 VersionMinor; // Lib version minor : version 1.2 => 2 + + // Add on 11/05/2011 + char VersionCmt[GLB_CMT_SZ]; // Commetn about lib version = content of lib + +#endif + + SInt8 InfInitDone; // Lib iit done or not + + EFRIO__TBoardConf ABoardsConf[EFRIO__MAX_BOARDS_NB]; // Acquisition boards config + EFRIO__TBoardStatus ABoardsStatus[EFRIO__MAX_BOARDS_NB]; // Acquisition boards status + + EFRIO__TBoardCheck BoardChk; // Reserved for future implementation + // Parameters record to check + // - Boards + // - Mimosa 26 Clk & Sync signals + + EFRIO__TAcqEmul AcqEmul; // DAQ emulation context + EFRIO__TFrCheck FrCheck; // Frames check functions context + + EFRIO__TRunCont RunCont; // Run context = parameters, memory allocated, results + + EFRIO__TMon MonCont; // Monitoring context + + EFRIO__TTestOnDataCont TestOnDataCont; // Test on data context + + EFRIO__TFrameList AAcqFrameList[1]; // Frame list of acquistion - Can be extended to more than one acq if needed + + // List of frame Id to read ( Eudet3Mode => Trigger + 2 following frames ) / acquistion - Can be extended to more than one acq if needed + + SInt16 AAAcqFrameWithTrigList[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + // Used to solve FW trigger bug ( Ultimate => extra channel info shifted by two frames ) + + // For each frame Id stored in AAAcqFrameWithTrigList + // we store in the trigger nb in FwTrigBugAAAcqFrameWithTrigTrigNb + + SInt16 FwTrigBugAAAcqFrameWithTrigTrigNb[1][EFRIO__MAX_FRAME_NB_PER_ACQ]; + + // Is set to 1 if this frame contains the trigger list of frame No - 2 + + SInt16 FwTrigBugAAAcqFrameWithTrigIsTrigListFrMinus2[1][EFRIO__MAX_FRAME_NB_PER_ACQ + 10]; + + + EFRIO__TTriggerRec* PtTmpTrigRec; // Temporary triggers record used for internal processing + +} EFRIO__TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/eudet_frio.var b/include/pxi_daq_lib_v.3.1/eudet_frio.var new file mode 100755 index 0000000..035ac58 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/eudet_frio.var @@ -0,0 +1,43 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.var +Goal : Variables definition of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_VAR +#define EUDET_FRIO_VAR + + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC EFRIO__TContext EFRIO__VGContext; + +EXTERN VAR_STATIC FIL__TCStreamFile EFRIO__VGRunDataFile ( "x:\\log\\err_TCStreamFile.txt", 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS, 512 /* DiskBlocSz */ ); +EXTERN VAR_STATIC FIL__TCBinFile EFRIO__VGRunConfFile ( "x:\\log\\err_TCBinFile.txt" , 1 /* EnableErrLog */, ERR_LOG_LVL_ERRORS ); + +#ifdef EFRIO__INCLUDE_JTAG + EXTERN VAR_STATIC SInt8 EFRIO__VGJtagChip; // 0 => Mi26, 1 => Ultimate + EXTERN VAR_STATIC TCOMIMI26MasterConf EFRIO_VGJtagMi26; + EXTERN VAR_STATIC TCOMIMI28COM EFRIO_VGJtagUlt1; + EXTERN VAR_STATIC TCOMIFSBBM0COM EFRIO_VGJtagFsbb0; + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.3.1/eudet_frio_fsbb0.c b/include/pxi_daq_lib_v.3.1/eudet_frio_fsbb0.c new file mode 100755 index 0000000..89fd1f4 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/eudet_frio_fsbb0.c @@ -0,0 +1,2883 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_fsbb0.c +Goal : Fsbb0 functions of flex rio board library for EUDET +Prj date : 01/10/2014 +File date : 01/10/2014 +Doc date : +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_FSBB0_C +#define EUDET_FRIO_FSBB0_C + + +// #define EFRIO__ULT1_BUG_FW_TRIG_DELAYED_BY_TWO_FRAMES + + +/* +#define ERR_LOG_LVL_NONE 0 +#define ERR_LOG_LVL_ALL 1 +#define ERR_LOG_LVL_WARINGS_ERRORS 2 +#define ERR_LOG_LVL_WARNINGS_ERRORS 2 +#define ERR_LOG_LVL_ERRORS 3 +*/ + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Class : +Prototype : +Goal : +Inputs : +Ouputs : +Remark : +Date : 02/02/2009 +Doc date : //2004 +Author : Gilles CLAUS - Labo IPHC - DRS - gilles.claus@ires.in2p3.fr */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSBB0_FMatDiscriPrintHit ( char* CmtStrTitle, SInt8 CmtSInt8MapsId, FSBB0__TMatDiscriBit* PtDest ) { + + SInt32 ViLine; + SInt32 ViCol; + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + msg (( MSG_OUT, "***************************************************************************" )); + msg (( MSG_OUT, "* FSBB M [%d] %s : Coordinates pixels with hit *", CmtSInt8MapsId, CmtStrTitle )); + msg (( MSG_OUT, "***************************************************************************" )); + + // Scan matrix => Print coordinates if hit + + for ( ViLine=0; ViLine < FSBB0__MAT_DISCRI_USEFUL_LINES_NB; ViLine++ ) { + + for ( ViCol=0; ViCol < FSBB0__REG_DISCRI_BIT_SZ; ViCol++ ) { + + if ( PtDest->AALineCol[ViLine][ViCol] == 1 ) { + msg (( MSG_OUT, "Hit => Line [%.4d] - Col [%.4d]", ViLine, ViCol )); + } + + } + + } + + msg (( MSG_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : SInt8 SUZE02_FHammingDecoder8_4(UInt8 CodedIn) + +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 10/07/2013 +Doc date : +Rev : + Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + + UInt8 EFRIO__FSBB0_FHammingDecoder8_4(UInt8 CodedIn) + { + UInt8 VResult; + + switch (CodedIn){ + case 0:{ + VResult = 0; + break; + } + case 0x87:{ + VResult = 1; + break; + } + case 0x99:{ + VResult = 2; + break; + } + case 0x1e:{ + VResult = 3; + break; + } + case 0xaa:{ + VResult = 4; + break; + } + case 0x2d:{ + VResult = 5; + break; + } + case 0x33:{ + VResult = 6; + break; + } + case 0xb4:{ + VResult = 7; + break; + } + case 0x4b:{ + VResult = 8; + break; + } + case 0xcc:{ + VResult = 9; + break; + } + case 0xd2:{ + VResult = 0xa; + break; + } + case 0x55:{ + VResult = 0xb; + break; + } + case 0xe1:{ + VResult = 0xc; + break; + } + case 0x66:{ + VResult = 0xd; + break; + } + case 0x78:{ + VResult = 0xe; + break; + } + case 0xff:{ + VResult = 0xf; + break; + } + + }/* end switch CodedIn */ + + return (VResult); + +} /* End FSBB0_FHammingDecoder8_4 */ + + + + + + + +/******************************************************************************* +Prototype :SInt32 EFRIO__FSBB0_FConvEfrioFrameToZsFFrame ( EFRIO__TFrame* Src, SInt8 MapsId, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : PrintLvl = 5 => Print states +Level : +Date : 14/10/2014 +Doc date : 14/10/2014 +Rev : copy of APP__FConvEfrioFrameToZsFFrame from read_flex_rio_daq_file_v22_gc + : +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 EFRIO__FSBB0_FConvEfrioFrameToZsFFrame ( EFRIO__TFrame* Src, SInt8 MapsId, FSBB0__TZsFFrame* Dest, SInt8 PrintLvl ) { + + SInt32 VRetW30Length; + SInt32 ViData; + UInt16 VDataW30Length; + UInt16 VLastW30; + SInt16 ViSrcW30; + SInt32 VOneMapsSzW8; + SInt32 VOneMapsSzW32; + UInt32* VPtDataU32; + + FSBB0__TStatesLine VStatesLine; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbG0; + SInt8 VStatesNbG1; + SInt16 VPrevLine; + SInt8 VG0Overflow; + SInt8 VG1Overflow; + + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + // Get useful data length + + VOneMapsSzW8 = Src->Data.OneMapsSz; + VOneMapsSzW32 = VOneMapsSzW8 / 4; + + VDataW30Length = Src->Header.AMapsDataLength[MapsId]; + VRetW30Length = Src->Header.AMapsDataLength[MapsId]; + + msg (( MSG_OUT, "Conv : VOneMapsSzW32=%d - TotSzW32=%d", VOneMapsSzW32, Src->Data.TotSz / 4 )); + + msg (( MSG_OUT, "Conv : VDataW30Length=%d", VDataW30Length )); + + + if ( (PrintLvl == 5) || (PrintLvl == 6) || (PrintLvl == 7)/*||(PrintLvl == 8)*/ ) { + msg (( MSG_OUT, "TOTAL frame length : %d W30", VDataW30Length )); + msg (( MSG_OUT, "" )); + } + + // Add a check of data length, if > FSBB0__ZS_FFRAME_RAW_MAX_W30, force 0 and continue processing ( no exit on error ) + + if ( VDataW30Length > FSBB0__ZS_FFRAME_RAW_MAX_W32 ) { + err_error (( ERR_OUT, "Bad data length get from FSBB0 = %d W30 => Force 0 W30", VDataW30Length )); + VDataW30Length = 0; + Src->Data.OneMapsSz = 0; + VRetW30Length = -1; + } + + // Copy information fields + + Dest->SStatus.AsicNo = MapsId; // Index of Asic <0..N-1> in case more than one is acquired + Dest->SStatus.AcqNo = Src->Header.AcqId; // Index of current acquisition + Dest->SStatus.FrameNoInAcq = Src->Header.FrameIdInAcq; // Index of frame in acquisition <0..AcqFrameNb-1> + Dest->SStatus.FrameNoInRun = -1; // Index of frame in run <0..TotEventNb-1> + + Dest->SStatus.HitCnt = 0; // Counter of hits in frame + // Used for monitoring, may be not set, therefore HitCnt = -1 + + Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK] = Src->Header.AMapsTrigInfo[0]; // Trigger in [Fsbb bits] + Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__LINE] = Src->Header.AMapsTrigInfo[0] / 32; // Trigger in [Fsbb line] + Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE] = Src->Header.AMapsTrigInfo[0] % 32; // Trigger offset in Fsbb line in [Fsbb line] + + // ------------- + + Dest->Header.F.H0 = Src->Header.AMapsHeader[MapsId] & 0x0000FFFF; + Dest->Header.F.H1 = (Src->Header.AMapsHeader[MapsId] & 0xFFFF0000) >> 16; + + Dest->FrameCnt = Src->Header.AMapsFrameCnt[MapsId]; + + Dest->DataLength = Src->Header.AMapsDataLength[MapsId]; + + Dest->Trailer.F.T0 = Src->Header.AMapsTrailer[MapsId] & 0x0000FFFF; + Dest->Trailer.F.T1 = (Src->Header.AMapsTrailer[MapsId] & 0xFFFF0000) >> 16; + + + Dest->TrigSignalClk = Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_CLK]; + Dest->TrigLine = Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__LINE]; + Dest->TrigSignalLine = Dest->SStatus.ATrigRes[ASIC__MI26_TRIG_RES__SIG_LINE]; + + // Process frame + + ViSrcW30 = 0; + ViStatesLine = 0; + VPrevLine = -1; + + if ( PrintLvl == 4 ) { + msg (( MSG_OUT, "Frame data length = %d [W30]", VDataW30Length )); + msg (( MSG_OUT, "" )); + } + + VPtDataU32 = &(Src->Data.ADataW32[MapsId * VOneMapsSzW32]); + + // msg (( MSG_OUT, "Msg" )); + + if ( VDataW30Length != 0 ) { + + while ( ViSrcW30 < VDataW30Length ) { // Odd W30 nb handling => Don't process last W30 + + // Copy StatesLine field + + VStatesLine.W32 = VPtDataU32[ViSrcW30]; + Dest->AStatesRec[ViStatesLine].StatesLine = VStatesLine; + VG0Overflow = 0; + VG1Overflow = 0; + + VStatesNbG0 = EFRIO__FSBB0_FHammingDecoder8_4(VStatesLine.F.HitNbG0); + VStatesNbG1 = EFRIO__FSBB0_FHammingDecoder8_4(VStatesLine.F.HitNbG1); + //msg (( MSG_OUT, " ViStatesLine :%d :VStatesLine.F.HitNbG0 : %X - VStatesNbG0 : %x - VStatesLine.F.HitNbG1 : %X - VStatesNbG1 : %x ", ViStatesLine, VStatesLine.F.HitNbG0,VStatesNbG0,VStatesLine.F.HitNbG1,VStatesNbG1 )); + + Dest->AStatesRec[ViStatesLine].NbWinG0 = VStatesNbG0; + Dest->AStatesRec[ViStatesLine].NbWinG1 = VStatesNbG1; + Dest->AStatesRec[ViStatesLine].NbWinTot = VStatesNbG0 + VStatesNbG1; + + if (VStatesNbG0 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ){ + VG0Overflow = VStatesNbG0; + VStatesNbG0 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + } + + if (VStatesNbG1 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ){ + VG1Overflow = VStatesNbG1; + VStatesNbG1 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + } + + if ( (PrintLvl == 5) || (PrintLvl == 7) ) { + msg (( MSG_OUT, " ViStatesLine :%d :VStatesLine.W32 : %X - NbWinG0 : %d - NbWinG1 : %d ", ViStatesLine, VStatesLine.W32,Dest->AStatesRec[ViStatesLine].NbWinG0,Dest->AStatesRec[ViStatesLine].NbWinG1 )); + + msg (( MSG_OUT, "Line %4d - %d HitNbG0 (Ovf:%d) - %d HitNbG1 (Ovf:%d)", VStatesLine.F.SLineAddr, VStatesNbG0, VG0Overflow,VStatesNbG1,VG1Overflow )); + + } + + ++ViSrcW30; + + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + + + // Copy states G1 + if (VStatesNbG1 > 0){ + for ( ViState=0; ViState < VStatesNbG1; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].W32 = VPtDataU32[ViSrcW30]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "-->G1: State %d : Delta : %d - Col %4d - %X pixels", ViState, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Delta , Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code )); + if ( (PrintLvl == 8)&&(((Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code)& 0xFFFFF) == 0)&&(ViSrcW30 < VDataW30Length) ) { + msg (( MSG_OUT, " G1 : Frame :%d ,Word : %d of %d, SLineAddr :%d : Window word : %X - Code = 0, %d state out of %d ", Dest->FrameCnt, ViSrcW30,VDataW30Length, VStatesLine.F.SLineAddr, Dest->AStatesRec[ViStatesLine].AStatesG1[ViState].W32,ViState ,VStatesNbG0 )); + } + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + } + } + // Copy states G0 + + if (VStatesNbG0 > 0){ + for ( ViState=0; ViState < VStatesNbG0; ViState++ ) { + // 22/05/14 - MS GCMODIF + + Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].W32 = VPtDataU32[ViSrcW30]; + if ( (PrintLvl == 5) || (PrintLvl == 7) ) msg (( MSG_OUT, "-->G0: State %d : Delta : %d - Col %4d - %X pixels", ViState, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Delta , Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.ColAddr, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code )); + if ( (PrintLvl == 8)&&(((Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code)& 0xFFFFF) == 0)&&(ViSrcW30 < VDataW30Length) ) { + msg (( MSG_OUT, " G0 : Frame :%d ,Word : %d out of %d, SLineAddr :%d : Window word : %X - Code = 0, %d state out of %d ", Dest->FrameCnt, ViSrcW30,VDataW30Length, VStatesLine.F.SLineAddr, Dest->AStatesRec[ViStatesLine].AStatesG0[ViState].W32,ViState ,VStatesNbG0 )); + } + ++ViSrcW30; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + } + } + + ++ViStatesLine; + if ( ViSrcW30 >= VDataW30Length ){ + break; + } + + // Add on 25/03/2011 during test with random frame size + with all data = 0 + + if ( ViStatesLine >= FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "Max number of states reached = %d => Abort => Corrupted data !", FSBB0__ZS_FFRAME_MAX_STATES_REC )); + break; + } + + } // End while + + } // End if ( VDataW30Length != 0 ) + + Dest->StatesRecNb = ViStatesLine; + +//#endif // Endif of #ifndef FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + + if ( (PrintLvl == 5)/* || (PrintLvl == 6)*/|| (PrintLvl == 7) /*|| (PrintLvl == 8)*/ ) { + msg (( MSG_OUT, "Conv : %d StatesLines", Dest->StatesRecNb )); + msg (( MSG_OUT, "" )); + } + + return (VRetW30Length); +} // end EFRIO__FSBB0_FConvEfrioFrameToZsFFrame + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 14/10/2014 +Doc date : 14/10/2014 +Rev : copy of APP__FConvZsFFrameToMatDiscriBit from read_flex_rio_daq_file_v22_gc + : +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 EFRIO__FSBB0_FConvZsFFrameToMatDiscriBit ( FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDest, SInt32* PtOvfCnt, SInt8 PrintLvl ) { + + SInt16 ViLine; + SInt16 ViFirstLine; + SInt16 ViTopLine; + SInt16 VFirstCol; + SInt16 VLastCol; + SInt16 ViCol; + SInt16 ViStatesLine; + SInt16 ViState; + SInt16 VStatesNbG0; + SInt16 VStatesNbG1; + SInt32 VHitCnt; + SInt32 VOfvCnt; + SInt32 VMask; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + + + // -------------------------------------------- + // Reset destination matrix + // -------------------------------------------- + + memset ( PtDest, 0, sizeof (FSBB0__TMatDiscriBit) ); + + // -------------------------------------------- + // Copy hits from ZsFFRame -> MatDiscriBit + // -------------------------------------------- + + // StatesRec loop + + VHitCnt = 0; + VOfvCnt = 0; + + if ( PtSrc->StatesRecNb > FSBB0__ZS_FFRAME_MAX_STATES_REC ) { + err_warning (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + err_error (( ERR_OUT, "StatesRecNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_REC=%d => Force %d", PtSrc->StatesRecNb, FSBB0__ZS_FFRAME_MAX_STATES_REC, FSBB0__ZS_FFRAME_MAX_STATES_REC )); + PtSrc->StatesRecNb = FSBB0__ZS_FFRAME_MAX_STATES_REC; + } + + if (PtSrc->StatesRecNb > 0){ + + for ( ViStatesLine=0; ViStatesLine < PtSrc->StatesRecNb; ViStatesLine++ ) { + + VStatesNbG0 = PtSrc->AStatesRec[ViStatesLine].NbWinG0; + VStatesNbG1 = PtSrc->AStatesRec[ViStatesLine].NbWinG1; + ViTopLine = ((PtSrc->AStatesRec[ViStatesLine].StatesLine.F.SLineAddr + 1) * 4) - 1 ; + + + // States in one StateRec loop + + + if ( VStatesNbG0 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNbG0, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP )); + VStatesNbG0 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + ++VOfvCnt; + } + if ( VStatesNbG1 > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP ) { + err_warning (( ERR_OUT, "StatesNb=%d > FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC=%d => Force %d", VStatesNbG1, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP, FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP )); + VStatesNbG1 = FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP; + ++VOfvCnt; + } + + + if ( ViTopLine >= FSBB0__MAT_DISCRI_LINES_NB) { + err_warning (( ERR_OUT, "ViTopLine=%d >= FSBB0__MAT_DISCRI_LINES_NB=%d => Force %d", ViTopLine, FSBB0__MAT_DISCRI_LINES_NB, FSBB0__MAT_DISCRI_LINES_NB - 1 )); + ViTopLine = FSBB0__MAT_DISCRI_LINES_NB - 1; + } + // Decode Hits for Group 1 + if ( VStatesNbG1 > 0 ){ + for ( ViState = 0; ViState < VStatesNbG1; ViState++ ) { + + VFirstCol = (PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.ColAddr) + 224; + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + // Hits in one State loop + ViFirstLine = ViTopLine - (PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Delta); + VMask = 0x80000; + for (ViLine = ViFirstLine; ViLine > (ViFirstLine - 4); ViLine-- ){ + if (ViLine < 0){ + break; + } + for ( ViCol = VFirstCol; ViCol > VFirstCol - 5; ViCol-- ) { + if (ViCol < 0){ + break; + } + if ( ((PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.Code) & VMask) != 0){ + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + // 01/08/2014 - MS : removed the printing of the decoding of the data words + /* + if (PrintLvl ==7){ + msg (( MSG_OUT, " G1 : ViStatesLine :%d :ViTopLine : %d : ViState:%d - Hit Line : %d - Col : %d , VMask :0x%X ", ViStatesLine, ViTopLine,ViState, ViLine,ViCol,VMask )); + }*/ + } + else{ + PtDest->AALineCol[ViLine][ViCol] = 0; + + } + VMask = VMask >> 1; + + } // End For ViCol + } // End For ViLine + + } // End States in one StateRec loop for G1 + } /* end decoding groups for G1 */ + + // Decode Hits for Group 0 + if ( VStatesNbG0 > 0 ){ + for ( ViState=0; ViState < VStatesNbG0; ViState++ ) { + + VFirstCol = PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.ColAddr ; + //VLastCol = VFirstCol + PtSrc->AStatesRec[ViStatesLine].AStatesG1[ViState].F.HitNb; // HitNb = 0 => 1 hit, 1 => 2 hits etc ... + // WARNING => Will slow down execution + + if ( VFirstCol >= FSBB0__REG_DISCRI_BIT_SZ ) { + err_warning (( ERR_OUT, "FirstCol=%d >= FSBB0__REG_DISCRI_BIT_SZ=%d => Force 0", VFirstCol, FSBB0__REG_DISCRI_BIT_SZ )); + VFirstCol = 0; + } + + // Hits in one State loop + ViFirstLine = ViTopLine - (PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Delta); + VMask = 0x80000; + for (ViLine = ViFirstLine; ViLine > ViFirstLine - 4; ViLine-- ){ + if (ViLine < 0){ + break; + } + for ( ViCol=VFirstCol; ViCol > VFirstCol - 5; ViCol-- ) { + if (ViCol < 0){ + break; + } + //msg (( MSG_OUT, " ViStatesLine :%d :ViLine : %d - ViCol : %d - PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code : %d ", ViStatesLine, ViLine,ViCol,PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code )); + if ( (PtSrc->AStatesRec[ViStatesLine].AStatesG0[ViState].F.Code & VMask) != 0){ + PtDest->AALineCol[ViLine][ViCol] = 1; + ++VHitCnt; + // 01/08/2014 - MS : removed the printing of the decoding of the data words + /* + if (PrintLvl ==7){ + msg (( MSG_OUT, " G0 : ViStatesLine :%d :ViTopLine : %d : ViState:%d - Hit Line : %d - Col : %d , VMask :0x%x ", ViStatesLine, ViTopLine,ViState, ViLine,ViCol,VMask )); + }*/ + } + VMask = VMask >> 1; + + } // End For ViCol + } // End For ViLine + + } // End States in one StateRec loop for G0 + } /* end decoding groups for G0 */ + } // End StatesRec loop + } /* end if (PtSrc->StatesRecNb > 0)*/ + + + if ( PtOvfCnt != NULL ) { + *PtOvfCnt = VOfvCnt; + } + + // err_error (( ERR_OUT, "TRACE - VHitCnt=%d", VHitCnt )); // 13/02/2013 + + return (VHitCnt); +} // end EFRIO__FSBB0_FConvZsFFrameToMatDiscriBit + + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet2Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Mi26 in EUDET mode 2 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 2 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 2, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : All frames are stored in memory, regardless of trigger state + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 29/10/2010 +Rev : + : 16/02/2011 + : - Update ResEventCnt = ResFrameCnt, set to 0 before + : +Rev : 21/02/2011 + : - Add demux of data part if EFRIO__DEMUX_MI26_DATA_PART defined in eudet_frio.def + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 24/02/2011 + : - Update new fields AcqStatus, TrigStatus of AAcqFrameList + : + : 12/03/2011 + : - Add parameter TriggerHandlingMode +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode ( SInt32 BoardId, void* PtFrmRaw, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + FSBB0__TZsFFrameRaw * VPtSrcFsbb0FRmRaw ; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + //SInt32 V6iFrame; + // 01/10/2014 - MS + SInt32 ViFrameX6[6]; + + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViFSBB0; + //UInt32* VPtCpySrcW32; + UInt32* VPtDataW32FSBBNo0; + UInt32* VPtDataW32FSBBNo1; + UInt32* VPtDataW32FSBBNo2; + UInt32* VPtDataW32FSBBNo3; + UInt32* VPtDataW32FSBBNo4; + UInt32* VPtDataW32FSBBNo5; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViFSBB0ChkDataLength; + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode (P=%x, EltNb=%d)", PtFrmRaw, EltNb )); + + // Pointers parameters check + + err_retnull ( PtFrmRaw, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ ) / 6; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + VPtSrcFsbb0FRmRaw = (FSBB0__TZsFFrameRaw*)PtFrmRaw; + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + ViFrameX6[0]= 6 * ViFrame; + ViFrameX6[1]= ViFrameX6[0] + 1; + ViFrameX6[2]= ViFrameX6[0] + 2; + ViFrameX6[3]= ViFrameX6[0] + 3; + ViFrameX6[4]= ViFrameX6[0] + 4; + ViFrameX6[5]= ViFrameX6[0] + 5; + + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__FSBB0; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].Header.W32; + VPtFrame->Header.AMapsHeader[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[1]].Header.W32; + VPtFrame->Header.AMapsHeader[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[2]].Header.W32; + VPtFrame->Header.AMapsHeader[3] = VPtSrcFsbb0FRmRaw[ViFrameX6[3]].Header.W32; + VPtFrame->Header.AMapsHeader[4] = VPtSrcFsbb0FRmRaw[ViFrameX6[4]].Header.W32; + VPtFrame->Header.AMapsHeader[5] = VPtSrcFsbb0FRmRaw[ViFrameX6[5]].Header.W32; + // VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + // ++ViSrcW32; + // ++VEChanTrigFieldCnt; + // Datalength + VADataLengthW32[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].UsefulDataLengthW30; + VADataLengthW32[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[1]].UsefulDataLengthW30; + VADataLengthW32[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[2]].UsefulDataLengthW30; + VADataLengthW32[3] = VPtSrcFsbb0FRmRaw[ViFrameX6[3]].UsefulDataLengthW30; + VADataLengthW32[4] = VPtSrcFsbb0FRmRaw[ViFrameX6[4]].UsefulDataLengthW30; + VADataLengthW32[5] = VPtSrcFsbb0FRmRaw[ViFrameX6[5]].UsefulDataLengthW30; + + VDataLengthW32Max = MATH_FUInt32Max ( VADataLengthW32, 6 ); + // Framecounter + VPtFrame->Header.AMapsFrameCnt[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[1]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[2]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[3] = VPtSrcFsbb0FRmRaw[ViFrameX6[3]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[4] = VPtSrcFsbb0FRmRaw[ViFrameX6[4]].DataLengthRemFrCnt.F.FrameCnt; + VPtFrame->Header.AMapsFrameCnt[5] = VPtSrcFsbb0FRmRaw[ViFrameX6[5]].DataLengthRemFrCnt.F.FrameCnt; + + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW32Max > FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW32Max )); + + for ( ViFSBB0ChkDataLength = 0; ViFSBB0ChkDataLength < 6; ViFSBB0ChkDataLength++ ) { + if ( VADataLengthW32[ViFSBB0ChkDataLength] > FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViFSBB0ChkDataLength, VADataLengthW16[ViFSBB0ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + } + + else { + + for ( ViFSBB0=0; ViFSBB0 < 6; ViFSBB0++ ) { + VADataLengthW8[ViFSBB0] = VADataLengthW32[ViFSBB0] * 4; + VADataLengthW16[ViFSBB0] = VADataLengthW32[ViFSBB0] * 2; + } + + VDataLengthW8Max = VDataLengthW32Max * 4; + VDataLengthW16Max = VDataLengthW32Max * 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtDataW32FSBBNo0 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[0] ].ADataW32; + VPtDataW32FSBBNo1 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[1] ].ADataW32; + VPtDataW32FSBBNo2 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[2] ].ADataW32; + VPtDataW32FSBBNo3 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[3] ].ADataW32; + VPtDataW32FSBBNo4 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[4] ].ADataW32; + VPtDataW32FSBBNo5 = (UInt32*) VPtSrcFsbb0FRmRaw[ ViFrameX6[5] ].ADataW32; + + + + //VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = VPtDataW32FSBBNo0[ViDataCpy]; + ++VAPtCpyDestW32[0]; + //++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = VPtDataW32FSBBNo1[ViDataCpy];; + ++VAPtCpyDestW32[1]; + // ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = VPtDataW32FSBBNo2[ViDataCpy];; + ++VAPtCpyDestW32[2]; + //++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = VPtDataW32FSBBNo3[ViDataCpy];; + ++VAPtCpyDestW32[3]; + // ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = VPtDataW32FSBBNo4[ViDataCpy];; + ++VAPtCpyDestW32[4]; + // ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = VPtDataW32FSBBNo5[ViDataCpy];; + ++VAPtCpyDestW32[5]; + //++VPtCpySrcW32; + + + // VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + // ++VPtCpySrcW32; + // ++VEChanTrigFieldCnt; + } + + // VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + // VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + //do { + // VEChanTrigField = *VPtEChanSrcW32; + + // if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + // err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + // break; + //} + + // VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + // VPtEChanSrcW32 += 7; + // ++VEChanTrigFieldCnt; + //} while ( (VEChanTrigField & 0x80000000) == 0 ); + + + //ViSrcW32 += (6 * FSBB0__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[1]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[2]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[3] = VPtSrcFsbb0FRmRaw[ViFrameX6[3]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[4] = VPtSrcFsbb0FRmRaw[ViFrameX6[4]].Trailer.W32; + + VPtFrame->Header.AMapsTrailer[5] = VPtSrcFsbb0FRmRaw[ViFrameX6[5]].Trailer.W32; + + //++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + //VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_MAX_W32 * ViFrameX6[0]) + 18 + (6 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + // VZero2 = PtSrcW32[(MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + //ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + // VTrigNb = (VZero & 0xFFFF0000) >> 16; + + //if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + // err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + // VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + //} + + //if ( VTrigNb != 0 ) { + // VATrigVal[0] = (VZero & 0x0000FFFF); + // VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + // VATrigVal[2] = (VZero2 & 0x0000FFFF); + + // VATrigLine[0] = VATrigVal[0] / 16; + // VATrigLine[1] = VATrigVal[1] / 16; + // VATrigLine[2] = VATrigVal[2] / 16; + + // VATrigClk[0] = VATrigVal[0] % 16; + // VATrigClk[1] = VATrigVal[1] % 16; + // VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + // VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + // VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + // VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + //} + + //else { + // VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + // } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].SStatus.ATrigRes[ASIC__ULT1_TRIG_TOT_NB]; + VPtFrame->Header.AMapsTrigInfo[0] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].SStatus.ATrigRes[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].SStatus.ATrigRes[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VPtSrcFsbb0FRmRaw[ViFrameX6[0]].SStatus.ATrigRes[2]; + + // Add trigger info in trigger record + + //VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + //VPtTmpTrigRec->TrigNb = VTrigNb; + //VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + //VPtTmpTrigRec->TrigType = 2; + + //memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + //VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + // VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + //EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 6 /* Mi26Nb */ ); + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} /*end EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode */ + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataEudet3Mode6Mi26 ( + : SInt32 BoardId , UInt32* PtSrcW32, SInt32 EltNb, + : SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode ) + : +Goal : Flex RIO readout function for six Fsbb0 in EUDET mode 3 + : + : Read data of one acquisition from Flex RIO, format them in EUDET mode 3 + : by adding extra information and fill PC RAM buffer. + : + : The extra channel is enabled in EUDET mode 3, therefore for each trigger + : two informations are stored + : + : - The TLU trigger -> see record EFRIO__TTluTrigger + : - The Flex RIO trigger / time stamp -> see record EFRIO__TFlexRioTimeStamp1 + : + :*************************************************************************** + : Only the frames with a trigger nb > 0 + EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + : frames after trigger are stored in memory. + : The selection is done by this function. + :*************************************************************************** + : +Inputs : BoardId - Board identifier + : PtSrcW32 - Pointer to board data ( output of Labview Vi ) + : EltNb - Board data size in W32 unit ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by labview + : TrigStatus - Trigger status flag provided by labview + : + : DataConvertMode - Not used => Global EFRIO__TRunCont.ParDataTransferMode is used + : + : TriggerHandlingMode - Reserved for future use + : + : +Ouputs : The function returns + : 0 if ok + : -1 if an error occurs + : +Globals : + : +Remark : + : +Level : This is a user level function. +Date : 01/10/2014 +Rev : +Doc date : 01/10/2014 +Author : Matthieu SPECHT +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : DRS - IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FSBB0_FConvNi6562ToFlexRIOEudet3Mode ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 VFrameId; + SInt16 ViFrameWithTrig; + SInt32 V7FrameId; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; +// SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViFSBB0; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + + SInt32 VFrameWithTrigCnt; + SInt32 VLastFrameWithTrig; + SInt16* VPtFrameWithTrigList; + static SInt32 VFrNbToTakeAtBeginOfAcqForLastTrig = -1; // Number of frames to take at beginning of Acq to complete last trigger of previous Acq + SInt32 VTotAcqSz; + + + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__FSBB0_FConvNi6562ToFlexRIOEudet3Mode (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + // ---------------------------------------------------------------------------------- + // List frames to extract => frame with trigger + 3 following frames + // ---------------------------------------------------------------------------------- + + // 02/03/2011 Replace hard coded size by sizeof () + + memset ( VPtCont->AAAcqFrameWithTrigList[0], 0xFF, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (VPtCont->AAAcqFrameWithTrigList[0][0]) ); + + // Init loop parameters + + VFrameWithTrigCnt = 0; + VLastFrameWithTrig = -1; + VPtFrameWithTrigList = VPtCont->AAAcqFrameWithTrigList[0]; + + + // If trigger mode = 1 => Take always first frame of acq EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + // + // Done by overwriting VFrNbToTakeAtBeginOfAcqForLastTrig ( set on previous acq ) with EFRIO__FRAME_NB_TO_READ_AFTER_TRIG + + if ( TriggerHandlingMode == 1 ) { + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG; + } + + + for ( VFrameId=0; VFrameId < VPtBoard->FrameNbPerAcq; VFrameId++ ) { + + V7FrameId = 7 * VFrameId; + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + // BUT first read it from board RAM in order to get real execution time + + else { + VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 7]; + VZero = (TrigStatus << 16); + } + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb != 0 ) { + VLastFrameWithTrig = VFrameId; + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + else { + + if ( (VFrameId < VFrNbToTakeAtBeginOfAcqForLastTrig) || ((VLastFrameWithTrig != -1) && ((VFrameId - VLastFrameWithTrig) <= EFRIO__FRAME_NB_TO_READ_AFTER_TRIG)) ) { + VPtFrameWithTrigList[VFrameWithTrigCnt] = VFrameId; + ++VFrameWithTrigCnt; + } + + } // End else + + } // End for ( ViFrame ) + + + // Calculate nb of frame to store on beginning of next acq to complete last trigger of current one + // If last trigger occurs before the last EFRIO__FRAME_NB_TO_READ_AFTER_TRIG frames, the result will be 0 or < 0 + // in this case it will be ignored by processing loop + + VFrNbToTakeAtBeginOfAcqForLastTrig = EFRIO__FRAME_NB_TO_READ_AFTER_TRIG - (VPtBoard->FrameNbPerAcq - 1 - VLastFrameWithTrig); + + + #ifdef EFRIO__INCLUDE_PARA_PORT + // PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + // Print list of frames to extract + +/* + msg (( MSG_OUT, "=========================================================" )); + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + msg (( MSG_OUT, "Readout => Trig on frame %.4d", VPtCont->AAAcqFrameWithTrigList[0][ViFrameWithTrig] )); + } +*/ + + // Extract data + + VDataLengthErrCnt = 0; + + for ( ViFrameWithTrig=0; ViFrameWithTrig < VFrameWithTrigCnt; ViFrameWithTrig++ ) { + + VFrameId = VPtFrameWithTrigList[ViFrameWithTrig]; + VEChanTrigFieldCnt = 0; + ViSrcW32 = VFrameId * 7 * FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32; + + V7FrameId = 7 * VFrameId; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = VFrameId; + VPtFrame->Header.MapsName = (UInt16) ASIC__MI26; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + if ( VDataLengthW16Max > 2304 ) { + + // 02/03/2011 Replace loop for array reset by memset () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + +/* Removed on 02/03/2011 + + for ( ViFSBB0=0; ViFSBB0 < 6; ViFSBB0++ ) { + VADataLengthW8[ViFSBB0] = 0; + VADataLengthW16[ViFSBB0] = 0; + VADataLengthW32[ViFSBB0] = 0; + } + +*/ + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + } + + else { + + for ( ViFSBB0=0; ViFSBB0 < 6; ViFSBB0++ ) { + VADataLengthW8[ViFSBB0] = VADataLengthW16[ViFSBB0] * 2; + VADataLengthW32[ViFSBB0] = VADataLengthW16[ViFSBB0] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + + + #ifndef EFRIO__DEMUX_MI26_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + + ViSrcW32 += (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * MI26__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7FrameId) + 21 + (7 * MI26__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 16; + VATrigLine[1] = VATrigVal[1] / 16; + VATrigLine[2] = VATrigVal[2] / 16; + + VATrigClk[0] = VATrigVal[0] % 16; + VATrigClk[1] = VATrigVal[1] % 16; + VATrigClk[2] = VATrigVal[2] % 16; + + // Before 13/07/2012 + // + // VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + // VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + // VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + + // Since 13/07/2012 + + VAMi26Trig[0] = VATrigLine[0] + ( VATrigClk[0] << 10 ); + VAMi26Trig[1] = VATrigLine[1] + ( VATrigClk[1] << 10 ); + VAMi26Trig[2] = VATrigLine[2] + ( VATrigClk[2] << 10 ); + + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + (VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // EFRIO__MI26_FChkFrameLight ( 0 /* FuncId */ , VFrameId, VPtFrame, 6 /* Mi26Nb */ ); + + + + ++VPtFrList->TotFrameNb; + + // ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 15/02/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrameWithTrig < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + } // End for ViFrameWithTrig + + + /* Before 12/03/2011 + + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + + */ + + if ( VPtFrList->TotFrameNb != 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResFrameCnt + VPtFrList->TotFrameNb; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + + + + +// $$$$$$$$$$$$$$ + +// : 03/02/2014 +// : - Add new tests on data + + +SInt32 EFRIO__FSBB0_FFRioAcqDeserDataEudet2Mode6Ult1 ( SInt32 BoardId, UInt32* PtSrcW32, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, SInt8 DataConvertMode, SInt8 TriggerHandlingMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TBoardConf* VPtBoard = NULL; + EFRIO__TRunCont* VPtRun = &VPtCont->RunCont; + EFRIO__TFrameList* VPtFrList = &VPtCont->AAcqFrameList[0]; + EFRIO__TFrame* VPtFrame; + EFRIO__TTriggerRec* VPtTmpTrigRec = VPtCont->PtTmpTrigRec; + EFRIO__TTestOnDataCont* VPtDataTest = &VPtCont->TestOnDataCont; + + + SInt32 VAcqId; + UInt8* VPtAcqData; + SInt32 VFrameNbFromBoardDrv; + SInt32 ViFrame; + SInt32 V7iFrame; + UInt32 VADataLengthField[6]; + UInt32 VADataLengthW8[6]; + UInt16 VADataLengthW16[6]; + UInt32 VADataLengthW32[6]; + UInt32 VDataLengthW8Max; + UInt32 VDataLengthW16Max; + UInt32 VDataLengthW32Max; + UInt32 VDataLengthW32ToCpy; + UInt32 VDataLengthW8ToCpy; + SInt32 ViSrcW32; + SInt32 ViDataCpy; + SInt32 ViDataCpyP1; + SInt32 ViDataCpyP2; + SInt32 VRunFrameCnt; + SInt32 VLastFrameWithTrigAllowed; + UInt32 VZero; + UInt32 VZero2; + SInt16 VTrigNb; + UInt16 VATrigVal[3]; + UInt16 VATrigLine[3]; + UInt16 VATrigClk[3]; + UInt16 VAMi26Trig[3]; + EFRIO__TTriggerRec* VPtTrigRec; + UInt32 VFullFrameRecSz; + UInt32 VEmptyFrameRecSz; + UInt32 VEmptyTrigRecSz; + SInt32 VDataLengthErrCnt; + SInt8 ViMi26; + UInt32* VPtCpySrcW32; + UInt32* VAPtCpyDestW32[6]; + UInt64* VPtCpySrcW64; + UInt64* VPtCpyDestW64; + UInt32* VPtEChanSrcW32; + SInt16 VEChanTrigFieldCnt; // Extra channel trigger fields counter + UInt32 VEChanTrigField; + SInt32 VTotAcqSz; + SInt8 ViFsbb0ChkDataLength; + SInt32 VErrorsOnData; // 25/04/2013 + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 1 /* State */ ); + #endif + + if ( VPtCont->InfInitDone == 0 ) { + err_retfail ( -1, (ERR_OUT,"Abort because : Init not done") ); + } + + err_trace (( ERR_OUT, "EFRIO__ULT1_FFRioAcqDeserDataEudet2Mode6Ult1 (P=%x, EltNb=%d)", PtSrcW32, EltNb )); + + // Pointers parameters check + + err_retnull ( PtSrcW32, (ERR_OUT,"PtSrcW32 = NULL") ); + + // Init board conf record pointer + + if ( (BoardId < 0) || (BoardId >= EFRIO__MAX_BOARDS_NB) ) { + err_retfail ( -1, (ERR_OUT,"Abort : Board Id=%d out of range [0..%d])", BoardId, EFRIO__MAX_BOARDS_NB - 1) ); + } + + VPtBoard = &EFRIO__VGContext.ABoardsConf[BoardId]; + + // Check data size + + VFrameNbFromBoardDrv = ( EltNb / FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ ) / 7; // Divide by 7 because of extral channel + + // It must be => ( (EltNb * 2) / (ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ * 2) ); + // But result is the SAME if we divide both part of fraction by 2 ;-) + + if ( VFrameNbFromBoardDrv != VPtBoard->FrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Bad number of samples : %d frames acquired <> %d frames requested", VFrameNbFromBoardDrv, VPtBoard->FrameNbPerAcq ) ); + } + + // Reset total size of acquisition + + VTotAcqSz = 0; + + // Get acq id + + VAcqId = VPtCont->RunCont.ResAcqCnt; + + // Get last frame with trigger allowed / acq + + VLastFrameWithTrigAllowed = VPtBoard->FrameNbPerAcq - 1; // Last n frames of Acq MUST have NO trigger information - NOW n = 0 !!! + + // Check if buffer is allocated ( this is total buffer, not only the part where we will write ) + + err_retnull ( VPtRun->PtFrame, (ERR_OUT,"Abort : EUDET frames buffer not allocated !") ); + + // Reset frame list pointer + + VPtFrList->AcqStatus = AcqStatus; + VPtFrList->TrigStatus = TrigStatus; + VPtFrList->TotFrameNb = 0; + + memset ( VPtFrList->AFramePtr, 0, EFRIO__MAX_FRAME_NB_PER_ACQ * sizeof (EFRIO__TFrame*) ); + + // Reset mon size + + VPtCont->MonCont.InfSzToSend = 0; + + // Calculate size of records WITHOUT variable length part counted here as one elt + + VEmptyTrigRecSz = sizeof ( EFRIO__TTriggerRec ); + VEmptyFrameRecSz = sizeof ( EFRIO__TFrame ); + + + // Reset tmp triggers buffer + + memset ( VPtTmpTrigRec, 0, sizeof (EFRIO__TTriggerRec) + (EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ) ); + + // Extract data + + ViSrcW32 = 0; + VDataLengthErrCnt = 0; + + for ( ViFrame=0; ViFrame < VPtBoard->FrameNbPerAcq; ViFrame++ ) { + + V7iFrame = 7 * ViFrame; + + VEChanTrigFieldCnt = 0; + + // Update pointer to next frame + + if ( VPtFrList->TotFrameNb == 0 ) { + VPtFrame = VPtFrList->AFramePtr[0] = VPtRun->PtFrame; + } + + else { + + if ( VPtFrList->TotFrameNb >= VPtCont->RunCont.ParFrameNbPerAcq ) { + err_retfail ( -1, (ERR_OUT,"Abort try to process frame %d > Max = %d ", VPtFrList->TotFrameNb, VPtCont->RunCont.ParFrameNbPerAcq) ); + } + + VPtFrame = VPtFrList->AFramePtr[VPtFrList->TotFrameNb] = (EFRIO__TFrame*) ((UInt8*) VPtFrList->AFramePtr[VPtFrList->TotFrameNb - 1] + VFullFrameRecSz); + + } + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Tag = EFRIO__FRAME_TAG; + VPtFrame->Header.Tag = EFRIO__FRAME_TAG_HEADER; + #endif + + + VPtFrame->Header.AcqStatus = AcqStatus; + VPtFrame->Header.TrigStatus = TrigStatus; + VPtFrame->Header.AcqId = VAcqId; + VPtFrame->Header.FrameIdInAcq = ViFrame; + VPtFrame->Header.MapsName = (UInt16) ASIC__ULT1; + VPtFrame->Header.MapsNb = VPtRun->ParMi26Nb; + + VPtFrame->Header.AMapsHeader[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsHeader[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VPtFrame->Header.AMapsFrameCnt[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtFrame->Header.AMapsFrameCnt[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthField[0] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[1] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[2] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[3] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[4] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VADataLengthField[5] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = PtSrcW32[ViSrcW32]; + ++ViSrcW32; + ++VEChanTrigFieldCnt; + + + VADataLengthW16[0] = (VADataLengthField[0] & 0x0000FFFF) + ((VADataLengthField[0] & 0xFFFF0000) >> 16); + VADataLengthW16[1] = (VADataLengthField[1] & 0x0000FFFF) + ((VADataLengthField[1] & 0xFFFF0000) >> 16); + VADataLengthW16[2] = (VADataLengthField[2] & 0x0000FFFF) + ((VADataLengthField[2] & 0xFFFF0000) >> 16); + VADataLengthW16[3] = (VADataLengthField[3] & 0x0000FFFF) + ((VADataLengthField[3] & 0xFFFF0000) >> 16); + VADataLengthW16[4] = (VADataLengthField[4] & 0x0000FFFF) + ((VADataLengthField[4] & 0xFFFF0000) >> 16); + VADataLengthW16[5] = (VADataLengthField[5] & 0x0000FFFF) + ((VADataLengthField[5] & 0xFFFF0000) >> 16); + + VDataLengthW16Max = MATH_FUInt16Max ( VADataLengthW16, 6 ); + + + // A better test ( on each VADataLengthW16[i] ? on each W16 on D0 & D1 ? ) should be done ! + + // err_error (( ERR_OUT, "VDataLengthW16Max = %d", VDataLengthW16Max )); + + if ( VDataLengthW16Max > FSBB0__ZS_FFRAME_RAW_MAX_W16 ) { + + ++VDataLengthErrCnt; + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + err_error (( ERR_OUT, "HW error on data length -> Max W16 nb = %d -> Force 0 !", VDataLengthW16Max )); + + for ( ViFsbb0ChkDataLength = 0; ViFsbb0ChkDataLength < 6; ViFsbb0ChkDataLength++ ) { + if ( VADataLengthW16[ViFsbb0ChkDataLength] > FSBB0__ZS_FFRAME_RAW_MAX_W16 ) { + err_error (( ERR_OUT, "Error chip[%d] = %d W16", ViFsbb0ChkDataLength, VADataLengthW16[ViFsbb0ChkDataLength] )); + } + } + + err_error (( ERR_OUT, "---------------------------------------------------------------------" )); + + // 02/03/2011 Replace hard coded arrays size in memset by sizeof () + + memset ( VADataLengthW8 , 0, 6 * sizeof (VADataLengthW8[0] ) ); + memset ( VADataLengthW16, 0, 6 * sizeof (VADataLengthW16[0]) ); + memset ( VADataLengthW32, 0, 6 * sizeof (VADataLengthW32[0]) ); + + VDataLengthW8Max = 0; + VDataLengthW32Max = 0; + + // 25/04/2013 + + err_retfail ( -2, (ERR_OUT,"Abort because bad data size !") ); + + } + + else { + + for ( ViMi26=0; ViMi26 < 6; ViMi26++ ) { + VADataLengthW8[ViMi26] = VADataLengthW16[ViMi26] * 2; + VADataLengthW32[ViMi26] = VADataLengthW16[ViMi26] / 2; + } + + VDataLengthW8Max = VDataLengthW16Max * 2; + VDataLengthW32Max = VDataLengthW16Max / 2; + } + + VPtFrame->Header.AMapsDataLength[0] = VADataLengthW8[0]; + VPtFrame->Header.AMapsDataLength[1] = VADataLengthW8[1]; + VPtFrame->Header.AMapsDataLength[2] = VADataLengthW8[2]; + VPtFrame->Header.AMapsDataLength[3] = VADataLengthW8[3]; + VPtFrame->Header.AMapsDataLength[4] = VADataLengthW8[4]; + VPtFrame->Header.AMapsDataLength[5] = VADataLengthW8[5]; + + // Copy useful data part + + VDataLengthW32ToCpy = VDataLengthW32Max * 6; + VDataLengthW8ToCpy = VDataLengthW32ToCpy * 4; + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtFrame->Data.Tag = EFRIO__FRAME_TAG_DATA; + #endif + + + VPtFrame->Data.TotSz = VDataLengthW8ToCpy; + VPtFrame->Data.OneMapsSz = VDataLengthW8Max; + + #ifndef EFRIO__DEMUX_ULT1_DATA_PART + + VPtCpySrcW64 = (UInt64*) &PtSrcW32[ViSrcW32]; + VPtCpyDestW64 = (UInt64*) VPtFrame->Data.ADataW32; + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + *VPtCpyDestW64 = *VPtCpySrcW64; + ++VPtCpyDestW64; + ++VPtCpySrcW64; + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *((UInt32*) VPtCpySrcW64); + (UInt32) VPtCpySrcW64 = (UInt32) (VPtCpySrcW64) + 4; + ++VEChanTrigFieldCnt; + + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW64; + + + #else + + VPtCpySrcW32 = (UInt32*) &PtSrcW32[ViSrcW32]; + VAPtCpyDestW32[0] = (UInt32*) VPtFrame->Data.ADataW32; + VAPtCpyDestW32[1] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + VDataLengthW32Max ); + VAPtCpyDestW32[2] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 2 * VDataLengthW32Max ) ); + VAPtCpyDestW32[3] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 3 * VDataLengthW32Max ) ); + VAPtCpyDestW32[4] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 4 * VDataLengthW32Max ) ); + VAPtCpyDestW32[5] = (UInt32*) ( (UInt32*) VPtFrame->Data.ADataW32 + ( 5 * VDataLengthW32Max ) ); + + for ( ViDataCpy=0; ViDataCpy < VDataLengthW32Max; ViDataCpy++ ) { + + *VAPtCpyDestW32[0] = *VPtCpySrcW32; + ++VAPtCpyDestW32[0]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[1] = *VPtCpySrcW32; + ++VAPtCpyDestW32[1]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[2] = *VPtCpySrcW32; + ++VAPtCpyDestW32[2]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[3] = *VPtCpySrcW32; + ++VAPtCpyDestW32[3]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[4] = *VPtCpySrcW32; + ++VAPtCpyDestW32[4]; + ++VPtCpySrcW32; + + *VAPtCpyDestW32[5] = *VPtCpySrcW32; + ++VAPtCpyDestW32[5]; + ++VPtCpySrcW32; + + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = *VPtCpySrcW32; + ++VPtCpySrcW32; + ++VEChanTrigFieldCnt; + } + + VPtEChanSrcW32 = (UInt32*) VPtCpySrcW32; + + + #endif + + + // Continue extraction of trigger fields from trigger channel WHILE needed + + VPtEChanSrcW32 += 6; // Bypass Mi26 x 6 data + + do { + VEChanTrigField = *VPtEChanSrcW32; + + if ( VEChanTrigFieldCnt >= EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB ) { + err_warning (( ERR_OUT, "Max trigger field nb reached = %d <=> %d max trigger info !", EFRIO__EXTRA_CHAN__MAX_TRIGGER_FIELD_NB, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB )); + break; + } + + VPtTmpTrigRec->ATrig[VEChanTrigFieldCnt] = VEChanTrigField; + VPtEChanSrcW32 += 7; + ++VEChanTrigFieldCnt; + } while ( (VEChanTrigField & 0x80000000) == 0 ); + + + ViSrcW32 += (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32); + + + // VptZsFFrameRaw[V6iFrame].Trailer = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * VADataLengthW32[0])]; // 18 = 6 x 3 Fields nb before first data = Header, Frame cnt, Data length + // ++ViSrcW32; + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 6]; + // VptZsFFrameRaw[V6iFrame].Zero = VZero; + // ++ViSrcW32; + + // VZero2 = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V6iFrame) + 18 + (6 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 12]; + // VptZsFFrameRaw[V6iFrame].Zero2 = VZero2; + // ++ViSrcW32; + + + VPtFrame->Header.AMapsTrailer[0] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * VADataLengthW32[0])]; // 21 = 7 x 3 Fields nb before first data = Header, Frame cnt, Data length + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[1] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 1 + (7 * VADataLengthW32[1])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[2] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 2 + (7 * VADataLengthW32[2])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[3] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 3 + (7 * VADataLengthW32[3])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[4] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 4 + (7 * VADataLengthW32[4])]; + ++ViSrcW32; + + VPtFrame->Header.AMapsTrailer[5] = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + 5 + (7 * VADataLengthW32[5])]; + ++ViSrcW32; + + ++ViSrcW32; // To count extra channel + + + // Read trigger number from "Mi26" frame + + if ( TrigStatus == 0 ) { + VZero = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 7]; + } + + // Emulate trigger by overwriting info from "Mi26" frame + + else { + VZero = (TrigStatus << 16); + } + + // VZero = PtSrcW32[(ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * ULT1__ZS_FFRAME_RAW_MAX_W32) + 7]; + + + + VZero2 = PtSrcW32[(FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 * V7iFrame) + 21 + (7 * FSBB0__ZS_FFRAME_RAW_MAX_W32) + 14]; + + ViSrcW32 += 14; // 7 times 2 zero fields = 14 + + // Extraction of trigger info from "Mimosa 26 frame" zero fields + + VTrigNb = (VZero & 0xFFFF0000) >> 16; + + if ( VTrigNb > EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 ) { + err_warning (( ERR_OUT, "VTrigNb=%d > Max=%d => Limit to max compatible with Mi26 !", VTrigNb, EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26 )); + VTrigNb = EFRIO__EXTRA_CHAN__MAX_TRIGGER_INFO_NB_COMPATIBLE_WITH_MI26; + } + + // 09/06/2011 + // => Bug fixed : 32 clock / line for Ultimate, not 16 like Mi26 + + if ( VTrigNb != 0 ) { + VATrigVal[0] = (VZero & 0x0000FFFF); + VATrigVal[1] = (VZero2 & 0xFFFF0000) >> 16; + VATrigVal[2] = (VZero2 & 0x0000FFFF); + + VATrigLine[0] = VATrigVal[0] / 32; + VATrigLine[1] = VATrigVal[1] / 32; + VATrigLine[2] = VATrigVal[2] / 32; + + VATrigClk[0] = VATrigVal[0] % 32; + VATrigClk[1] = VATrigVal[1] % 32; + VATrigClk[2] = VATrigVal[2] % 32; + + VAMi26Trig[0] = VATrigLine[0] /* + ( VATrigClk[0] << 10 ) */; + VAMi26Trig[1] = VATrigLine[1] /* + ( VATrigClk[1] << 10 ) */; + VAMi26Trig[2] = VATrigLine[2] /* + ( VATrigClk[2] << 10 ) */; + } + + else { + VAMi26Trig[0] = VAMi26Trig[1] = VAMi26Trig[2] = 0; + } + + // Add trigger info in frame header + + VPtFrame->Header.TriggerNb = VTrigNb; + VPtFrame->Header.AMapsTrigInfo[0] = VAMi26Trig[0]; + VPtFrame->Header.AMapsTrigInfo[1] = VAMi26Trig[1]; + VPtFrame->Header.AMapsTrigInfo[2] = VAMi26Trig[2]; + + // Add trigger info in trigger record + + VPtTrigRec = (EFRIO__TTriggerRec*) (VPtFrame->Data.ADataW32 + VDataLengthW32ToCpy); + + #ifdef EFRIO__FRAME_TAGS_ENABLE + VPtTmpTrigRec->Tag = EFRIO__FRAME_TAG_TRIG; + #endif + + + VPtTmpTrigRec->TrigNb = VTrigNb; // 3; !!! 08/06/2011 => Force 3 triggers !!! + VPtTmpTrigRec->TotSz = VEmptyTrigRecSz + ( /* !!! 08/06/2011 => Force 3 triggers !!! 3 */ VTrigNb * EFRIO__EXTRA_CHAN__TRIGGER_INFO_SZ); + VPtTmpTrigRec->TrigType = 2; + + memcpy ( VPtTrigRec, VPtTmpTrigRec, VPtTmpTrigRec->TotSz ); + + // Calculate size of frame record while filled ( fixed part + variable length (data & trigger) ) + + // Calculate size will be 2 x W32 higher than needed, because following fields will be counted twice + // + // - Field UInt32 ADataW32[0] of data record -> EFRIO__TFrameData + // - Field UInt32 ATrig[0] of trigger record -> EFRIO__TTriggerRec + + VFullFrameRecSz = VEmptyFrameRecSz + VDataLengthW8ToCpy + VPtTrigRec->TotSz; + + VTotAcqSz += VFullFrameRecSz; + + // Update frame field total size & trigger offset size + + VPtFrame->TotSz = VFullFrameRecSz; + VPtFrame->TrigRecOffset = VEmptyFrameRecSz + VDataLengthW8ToCpy; + + + // 03/02/14 + // Check frame relevant fields ( DataLength, Header, frame counter, trailer => NOT data part ) + // Enable / Disable done by a call to EFRIO__FTestOnDataStartStop ( Start, PrintLvl ) + + // msg (( MSG_OUT, VPtDataTest->ParTestType=%d", VPtDataTest->ParTestType )); + + switch ( VPtDataTest->ParTestType ) { + + case 1 : { + //VErrorsOnData = EFRIO__ULT1_FChkFrameLight ( 0 /* FuncId */ , ViFrame, VPtFrame, 8 /* Mi26Nb */ ); + break; } + + case 2 : { + //VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailer ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 23/01/2014 : For timing tests at lab + break; } + + case 3 : { + // VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 4 : { + // VErrorsOnData = EFRIO__ULT1_FChkFrameHeaderFrameCntIncTrailerMatrix ( 0 /* FuncId */ , VPtFrame, ViFrame, 8 /* Mi26Nb */, VPtFrList->AFramePtr[0]->Header.AMapsFrameCnt[0] /* FrameCntOfFirstFrameOfAcq */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 5 : { + // VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* EmulErr */ ); + // VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + case 6 : { + //VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 0 /* PrintLevel */ ); + break; } + + case 7 : { + //VErrorsOnData = EFRIO__ULT1_FCheckTFrame ( VPtFrame, 1 /* EmulErr */ ); + //VErrorsOnData = VErrorsOnData || EFRIO__ULT1_FChkFrameHeaderFrameCntCmpTrailerMatrix ( 0 /* FuncId */ , VPtFrame, 8 /* Mi26Nb */ ); // 24/01/2014 : For timing tests at lab + break; } + + } + + + ++VPtFrList->TotFrameNb; + + ++VRunFrameCnt; + + // Update size of acquisition to send on Ethernet for monitoring + // 11/03/2011 + // + // The update is done after processing each frame + // -> it cost execution time + // -> but we are sure that update has been done + + if ( ViFrame < VPtCont->MonCont.InfFrameNbToSend ) { + VPtCont->MonCont.InfSzToSend = VTotAcqSz; + } + + + } // End for ViFrame + + // Update frames & events counters ONLY if there is no errors on data - 25/04/2013 + + if ( VErrorsOnData == 0 ) { + ++VPtCont->RunCont.ResAcqCnt; + VPtCont->RunCont.ResFrameCnt = VPtCont->RunCont.ResAcqCnt * VPtCont->RunCont.ParFrameNbPerAcq; + VPtCont->RunCont.ResEventCnt = VPtCont->RunCont.ResFrameCnt; + } + + + #ifdef EFRIO__INCLUDE_PARA_PORT + PPO_FOutD5 ( 0 /* Id */, 0 /* State */ ); + #endif + + return (VTotAcqSz); +} + + + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__MI26_FFRioAcqDeserDataMi26 ( + : SInt8 Mi26Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, + : SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, + : SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) + : +Goal : This function is the upper level of Flex RIO readout functions, it calls + : the right redaout function depending on Mi26Nb & DataConvertMode parameters. + : On Labview side, this function is encapsulated in a Vi of the same name, + : which is called each time an acquisition is finished. + : + : This function also calls the frames emulation functions if emulation mode + : is enabled. + : + : +Inputs : Mi26Nb - Number of Mimosa 26 to acquire + : BoardId - Board identifier + : + : PtSrcW32AsPt - Pointer on Flex RIO DRAM as pointer + : PtSrcW32AsInt - Pointer on Flex RIO DRAM as an integer + : + : EltNb - Size of flex RIO DRAM in W32 ( 1 Elt = 1 W32 ) + : AcqStatus - Acquisition status flag provided by board + : TrigStatus - Trigger status flag provided by board + : WaitMsAtEnd - Wait ( in ms ) at end of function to measure free time + : + : DataConvertMode - = DataTransferMode of EFRIO__FConfRun + : See EFRIO__FConfRun for more inforation + : Read also Rev 27/01/2011 comment about DataConvertMode handling + : + : TriggerHandlingMode - Mode of trigger operation + + : EmuleMode - Enable frames emulation mode + : + : - 0 -> No frames emulation + : + : - 1 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> no trigger / frame + : + : - < 0 -> Emulation mode + : Mode IPHC & EUDET 1 -> 3 triggers / frame + : Mode EUDET 2 & 3 -> | EmuleMode | triggers / frame + : + : +Ouputs : The function returns + : -1 if an error occurs + : > 0 = if OK = Total acquisition size ( in bytes ) = size of data bloc after data processing ( for example : extraction of frames with trigger ) + : This is the USEFUL size of buffer pointer by EFRIO__VGContext.RunCont.PtFrame which contains all frames of one acquisition + : +Globals : + : +Remark : + : +Level : +Date : 11/08/2010 +Rev : 25/10/2010 + : - EUDET data formatting mode + trigger handling implementation + : + : 27/01/2011 + : - Modify handling of parameter DataConvertMode + : If DataConvertMode == -1 => Use EFRIO__FConfRun.ParDataTransferMode + : otherwise use DataConvertMode ( as is was before 27/01/2011 ) + : + : 23/02/2011 + : - Modify types of AcqStatus, TrigStatus parameters to SInt32 + : + : 17/01/2012 + : - Implementation of "sw" handling of Mi26 / "hard coded" + : It is enable by EFRIO__FREE_MI26_NB directive and ONLY implemented in mode EUDET 2 + : +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// Use data source pointer as pointer => Set PtSrcW32AsInt to 0 +// Use data source pointer as integer => Set pointer value in PtSrcW32AsInt, don't care about PtSrcW32AsPt + +// DataConvertMode +// 0 - IPHC mode = Demultiplex the data part, doesn't handle extra channel -> for compatibility with IPHC DAQ sw +// 1 - EUDET mode 1 = Don't demultiplex data part, don't care about extra channel, send all frames +// 2 - EUDET mode 2 = Don't demultiplex data part, extract trigger info from extra channel, send all frames +// 3 - EUDET mode 3 = Don't demultiplex data part, extract trigger info from extra channel, send only frames with trigger ( use TriggerHandlingMode parameter ) + +// 0 - EFRIO__TRF_MODE_IPHC +// 1 - EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN, +// 2 - EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES, +// 3 - EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG + + +SInt32 EFRIO__FSBB0_FFRioAcqDeserDataFsbb0 ( SInt8 Fsbb0Nb, SInt32 BoardId, UInt32* PtSrcW32AsPt, UInt32 PtSrcW32AsInt, SInt32 EltNb, SInt32 AcqStatus, SInt32 TrigStatus, UInt32 WaitMsAtEnd, SInt8 DataConvertMode, SInt8 TriggerHandlingMode, SInt16 EmuleMode ) { + + EFRIO__TContext* VPtCont = &EFRIO__VGContext; + EFRIO__TRunCont* VPtRunCont = &EFRIO__VGContext.RunCont; + EFRIO__USR_TContext* VPtUsrContext = &EFRIO__USR_VGContext; + + SInt32 VRet = 0; + SInt32 VEmuleFrameNb; + static UInt32 VEmuleFirstFrameNo = 0; + + SInt32 VDbgOffset; + +#ifndef NO_MI26 + + + // 27/01/11 + + if ( DataConvertMode == -1 ) { + DataConvertMode = VPtRunCont->ParDataTransferMode; + } + + + if ( PtSrcW32AsInt != 0 ) { + PtSrcW32AsPt = (UInt32*) PtSrcW32AsInt; + } + + +/* Uncomment to enable data dump + + msg (( MSG_OUT, "-------------------------------------" )); + msg (( MSG_OUT, "Data dump" )); + msg (( MSG_OUT, "-------------------------------------" )); + + msg (( MSG_OUT, "Header [H]" )); + msg (( MSG_OUT, "U32 0 = %4x", PtSrcW32AsPt[0] )); + msg (( MSG_OUT, "U32 1 = %4x", PtSrcW32AsPt[1] )); + msg (( MSG_OUT, "U32 2 = %4x", PtSrcW32AsPt[2] )); + msg (( MSG_OUT, "U32 3 = %4x", PtSrcW32AsPt[3] )); + msg (( MSG_OUT, "U32 4 = %4x", PtSrcW32AsPt[4] )); + msg (( MSG_OUT, "U32 5 = %4x", PtSrcW32AsPt[5] )); + msg (( MSG_OUT, "U32 6 = %4x", PtSrcW32AsPt[6] )); + + msg (( MSG_OUT, "Frame cnt [D]" )); + msg (( MSG_OUT, "U32 7 = %4d", PtSrcW32AsPt[7] )); + msg (( MSG_OUT, "U32 8 = %4d", PtSrcW32AsPt[8] )); + msg (( MSG_OUT, "U32 9 = %4d", PtSrcW32AsPt[9] )); + msg (( MSG_OUT, "U32 10 = %4d", PtSrcW32AsPt[10] )); + msg (( MSG_OUT, "U32 11 = %4d", PtSrcW32AsPt[11] )); + msg (( MSG_OUT, "U32 12 = %4d", PtSrcW32AsPt[12] )); + msg (( MSG_OUT, "U32 13 = %4d", PtSrcW32AsPt[13] )); + + msg (( MSG_OUT, "Data length [D]" )); + msg (( MSG_OUT, "U32 7 = %4x", PtSrcW32AsPt[14] )); + msg (( MSG_OUT, "U32 8 = %4x", PtSrcW32AsPt[15] )); + msg (( MSG_OUT, "U32 9 = %4x", PtSrcW32AsPt[16] )); + msg (( MSG_OUT, "U32 10 = %4x", PtSrcW32AsPt[17] )); + msg (( MSG_OUT, "U32 11 = %4x", PtSrcW32AsPt[18] )); + msg (( MSG_OUT, "U32 12 = %4x", PtSrcW32AsPt[19] )); + msg (( MSG_OUT, "U32 13 = %4x", PtSrcW32AsPt[20] )); + + msg (( MSG_OUT, "Data [H]" )); + msg (( MSG_OUT, "U32 14 = %4x", PtSrcW32AsPt[21] )); + msg (( MSG_OUT, "U32 15 = %4x", PtSrcW32AsPt[22] )); + msg (( MSG_OUT, "U32 16 = %4x", PtSrcW32AsPt[23] )); + msg (( MSG_OUT, "U32 17 = %4x", PtSrcW32AsPt[24] )); + msg (( MSG_OUT, "U32 19 = %4x", PtSrcW32AsPt[25] )); + msg (( MSG_OUT, "U32 20 = %4x", PtSrcW32AsPt[26] )); + msg (( MSG_OUT, "U32 21 = %4x", PtSrcW32AsPt[27] )); + +*/ + + if ( VPtRunCont->ParMeasDataRate == 1 ) { + + if ( VPtRunCont->ResAcqCnt == 0 ) { + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->ResDataRateMBytesPerSec = 0; + } + + else { + + if ( (VPtRunCont->ResAcqCnt % VPtRunCont->ParAcqNbToMeasDataRate) == 0 ) { + + // Calculate data rate + + VPtRunCont->InfDataRateMeasStopTimeMs = GetTickCount (); + VPtRunCont->InfDataRateMeasTotalTimeMs = VPtRunCont->InfDataRateMeasStopTimeMs - VPtRunCont->InfDataRateMeasStartTimeMs; + + if ( VPtRunCont->InfDataRateMeasTotalTimeMs > 0 ) { + VPtRunCont->ResDataRateMBytesPerSec = 1000 * ( (float) VPtRunCont->InfDataRateMeasTotalSz / (float) VPtRunCont->InfDataRateMeasTotalTimeMs ) / (float) ( 1024 * 1024 ); + } + + // msg (( MSG_OUT, "Data rate - ResAcqCnt=%d - Time=%d [ms] - Size=%d [Bytes] - DR=%.3f [MB/s]))", VPtRunCont->ResAcqCnt, VPtRunCont->InfDataRateMeasTotalTimeMs, VPtRunCont->InfDataRateMeasTotalSz, VPtRunCont->ResDataRateMBytesPerSec )); + + // Reset variables for next measure + + VPtRunCont->InfDataRateMeasTotalSz = 0; + VPtRunCont->InfDataRateMeasStopTimeMs = 0; + VPtRunCont->InfDataRateMeasTotalTimeMs = 0; + VPtRunCont->InfDataRateMeasStartTimeMs = GetTickCount (); + } + + } + + } + + + VEmuleFrameNb = VPtCont->RunCont.ParFrameNbPerAcq; + VEmuleFirstFrameNo = 0; + + + + while (1) { + + // IPHC mode + + if ( DataConvertMode == EFRIO__TRF_MODE_IPHC ) { + + switch ( Fsbb0Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This mode is not handled now", Fsbb0Nb ) ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This mode is not handled now", Fsbb0Nb ) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_IPHC -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + } + + break; + } + + // EUDET mode 1 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN ) { + + switch ( Fsbb0Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This mode is not handled now", Fsbb0Nb ) ); + break; } + + case 6 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This mode is not handled now", Fsbb0Nb ) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_1__NO_TRG_CHAN -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + } + + break; + } + + // EUDET mode 2 + + + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES ) { + + + #ifdef EFRIO__FREE_MI26_NB + + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet2ModeNMi26 ( Fsbb0Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + + #else + + switch ( Fsbb0Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 5 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 6 : { + // to modify : fsbb0_frame raw not yet defined and initiialized + VRet = EFRIO__FSBB0_FConvNI6562ToFlexRIOEudet2Mode ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 12 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_2__TRG_CHAN__SEND_ALL_FRAMES -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + } + + #endif + + break; + } + + // EUDET mode 3 + + if ( DataConvertMode == EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG ) { + + + #ifdef EFRIO__FREE_MI26_NB + + // 14/06/13 : Uses ReadoutMode command line parameter to select between normal readout & readout with etra trigger info (Debug BT June 2013) + + if ( VPtUsrContext->ParReadoutMode == 0) { + // msg (( MSG_OUT, "Normal readout" )); + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26 ( Fsbb0Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + } + + else { + // msg (( MSG_OUT, "Readout WITH extra trigger info" )); + VRet = EFRIO__MI26_FFRioAcqDeserDataEudet3ModeNMi26ExtaTrigInfo ( Fsbb0Nb, BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + } + + + #else + + switch ( Fsbb0Nb ) { + + case 1 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 5 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + case 6 : { + //VRet = EFRIO__FSBB0_FConvNi6562ToFlexRIOEudet3Mode ( BoardId, PtSrcW32AsPt, EltNb, AcqStatus, TrigStatus, DataConvertMode, TriggerHandlingMode ); + break; } + + case 8 : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Abort : EFRIO__TRF_MODE_EUDET_3__TRG_CHAN__SEND_FRAMES_WITH_TRIG -> This number of Mi26 = %d is not handled now", Fsbb0Nb ) ); + break; } + + } + + #endif + + + break; + } + + } // End while (1) + + + if ( WaitMsAtEnd != 0 ) { + // 10/10/14 - MS : is it still usefull ?? + // Sleep ( WaitMsAtEnd ); + } + + VPtCont->RunCont.ResAcqFunctRetCode = VRet; + + if ( VRet > 0 ) { + VPtRunCont->InfDataRateMeasTotalSz += VRet; + } + + return (VRet); + +#endif // NO_MI26 + +} + + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/eudet_frio_print.c b/include/pxi_daq_lib_v.3.1/eudet_frio_print.c new file mode 100755 index 0000000..3a125eb --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/eudet_frio_print.c @@ -0,0 +1,1460 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio.c +Goal : Functions of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : 05/08/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_PRINT_C +#define EUDET_FRIO_PRINT_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert TLU trigger info record to string for print or display +: +Inputs : Trig - Source trigger record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTluTrigger2Str ( UInt32 Trig, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TTluTrigger VTrig; + + VTrig.W32 = Trig; + + // Convert in string + + sprintf ( VStr, "F%.4d - T%.4d", VTrig.F.FrameIdInAcq, VTrig.F.TrigCnt ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf (DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +: +Goal : Convert Flex RIO trigger / ime stamp info record to string for print or display +: +Inputs : Ts - Source time stamp record ( it's only a W32 ) +: DestStr - Destination string +: MaxDestSz - Destination string size +: +Ouputs : The trigger / timestamp as a string in an human readable format +: +Globals : +: +Remark : If DestStr = NULL or is too small, a pointer to static local variable is +: returned. But please do a copy of the string, because if you use via the +: pointer, string content may / will change at next function call ! +: +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* EFRIO__FTimeStamp2Str ( UInt32 Ts, char* DestStr, SInt32 MaxDestSz ) +{ + static char VStr [30]; + EFRIO__TFlexRioTimeStamp1 VTs; + + VTs.W32 = Ts; + + // Convert in string + + sprintf ( VStr, "F%.4d - L%.4d", VTs.F.Mi26Frame, VTs.F.Mi26Line ); + + // Fill DestStr param if possible + + if ( (DestStr != NULL) && (MaxDestSz >= 30) ) { + sprintf ( DestStr, "%s", VStr ); + return (DestStr); + } + + // Return local var if no valid DestStr + + return (VStr); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) + : +Goal : Print run context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Rev : 21/02/2011 + : - Print new fields ParDaqVersion, ParMapsName +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunContRec ( EFRIO__TRunCont* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Run context record" )); + msg (( MSG_OUT, "============================================================" )); +// msg (( MSG_OUT, "ParDaqVersion = %.4d", PtRec->ParDaqVersion )); +// msg (( MSG_OUT, "ParMapsName = %.4d", PtRec->ParMapsName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParMi26Nb = %.4d", PtRec->ParMi26Nb )); + msg (( MSG_OUT, "ParFrameNbPerAcq = %.4d", PtRec->ParFrameNbPerAcq )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParRunNo = %.4d", PtRec->ParRunNo )); + msg (( MSG_OUT, "ParTotEvNb = %.4d", PtRec->ParTotEvNb )); + msg (( MSG_OUT, "ParEvNbPerFile = %.4d", PtRec->ParEvNbPerFile )); + msg (( MSG_OUT, "ParDataTransferMode = %.4d", PtRec->ParDataTransferMode )); + msg (( MSG_OUT, "ParTrigMode = %.4d", PtRec->ParTrigMode )); + msg (( MSG_OUT, "ParSaveOnDisk = %.4d", PtRec->ParSaveOnDisk )); + msg (( MSG_OUT, "ParSendOnEth = %.4d", PtRec->ParSendOnEth )); + msg (( MSG_OUT, "ParSendOnEthPCent = %.4d", PtRec->ParSendOnEthPCent )); + msg (( MSG_OUT, "ParDestDir = %s" , PtRec->ParDestDir )); + msg (( MSG_OUT, "ParFileNamePrefix = %s" , PtRec->ParFileNamePrefix )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParJtagFileName = %s ", PtRec->ParJtagFileName )); + msg (( MSG_OUT, "------------------------------------------------------------" )); +// msg (( MSG_OUT, "InfMi26FrameSzFromFlexRio = %.4d", PtRec->InfMi26FrameSzFromFlexRio )); + msg (( MSG_OUT, "InfZsFFrameRawBuffSz = %.4d", PtRec->InfZsFFrameRawBuffSz )); + msg (( MSG_OUT, "InfFrameBuffSz = %.4d", PtRec->InfFrameBuffSz )); + msg (( MSG_OUT, "InfConfFileName = %s" , PtRec->InfConfFileName )); + msg (( MSG_OUT, "InfDataFileName = %s" , PtRec->InfDataFileName )); + msg (( MSG_OUT, "InfSaveDataOnDiskRunning = %.4d", PtRec->InfSaveDataOnDiskRunning )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "CmdRun = %.4d", PtRec->CmdRun )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResFrameCnt = %.4d", PtRec->ResFrameCnt )); + msg (( MSG_OUT, "ResEventCnt = %.4d", PtRec->ResEventCnt )); + msg (( MSG_OUT, "ResDataRateMBytesPerSec = %.3f", PtRec->ResDataRateMBytesPerSec )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "PtZsFFrameRaw = %.8x", PtRec->PtZsFFrameRaw )); + msg (( MSG_OUT, "PtFrame = %.8x", PtRec->PtFrame )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintRunCont () + : +Goal : Print lib run context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintRunCont () { + + return ( EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) + : +Goal : Print board conf record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintBoardConfRec ( EFRIO__TBoardConf* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board conf record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "AsicName = %s", PtRec->AsicName )); + msg (( MSG_OUT, "AsicNb = %.4d", PtRec->AsicNb )); + msg (( MSG_OUT, "ReadoutMode = %.4d", PtRec->ReadoutMode )); + msg (( MSG_OUT, "DataClkFrequency = %2.f", PtRec->DataClkFrequency )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "DmaHostSz = %.4d", PtRec->DmaHostSz )); + msg (( MSG_OUT, "FrameNbPerAcq = %.4d", PtRec->FrameNbPerAcq )); + msg (( MSG_OUT, "EnableExtraChannel = %.4d", PtRec->EnableExtraChannel )); + msg (( MSG_OUT, "AcqNbPerTrig = %.4d", PtRec->AcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TriggerMode = %.4d", PtRec->TriggerMode )); + msg (( MSG_OUT, "TriggerDetectTimeWindow = %.4d", PtRec->TriggerDetectTimeWindow )); + msg (( MSG_OUT, "TriggerDetectOccurNb = %.4d", PtRec->TriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "TimeStampRes = %.4d", PtRec->TimeStampRes )); + msg (( MSG_OUT, "EnableTimeStamping = %.4d", PtRec->EnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "EnableTrigCnt = %.4d", PtRec->EnableTrigCnt )); + msg (( MSG_OUT, "TagEventsStoredByDUT = %.4d", PtRec->TagEventsStoredByDUT )); + msg (( MSG_OUT, "ReadTluTrigCntEachNTrig = %.4d", PtRec->ReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) + : +Goal : Print lib board conf record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardConf ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardConfRec ( &EFRIO__VGContext.ABoardsConf[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) + : +Goal : Print board status record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatusRec ( EFRIO__TBoardStatus* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Board status record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "BoardId = %.4d", PtRec->BoardId )); + msg (( MSG_OUT, "BoardPresent = %.4d", PtRec->BoardPresent )); + msg (( MSG_OUT, "FwLoaded = %.4d", PtRec->FwLoaded )); + msg (( MSG_OUT, "ConfDone = %.4d", PtRec->ConfDone )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "StatusCode = %.4d", PtRec->StatusCode )); + msg (( MSG_OUT, "StatusStr = %.4d", PtRec->StatusStr )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ErrorMsgList = %s", PtRec->ErrorMsgList )); + msg (( MSG_OUT, "LastErrorMsg = %s", PtRec->LastErrorMsg )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegDmaHostSz = %.4d", PtRec->RegDmaHostSz )); + msg (( MSG_OUT, "RegFrameNbPerAcq = %.4d", PtRec->RegFrameNbPerAcq )); + msg (( MSG_OUT, "RegEnableExtraChannel = %.4d", PtRec->RegEnableExtraChannel )); + msg (( MSG_OUT, "RegAcqNbPerTrig = %.4d", PtRec->RegAcqNbPerTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTriggerMode = %.4d", PtRec->RegTriggerMode )); + msg (( MSG_OUT, "RegTriggerDetectTimeWindow = %.4d", PtRec->RegTriggerDetectTimeWindow )); + msg (( MSG_OUT, "RegTriggerDetectOccurNb = %.4d", PtRec->RegTriggerDetectOccurNb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStampRes = %.4d", PtRec->RegTimeStampRes )); + msg (( MSG_OUT, "RegEnableTimeStamping = %.4d", PtRec->RegEnableTimeStamping )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegEnableTrigCnt = %.4d", PtRec->RegEnableTrigCnt )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTagEventsStoredByDUT = %.4d", PtRec->RegTagEventsStoredByDUT )); + msg (( MSG_OUT, "RegReadTluTrigCntEachNTrig = %.4d", PtRec->RegReadTluTrigCntEachNTrig )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "RegTimeStamp = %.4d", PtRec->RegTimeStamp )); + msg (( MSG_OUT, "RegTrigCnt = %.4d", PtRec->RegTrigCnt )); + msg (( MSG_OUT, "RegTluTrigCnt = %.4d", PtRec->RegTluTrigCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) + : +Goal : Print lib board status record of BoardId in log file + : +Inputs : BoardId - Board identifier + : +Ouputs : The function returns + : 0 if ok + : -1 if BoardId is not valid + : +Globals : + : +Remark : Call EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) + : +Level : +Date : 09/08/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintBoardStatus ( SInt32 BoardId ) { + + EFRIO__CHK_BOARD_ID (BoardId); + + return ( EFRIO__FPrintBoardStatusRec ( &EFRIO__VGContext.ABoardsStatus[BoardId] ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) + : +Goal : Print acquisition emulation context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmulRec ( EFRIO__TAcqEmul* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Acquistion emulation record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqCycleMs = %.4d", PtRec->ParAcqCycleMs )); + msg (( MSG_OUT, "ParEmuleDRamReadMs = %.4d", PtRec->ParEmuleDRamReadMs )); + msg (( MSG_OUT, "ParEmuleFunctNo = %.4d", PtRec->ParEmuleFunctNo )); + msg (( MSG_OUT, "InfEmuleFuncCmt = %s" , PtRec->InfEmuleFuncCmt )); + msg (( MSG_OUT, "ParRandomDataSz = %d" , PtRec->ParRandomDataSz )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParAHeader[0] , PtRec->ParAHeader[1] , PtRec->ParAHeader[2] , PtRec->ParAHeader[3] , PtRec->ParAHeader[4] , PtRec->ParAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ParATrailer[0], PtRec->ParATrailer[1], PtRec->ParATrailer[2], PtRec->ParATrailer[3], PtRec->ParATrailer[4], PtRec->ParATrailer[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ParTrigNbPerFrame = %.4d", PtRec->ParTrigNbPerFrame )); + msg (( MSG_OUT, "ParTrigOnOneFrameOverN = %.4d", PtRec->ParTrigOnOneFrameOverN )); + msg (( MSG_OUT, "ParTrigOnNConsecutiveFrames = %.4d", PtRec->ParTrigOnNConsecutiveFrames )); + msg (( MSG_OUT, "Trig [0]=%.4d [1]=%.4d [2]=%.4d [Last]=%.4d", PtRec->ParATrig[0], PtRec->ParATrig[1], PtRec->ParATrig[2], PtRec->ParATrig[3] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfDRamSzMb = %.4d", PtRec->InfDRamSzMb )); + msg (( MSG_OUT, "InfDRamSz = %.4d", PtRec->InfDRamSz )); + msg (( MSG_OUT, "InfDRamPtr = %.8x", PtRec->InfDRamPtr )); + msg (( MSG_OUT, "InfExtraChan = %.4d", PtRec->InfExtraChan )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResAcqFunctRetCode = %.4d", PtRec->ResAcqFunctRetCode )); + msg (( MSG_OUT, "ResAcqCnt = %.4d", PtRec->ResAcqCnt )); + msg (( MSG_OUT, "ResEvCnt = %.4d", PtRec->ResEvCnt )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintAcqEmul () + : +Goal : Print lib acquisition emulation context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.AcqEmul = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) + : +Level : +Date : 06/11/2010 +Doc date : 06/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintAcqEmul () { + + return ( EFRIO__FPrintAcqEmulRec ( &EFRIO__VGContext.AcqEmul ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheckRec ( EFRIO_TFrCheck* PtRec ) + : +Goal : Print frame check context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 31/10/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheckRec ( EFRIO__TFrCheck* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Frames check record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParAcqNo = %.4d", PtRec->ParAcqNo )); + msg (( MSG_OUT, "ParFrNo = %.4d", PtRec->ParFrNo )); + msg (( MSG_OUT, "ParChkMode = %.4d", PtRec->ParChkMode )); + msg (( MSG_OUT, "ParFrPrintLevel = %.4d", PtRec->ParFrPrintLevel )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "InfMi26Nb = %.4d", PtRec->InfMi26Nb )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "H [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResAHeader[0] , PtRec->ResAHeader[1] , PtRec->ResAHeader[2] , PtRec->ResAHeader[3] , PtRec->ResAHeader[4] , PtRec->ResAHeader[5] )); + msg (( MSG_OUT, "T [0]=%.8x [1]=%.8x [2]=%.8x [3]=%.8x [4]=%.8x [5]=%.8x", PtRec->ResATrailer[0] , PtRec->ResATrailer[1] , PtRec->ResATrailer[2] , PtRec->ResATrailer[3] , PtRec->ResATrailer[4] , PtRec->ResATrailer[5] )); + msg (( MSG_OUT, "FC [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResAFrameCnt[0] , PtRec->ResAFrameCnt[1] , PtRec->ResAFrameCnt[2] , PtRec->ResAFrameCnt[3] , PtRec->ResAFrameCnt[4] , PtRec->ResAFrameCnt[5] )); + msg (( MSG_OUT, "DL [0]=%.8d [1]=%.8d [2]=%.8d [3]=%.8d [4]=%.8d [5]=%.8d", PtRec->ResADataLenght[0], PtRec->ResADataLenght[1], PtRec->ResADataLenght[2], PtRec->ResADataLenght[3], PtRec->ResADataLenght[4], PtRec->ResADataLenght[5] )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "ResTrigNb = %.4d", PtRec->ResTrigNb )); + msg (( MSG_OUT, "TRG [0]=%.8d [1]=%.8d [3]=%.8d [Last]=%.8d", PtRec->ResATrig[0], PtRec->ResATrig[1], PtRec->ResATrig[2], PtRec->ResATrig[3] )); + msg (( MSG_OUT, "============================================================" )); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrCheck () + : +Goal : Print lib frame check context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.FrCheck = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) + : +Level : +Date : 06/11/2010 +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 EFRIO__FPrintFrCheck () { + + return ( EFRIO__FPrintFrCheckRec ( &EFRIO__VGContext.FrCheck ) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - > 0 -> print state list for each line + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 22/12/2010 +Rev : 30/12/2010 + : - Add handling of N Mimosa 26 + : +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameData ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + + UInt16 VOneMapsSzW16; + UInt16 VDataW16Length; + UInt16 VLastW16; + SInt32 ViSrcW16; + UInt16* VPtSrcW16; + MI26__TStatesLine VStatesLine; + MI26__TState VState; + SInt16 ViMi26; + SInt16 ViStatesLine; + SInt8 ViState; + SInt8 VStatesNbPerLine; + char VStrState[255]; + char VStrLine[255]; + + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + VOneMapsSzW16 = VPtData->OneMapsSz / 2; + + + for ( ViMi26=0; ViMi26 < VPtHead->MapsNb ; ViMi26++ ) { + + VPtSrcW16 = (UInt16*) ( (UInt16*) VPtData->ADataW32 + ( ViMi26 * VOneMapsSzW16 ) ); + VDataW16Length = VPtHead->AMapsDataLength[ViMi26] / 2; + ViSrcW16 = 0; + + msg (( MSG_OUT, "===================================================================================" )); + msg (( MSG_OUT, " Mimosa 26 No %2d ", ViMi26 )); + msg (( MSG_OUT, "===================================================================================" )); + + + if ( VDataW16Length != 0 ) { + + // ------------------------------------------------------------------------------------------------- + // Odd W16 nb handling ! + // + // It can seem strange that this can be done by processing one W16 less than total data length in all + // cases, this is due to data processing method used in loop, read explanation below if needed. + // ------------------------------------------------------------------------------------------------- + // If the total W16 number is odd, Mi26 add one more bad W16 to get an even W16 number. + // This bad W16 will be seen as a StatesLine field followed by NO state because it is the last W16. + // Therefore if at the beginning of the while loop there is only one W16 to process, this W16 is the + // bad one, because it is a StateLines field followed by no states. In others words, if the index of + // the W16 at the beginning of loop is the index of last W16 this W16 is the bad one which must be + // rejected, we must not enter the loop. In normal case, even W16 number, after processing of last + // state of last line the index of W16 equal W16 number, therefore is > of index of last W16, and + // we don't enter the loop. + + VLastW16 = VDataW16Length - 1; + + ViStatesLine = 0; + + while ( ViSrcW16 < VLastW16 ) { // Odd W16 nb handling => Don't process last W16 + + // Copy StatesLine field + + VStatesLine.W16 = VPtSrcW16[ViSrcW16]; + VStatesNbPerLine = VStatesLine.F.StateNb; + + sprintf ( VStrLine, "Mi26 %2d Line %4d - %d state(s) - %d Ovf : ", ViMi26, VStatesLine.F.LineAddr, VStatesLine.F.StateNb, VStatesLine.F.Ovf ); + + if ( (PrintLevel != 0) ) { + msg (( MSG_OUT, "%s", VStrLine )); + } + + ++ViSrcW16; + + // Copy states + + for ( ViState=0; ViState < VStatesNbPerLine; ViState++ ) { + VState.W16 = VPtSrcW16[ViSrcW16]; + + sprintf ( VStrState, "[Col %4d - %1d pixel(s)] ", VState.F.ColAddr, VState.F.HitNb + 1 ); + // strcat ( VStrLine , VStrState ); + + if ( (PrintLevel != 0) ) { + msg (( MSG_OUT, "%s", VStrState )); + } + + ++ViSrcW16; + } + + // if ( (PrintLevel != 0) ) { + // msg (( MSG_OUT, "%s", VStrLine )); + // } + + ++ViStatesLine; + + + } // End while + + } // End if ( VDataW16Length != 0 ) + + + } // End for ( ViMi26 ) + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - 1 -> Print AcqId & FrId + : - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + : - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + : - 4 -> Print trigger list + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 06/11/2010 +Rev : 21/02/2011 + : - Print new field DaqVersion + : 23/06/2013 + : - Print header, frame cnt, data sz, header of MAPS No 6 (debug time-stamping) +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTriggerRec* VPtTrig; + SInt16 ViTrig; + char VStrTrig[30]; + char VStrTs [30]; + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Trigger record follows the data record which has a VARIABLE size + + VPtTrig = (EFRIO__TTriggerRec*) ( (UInt8*) PtRec + PtRec->TrigRecOffset ); + + // ------------------------------------- + // Print TFrame fields + // ------------------------------------- + + if ( PrintLevel == 1 ) { + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, "AcqId = %.4d - FrameIdInAcq = %.4d - TrigNb = %.4d [D]", VPtHead->AcqId, VPtHead->FrameIdInAcq, VPtTrig->TrigNb )); + msg (( MSG_OUT, "Trigger line [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] & 0x3FF, VPtHead->AMapsTrigInfo[1] & 0x3FF, VPtHead->AMapsTrigInfo[2] & 0x3FF)); + msg (( MSG_OUT, "Trigger TS [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] >> 10, VPtHead->AMapsTrigInfo[1] >> 10, VPtHead->AMapsTrigInfo[2] >> 10)); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + + return (0); + } + + + msg (( MSG_OUT, "==============================================" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "Tag = %.8X [H]", PtRec->Tag )); +#endif + msg (( MSG_OUT, "DaqVersion = %.4d [D]", PtRec->DaqVersion )); + msg (( MSG_OUT, "TotSz = %.4d [D]", PtRec->TotSz )); + msg (( MSG_OUT, "TrigRecOffset = %.4d [D]", PtRec->TrigRecOffset )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "H.Tag = %.8X [H]", VPtHead->Tag )); +#endif + msg (( MSG_OUT, "H.AcqStatus = %.4d [D]", VPtHead->AcqStatus )); + msg (( MSG_OUT, "H.TrigStatus = %.4d [D]", VPtHead->TrigStatus )); + msg (( MSG_OUT, "H.AcqId = %.4d [D]", VPtHead->AcqId )); + msg (( MSG_OUT, "H.FrameIdInAcq = %.4d [D]", VPtHead->FrameIdInAcq )); + msg (( MSG_OUT, "H.MapsName = %.4d [D]", VPtHead->MapsName )); + msg (( MSG_OUT, "H.MapsNb = %.4d [D]", VPtHead->MapsNb )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.Header [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsHeader[0] , VPtHead->AMapsHeader[1] , VPtHead->AMapsHeader[2] , VPtHead->AMapsHeader[3] , VPtHead->AMapsHeader[4] , VPtHead->AMapsHeader[5], VPtHead->AMapsHeader[6], VPtHead->AMapsHeader[7] )); + msg (( MSG_OUT, "H.FrCnt [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsFrameCnt[0] , VPtHead->AMapsFrameCnt[1] , VPtHead->AMapsFrameCnt[2] , VPtHead->AMapsFrameCnt[3] , VPtHead->AMapsFrameCnt[4] , VPtHead->AMapsFrameCnt[5], VPtHead->AMapsFrameCnt[6], VPtHead->AMapsFrameCnt[7] )); + msg (( MSG_OUT, "H.DataSz [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsDataLength[0], VPtHead->AMapsDataLength[1], VPtHead->AMapsDataLength[2], VPtHead->AMapsDataLength[3], VPtHead->AMapsDataLength[4], VPtHead->AMapsDataLength[5], VPtHead->AMapsDataLength[6], VPtHead->AMapsDataLength[7] )); + msg (( MSG_OUT, "H.Trailer [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsTrailer[0] , VPtHead->AMapsTrailer[1] , VPtHead->AMapsTrailer[2] , VPtHead->AMapsTrailer[3] , VPtHead->AMapsTrailer[4] , VPtHead->AMapsTrailer[5], VPtHead->AMapsTrailer[6], VPtHead->AMapsTrailer[7] )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.TriggerNb = %.4d [D]", VPtHead->TriggerNb )); + // msg (( MSG_OUT, "H.TrigInfo [0]=%.8X [1]=%.8X [2]=%.8X ", VPtHead->AMapsTrigInfo[0], VPtHead->AMapsTrigInfo[1], VPtHead->AMapsTrigInfo[2] )); + msg (( MSG_OUT, "H.TrigInfo line [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] & 0x3FF, VPtHead->AMapsTrigInfo[1] & 0x3FF, VPtHead->AMapsTrigInfo[2] & 0x3FF)); + msg (( MSG_OUT, "H.TrigInfo TS [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] >> 10, VPtHead->AMapsTrigInfo[1] >> 10, VPtHead->AMapsTrigInfo[2] >> 10)); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "D.Tag = %.8X [H]", VPtData->Tag )); +#endif + msg (( MSG_OUT, "D.TotSz = %.4d [D]", VPtData->TotSz )); + msg (( MSG_OUT, "D.OneMapsSz = %.4d [D]", VPtData->OneMapsSz )); + + if ( PrintLevel == 3 ) { + EFRIO__FPrintFrameData ( PtRec, PrintLevel ); + } + + if ( PrintLevel < 4 ) { + msg (( MSG_OUT, "===================================================================================" )); + return (0); + } + + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "T.Tag = %X [H]", VPtTrig->Tag )); +#endif + msg (( MSG_OUT, "T.TotSz = %.4d [D]", VPtTrig->TotSz )); + msg (( MSG_OUT, "T.TrigNb = %.4d [D]", VPtTrig->TrigNb )); + msg (( MSG_OUT, "T.TrigType = %d [D]", VPtTrig->TrigType )); + + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "" )); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameDataFsbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - > 0 -> print state list for each line + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 22/12/2010 +Rev : 30/12/2010 + : - Add handling of N Mimosa 26 + : +Doc date : 22/12/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ +#ifdef EFRIO_FSBB0 +SInt32 EFRIO__FPrintFrameDataFsbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + SInt16 ViFsbb0; + EFRIO__TFrameHeader* VPtHead; + + FSBB0__TZsFFrame VZsFFrame; + FSBB0__TMatDiscriBit VMatBit; + SInt32 VOvfCnt; + + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + VPtHead = &PtRec->Header; + + memset ( &VZsFFrame, 0, sizeof (VZsFFrame) ); + memset ( &VMatBit , 0, sizeof (VMatBit) ); + + for ( ViFsbb0=0; ViFsbb0 < VPtHead->MapsNb ; ViFsbb0++ ) { + + msg (( MSG_OUT, "===================================================================================" )); + msg (( MSG_OUT, " Fsbb0 No %2d ", ViFsbb0 )); + msg (( MSG_OUT, "===================================================================================" )); + + EFRIO__FSBB0_FConvEfrioFrameToZsFFrame ( PtRec /* Src */, ViFsbb0 /* MapsId */, &VZsFFrame, 0 /* PrintLvl */ ); + + EFRIO__FSBB0_FConvZsFFrameToMatDiscriBit ( &VZsFFrame /* PtSrc */, &VMatBit /* PtDest */ , &VOvfCnt /* PtOvfCnt */, 0 /* PrintLvl */ ); + + EFRIO__FSBB0_FMatDiscriPrintHit ( "" /* CmtStrTitle */, ViFsbb0 /* CmtSInt8MapsId */, &VMatBit ); + } // End for ( ViFsbb0 ) + return (0); + +} /* end EFRIO__FPrintFrameDataFsbb0 */ +#endif + + + + + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintFrameRecFSbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) + : +Goal : print one frame content in log file + : +Inputs : PtRec - Pointer on the record + : + : PrintLevel - 0 -> Print nothing + : - 1 -> Print AcqId & FrId + : - 2 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + : - 3 -> Print AcqId, FrId ... Mi26 header, trailer ... + Trig nb + Data + : - 4 -> Print trigger list + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : copy of function SInt32 EFRIO__FPrintFrameRec ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) from GC + : +Level : +Date : 09/10/2014 +Rev : +Doc date : 09/10/2014 +Author : Matthieu SPecht +E-mail : matthieu.specht@iphc.cnrs.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ +#ifdef EFRIO_FSBB0 + +SInt32 EFRIO__FPrintFrameRecFsbb0 ( EFRIO__TFrame* PtRec, SInt8 PrintLevel ) { + + EFRIO__TFrameHeader* VPtHead; + EFRIO__TFrameData* VPtData; + EFRIO__TTriggerRec* VPtTrig; + SInt16 ViTrig; + char VStrTrig[30]; + char VStrTs [30]; + + err_retnull ( PtRec, (ERR_OUT,"PtRec == NULL !") ); + + if ( PrintLevel == 0 ) { + return (0); + } + + // ------------------------------------- + // Init pointers on TFrame sub records + // ------------------------------------- + + VPtHead = &PtRec->Header; + VPtData = &PtRec->Data; + + // Trigger record follows the data record which has a VARIABLE size + + VPtTrig = (EFRIO__TTriggerRec*) ( (UInt8*) PtRec + PtRec->TrigRecOffset ); + + // ------------------------------------- + // Print TFrame fields + // ------------------------------------- + + if ( PrintLevel == 1 ) { + msg (( MSG_OUT, "==============================================" )); + msg (( MSG_OUT, "AcqId = %.4d - FrameIdInAcq = %.4d - TrigNb = %.4d [D]", VPtHead->AcqId, VPtHead->FrameIdInAcq, VPtTrig->TrigNb )); + msg (( MSG_OUT, "Trigger line [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] & 0x3FF, VPtHead->AMapsTrigInfo[1] & 0x3FF, VPtHead->AMapsTrigInfo[2] & 0x3FF)); + msg (( MSG_OUT, "Trigger TS [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] >> 10, VPtHead->AMapsTrigInfo[1] >> 10, VPtHead->AMapsTrigInfo[2] >> 10)); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + + return (0); + } + + + msg (( MSG_OUT, "==============================================" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "Tag = %.8X [H]", PtRec->Tag )); +#endif + msg (( MSG_OUT, "DaqVersion = %.4d [D]", PtRec->DaqVersion )); + msg (( MSG_OUT, "TotSz = %.4d [D]", PtRec->TotSz )); + msg (( MSG_OUT, "TrigRecOffset = %.4d [D]", PtRec->TrigRecOffset )); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "H.Tag = %.8X [H]", VPtHead->Tag )); +#endif + msg (( MSG_OUT, "H.AcqStatus = %.4d [D]", VPtHead->AcqStatus )); + msg (( MSG_OUT, "H.TrigStatus = %.4d [D]", VPtHead->TrigStatus )); + msg (( MSG_OUT, "H.AcqId = %.4d [D]", VPtHead->AcqId )); + msg (( MSG_OUT, "H.FrameIdInAcq = %.4d [D]", VPtHead->FrameIdInAcq )); + msg (( MSG_OUT, "H.MapsName = %.4d [D]", VPtHead->MapsName )); + msg (( MSG_OUT, "H.MapsNb = %.4d [D]", VPtHead->MapsNb )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.Header [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsHeader[0] , VPtHead->AMapsHeader[1] , VPtHead->AMapsHeader[2] , VPtHead->AMapsHeader[3] , VPtHead->AMapsHeader[4] , VPtHead->AMapsHeader[5], VPtHead->AMapsHeader[6], VPtHead->AMapsHeader[7] )); + msg (( MSG_OUT, "H.FrCnt [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsFrameCnt[0] , VPtHead->AMapsFrameCnt[1] , VPtHead->AMapsFrameCnt[2] , VPtHead->AMapsFrameCnt[3] , VPtHead->AMapsFrameCnt[4] , VPtHead->AMapsFrameCnt[5], VPtHead->AMapsFrameCnt[6], VPtHead->AMapsFrameCnt[7] )); + msg (( MSG_OUT, "H.DataSz [0]=%8d [1]=%8d [2]=%8d [3]=%8d [4]=%8d [5]=%8d [6]=%8d [7]=%8d", VPtHead->AMapsDataLength[0], VPtHead->AMapsDataLength[1], VPtHead->AMapsDataLength[2], VPtHead->AMapsDataLength[3], VPtHead->AMapsDataLength[4], VPtHead->AMapsDataLength[5], VPtHead->AMapsDataLength[6], VPtHead->AMapsDataLength[7] )); + msg (( MSG_OUT, "H.Trailer [0]=%.8X [1]=%.8X [2]=%.8X [3]=%.8X [4]=%.8X [5]=%.8X [6]=%.8X [7]=%.8X" , VPtHead->AMapsTrailer[0] , VPtHead->AMapsTrailer[1] , VPtHead->AMapsTrailer[2] , VPtHead->AMapsTrailer[3] , VPtHead->AMapsTrailer[4] , VPtHead->AMapsTrailer[5], VPtHead->AMapsTrailer[6], VPtHead->AMapsTrailer[7] )); + msg (( MSG_OUT, "----------------------------------------------" )); + msg (( MSG_OUT, "H.TriggerNb = %.4d [D]", VPtHead->TriggerNb )); + // msg (( MSG_OUT, "H.TrigInfo [0]=%.8X [1]=%.8X [2]=%.8X ", VPtHead->AMapsTrigInfo[0], VPtHead->AMapsTrigInfo[1], VPtHead->AMapsTrigInfo[2] )); + msg (( MSG_OUT, "H.TrigInfo line [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] & 0x3FF, VPtHead->AMapsTrigInfo[1] & 0x3FF, VPtHead->AMapsTrigInfo[2] & 0x3FF)); + msg (( MSG_OUT, "H.TrigInfo TS [0]=%.4d [1]=%.4d [2]=%.4d ", VPtHead->AMapsTrigInfo[0] >> 10, VPtHead->AMapsTrigInfo[1] >> 10, VPtHead->AMapsTrigInfo[2] >> 10)); + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "D.Tag = %.8X [H]", VPtData->Tag )); +#endif + msg (( MSG_OUT, "D.TotSz = %.4d [D]", VPtData->TotSz )); + msg (( MSG_OUT, "D.OneMapsSz = %.4d [D]", VPtData->OneMapsSz )); + + if ( PrintLevel == 3 ) { + EFRIO__FPrintFrameDataFsbb0 ( PtRec, PrintLevel ); + } + + if ( PrintLevel < 4 ) { + msg (( MSG_OUT, "===================================================================================" )); + return (0); + } + + msg (( MSG_OUT, "----------------------------------------------" )); +#ifdef EFRIO__FRAME_TAGS_ENABLE + msg (( MSG_OUT, "T.Tag = %X [H]", VPtTrig->Tag )); +#endif + msg (( MSG_OUT, "T.TotSz = %.4d [D]", VPtTrig->TotSz )); + msg (( MSG_OUT, "T.TrigNb = %.4d [D]", VPtTrig->TrigNb )); + msg (( MSG_OUT, "T.TrigType = %d [D]", VPtTrig->TrigType )); + + for ( ViTrig=0; ViTrig < VPtTrig->TrigNb; ViTrig++ ) { + EFRIO__FTluTrigger2Str ( VPtTrig->ATrig[(2 * ViTrig)] , VStrTrig, 30 /* MaxDestSz */ ); + EFRIO__FTimeStamp2Str ( VPtTrig->ATrig[(2 * ViTrig) + 1], VStrTs , 30 /* MaxDestSz */ ); + + msg (( MSG_OUT, "T.[%.3d] Trig = %s - Ts = %s", ViTrig, VStrTrig, VStrTs )); + } + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "" )); + +} +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) + : +Goal : Print monitor context record in log file + : +Inputs : PtRec - Pointer on the record + : +Ouputs : The function returns + : 0 if ok + : -1 if PtRec = NULL + : +Globals : + : +Remark : + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMonContRec ( EFRIO__TMon* PtRec ) { + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Monitor context record" )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "InfFrameNbToSend = %.4d", PtRec->InfFrameNbToSend )); + msg (( MSG_OUT, "InfSzToSend = %.4d", PtRec->InfSzToSend )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMonCont () + : +Goal : Print lib monitor context record in log file + : +Inputs : None + : +Ouputs : The function returns + : 0 if ok + : -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible + : +Globals : + : +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) + : +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMoniCont () { + + return ( EFRIO__FPrintMonContRec (&EFRIO__VGContext.MonCont) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintTestOnDataContRec ( EFRIO__TTestOnDataCont* PtRec, char* Msg ) +: +Goal : Print monitor context record in log file +: +Inputs : PtRec - Pointer on the record +: +Ouputs : The function returns +: 0 if ok +: -1 if PtRec = NULL +: +Globals : +: +Remark : +: +Level : +Date : 15/02/2011 +Doc date : 15/02/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintTestOnDataContRec ( EFRIO__TTestOnDataCont* PtRec, char* Msg ) { + + SInt8 ViMaps; + + err_retnull ( PtRec, (ERR_OUT,"Abort : PtRec == NULL") ); + + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "Test on data context record => Print only relevant fields !" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "Message : %s", Msg )); + msg (( MSG_OUT, "============================================================" )); + msg (( MSG_OUT, "ParModeEnable = %d", PtRec->ParModeEnable )); + msg (( MSG_OUT, "ParResetCnt = %d", PtRec->ParResetCnt )); + msg (( MSG_OUT, "ParPrintLvl = %d", PtRec->ParResetCnt )); + msg (( MSG_OUT, "ParMapsNb = %d", PtRec->ParMapsNb )); + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ParAMapsHeaderRef[%d] = %.8x", ViMaps, PtRec->ParAMapsHeaderRef[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ParAMapsTrailerRef[%d] = %8x", ViMaps, PtRec->ParAMapsTrailerRef[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsErrCnt[ViMaps] )); + } + + + msg (( MSG_OUT, "------------------------------------------------------------" )); + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsHeaderErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsHeaderErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsFrameCntErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsFrameCntErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsDataLengthErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsDataLengthErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsTrailerErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsTrailerErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + for ( ViMaps=0; ViMaps < PtRec->ParMapsNb; ViMaps++ ) { + msg (( MSG_OUT, "ResAMapsMatrixErrCnt[%d] = %d", ViMaps, PtRec->ResAMapsMatrixErrCnt[ViMaps] )); + } + + msg (( MSG_OUT, "------------------------------------------------------------" )); + + + msg (( MSG_OUT, "ResTotErrCnt = %.4d", PtRec->ResTotErrCnt )); + msg (( MSG_OUT, "ResFrameNbWithErr = %.4d", PtRec->ResFrameNbWithErr )); + msg (( MSG_OUT, "============================================================" )); + + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintTestOnDataCont ( char* Msg ) +: +Goal : Print lib monitor context record in log file +: +Inputs : None +: +Ouputs : The function returns +: 0 if ok +: -1 if &EFRIO__VGContext.RunCont = NULL => But it's not possible +: +Globals : +: +Remark : Call EFRIO__FPrintRunContRec (&EFRIO__VGContext.RunCont) +: +Level : +Date : 29/04/2011 +Doc date : 29/04/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintTestOnDataCont ( char* Msg ) { + + return ( EFRIO__FPrintTestOnDataContRec (&EFRIO__VGContext.TestOnDataCont, Msg) ); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMsg ( + : SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, + : SInt8 PrintAsError, char* Msg ) + : +Goal : Print messages in msg or error log file from LabView -> A Vi encapsulets this function. + : +Inputs : DummyS32In - Dummy value used under Labview to easily " chain " function execution. + : + : To execute it after a Vi call, connect any output of this Vi to the + : DummyS32In pin and it will be automatically called after Vi end. + : To execute it before a Vi call, if this Vi has an integer parameter + : cut the wire and insert DummyS32In input and function output on it. + : + : Printing mode flags + : + : PrintAsMsg - If 1 -> Print in messages log file + : PrintAsTrace - If 1 -> Print in errors log file as a trace message + : PrintAsWarning - If 1 -> Print in errors log file as a warning message + : PrintAsError - If 1 -> Print in errors log file as an error message + : + : Msg - Message to print ( string ) + : +Ouputs : The function always returns the input parameter DummyS32In. + : +Globals : + : +Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) + : It can be used to insert this function call on an integer datapath under LabView + : + : If more than one printing mode flag is enabled therefore the same message will + : be printed in different ways. + : +Level : +Date : 09/08/2010 +Rev : 25/10/2010 + : - Implementation -> Empty function before +Doc date : 07/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 EFRIO__FPrintMsg ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", Msg )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", Msg )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", Msg )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", Msg )); + + return (DummyS32In); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 EFRIO__FPrintMsg ( +: SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, +: SInt8 PrintAsError, char* Msg ) +: +Goal : Print messages in msg or error log file from LabView -> A Vi encapsulets this function. +: +Inputs : DummyS32In - Dummy value used under Labview to easily " chain " function execution. +: +: To execute it after a Vi call, connect any output of this Vi to the +: DummyS32In pin and it will be automatically called after Vi end. +: To execute it before a Vi call, if this Vi has an integer parameter +: cut the wire and insert DummyS32In input and function output on it. +: +: Printing mode flags +: +: PrintAsMsg - If 1 -> Print in messages log file +: PrintAsTrace - If 1 -> Print in errors log file as a trace message +: PrintAsWarning - If 1 -> Print in errors log file as a warning message +: PrintAsError - If 1 -> Print in errors log file as an error message +: +: Msg - Message to print ( string ) +: +Ouputs : The function always returns the input parameter DummyS32In. +: +Globals : +: +Remark : Return the value of the input parameter name DummyS32In ( SInt32 ) +: It can be used to insert this function call on an integer datapath under LabView +: +: If more than one printing mode flag is enabled therefore the same message will +: be printed in different ways. +: +Level : +Date : 24/04/2013 +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef CC_UNIX + +SInt32 EFRIO__FPrintMsgWithTimeStamp ( SInt32 DummyS32In, SInt8 PrintAsMsg, SInt8 PrintAsTrace, SInt8 PrintAsWarning, SInt8 PrintAsError, char* Msg ) { + + TDateTime VDateTime; + char VStrMsgDateTime[GLB_CMT_SZ]; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + unsigned short VHour; + unsigned short VMin; + unsigned short VSec; + unsigned short VMSec; + + + VDateTime = VDateTime.CurrentDateTime(); + + VDateTime.DecodeDate ( &VYear, &VMonth, &VDay ); + VDateTime.DecodeTime ( &VHour, &VMin, &VSec, &VMSec ); + + + sprintf ( VStrMsgDateTime, "%.2d/%.2d/%.2d - %.2d:%.2d:%.2d|%.2d : %s", VDay, VMonth, VYear, VHour, VMin, VSec, VMSec, Msg ); + + if ( PrintAsMsg ) msg (( MSG_OUT, "%s", VStrMsgDateTime )); + if ( PrintAsTrace ) err_trace (( ERR_OUT, "%s", VStrMsgDateTime )); + if ( PrintAsWarning ) err_warning (( ERR_OUT, "%s", VStrMsgDateTime )); + if ( PrintAsError ) err_error (( ERR_OUT, "%s", VStrMsgDateTime )); + + return (DummyS32In); +} + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.3.1/eudet_frio_usr.def b/include/pxi_daq_lib_v.3.1/eudet_frio_usr.def new file mode 100755 index 0000000..77d6586 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/eudet_frio_usr.def @@ -0,0 +1,66 @@ + + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_usr.def +Goal : Macros definition of USER PART of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 11/11/2010 +Doc date : 11/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_USR_DEF +#define EUDET_FRIO_USR_DEF + + +/* ======================= */ +/* Conditional compilation */ +/* ======================= */ + + +/* ================= */ +/* Macro */ +/* ================= */ + + + + +/* ================= */ +/* Constants */ +/* ================= */ + +#define EFRIO__USR_CONST 0 + +#define EFRIO__USR_RUN_CTRL_MSG_CODE_STR_MAX_SZ 50 + +typedef enum EFRIO__USR_ENUM { + EFRIO__USR_ENUM_ITEM_0, + EFRIO__USR_ENUM_ITEM_1, + EFRIO__USR_ENUM_ITEM_2, + EFRIO__USR_ENUM_ITEM_NB + +} EFRIO__USR_TUsrEnum; + + +typedef enum { + + EFRIO__USR_RUN_CTRL_MSG_CONF, + EFRIO__USR_RUN_CTRL_MSG_START_RUN, + EFRIO__USR_RUN_CTRL_MSG_GET_RUN_STATUS_RQ, + EFRIO__USR_RUN_CTRL_MSG_GET_RUN_STATUS_ANS, + EFRIO__USR_RUN_CTRL_MSG_STOP_RUN + +} EFRIO__USR_TMsgCode; + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/eudet_frio_usr.typ b/include/pxi_daq_lib_v.3.1/eudet_frio_usr.typ new file mode 100755 index 0000000..9bf7fbf --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/eudet_frio_usr.typ @@ -0,0 +1,105 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_usr.typ +Goal : Types definition of USER PART of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 11/11/2010 +Doc date : 11/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_USR_TYP +#define EUDET_FRIO_USR_TYP + + + +// 03/02/2011 + +typedef struct { + + SInt32 TotMsgSz; + SInt32 HeaderSz; + SInt8 MsgCode; + char StrMsgCode[EFRIO__USR_RUN_CTRL_MSG_CODE_STR_MAX_SZ]; + + UInt8 Data; + +} EFRIO__USR_TRunCtrlMsgHeader; + + + +// 16/02/2011 + +typedef struct { + + EFRIO__TRunCont RunCont; + +} EFRIO__USR_TRunCtrlRunStatusAns; + + +/* ============================================== */ +/* Lib context record */ +/* ---------------------------------------------- */ +/* This record contains all lib global variables */ +/* ---------------------------------------------- */ +/* Date : dd/mm/2010 */ +/* Doc date : dd/mm/2010 */ +/* Author : */ +/* E-mail : */ +/* Labo : */ +/* ============================================== */ + + +typedef struct { + + SInt8 InfInitDone; // Lib iit done or not + + char LastMsgToGui[GLB_CMT_SZ]; // Last message to GUI + +// Set in comment #ifdef EFRIO__INCLUDE_RUN_CTRL on 13/06/2013 +// Because otherwise the data plot application doesn't compile +// Dont' remember why this CC had been added ? + +// #ifdef EFRIO__INCLUDE_RUN_CTRL + + char ParRunCtrlIPAddr[GLB_FILE_PATH_SZ]; + SInt32 ParRunCtrlPort; + SInt32 ParDaqPort; + SInt8 ParCrIndexFile; // Create index file for synchro with DUT DAQ - 26/03/2013 + SInt32 ParReadoutMode; // Reserved for future use (data demux hard coded / free nb of Mimosa) - 26/03/2013 + + // 01/03/2013 + SInt8 ParDisableRunCtrlMsgProcessing; // Disable RC requests processing display only request in GUI if ParEnableRunCtrlMsgDisplay = 1 + // used to test a run ctrl application + SInt8 ParEnableRunCtrlMsgDisplay; // Enable RC requests display in GUI + + SInt32 InfRunCtrlSenderId; + SInt32 InfRunCtrlReceiverId; + DWORD InfThreadRespondRunCtrlId; + HANDLE InfThreadRespondRunCtrlHnd; + HANDLE InfEventRespondRunCtrlHnd; + SInt32 InfFOnConfByRunCtrlRetCode; + SInt32 InfFOnStartRunByRunCtrlRetCode; + SInt32 InfFOnGetRunStatusByRunCtrl; + SInt32 InfFOnStopRunByRunCtrl; + + SInt32 ResRunCtrlMsgReady; // Indicates that a Run Ctrl message has been received and can be read from ResRunCtrlMsgStr + char ResRunCtrlMsgStr[GLB_CMT_SZ]; // Last Run Ctrl message + + +// #endif + + +} EFRIO__USR_TContext; + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/eudet_frio_usr.var b/include/pxi_daq_lib_v.3.1/eudet_frio_usr.var new file mode 100755 index 0000000..e30f7d0 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/eudet_frio_usr.var @@ -0,0 +1,34 @@ + +/******************************************************************************* +File : x:\lib\win\eudet_frio\eudet_frio_usr.var +Goal : Variables definition of USER PART of flex rio board library for EUDET Mimosa 26 DAQ +Prj date : 05/08/2010 +File date : 11/11/2010 +Doc date : 11/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef EUDET_FRIO_USR_VAR +#define EUDET_FRIO_USR_VAR + + + + +/* ================= */ +/* Global variables */ +/* ================= */ + +EXTERN VAR_STATIC EFRIO__USR_TContext EFRIO__USR_VGContext; + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/files.c b/include/pxi_daq_lib_v.3.1/files.c new file mode 100755 index 0000000..6e946c2 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/files.c @@ -0,0 +1,5135 @@ + +/******************************************************************************* +File : x:\lib\com\files\files.c +Goal : Functions of files library +Prj date : XX/XX/2003 +File date : XX/XX/2003 + : +Rev : 11/01/2012 + : - Plume BT bug fix in TCStreamFile(ProParBlocSz -> ProAParBlocSz) + : 12/01/2012 + : - Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed, these blocs will be removed from blocs index table + : - Save two index files : + : *.inf = normal without info on blocs not saved + : *.all.inf = default with all blocs info + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr + : +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FIL_C +#define FIL_C + + +#ifdef CC_UNIX + +UInt32 GetTickCount () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + + +SInt32 GetLastError () { + err_warning (( ERR_OUT, "Not supported under Unix" )); + return (0); +} + +#endif + +/******************************************************************************* +Prototype : SInt32 FIL_FFileExists ( char* FilePath ) +Goal : Test if the file exists. +Inputs : The file name ( full path if needed ). +Ouputs : 1 if the file exists, else 0. +Globals : +Remark : The result is not guaranted in case of multi application lock to file. +Level : This is a user level function. +Date : 17/04/2003 +Doc date : 17/04/2003 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FFileExists ( char* FilePath ) { + + SInt32 VRet; + FILE* VPf; + + VPf = fopen ( FilePath, "r" ); + + if ( VPf == NULL ) { + VRet = 0; + } + + else { + fclose ( VPf ); + VRet = 1; + } + + + return (VRet); +} + +/* 13/10/2004 */ + +SInt32 FIL_FFileSize ( char* FilePath ) { + + FILE* VPf; + SInt32 VFileSz; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fopen fail !" ) )); + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + if ( fclose (VPf) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fclose fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "%d Bytes", VFileSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FCpyFile ( char* Src, char* Dest ) + : +Goal : Copy SrcFile to DestFile. + : +Inputs : Src - Source file + : Dest - Destination file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - fonction moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FCpyFile ( char* Src, char* Dest ) { + + FILE* VPfSrc; + FILE* VPfDest; + SInt8 VBuffer[512]; // Debug 02/06/2007 move storage class static to auto + SInt32 VReadBytesCnt; + SInt32 VTotBytesCnt; + SInt32 VRet; + + VPfSrc = fopen ( Src, "rb" ); + + err_retnull ( VPfSrc, (ERR_OUT,"Source file %d open failed", Src ) ); + + VPfDest = fopen ( Dest, "wb" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", VPfDest ) ); + + VTotBytesCnt = 0; + + while ( ( VReadBytesCnt = fread ( VBuffer, 1 /* byte size */ , 512 /* bytes number */, VPfSrc ) ) > 0 ) { + fwrite ( VBuffer, 1 /* byte size */, VReadBytesCnt, VPfDest ); + VTotBytesCnt += VReadBytesCnt; + } + + fclose (VPfSrc); + fclose (VPfDest); + + err_retok (( ERR_OUT, "file %s copied in %s => %d bytes", Src, Dest, VTotBytesCnt )); +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FRemoveFile ( char* FilePath ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FRemoveFile ( char* FilePath ) { + + SInt32 VRet; + char* VStrError; + + VRet = remove ( FilePath ); + + err_retfail ( VRet, (ERR_OUT,"Remove file=%s failed => %s", FilePath, _strerror ("")) ); + err_retok (( ERR_OUT, "")); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) + : +Goal : List the directory SrcDir and write the result in DestDirFile. + : +Inputs : SrcDir - The directory to list + : DestDirFile - The result file + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 09/06/2005 +Doc date : 09/06/2005 +Modif : 18/06/2005 + : - Function moved from WDAQ +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifdef CC_APP_WINDOWS + +#ifndef FILE__VCPP_COMPIL + +SInt32 FIL_FDosDirOutFile ( char* SrcDir, char* DestDirFile ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + + VPf = fopen ( DestDirFile, "wt" ); + + if ( VPf == NULL ) { + err_retfail ( -1, (ERR_OUT, "Dir file %s creation failed ", DestDirFile ) ); + } + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + ++VItemCnt; + fprintf( VPf, "%s\n", VFileInfo.ff_name); + VRet = findnext(&VFileInfo); + } + + fclose ( VPf ); + + return (0); +} + +#endif + +#endif + + +SInt32 FIL_FDirOutFile ( char* SrcDir, char* DestDirFile ) { + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + return ( FIL_FDosDirOutFile ( SrcDir, DestDirFile ) ); + + #else + err_retfail ( -1, (ERR_OUT,"Function not handled under VC++") ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + + +/******************************************************************************* +Prototype : SInt32 FIL_FDosDelDir ( char* SrcDir ) +Goal : +Inputs : +Ouputs : +Globals : +Remark : Compiled only if CC_APP_WINDOWS is defined +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + +#ifdef CC_APP_WINDOWS + +#ifndef FILE__VCPP_COMPIL + +SInt32 FIL_FDosRmDirFiles ( char* SrcDir ) { + + FILE* VPf; + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; + char VFileToDelete[GLB_FILE_PATH_SZ]; + SInt32 VItemCnt; + SInt32 VRet; + SInt32 VRetRemove; + SInt32 VFuncRet; + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); + + VFuncRet = 0; + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + sprintf ( VFileToDelete, "%s\\%s", SrcDir, VFileInfo.ff_name ); + VRetRemove = FIL_FRemoveFile ( VFileToDelete ); + + if ( VRetRemove < 0 ) { + VFuncRet = -1; + err_error (( ERR_OUT, "Remove file=%s failed => %s", VFileToDelete, _strerror ("") )); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + + return (VFuncRet); +} + +#endif + +#endif + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDirFiles ( char* SrcDir ) +Goal : Remove all the files in directory SrcDir but let the direcory +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDirFiles ( char* SrcDir ) { + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + return ( FIL_FDosRmDirFiles (SrcDir) ); + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available under VC++ !", SrcDir) ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"FIL_FRmDirFiles (SrcDir=%s) IS NOT available !", SrcDir) ); +#endif + + +} + + +/******************************************************************************* +Prototype : SInt32 FIL_FRmDir ( char* SrcDir ) +Goal : Remove the directory SrcDir if empty +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + + + +SInt32 FIL_FRmDir ( char* SrcDir ) { + + SInt32 VRet; + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + + // VRet = _rtl_chmod( SrcDir, 1 , FA_NORMAL ); + // err_retfail ( VRet, (ERR_OUT,"Chmod failed on directory=%s", SrcDir) ); + + VRet = rmdir ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"Remove directory=%s failed => %s ", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"Function handled only under VC++") ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"Function handled only under Windows") ); +#endif + +} + +/******************************************************************************* +Prototype : +Goal : Delete direcory files and directory itself +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelDir ( char* SrcDir ) { + + SInt32 VRet; + char VNewName[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + + sprintf ( VNewName, "%s.old", SrcDir ); + + VRet = rename ( SrcDir, VNewName ); + + err_retfail ( VRet, (ERR_OUT,"Rename Dir=%s to %s failed !", SrcDir, VNewName ) ); + + err_warning (( ERR_OUT, "Directory %s renamed in %s because delete is impossible !", SrcDir, VNewName )); + + err_retok (( ERR_OUT, "" )); + +/* + VRet = FIL_FRmDirFiles ( SrcDir ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDirFiles (%s) failed ", SrcDir) ); + + VRet = FIL_FRmDir ( VNewName ); + err_retfail ( VRet, (ERR_OUT,"FIL_FRmDir (%s) failed ", SrcDir) ); + + err_retok (( ERR_OUT, "" )); +*/ + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 19/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FMkDir ( char* SrcDir ) { + + SInt32 VRet; + char VStrCmd[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + + #ifdef APP_DAQ + + err_retfail ( -1, (ERR_OUT,"Function NOT available under LynxOS !") ); + + #endif + + #ifdef CC_APP_LINUX + sprintf ( VStrCmd, "mkdir %s", SrcDir ); + system ( VStrCmd ); + #endif + + + #ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + + VRet = mkdir ( SrcDir ); + + err_retfail ( VRet, (ERR_OUT,"Creation of directory=%s failed => %s", SrcDir, _strerror ("") ) ); + err_retok (( ERR_OUT, "" )); + + #else + err_retfail ( -1, (ERR_OUT,"Function NOT available under VC++ !") ); + #endif + + #else + err_retfail ( -1, (ERR_OUT,"FIL_FMkDir (SrcDir=%s) IS NOT available !", SrcDir) ); + #endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in + : the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT + : are not written in list. +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +#ifndef FILE__VCPP_COMPIL + +SInt32 FIl_FDosListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\*.*", SrcDir ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + +#endif + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : The file number +Globals : +Remark : If file number is > FIL_LIST_DIR_FILES_MAX_CNT, all the files in +: the directory are counted, but files with index >= FIL_LIST_DIR_FILES_MAX_CNT +: are not written in list. +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +#ifdef CC_APP_WINDOWS + +#ifndef FILE__VCPP_COMPIL + +SInt32 FIL_FExtDosListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + struct ffblk VFileInfo; + char VSrcDirPlusJoker[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + SInt32 VItemCnt; + SInt32 VRet; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); /* GC 29/09/05 */ + + sprintf ( VSrcDirPlusJoker, "%s\\%s", SrcDir, Joker ); /* !!! */ + + VItemCnt = 0; + VRet = findfirst( VSrcDirPlusJoker, &VFileInfo, FA_NORMAL ); + + while ( VRet == 0 ) { + + if ( VItemCnt < FIL_DIR_FILES_LIST_MAX_CNT ) { + sprintf ( PtList->AList[VItemCnt], "%s", VFileInfo.ff_name ); + } + + ++VItemCnt; + VRet = findnext(&VFileInfo); + } + + return ( VItemCnt ); +} + +#endif + +#endif + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIl_FListDirFiles ( char* SrcDir, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + return ( FIl_FDosListDirFiles ( SrcDir, PtList ) ); + + #else + err_retfail ( -1, (ERR_OUT,"Function not handled under VC++") ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 27/05/2006 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtListDirFiles ( char* SrcDir, char* Joker, FIL_TDirFilesList* PtList ) { + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__VCPP_COMPIL + return ( FIL_FExtDosListDirFiles ( SrcDir, Joker, PtList ) ); + + #else + err_retfail ( -1, (ERR_OUT,"Function not handled under VC++") ); + #endif + +#else + err_retfail ( -1, (ERR_OUT,"Function not handled under Linux or LynxOs") ); +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 23/06/2005 +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FCntRmpFiles ( char* RmpDataPath, FIL_TDirFilesList* PtList ) { + + SInt32 VRet; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + VFilesCnt = FIl_FListDirFiles ( VRmpDirPath, PtList ); + + return ( VFilesCnt ); +} + + + +#ifndef APP_DAQ + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Extended version which handles conf extension i,j,k +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FExtDelRmpFiles ( char* RmpDataPath, char ConfExt, SInt32 RunNo, SInt32 MaxFileCnt ) { + + SInt32 VRet; + SInt32 ViFile; + SInt32 VFilesCnt; + char VRmpDirPath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VInfoFilePath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + char VData0Filepath[GLB_FILE_PATH_SZ]; // Debug 02/06/2007 move storage class static to auto + FIL_TDirFilesList VFilesList; // Debug 02/06/2007 move storage class static to auto + + + char VFileToDelete[GLB_FILE_PATH_SZ]; + + + sprintf ( VRmpDirPath, "%s", RmpDataPath ); + VRmpDirPath[strlen (VRmpDirPath) - 3] = 0; /* To remove the "RUN" word from path */ + + sprintf ( VInfoFilePath , "RUN_%d_%c.rz", RunNo, ConfExt ); + sprintf ( VData0Filepath, "RUN_%d_0.rz" , RunNo ); + + VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &VFilesList ); + + /* !!! DESY 20/09/05 !!! MUST BE CHECKED ! */ + /* previous line replaced by this one in order to be able to compile boards_db_man */ + /* VFilesCnt = FIL_FCntRmpFiles ( RmpDataPath, &(VPtAFilesPath) ); */ + + err_retfail ( VFilesCnt, (ERR_OUT,"FIL_FCntRmpFiles (%s) failed Ret=%d", RmpDataPath, VFilesCnt ) ); + + if ( VFilesCnt < MaxFileCnt ) { + err_retok (( ERR_OUT, "Nothing to do VFilesCnt=%d < MaxFileCnt=%d", VFilesCnt, MaxFileCnt )); + } + + err_warning (( ERR_OUT, "%d RMP files are not deleted by monitoring => I will remove them", VFilesCnt )); + + for ( ViFile = 0; ViFile < VFilesCnt; ViFile++ ) { + + if ( strcmp ( VFilesList.AList[ViFile], VInfoFilePath ) == 0 ) { + continue; + } + + if ( strcmp ( VFilesList.AList[ViFile], VData0Filepath ) == 0 ) { + continue; + } + + sprintf ( VFileToDelete, "%s\\%s", VRmpDirPath, VFilesList.AList[ViFile] ); + + err_warning (( ERR_OUT, "FIL_FDelRmpFilesv => File = %s", VFileToDelete )); + + FIL_FRemoveFile ( VFileToDelete ); + + } + + return (0); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : This is a user level function. +Date : 18/06/2005 +Rev : 30/07/2006 + : - Creation of FIL_FExtDelRmpFiles to replace FIL_FDelRmpFiles + : - FIL_FDelRmpFiles call FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) +Doc date : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/******************************************************************************/ + +SInt32 FIL_FDelRmpFiles ( char* RmpDataPath, SInt32 RunNo, SInt32 MaxFileCnt ) { + return ( FIL_FExtDelRmpFiles ( RmpDataPath, 'i', RunNo, MaxFileCnt ) ); +} + +#endif + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : + : +Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : +Globals : None + : +Remark : None + : +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FFloatVectorsToTextFile ( float** SrcVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** VectorsNames, char DataSep, char* DestFile ) { + + char VFuncName[] = "FIL_FFloatVectorsToTextFile"; + + FILE* VPfDest; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet; + + + VPfDest = fopen ( DestFile, "wt" ); + err_retnull ( VPfDest, (ERR_OUT,"Destination file %s creation failed", DestFile ) ); + + + if ( HeaderLine != NULL ) { + VRet = fprintf ( VPfDest, "%s \n", HeaderLine ); + } + + else { + VRet = fprintf ( VPfDest, "No header line \n", HeaderLine ); + } + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing Header line file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + + if ( VectorsNames != NULL ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + VRet = fprintf ( VPfDest, "%-21s", VectorsNames[ViVector]); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing vectors names line - Vector=%d file=%s => %s", ViVector, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + VRet = fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR file=%s => %s", DestFile, _strerror ( "System says :" ) ) ); + } + + } + + else { + fprintf ( VPfDest, "No vectors names line \n", HeaderLine ); + } + + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + VRet = fprintf ( VPfDest, "%.6f%c", SrcVectors[ViVector][ViLine], DataSep); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing line=%d in file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + fprintf ( VPfDest, "\n" ); + + if ( VRet == EOF ) { + fflush (VPfDest); + fclose (VPfDest); + err_retfail ( -1, (ERR_OUT,"Error writing CR line=%d file=%s => %s", ViLine, DestFile, _strerror ( "System says :" ) ) ); + } + + } + + + fflush (VPfDest); + fclose (VPfDest); + + err_retok (( ERR_OUT, "%d line written in file", EltNbPerVector, DestFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FTextFileToFloatVectors ( char* SrcFile, char DataSep, float** DestVectors, SInt16 VectorsNb, SInt32 EltNbPerVector, char* HeaderLine, char** AVectorsNames, char* StrVectorsNames ) { + + char VFuncName[] = "FIL_FTextFileToFloatVectors"; + + FILE* VPf; + SInt32 ViVector; + SInt32 ViLine; + SInt32 VRet = 1; // Antonin Maire, proper initialisation of the return variable, 16 oct 2014 + char VStrCR[2]; + char VDataSep; + + /* Check parameters */ + + err_retnull ( SrcFile , (ERR_OUT,"SrcFile == NULL" ) ); + err_retnull ( DestVectors , (ERR_OUT,"DestVectors == NULL" ) ); + err_retnull ( HeaderLine , (ERR_OUT,"HeaderLine == NULL" ) ); + err_retnull ( AVectorsNames , (ERR_OUT,"AVectorsNames == NULL" ) ); + err_retnull ( StrVectorsNames , (ERR_OUT,"StrVectorsNames == NULL" ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 1" )); + + /* Try to open file */ + + VPf = fopen ( SrcFile, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFile ) ); + + err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read header line */ +#ifndef CC_64B + VRet = (SInt32) fgets( HeaderLine, 255, VPf ); + + char *c = 0x0; + c = fgets( HeaderLine, 255, VPf ); + if( c == 0x0 ) VRet = 0; + c = 0x0; + // change Antonin Maire, 16 oct 2014 (cancel Jérôme Baudot's commit 1027) + // Was before : VRet = (SInt32) fgets( HeaderLine, 255, VPf ); + // Pb : Unlike fscanf, fgets return a char* and not an int... + // -> http://www.cplusplus.com/reference/cstdio/fgets/ + // gcc compilation does not like the cast char* to SInt32 VRet. +#endif + + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read header line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + /* Read vectors names line */ + +#ifndef CC_64B + VRet = (SInt32) fgets( StrVectorsNames, 255, VPf ); + c = fgets( StrVectorsNames, 255, VPf ); + // change Antonin Maire, 16 oct 2014 + if( c == 0x0 ) VRet = 0; + c = 0x0; + // change Antonin Maire, 16 oct 2014 (cancel Jérôme Baudot's commit 1027) + // Was before : VRet = (SInt32) fgets( StrVectorsNames, 255, VPf ); + // Pb : Unlike fscanf, fgets return a char* and not an int... + // -> http://www.cplusplus.com/reference/cstdio/fgets/ + // gcc compilation does not like the cast char* to SInt32 VRet. + +#endif + if ( VRet == 0 ) { + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Read vectors names line failed file=%s => %s ", SrcFile, _strerror ( "System says :" ) ) ); + } + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + sprintf ( AVectorsNames[ViVector], "" ); + }; + + + /* Read vectors */ + + for ( ViLine=0; ViLine < EltNbPerVector; ViLine++ ) { + + for ( ViVector=0; ViVector < VectorsNb; ViVector++ ) { + + if ( ViVector == VectorsNb-1 ) { + VRet = fscanf ( VPf, "%f%c", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + else { + VRet = fscanf ( VPf, "%f%c\n", &DestVectors[ViVector][ViLine], &VDataSep ); + } + + + if ( VRet != 2 ) { + fflush (VPf); + fclose (VPf); + err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s", ViLine, SrcFile, VRet, _strerror ( "System says :" ) ) ); + } + + } + + } + + + fflush (VPf); + fclose (VPf); + + err_retok (( ERR_OUT, "%d line Read in file", EltNbPerVector, SrcFile )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/02/2007 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifdef CC_APP_WINDOWS + + #ifndef FILE__NO_GET_APP_RUN_DIR + + SInt32 FIL_FGetAppRunDir ( char* StrRunDir, TApplication* PtApp ) { + + char* VPtStrExeName; + AnsiString VAStrExeName; + char VExeDriveLetter; + char VExeDriveId; /* 0 = default, 1 = A, 2 = B ... */ + char VStrCurDir[GLB_FILE_PATH_SZ]; + char VStrCurDirPath[GLB_FILE_PATH_SZ]; + + err_retfailnull ( StrRunDir, (ERR_OUT,"StrRunDir == NULL") ); + + VPtStrExeName = FStr2PCh ( &(PtApp->ExeName) ); + + VExeDriveLetter = toupper ( VPtStrExeName[0] ); + + switch ( VExeDriveLetter ) { + + case 'A' : { + VExeDriveId = 1; + break; } + + case 'B' : { + VExeDriveId = 2; + break; } + + case 'C' : { + VExeDriveId = 3; + break; } + + case 'D' : { + VExeDriveId = 4; + break; } + + case 'E' : { + VExeDriveId = 5; + break; } + + case 'F' : { + VExeDriveId = 6; + break; } + + case 'G' : { + VExeDriveId = 7; + break; } + + default : { + err_retfail ( -1, (ERR_OUT,"Unknown drive id=%d", VExeDriveId) ); + VExeDriveId = 0; + } + + } + + getcurdir( VExeDriveId, VStrCurDir ); + + sprintf ( VStrCurDirPath, "%c:\\%s", VExeDriveLetter, VStrCurDir ); + sprintf ( StrRunDir, "%s", VStrCurDirPath ); + + // msg (( MSG_OUT, "VStrCurDirPath = %s", VStrCurDirPath )); + + err_retok (( ERR_OUT, "" )); + } + + #else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + + #endif + +#else + + SInt32 FIL_FGetAppRunDir ( char* RunDirStr ) { + + err_retnull ( RunDirStr, (ERR_OUT,"RunDirStr == NULL") ); + + sprintf ( RunDirStr, "%s", "Available only under Windows !" ); + + return (0); + + } + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 07/03/2011 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FGetDiskSectorSz ( char* Drive ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported under Unix !" ) ); + +#else + + DWORD VDummyW; + DWORD VBytesPerSector; + BOOL VRetBool; + + // BOOL GetDiskFreeSpace( + // + // LPCTSTR lpRootPathName, // address of root path + // LPDWORD lpSectorsPerCluster, // address of sectors per cluster + // LPDWORD lpBytesPerSector, // address of bytes per sector + // LPDWORD lpNumberOfFreeClusters, // address of number of free clusters + // LPDWORD lpTotalNumberOfClusters // address of total number of clusters + // ); + + + VRetBool = GetDiskFreeSpace( + Drive, // address of root path + &VDummyW, // address of sectors per cluster + &VBytesPerSector, // address of bytes per sector + &VDummyW, // address of number of free clusters + &VDummyW // address of total number of clusters + ); + + if ( VRetBool == True ) { + return ( VBytesPerSector ); + } + + else { + return (-1); + } + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCBinFile :: ~FIL__TCBinFile () { +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ) { + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + + // Parameters from conf + + sprintf ( ProParDataFile, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + + // Variables for internal processing + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdEltId = 0; + ProCurRdSz = 0; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProPtFile = NULL; + + err_trace (( ERR_OUT, "" )); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + ProParRWBMode = RWBMode; + ProParMaxBlocSz = MaxBlocSz; + ProParBlocSz = BlocSz; + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + ProConfDone = 1; + + + // Allocate memory buffer for data read from file + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = MaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCBinFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProPtFile == NULL ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + + // Store current ( initial ) position in file + + if ( (VCurPos = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Goto end of file + + if ( fseek ( ProPtFile, 0, SEEK_END ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_END fail !" ) )); + } + + // Get current position = END in file => it's file size + + if ( (VFileSz = ftell ( ProPtFile )) == -1 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "ftell fail !" ) )); + } + + // Restor initial position in file + + if ( fseek ( ProPtFile, VCurPos, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,_strerror ( "fseek SEEK_SET fail !" ) )); + } + + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + + } // End file is already open + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFCreate () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can create a file when RWB mode IS NOT Write !") ); + } + + ProPtFile = fopen ( ProParDataFile, "wb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = 1; + ProReadyToRead = -1; + + ProCurWrEltId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFOpen () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + ProPtFile = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProPtFile, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz ) { + SInt8 VBlocNbWritten; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can write to a file when RWB mode IS NOT Write !") ); + } + + ProCurWrSz = DataSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbWritten = fwrite ( PtrData, DataSz /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbWritten != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc write failed ! => System : %s", _strerror ("") ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + fflush ( ProPtFile ); + } + + ++ProCurWrEltId; + ProTotWrSz += ProCurWrSz; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", DataSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + + SInt64 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + if ( DataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > MaxDestSz=%d", DataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + //msg (( MSG_OUT, "sizeof (ProPtFile) = %d", sizeof (ProPtFile) )); + //msg (( MSG_OUT, "ProCurRdSz = %d", ProCurRdSz )); + + VBlocNbRead = fread ( DestPtr, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Bloc read of %d bytes failed ! - VBlocNbRead = %d => System : %s", DataSzToRead, VBlocNbRead, _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt8 VBlocNbRead; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + if ( DataSzToRead > ProParMaxBlocSz ) { + err_retfailnull ( -1, (ERR_OUT,"Read abort : DataSzToRead=%d > ProParMaxBlocSz=%d", DataSzToRead, ProParMaxBlocSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfailnull ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + ProCurRdSz = DataSzToRead; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VBlocNbRead = fread ( ProPtrBuffRdData, DataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProPtFile ); + + if ( VBlocNbRead != 1 ) { + err_retfailnull ( -1, (ERR_OUT,"Bloc read failed ! => System : %s", _strerror ("") ) ); + } + + ++ProCurRdEltId; + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFGotoBloc ( SInt32 BlocNo ) { + + SInt32 VOffset; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + VOffset = BlocNo * ProParBlocSz; + + if ( fseek ( ProPtFile, VOffset, SEEK_SET ) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Goto bloc %d => %d bytes from beginning failed !", BlocNo ) ); + } + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ) { + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCBinFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCBinFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCBinFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFFlush () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + fflush ( ProPtFile ); + + err_retok (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 30/01/2009 +Doc date : 30/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCBinFile :: PubFClose () { + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProReadyToWrite == 1 ) { + fflush ( ProPtFile ); + } + + fclose ( ProPtFile ); + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + ProConfDone = 0; + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FWriteRecord ( char* FileName, void* PtSrc, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_WRITE, RecSz, RecSz, 1 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFCreate (); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqWrite ( PtSrc, RecSz ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/07/2009 +Doc date : 08/07/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FReadRecord ( char* FileName, void* PtDest, SInt32 RecSz ) { + + SInt32 VRet; + FIL__TCBinFile VBinFile ( ERR_FGetLogFilePath (), ERR_FGetFileLogEnabled () /* EnableErrLog */, ERR_FGetFileLogLevel () ); + + err_retnull ( PtDest, (ERR_OUT,"PtSrc == NULL") ); + + VRet = VBinFile.PubFConf ( FileName, FIL__TCBinFile_RWB_MODE_READ, RecSz, RecSz, 0 /* FlushAfterWrite */, 0 /* MeasTime */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFOpen(); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFSeqRead ( PtDest, RecSz /* MaxDestSz */, RecSz /* DataSzToRead */ ); + err_retfail ( VRet, (ERR_OUT,"") ); + + VRet = VBinFile.PubFClose (); + err_retfail ( VRet, (ERR_OUT,"") ); + + err_retok (( ERR_OUT, "" )); +} + + +// msg (( MSG_OUT, "Msg" )); + + + +// **************************** +// FIL__TCStreamFile +// **************************** + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + PubFBegin ( ErrLogFile, EnableErrLog, ErrLogLvl, DiskBlocSz ); + + err_trace (( ERR_OUT, "" )); +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +FIL__TCStreamFile :: ~FIL__TCStreamFile () { + + // Free info record + + if ( ProPtRecInfFile != NULL ) { + free ( ProPtRecInfFile ); + } + + // Free info record cpy + + if ( ProPtRecInfFileCpy != NULL ) { + free ( ProPtRecInfFileCpy ); + } + + +#ifndef CC_UNIX + TerminateThread ( ProThreadHnd , 0 /* Thread exit code */ ); + + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + DeleteCriticalSection ( &ProCsPrintMsg ); + #endif + + +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : 05/11/2010 + : - Error handling on disk access is not properly done, a message is printed + : but the error is not propagated => MUST be done. +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ + : +Rev : 09/05/2010 + : - Circular buffer implementation + : 11/01/2012 + : - "Plume BT bug" fix, using new field ProAParBlocSz instead of ProABlocSz + : 12/01/2012 + : - Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed, these blocs will be removed from blocs index table + : +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +#ifndef CC_UNIX + +DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ) { + + FIL__TCStreamFile* VPtObj = (FIL__TCStreamFile*) lpParam; + + SInt32 VRet; + DWORD VBuffFull; + UInt32 VNbBytesToWrite; + UInt32 VNbBytesWritten; + char VStrMsg[GLB_CMT_SZ]; + + static SInt32 VDbgSaveCnt = 0; + + #ifdef FIL__DEBUG + EFRIO__TFrame* VDbgPtFrame; + #endif + + + while (1) { + + + // Wait on buffer to read + + VBuffFull = WaitForSingleObject ( VPtObj->ProSemRdBuffHnd, INFINITE ); + + switch ( VBuffFull ) { + + case WAIT_OBJECT_0 : { + + VNbBytesToWrite = VPtObj->ProAParBlocSz[VPtObj->ProIndexRdBuff]; // 11/01/2012 Plume BT bug fix + + // Emulates error during write on RAID 1 each 100 access + // It's DISABLED now + + ++VDbgSaveCnt; + + if ( 0 /* (VDbgSaveCnt % 100) == 0 */ ) { // + VNbBytesWritten = 0; + } + + else { + + WriteFile( + VPtObj->ProFileHnd, // handle to file to write to + VPtObj->ProABuff[VPtObj->ProIndexRdBuff], // pointer to data to write to file + VNbBytesToWrite, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + } + + + if ( VNbBytesWritten != VNbBytesToWrite ) { + + // 12/01/2012 + // - Tag an error maker on the bloc = set its size to negative value + // - This tag will be used by ProFUpdateIndexTable () in PubFClose () to remove blocs not saved from blocs table + + *(VPtObj->ProAPtBlocSz[VPtObj->ProIndexRdBuff]) = -(*(VPtObj->ProAPtBlocSz[VPtObj->ProIndexRdBuff])); + + // Log error + + sprintf ( VStrMsg, "ThreadDisk => Writing buff %d error !", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg, FIL__TCStreamFile_LOG_ERR_ERROR ); + } + + else { + sprintf ( VStrMsg, "ThreadDisk => Buffer %d save to disk", VPtObj->ProIndexRdBuff ); + VPtObj->PubFPrintMsg ( VStrMsg, FIL__TCStreamFile_LOG_ERR_TRACE ); + } + + if ( VPtObj->ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( VPtObj->ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + ++VPtObj->ProIndexRdBuff; + + err_retfail ( VPtObj->ProIndexRdBuff, (ERR_OUT,"Bad variable size => ProIndexRdBuff=%d < 0", VPtObj->ProIndexRdBuff) ); + + if ( VPtObj->ProIndexRdBuff >= FIL__TCStreamFile_MAX_BUFF_NB ) { + VPtObj->ProIndexRdBuff = 0; + } + + ReleaseSemaphore ( VPtObj->ProSemWrBuffHnd, 1, NULL ); + + + break; } + + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFull )); + break; } + + } + + + + } // End while (1) + + return 0; +} + +#endif + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 05/11/2010 +Doc date : 05/11/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFCalcProParBlocSz ( SInt32 DataSz ) { + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VRecInfSz; + + VNotIntegerDiskBlocNb = DataSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (DataSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = DataSz; + } + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ) { + + SInt8 ViBuff; + + ProConfDone = -1; + ProParEnableErrLog = EnableErrLog; + ProParErrLogLvl = ErrLogLvl; + + sprintf ( ProParErrLogFile, "%s", ErrLogFile ); + + // -------------------------------------- + // Init all variables / parameters + // -------------------------------------- + + // Parameters from constructor + + sprintf ( ProParErrLogFile, "" ); + + ProParEnableErrLog = 0; + ProParErrLogLvl = ERR_LOG_LVL_NONE; + ProParDiskBlocSz = DiskBlocSz; + + // Parameters from conf + + sprintf ( ProParDataFile , "" ); + sprintf ( ProInfFileName , "" ); + sprintf ( ProInfFileNameAll, "" ); + + ProParRWBMode = FIL__TCBinFile_RWB_MODE_READ; + ProParMaxBlocSz = 0; + ProParFlushAfterWrite = 0; + ProParMeasTime = 0; + ProParFixedBlocSzMode = 1; + + // Parameter used for multithreading data saving mode + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProAParBlocSz[FIL__TCStreamFile_MAX_BUFF_NB] = 0; + } + + // Variables for internal processing + + ProUseThread = 0; + + ProFileHasBeenClosed = 0; + + ProFileHnd = INVALID_HANDLE_VALUE; + ProPtInfFile = NULL; + ProPtInfFileAll = NULL; + +#ifndef CC_UNIX + + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + InitializeCriticalSection ( &ProCsPrintMsg ); + #endif + +#endif + + ProThreadHnd = INVALID_HANDLE_VALUE; + ProThreadId = 0; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++ ) { + ProABuff[ViBuff] = NULL; + ProAPtBlocSz[ViBuff] = NULL; + } + + ProSemWrBuffHnd = INVALID_HANDLE_VALUE; + ProSemRdBuffHnd = INVALID_HANDLE_VALUE; + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + ProBuffSz = 0; + + ProPtRecInfFile = NULL; + ProPtRecInfFileCpy = NULL; + ProRecInfSz = 0; + + ProReadyToWrite = -1; + ProReadyToRead = -1; + + ProCurRdBlocId = 0; + ProCurRdSz = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProPtrBuffRdData = NULL; + ProSzBuffRdData = 0; + + ProResWrBlocFailCnt = 0; + + + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetDiskSectorSz ( SInt32 DiskBlocSz ) { + + ProParDiskBlocSz = DiskBlocSz; + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 07/03/2011 +Doc date : 07/03/2011 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetDiskSectorSz () { + + return (ProParDiskBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : Msg - The message string + : MsgLevel - It can be + : - FIL__TCStreamFile_LOG_GENERAL_MSG + : - FIL__TCStreamFile_LOG_ERR_TRACE + : - FIL__TCStreamFile_LOG_ERR_WARNING + : - FIL__TCStreamFile_LOG_ERR_ERROR + : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void FIL__TCStreamFile :: PubFPrintMsg ( char* Msg, SInt8 MsgLevel ) { + +#ifndef CC_UNIX + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + EnterCriticalSection( &ProCsPrintMsg ); + #endif +#endif + + switch ( MsgLevel ) { + + case FIL__TCStreamFile_LOG_GENERAL_MSG : { + msg (( MSG_OUT, "%s", Msg )); + break; } + + case FIL__TCStreamFile_LOG_ERR_TRACE : { + err_trace (( ERR_OUT, "%s", Msg )); + break; } + + case FIL__TCStreamFile_LOG_ERR_WARNING : { + err_warning (( ERR_OUT, "%s", Msg )); + break; } + + case FIL__TCStreamFile_LOG_ERR_ERROR : { + err_error (( ERR_OUT, "%s", Msg )); + break; } + + default : { + msg (( MSG_OUT, "%s", Msg )); + break; } + + } + + +#ifndef CC_UNIX + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + LeaveCriticalSection( &ProCsPrintMsg ); + #endif +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : +Rev : 11/01/2012 + : - "Plume BT bug" fix, add cpy of RecInfFile => ProPtRecInfFileCpy + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ) { + + SInt8 ViBuff; + SInt32 VNotIntegerDiskBlocNb; + +#ifndef CC_UNIX + #ifndef FILE__NO_DATE_TIME_HANDLING + TDateTime VODateTime; + #endif +#endif + + + + // ------------------------------------------------------- + // Set class parameters from PubFConf parameters list + // ------------------------------------------------------- + + err_retnull ( PtMyself, (ERR_OUT,"PtMyself == NULL") ); + + PriPtMyself = PtMyself; + + ProUseThread = UseThread; + + sprintf ( ProParDataFile, "%s", DataFile ); + + sprintf ( ProInfFileName, "%s.inf", ProParDataFile ); + + sprintf ( ProInfFileNameAll, "%s.all.inf", ProParDataFile ); + + ProParRWBMode = RWBMode; + + ProParFixedBlocSzMode = FixedBlocSzMode; + + ProParRequestedBlocSz = BlocSz; + + VNotIntegerDiskBlocNb = ProParRequestedBlocSz % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + ProParBlocSz = ( (ProParRequestedBlocSz / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + ProParBlocSz = ProParRequestedBlocSz; + } + + err_trace (( ERR_OUT, "RequestedBlocSz=%d - BlocSz=%d", ProParRequestedBlocSz, ProParBlocSz )); + + + ProParRequestedMaxBlocSz = MaxBlocSz; + + if ( ProParRequestedMaxBlocSz >= ProParBlocSz ) { + ProParMaxBlocSz = ProParRequestedMaxBlocSz; + } + + else { + err_warning (( ERR_OUT, "ProParMaxBlocSz=%d must be adjusted -> Set to ProParBlocSz=%d", ProParMaxBlocSz, ProParBlocSz )); + ProParMaxBlocSz = ProParBlocSz; + } + + ProParFlushAfterWrite = FlushAfterWrite; + ProParMeasTime = MeasTime; + + // ------------------------------------------------------- + // Alloc information file record + // ------------------------------------------------------- + + if ( ProParFixedBlocSzMode == 1 ) { + ProRecInfSz = sizeof (FIL__TCStreamFile_Old_TRecInfFile); + } + + else { + + // BUG ? + + // ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (UInt64) ); + + ProRecInfSz = sizeof (FIL__TCStreamFile_TRecInfFile) + ( FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE * sizeof (FIL__TCStreamFile_TBlocInf) ); + + } + + err_warning (( ERR_OUT, "ProRecInfSz=%d ", ProRecInfSz )); // added, JB 2014/10/16 + + ProPtRecInfFile = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFile, (ERR_OUT,"Allocation of info record failed !") ); + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // Add cpy of RecInfFile on 11/01/2012 + + ProPtRecInfFileCpy = (FIL__TCStreamFile_TRecInfFile*) malloc ( ProRecInfSz ); + + err_retnull ( ProPtRecInfFileCpy, (ERR_OUT,"Allocation of info record cpy failed !") ); + + memset ( ProPtRecInfFileCpy, 0, ProRecInfSz ); + + + // ------------------------------------------------------- + // Create or open information file + // ------------------------------------------------------- + + // Write mode => Create info file + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProPtRecInfFile->Version = 1; + ProPtRecInfFile->FixedBlocSz = ProParFixedBlocSzMode; + ProPtRecInfFile->MaxBlocSz = ProParMaxBlocSz; + ProPtRecInfFile->BlocSz = ProParBlocSz; + ProPtRecInfFile->BlocNb = 0; + ProPtRecInfFile->ABlocInf[0].Offset = 0; + ProPtRecInfFile->ABlocInf[0].Sz = 0; + +#ifndef CC_UNIX + #ifndef FILE__NO_DATE_TIME_HANDLING + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateCreate = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeCreate = TIME__FConvDateTime2Time ( VODateTime ); + #endif +#else + ProPtRecInfFile->DateCreate.W32 = 0; + ProPtRecInfFile->TimeCreate.W32 = 0; +#endif + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Creation of info file %s failed !", ProInfFileName) ); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + err_trace (( ERR_OUT, "Info file=%s created", ProInfFileName )); + } + + // Read mode => Open info file + + else { + + ProPtInfFile = fopen ( ProInfFileName, "rb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Open info file %s failed => system : %s", ProInfFileName, _strerror ( "" ) )); + err_trace (( ERR_OUT, "Info file=%s read", ProInfFileName )); + + if ( fread ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Read info file %s failed => system : %s", ProInfFileName, _strerror ( "" )) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"Close info file %s failed !", ProInfFileName) ); + } + + // Print info file + + PubFPrintInfFile (); + + // Set bloc size + + ProParBlocSz = ProPtRecInfFile->BlocSz; + + if ( ProParRequestedBlocSz != ProParBlocSz ) { + err_warning (( ERR_OUT, "Requested bloc sz=%d <> Info file bloc sz=%d => Use Info file bloc sz", ProParRequestedBlocSz, ProParBlocSz )); + } + + } + + + // ------------------------------------------------------------- + // Write mode => Allocate buffers, create semaphores and thread + // ------------------------------------------------------------- + + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_WRITE ) { + + if ( FIL__TCStreamFile_MAX_BUFF_NB > 4 ) { + err_retfail ( -1, (ERR_OUT,"FIL__TCStreamFile_MAX_BUFF_NB = %d ! Handling of more than 4 buffers is NOT implemented !", FIL__TCStreamFile_MAX_BUFF_NB) ); + } + + // Allocate buffers + + ProBuffSz = ProParMaxBlocSz; + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + // If already allocated => Free + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + } + + // Allocate + + ProABuff[ViBuff] = (UInt8*) malloc ( ProBuffSz ); + + err_retnull ( ProABuff[ViBuff], (ERR_OUT,"Allocation buffer[%d] of %d bytes failed !", ViBuff, ProBuffSz ) ); + err_trace (( ERR_OUT, "Buffer[%d] of %d bytes allocated", ViBuff, ProBuffSz )); + + // Reset content with $FF + + memset ( ProABuff[ViBuff], 0xFF, ProBuffSz ); + } + + // Create & init semaphores + + #ifndef CC_UNIX + ProSemWrBuffHnd = CreateSemaphore( NULL, FIL__TCStreamFile_MAX_BUFF_NB, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = Max = Max buff nb + + err_retnull ( ProSemWrBuffHnd, (ERR_OUT,"Create SemWrBuff failed ! - LastError=%d", GetLastError ()) ); + + ProSemRdBuffHnd = CreateSemaphore( NULL, 0, FIL__TCStreamFile_MAX_BUFF_NB, NULL ); // Init = 0, Max = Max buff nb + + err_retnull ( ProSemRdBuffHnd, (ERR_OUT,"Create SemRdBuff failed ! - LastError=%d", GetLastError ()) ); + #endif + + // Init buffers index + + ProIndexWrBuff = 0; + ProIndexRdBuff = 0; + + // Create thread + + #ifndef CC_UNIX + ProThreadHnd = CreateThread ( NULL, 0, FIL__TCStreamFile_FThread, (void*) PriPtMyself /* Param */ , 0, &ProThreadId ); + err_retnull ( ProThreadHnd, (ERR_OUT,"Thread creation failed ! LastError=%d", GetLastError ()) ); + #endif + + } + + // ------------------------------------------------------------- + // Read mode => Allocate memory buffer for data read from file + // ------------------------------------------------------------- + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + + ProSzBuffRdData = ProParMaxBlocSz; + ProPtrBuffRdData = malloc ( ProSzBuffRdData ); + + err_retnull ( ProPtrBuffRdData, (ERR_OUT,"Malloc of %d bytes failed !", ProSzBuffRdData) ); + } + + ProConfDone = 1; + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFileName ( char* DataFile ) { + + sprintf ( ProParDataFile, "%s", DataFile ); + + err_retok (( ERR_OUT, "%s", DataFile )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 03/02/2009 +Doc date : 03/02/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSetFlushMode ( SInt8 FlushAfterWrite ) { + + ProParFlushAfterWrite = FlushAfterWrite; + + + err_retok (( ERR_OUT, "" )); +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : Prints record passed as parameter, not the one of the class like PubFPrintInfFile () + : It's also possible to add a comment and a "tag string" at the beginning of each line. +Level : +Date : 13/01/2012 +Doc date : 13/01/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFileRec ( FIL__TCStreamFile_TRecInfFile* Pt, char* Cmt, char* TagStr ) { + + SInt32 ViBloc; + SInt16 ViSpareW32Info; + + msg (( MSG_OUT, "" )); + msg (( MSG_OUT, "$" )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record - %s", Cmt )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "%s Version = %d", TagStr, Pt->Version )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "%s Date create = %s", TagStr, TIME__FDateL2Str ( Pt->DateCreate, NULL, 0 ) )); + msg (( MSG_OUT, "%s Time create = %s", TagStr, TIME__FTime2Str ( Pt->TimeCreate, NULL, 0 ) )); + msg (( MSG_OUT, "%s Date close = %s", TagStr, TIME__FDateL2Str ( Pt->DateClose , NULL, 0 ) )); + msg (( MSG_OUT, "%s Time close = %s", TagStr, TIME__FTime2Str ( Pt->TimeClose , NULL, 0 ) )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "%s FixedBlocSz = %d", TagStr, Pt->FixedBlocSz )); + msg (( MSG_OUT, "%s MaxBlocSz = %d", TagStr, Pt->MaxBlocSz )); + msg (( MSG_OUT, "%s BlocSz = %d", TagStr, Pt->BlocSz )); + msg (( MSG_OUT, "%s BlocNb = %d", TagStr, Pt->BlocNb )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "%s ABlocInf[0].Offset = %Lu" , TagStr, Pt->ABlocInf[0].Offset )); + msg (( MSG_OUT, "%s ABlocInf[0].Sz = %d ", TagStr, Pt->ABlocInf[0].Sz )); + msg (( MSG_OUT, "%s ABlocInf[0].SpareW32InfoFormat = %d ", TagStr, Pt->ABlocInf[0].SpareW32InfoFormat )); + msg (( MSG_OUT, "%s ABlocInf[0].SpareW32InfoNb = %d ", TagStr, Pt->ABlocInf[0].SpareW32InfoNb )); + + for ( ViSpareW32Info=0; ViSpareW32Info < Pt->ABlocInf[0].SpareW32InfoNb; ViSpareW32Info++ ) { + msg (( MSG_OUT, "%s ABlocInf[0].ASpareW32Info[%.2d] = %d ", TagStr, ViSpareW32Info, Pt->ABlocInf[0].ASpareW32Info[ViSpareW32Info] )); + } + + + if ( Pt->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < 200 /* Pt->BlocNb */; ViBloc++ ) { + msg (( MSG_OUT, "%s Bloc[%.4d] : Offset=%.12Lu - Sz=%.8d [Bytes] - ASpare [0]=%.4d [1]=%.4d [2]=%.4d [3]=%.4d", TagStr, ViBloc, Pt->ABlocInf[ViBloc].Offset, Pt->ABlocInf[ViBloc].Sz, Pt->ABlocInf[ViBloc].ASpareW32Info[0], Pt->ABlocInf[ViBloc].ASpareW32Info[1], Pt->ABlocInf[ViBloc].ASpareW32Info[2], Pt->ABlocInf[ViBloc].ASpareW32Info[3] )); + } + + } + + msg (( MSG_OUT, "#" )); + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 20/05/2010 +Doc date : 20/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFPrintInfFile () { + + SInt32 ViBloc; + SInt16 ViSpareW32Info; + + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, " Info file record " )); + msg (( MSG_OUT, "-------------------------" )); + msg (( MSG_OUT, "Version = %d", ProPtRecInfFile->Version )); + msg (( MSG_OUT, "-------------------------" )); + //msg (( MSG_OUT, "Date create = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateCreate, NULL, 0 ) )); + //msg (( MSG_OUT, "Time create = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeCreate, NULL, 0 ) )); + //msg (( MSG_OUT, "Date close = %s", TIME__FDateL2Str ( ProPtRecInfFile->DateClose , NULL, 0 ) )); + //msg (( MSG_OUT, "Time close = %s", TIME__FTime2Str ( ProPtRecInfFile->TimeClose , NULL, 0 ) )); + //msg (( MSG_OUT, "-------------------------" )); + //msg (( MSG_OUT, "FixedBlocSz = %d", ProPtRecInfFile->FixedBlocSz )); + //msg (( MSG_OUT, "MaxBlocSz = %d", ProPtRecInfFile->MaxBlocSz )); + //msg (( MSG_OUT, "BlocSz = %d", ProPtRecInfFile->BlocSz )); + //msg (( MSG_OUT, "BlocNb = %d", ProPtRecInfFile->BlocNb )); + //msg (( MSG_OUT, "-------------------------" )); + //msg (( MSG_OUT, "ABlocInf[0].Offset = %Lu", ProPtRecInfFile->ABlocInf[0].Offset )); + //msg (( MSG_OUT, "ABlocInf[0].Sz = %d ", ProPtRecInfFile->ABlocInf[0].Sz )); + //msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoFormat = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoFormat )); + //msg (( MSG_OUT, "ABlocInf[0].SpareW32InfoNb = %d ", ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb )); + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[0].SpareW32InfoNb; ViSpareW32Info++ ) { + msg (( MSG_OUT, "ABlocInf[0].ASpareW32Info[%.2d] = %d ", ViSpareW32Info, ProPtRecInfFile->ABlocInf[0].ASpareW32Info[ViSpareW32Info] )); + } + + + if ( ProPtRecInfFile->FixedBlocSz == 0 ) { + + for ( ViBloc=0; ViBloc < ProPtRecInfFile->BlocNb; ViBloc++ ) { + msg (( MSG_OUT, "Bloc[%.4d] : Offset=%.12Lu - Sz=%.8d [Bytes] - ASpare [0]=%.4d [1]=%.4d [2]=%.4d [3]=%.4d", ViBloc, ProPtRecInfFile->ABlocInf[ViBloc].Offset, ProPtRecInfFile->ABlocInf[ViBloc].Sz, ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[0], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[1], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[2], ProPtRecInfFile->ABlocInf[ViBloc].ASpareW32Info[3] )); + } + + } + + msg (( MSG_OUT, "-------------------------" )); + + err_retok (( ERR_OUT, "" )); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFGetFileSz () { + + SInt32 VFileSz; + SInt32 VCurPos; + + // If object conf not done => Read file size with FIL_FFileSize () + + if ( ProConfDone == 0 ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If conf done + + // If file in read mode + + if ( ProParRWBMode == FIL__TCBinFile_RWB_MODE_READ ) { + + // If file is closed + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + VFileSz = FIL_FFileSize ( ProParDataFile ); + err_retval ( VFileSz, ( ERR_OUT, "File size = %d Bytes", VFileSz ) ); + } + + // If file is already open + + else { + err_retfail ( -1, (ERR_OUT,"File is opened => Get file size not coded in this state (TOB ...)") ); + } + + } + + // File is in write mode OR in RW mode + + else { + err_retval ( ProTotWrSz, ( ERR_OUT, "Current file size = %d Bytes", ProTotWrSz ) ); + } + + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 31/01/2009 + : - Calculation => file size / block size +Rev : 20/05/2010 + : - Read from info file field BlocNb + : +Doc date : 31/01/2009 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGetBlocNb () { + + SInt32 VBlocNb; + SInt32 VRemainder; + SInt32 VFileSz; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + +/* Before 20/05/2010 + + VFileSz = PubFGetFileSz (); + + err_retfail ( VFileSz, (ERR_OUT,"File size calculation failed !" ) ); + + VBlocNb = VFileSz / ProParBlocSz; + VRemainder = VFileSz % ProParBlocSz; + + if ( VRemainder != 0 ) { + err_retfail ( -VBlocNb, (ERR_OUT,"Not integer bloc number ! %d blocs + %d bytes !", VBlocNb, VRemainder ) ); + } + +*/ + + VBlocNb = ProPtRecInfFile->BlocNb; + + err_retval ( VBlocNb, ( ERR_OUT, "File %s contains %d blocs ", ProParDataFile, VBlocNb ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 13/01/2012 + : - Add handling of flag ProFileHasBeenClosed, needed for Robustness + : improvment of data saving on RAID implemented on 12/01/2012. + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFCreate () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't create a file when RWB mode IS NOT Write !") ); + } + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_WRITE | GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for wb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = 1; + ProReadyToRead = -1; + ProFileHasBeenClosed = 0; + + ProCurWrBlocId = 0; + ProCurWrSz = 0; + ProTotWrSz = 0; + + ProResWrBlocFailCnt = 0; + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 13/01/2012 + : - Add handling of flag ProFileHasBeenClosed, needed for Robustness + : improvment of data saving on RAID implemented on 12/01/2012. + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFOpen () { + +#ifdef CC_UNIX + + ProFilePtUx = fopen ( ProParDataFile, "rb" ); + + err_retnull ( ProFilePtUx, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + + ProReadyToWrite = -1; + ProReadyToRead = 1; + ProFileHasBeenClosed = 0; + + err_retok (( ERR_OUT, "" )); + +#else + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can't open a file when RWB mode IS NOT Read !") ); + } + + + ProFileHnd = CreateFile( + ProParDataFile, // pointer to name of the file + GENERIC_READ, // access (read-write) mode + FILE_SHARE_READ , // share mode + NULL , // pointer to security attributes + OPEN_ALWAYS, // how to create + FILE_FLAG_NO_BUFFERING, // file attributes + NULL // handle to file with attributes to copy + ); + + + if ( ProFileHnd == INVALID_HANDLE_VALUE ) { + err_retfail ( -1, (ERR_OUT,"Open for rb of file=%s failed ! => System : %s", ProParDataFile, _strerror ("") ) ); + } + + + ProReadyToWrite = -1; + ProReadyToRead = 1; + + err_retok (( ERR_OUT, "" )); + +#endif +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : - First implementation with 2 buffers for testing DAQ +Rev : 09/05/2010 + : - Circular buffer implementation + : + : 24/02/2011 + : - Handle SpareW32Info as an array now => New parameters + : + : 11/01/2012 + : - Plume BT bug fix (corrupted data while saving in multithreading mode) + : - Bloc size saving per bloc was not implemented, it was done for one bloc + : - Implementation done via ProAParBlocSz array. + : + : 12/01/2012 + : - Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed, these blocs will be removed from blocs index table + : + : +Doc date : 07/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + + +SInt32 FIL__TCStreamFile :: PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ) { + + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + SInt16 ViSpareW32Info; + DWORD VBuffFree; + UInt32 VNbBytesWritten; + + #ifdef FIL__DEBUG + EFRIO__TFrame* VDbgPtFrame; + EFRIO__TFileSpareW32Info* VDbgPtSpareW32Info; + #endif + + + + #ifdef FIL__DEBUG + VDbgPtFrame = (EFRIO__TFrame*) PtrData; + VDbgPtSpareW32Info = (EFRIO__TFileSpareW32Info*) PtSpareW32Info; + #endif + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") ); + + err_retnull ( PtrData, (ERR_OUT,"PtrData == NULL") ); + + if ( DataSz > ProParMaxBlocSz ) { + err_retfail ( -1, (ERR_OUT,"Write abort : DataSz=%d > ProParMaxBlocSz=%d", DataSz, ProParMaxBlocSz) ); + } + + err_retnull ( PtSpareW32Info, (ERR_OUT,"PtSpareW32Info == NULL") ); + + if ( SpareW32InfoNb > FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) { + err_retfail ( -1, (ERR_OUT,"SpareW32InfoNb=%d > Max=%d", SpareW32InfoNb, FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB ) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_WRITE ) { + err_retfail ( -1, (ERR_OUT,"Abort : Cant write to a file when RWB mode IS NOT Write !") ); + } + + // If variable bloc sz mode => Test max nb of blocs allowed & Adjust ProParBlocSz + + if ( ProParFixedBlocSzMode == 0 ) { + + if ( ProPtRecInfFile->BlocNb >= FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE ) { + err_retfail ( -2, (ERR_OUT,"$$$ Max bloc nb = %d reached in variable bloc sz mode !", FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE) ); + } + + ProFCalcProParBlocSz ( DataSz ); + } + + // err_error (( ERR_OUT, "DataSz=%d - ProParBlocSz=%d bytes", DataSz, ProParBlocSz )); + + ProCurWrSz = ProParBlocSz; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + // Let thread write data to disk in background task + + if ( ProUseThread == 1 ) { + + + // Wait on buffer to write + + VBuffFree = WaitForSingleObject ( ProSemWrBuffHnd, 1 /* ms */ ); + + switch ( VBuffFree ) { + + case WAIT_TIMEOUT : { + ++ProResWrBlocFailCnt; + err_retfail ( -1, (ERR_OUT,"Write failed for the %d time -> No buffer available - DbgCallPar=%d !", ProResWrBlocFailCnt, DbgCallPar ) ); + break; } + + case WAIT_OBJECT_0 : { + + // Update index file table => Code moved here on 12/01/2012 + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ProAPtBlocSz[ProIndexWrBuff] = &ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz; // Store ptr on bloc size + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + // Update index file table => Code moved here on 12/01/2012 + + ProAParBlocSz[ProIndexWrBuff] = ProParBlocSz; // 11/01/2012 Plume BT bug fix + + memcpy ( ProABuff[ProIndexWrBuff], PtrData, DataSz ); + + + // PubFPrintMsg ( "Thread => Buffer %d filled", ProIndexWrBuff ); + err_trace (( ERR_OUT, "Thread => Buffer %d filled - DbgCallPar=%d", ProIndexWrBuff, DbgCallPar )); + + ++ProIndexWrBuff; + + err_retfail ( ProIndexWrBuff, (ERR_OUT,"Bad variable size => ProIndexWrBuff=%d < 0", ProIndexWrBuff) ); + + if ( ProIndexWrBuff >= FIL__TCStreamFile_MAX_BUFF_NB) { + ProIndexWrBuff = 0; + } + + ReleaseSemaphore ( ProSemRdBuffHnd, 1, NULL ); + break; } + + default : { + err_error (( ERR_OUT, "Unknown WaitForMultipleObjects call return value = %d", VBuffFree )); + break; } + + } + + } + + // Write NOW data to disk + + else { + + // Copy to buffer -> "Automatically" add padding bytes + + memcpy ( ProABuff[0], PtrData, DataSz ); + + // Warning => Write ProParBlocSz bytes AND NOT the value passed via parameter DataSz + // because non buffered I/O functions MUST write multiple of DISK bloc size + + WriteFile( + ProFileHnd, // handle to file to write to + ProABuff[0], // pointer to data to write to file + ProParBlocSz, // number of bytes to write + &VNbBytesWritten, // pointer to number of bytes written + NULL // pointer to structure needed for overlapped I/O + ); + + if ( VNbBytesWritten != ProParBlocSz ) { + err_retfail ( VRet, (ERR_OUT,"Writing block %d failed %d bytes written - %d bytes requested ! - %s", ProCurWrBlocId, VNbBytesWritten, ProParBlocSz, strerror ( errno ) ) ); + } + + if ( ProParFlushAfterWrite == 1 ) { + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + } + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + + } // END "else write now data on disk" + + +/* Modified on 12/01/2012 + => This part can not be common for non multithreading and multithreading data saving mode + => Because it must be executed before before data saving code in case of multithreading and after otherwise + => Therefore, it has been dupplicated in the part of source code which handles each mode + + + if ( ProParFixedBlocSzMode == 0 ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Offset = ProTotWrSz; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].Sz = ProCurWrSz; + + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoFormat = SpareW32InfoFormat; + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].SpareW32InfoNb = SpareW32InfoNb; + + for ( ViSpareW32Info=0; ViSpareW32Info < SpareW32InfoNb; ViSpareW32Info++ ) { + ProPtRecInfFile->ABlocInf[ProPtRecInfFile->BlocNb].ASpareW32Info[ViSpareW32Info] = PtSpareW32Info[ViSpareW32Info]; + } + + } + + ++ProPtRecInfFile->BlocNb; + + ++ProCurWrBlocId; + ProTotWrSz += ProCurWrSz; + +*/ + + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + + if ( ProUseThread == 1 ) { + err_trace (( ERR_OUT, "Copy bloc of %d bytes done in %d [ms]", DataSz, ProTimeExec )); + } + + else { + err_trace (( ERR_OUT, "Bloc of %d bytes written in %d [ms]", VNbBytesWritten, ProTimeExec )); + } + + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ) { + +#ifdef CC_UNIX + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + SInt32 VBlocNbRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VBlocNbRead = fread ( DestPtr, VDataSzToRead /* Bloc size */, 1 /* Bloc NB */, ProFilePtUx ); + + if ( VBlocNbRead != 1 ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed of %d bytes ! - %s", ProCurRdBlocId, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#else + + SInt32 VNotIntegerDiskBlocNb; + SInt32 VDataSzToRead; + UInt32 VNbBytesRead; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + err_retnull ( DestPtr, (ERR_OUT,"DestPtr == NULL") ); + + // Calculate real size to read => MUST be a multiple of DISK bloc size + + VNotIntegerDiskBlocNb = DataSzToRead % ProParDiskBlocSz; + + if ( VNotIntegerDiskBlocNb ) { + VDataSzToRead = ( (DataSzToRead / ProParDiskBlocSz) + 1 ) * ProParDiskBlocSz; + } + + else { + VDataSzToRead = DataSzToRead; + } + + if ( VDataSzToRead > MaxDestSz ) { + err_retfail ( -1, (ERR_OUT,"Read abort : VDataSzToRead=%d > MaxDestSz=%d", VDataSzToRead, MaxDestSz) ); + } + + if ( ProParRWBMode != FIL__TCBinFile_RWB_MODE_READ ) { + err_retfail ( -1, (ERR_OUT,"Abort : Can read from a file when RWB mode IS NOT Read !") ); + } + + + ProCurRdSz = VDataSzToRead; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + ReadFile( + ProFileHnd, // handle of file to read + DestPtr, // address of buffer that receives data + VDataSzToRead, // number of bytes to read + &VNbBytesRead, // address of number of bytes read + NULL // address of structure for data + ); + + if ( VNbBytesRead != VDataSzToRead ) { + err_retfail ( -1, (ERR_OUT,"Reading block %d failed : %d bytes read - %d bytes requested ! - %s", ProCurRdBlocId, VNbBytesRead, VDataSzToRead, strerror ( errno ) ) ); + } + + ++ProCurRdBlocId; + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc of %d bytes read in %d [ms]", DataSzToRead, ProTimeExec )); + #endif + } + #endif + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFSeqRead ( SInt32 DataSzToRead ) { + + SInt32 VRet; + + VRet = PubFSeqRead ( ProPtrBuffRdData, ProSzBuffRdData, DataSzToRead ); + + err_retfailnull ( VRet, (ERR_OUT,"PubFSeqRead failed !") ); + + err_retval ( ProPtrBuffRdData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 + : Limited to 4 GB files + : +Rev : 09/05/2010 + : - Use W64 offset => Not limited to 4 GB file +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFGotoBloc ( SInt32 BlocNo ) { + +#ifdef CC_UNIX + + SInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = fseeko ( ProFilePtUx, (off_t) VOffsetW64, SEEK_SET ); + + err_retfail ( VRet, (ERR_OUT,"Bloc %d read failed ! => System : %s", BlocNo, _strerror ("") ) ); + + err_retok (( ERR_OUT, "" )); + +#else + + UInt32 VRet; + UInt64 VOffsetW64; + UInt32* VPtOffsetLow32; + UInt32* VPtOffsetHigh32; + LPVOID VMsgBuf; + + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + if ( BlocNo >= ProPtRecInfFile->BlocNb ) { + err_retfail ( -1, (ERR_OUT,"BlocNo=%d > Max=%d", BlocNo, ProPtRecInfFile->BlocNb-1 ) ); + } + + VPtOffsetLow32 = ((UInt32*) &VOffsetW64); + VPtOffsetHigh32 = ((UInt32*) &VOffsetW64) + 1; + + if ( ProParFixedBlocSzMode == 0 ) { + VOffsetW64 = ProPtRecInfFile->ABlocInf[BlocNo].Offset; + } + + else { + VOffsetW64 = (UInt64) BlocNo * (UInt64) ProParBlocSz; // Cast (UInt64) needed otherwise 32 bits arithmetic is used ; + } + + + VRet = SetFilePointer ( + ProFileHnd, // handle of file + *VPtOffsetLow32, // number of bytes to move file pointer + (SInt32*) VPtOffsetHigh32, // address of high-order word of distance to move + // lpDistanceToMoveHigh = 0 => Limited to 4 GB + FILE_BEGIN // how to move + ); + + + if ( VRet == 0xFFFFFFFF ) { + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &VMsgBuf, + 0, + NULL + ); + + err_retfail ( -1, (ERR_OUT,"Goto bloc %d failed => %s", BlocNo, VMsgBuf ) ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 24/02/2011 + : - Handle SpareW32Info as and array ASpareW32Info now => New parameters + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ) { + + SInt32 VRet; + SInt16 ViSpareW32Info; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );; + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfail ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + + if ( (PtSpareW32InfoFormat != NULL) && (PtSpareW32Info != NULL) && (ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb <= MaxSpareW32InfoNb) ) { + + *PtSpareW32InfoFormat = ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoFormat; + + for ( ViSpareW32Info=0; ViSpareW32Info < ProPtRecInfFile->ABlocInf[BlocNo].SpareW32InfoNb; ViSpareW32Info++ ) { + PtSpareW32Info[ViSpareW32Info] = ProPtRecInfFile->ABlocInf[BlocNo].ASpareW32Info[ViSpareW32Info]; + } + + } + + else { + err_warning (( ERR_OUT, "ASpareInfo bloc not updated ! Pointer NULL or Dest size too small ?" )); + } + + } + + VRet = PubFSeqRead ( DestPtr, MaxDestSz, ProParBlocSz ); + + err_retfail ( VRet, (ERR_OUT,"Read bloc %d failed !", BlocNo) ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + return (ProParBlocSz); +} + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +void* FIL__TCStreamFile :: PubFBlocRead ( SInt32 BlocNo ) { + + void* VPtData; + SInt32 VRet; + + err_retfailnull ( ProConfDone , (ERR_OUT,"Abort => Conf not done ") ); + err_retfailnull ( ProReadyToRead, (ERR_OUT,"Abort => File not open in RB !") ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + #ifndef CC_ROOT_DLL + if (ProParMeasTime) ProTime1 = GetTickCount (); + #endif + #endif + + + VRet = PubFGotoBloc ( BlocNo ); + + err_retfailnull ( VRet, (ERR_OUT,"Goto bloc %d failed !", BlocNo ) ); + + if ( ProParFixedBlocSzMode == 0 ) { + ProParBlocSz = ProPtRecInfFile->ABlocInf[BlocNo].Sz; + } + + VPtData = PubFSeqRead ( ProParBlocSz ); + + #ifdef FIL__TCStreamFile_MEAS_TIME + if (ProParMeasTime) { + #ifndef CC_ROOT_DLL + ProTime2 = GetTickCount (); + ProTimeExec = ProTime2 - ProTime1; + err_trace (( ERR_OUT, "Bloc [%4d] of %d bytes read in %d [ms]", BlocNo, ProParBlocSz, ProTimeExec )); + #endif + } + #endif + + err_retval ( VPtData, ( ERR_OUT, "" ) ); +} + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 13/01/2012 + : - Add handling of flag ProFileHasBeenClosed, needed for Robustness + : improvment of data saving on RAID implemented on 12/01/2012. + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFFlush () { + +#ifdef CC_UNIX + + err_retfail ( -1, (ERR_OUT,"Not supported undex UNIX !") ); + +#else + + SInt32 VRet; + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProFileHasBeenClosed == 1 ) { + err_warning (( ERR_OUT, "File has already been closed !" )); + return (0); + } + + + VRet = (SInt32) FlushFileBuffers ( ProFileHnd ); + + if ( VRet == 0 ) { + err_retfail ( -1, (ERR_OUT,"FlushFileBuffers (...) failed !") ); + } + + err_retok (( ERR_OUT, "" )); + +#endif + +} + + +/******************************************************************************* +Prototype : +Goal : Remove the blocs which have not been saved (write on RAID has failed) + : from blocs table. +Inputs : +Ouputs : +Globals : +Remark : Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed (FIL__TCStreamFile_FThread), these blocs will be removed + : from blocs index table. + : +Level : +Date : 12/01/2012 + : +Doc date : +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: ProFUpdateIndexTable () { + + SInt32 VRet; + SInt32 ViSrcBloc; + SInt32 ViDestBloc; + SInt32 VSrcTotBlocsNb; + SInt32 VDestGoodBlocsNb; + SInt32 VOffsetCorrection; + + + // Copy normal table in temporary record + + memcpy ( ProPtRecInfFileCpy, ProPtRecInfFile, ProRecInfSz ); + + // Reset normal table + + memset ( ProPtRecInfFile, 0, ProRecInfSz ); + + // Restor fields - We want to reset bloc list not "header fields" + + ProPtRecInfFile->Version = ProPtRecInfFileCpy->Version; + ProPtRecInfFile->DateCreate = ProPtRecInfFileCpy->DateCreate; + ProPtRecInfFile->TimeCreate = ProPtRecInfFileCpy->TimeCreate; + ProPtRecInfFile->DateClose = ProPtRecInfFileCpy->DateClose; + ProPtRecInfFile->TimeClose = ProPtRecInfFileCpy->TimeClose; + ProPtRecInfFile->FixedBlocSz = ProPtRecInfFileCpy->FixedBlocSz; + ProPtRecInfFile->MaxBlocSz = ProPtRecInfFileCpy->MaxBlocSz; + ProPtRecInfFile->BlocSz = ProPtRecInfFileCpy->BlocSz; + ProPtRecInfFile->BlocNb = ProPtRecInfFileCpy->BlocNb; + + + // Rebuild normal table with blocs non corrupted + + VOffsetCorrection = 0; + VSrcTotBlocsNb = ProPtRecInfFileCpy->BlocNb; + VDestGoodBlocsNb = 0; + ViDestBloc = 0; + + for ( ViSrcBloc=0; ViSrcBloc < VSrcTotBlocsNb; ViSrcBloc++ ) { + + if ( ProPtRecInfFileCpy->ABlocInf[ViSrcBloc].Sz > 0 ) { + ProPtRecInfFile->ABlocInf[ViDestBloc] = ProPtRecInfFileCpy->ABlocInf[ViSrcBloc]; + ProPtRecInfFile->ABlocInf[ViDestBloc].Offset = ProPtRecInfFileCpy->ABlocInf[ViSrcBloc].Offset + VOffsetCorrection; + ++ViDestBloc; + } + + else { + VOffsetCorrection = VOffsetCorrection + ProPtRecInfFileCpy->ABlocInf[ViSrcBloc].Sz; // Add negative size + } + + } // End for + + VDestGoodBlocsNb = ViDestBloc; + + // Overwrite normal table blocs nb with good blocs nb + + ProPtRecInfFile->BlocNb = VDestGoodBlocsNb; + + + err_retok (( ERR_OUT, "" )); +} + + + + +/******************************************************************************* +Prototype : +Goal : +Inputs : +Ouputs : +Globals : +Remark : +Level : +Date : 01/05/2010 +Rev : 12/01/2012 + : - Robustness improvment by tagging (add - to size info) buffers when write + : on RAID has failed, these blocs will be removed from blocs index table + : - Call ProFUpdateIndexTable () + : - Save two index files : + : *.inf = normal without info on blocs not saved + : *.all.inf = default with all blocs info + : + : 13/01/2012 + : - Add flag ProFileHasBeenClosed, in order to avoid multiple calls + : of this function, because it's NOT allowed with the new handling of + : index table (suppression of bad blocs). + : + : +Doc date : 01/05/2010 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +Labo : IPHC */ +/******************************************************************************/ + +SInt32 FIL__TCStreamFile :: PubFClose () { + + SInt32 VRet; + SInt8 ViBuff; + +#ifndef CC_UNIX + #ifndef FILE__NO_DATE_TIME_HANDLING + TDateTime VODateTime; + #endif +#endif + + err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") ); + + + if ( ProFileHasBeenClosed == 1 ) { + err_warning (( ERR_OUT, "File has already been closed !" )); + return (0); + } + + ProFileHasBeenClosed = 1; + + if ( ProReadyToWrite == 1 ) { + PubFFlush (); + } + + ProConfDone = 0; + +#ifndef CC_UNIX + CloseHandle ( ProFileHnd ); +#endif + + // Free read buffers + + if ( ProPtrBuffRdData != NULL ) { + free ( ProPtrBuffRdData ); + ProPtrBuffRdData = NULL; + } + + // Free write buffers + + for ( ViBuff=0; ViBuff < FIL__TCStreamFile_MAX_BUFF_NB; ViBuff++) { + + if ( ProABuff[ViBuff] != NULL ) { + free ( ProABuff[ViBuff] ); + ProABuff[ViBuff] = NULL; + } + + } + + + // Get close date & time + +#ifndef CC_UNIX + #ifndef FILE__NO_DATE_TIME_HANDLING + VODateTime = VODateTime.CurrentDateTime (); + ProPtRecInfFile->DateClose = TIME__FConvDateTime2DateL ( VODateTime ); + ProPtRecInfFile->TimeClose = TIME__FConvDateTime2Time ( VODateTime ); + #endif +#else + ProPtRecInfFile->DateClose.W32 = 0; + ProPtRecInfFile->TimeClose.W32 = 0; +#endif + + + + + ProFUpdateIndexTable (); + + + if ( ProReadyToWrite == 1 ) { + + // ------------------------------- + // Save updated index file table + // ------------------------------- + + // Overwrite info file with update close time & date + bloc nb + + ProPtInfFile = fopen ( ProInfFileName, "wb" ); + + err_retnull ( ProPtInfFile, (ERR_OUT,"Overwrite of info file %s failed !", ProInfFileName) ); + + err_error (( ERR_OUT, "TRACE ProPtRecInfFile = %X", ProPtRecInfFile )); + + if ( fwrite ( ProPtRecInfFile, ProRecInfSz, 1, ProPtInfFile ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileName) ); + } + + if ( fclose (ProPtInfFile) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file failed => System : %s", strerror ( errno ) ) ); + } + + // ------------------------------- + // Save default index file table = with all blocs info + // ------------------------------- + + // Create info file + + ProPtInfFileAll = fopen ( ProInfFileNameAll, "wb" ); + + err_retnull ( ProPtInfFileAll, (ERR_OUT,"Create of info file ALL %s failed !", ProInfFileNameAll) ); + + err_error (( ERR_OUT, "TRACE ProPtRecInfFile = %X", ProPtRecInfFile )); + + if ( fwrite ( ProPtRecInfFileCpy, ProRecInfSz, 1, ProPtInfFileAll ) != 1 ) { + err_retfail ( -1, (ERR_OUT,"Write info file %s failed !", ProInfFileNameAll) ); + } + + if ( fclose (ProPtInfFileAll) != 0 ) { + err_retfail ( -1, (ERR_OUT,"fclose on info file ALL failed => System : %s", strerror ( errno ) ) ); + } + + } + + err_retok (( ERR_OUT, "" )); +} + +// $$$ + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 09/07/2012 +Rev : 12/11/2012 + : - Add index file cpy +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileDutCreate ( char* FilePath ) { + + char VFuncName[] = "FIL_FIndexFileDutCreate"; + FIL__TIndexFileDut* VPtCont = &FIL__VGIndexFileDut; + SInt32 VRet; + + // Normal file + + sprintf ( VPtCont->FilePath, "%s", FilePath ); + + VPtCont->PfDest = fopen ( VPtCont->FilePath, "wb" ); + + err_retnull ( VPtCont->PfDest, (ERR_OUT,"Destination file %s creation failed => %s", VPtCont->FilePath, _strerror ( "System says :" )) ); + + VPtCont->EltCnt = 0; + + fclose (VPtCont->PfDest); + +#ifdef AFRIO__CREATE_INDEX_FILE_CPY + + // Cpy file + + VPtCont->PfDestCpy = fopen ( FIL__DUT_INDEX_FILE_CPY_NAME, "wb" ); + + err_retnull ( VPtCont->PfDestCpy, (ERR_OUT,"Destination file %s creation failed => %s", FIL__DUT_INDEX_FILE_CPY_NAME, _strerror ( "System says :" )) ); + + fclose (VPtCont->PfDestCpy); + +#endif + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 09/07/2012 +Rev : 12/11/2012 + : - Add index file cpy +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileDutAddEv ( UInt32 EvId, UInt32 EvTag, UInt32 TrigLine, UInt32 TrigFrame, UInt32 TrigNbTot, UInt32 TrigNbAccepted, UInt32 SpareU32 ) { + + char VFuncName[] = "FIL_FIndexFileDutAddEv"; + FIL__TIndexFileDut* VPtCont = &FIL__VGIndexFileDut; + UInt32 VAFields[8]; + SInt32 VRet; + + + // Normal file + + // Add elt + + VPtCont->PfDest = fopen ( VPtCont->FilePath, "ab" ); + + err_retnull ( VPtCont->PfDest, (ERR_OUT,"Destination file %s open for append failed => %s", VPtCont->FilePath, _strerror ( "System says :" ) )); + + VAFields[0] = 1; // Version + VAFields[1] = EvId; + VAFields[2] = EvTag; + VAFields[3] = TrigLine; + VAFields[4] = TrigFrame; + VAFields[5] = TrigNbTot; + VAFields[6] = TrigNbAccepted; + VAFields[7] = SpareU32; + + VRet = fwrite ( VAFields, 32 /* size = 8 x U32 */, 1 /* Elt nb */, VPtCont->PfDest ); + + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error writing record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + VRet = fflush ( VPtCont->PfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error flush record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPtCont->PfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + ++VPtCont->EltCnt; + + // Cpy file + // Rq : In case of error => log error BUT don't return < 0 error code because w/r conflict may happen + // on the cpy index file and must not stop run + +#ifdef AFRIO__CREATE_INDEX_FILE_CPY + if ( 1 ) { +#else + if ( 0 ) { +#endif + + while (1) { + + VPtCont->PfDestCpy = fopen ( FIL__DUT_INDEX_FILE_CPY_NAME, "ab" ); + + if ( VPtCont->PfDestCpy == NULL ) { + err_warning (( ERR_OUT, "Destination file %s open for append failed => %s", FIL__DUT_INDEX_FILE_CPY_NAME, _strerror ( "System says :" ) )); + break; + } + + VRet = fwrite ( VAFields, 32 /* size = 8 x U32 */, 1 /* Elt nb */, VPtCont->PfDestCpy ); + + if ( VRet != 1 ) { + err_warning (( ERR_OUT, "Error writing record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + VRet = fflush ( VPtCont->PfDestCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT, "Error flush record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + VRet = fclose ( VPtCont->PfDestCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT, "Error fclose record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + break; + + } // End while (1) + + } + + return (0); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 09/07/2012 +Rev : 13/11/2012 + : - Fill destination buffer with 0 before reading file +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileDutRead ( char* FilePath, UInt32* PtDest, SInt32 DestSz ) { + + char VFuncName[] = "FIL_FIndexFileDutRead"; + + FILE* VPfDest; + SInt32 VFileSz; + UInt32 VAFields[5]; + SInt32 VRet; + + + // Measure file size + + VFileSz = FIL_FFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + err_retfail ( -1, (ERR_OUT,"Buffer size=%d < File size=%d", DestSz, VFileSz ) ); + } + + err_error (( ERR_OUT, "TRACE => FileSize=%d", VFileSz )); + + // Fill destination buffer with 0 + + memset ( PtDest, 0, DestSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + err_retnull ( VPfDest, (ERR_OUT,"Source file %s open failed => %s", FilePath, _strerror ( "System says :" ) )); + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error reading source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + // Return record nb + + return ( VFileSz / 32 ); + +} + +// ##### + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 10/07/2012 +Rev : 12/11/2012 + : - Add index file cpy +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileTelCreate ( char* FilePath ) { + + char VFuncName[] = "FIL_FIndexFileTelCreate"; + FIL__TIndexFileTel* VPtCont = &FIL__VGIndexFileTel; + SInt32 VRet; + + + // Normal file + + sprintf ( VPtCont->FilePath, "%s", FilePath ); + + VPtCont->PfDest = fopen ( VPtCont->FilePath, "wb" ); + + err_retnull ( VPtCont->PfDest, (ERR_OUT,"Destination file %s creation failed => %s", VPtCont->FilePath, _strerror ( "System says :" )) ); + + VPtCont->EltCnt = 0; + + fclose (VPtCont->PfDest); + + +#ifdef EFRIO__CREATE_INDEX_FILE_CPY + + // Cpy file + + VPtCont->PfDestCpy = fopen ( FIL__TEL_INDEX_FILE_CPY_NAME, "wb" ); + + err_retnull ( VPtCont->PfDestCpy, (ERR_OUT,"Destination file %s creation failed => %s", FIL__TEL_INDEX_FILE_CPY_NAME, _strerror ( "System says :" )) ); + + fclose (VPtCont->PfDestCpy); + +#endif + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 10/07/2012 +Rev : 12/11/2012 + : - Add index file cpy +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileTelAddEv ( UInt32 EvId, UInt32 AcqId, UInt32 FrId, UInt32 EvTag, UInt16 Trig0, UInt16 Trig1, UInt16 Trig2, UInt16 FrTrigNb, UInt32 SpareU32 ) { + + char VFuncName[] = "FIL_FIndexFileTelAddEv"; + FIL__TIndexFileTel* VPtCont = &FIL__VGIndexFileTel; + UInt32 VAFields[10]; + SInt32 VRet; + + // Normal file + + // Add elt + + VPtCont->PfDest = fopen ( VPtCont->FilePath, "ab" ); + + err_retnull ( VPtCont->PfDest, (ERR_OUT,"Destination file %s open for append failed => %s", VPtCont->FilePath, _strerror ( "System says :" ) )); + + VAFields[0] = 1; // Version + VAFields[1] = EvId; + VAFields[2] = AcqId; + VAFields[3] = FrId; + VAFields[4] = EvTag; + VAFields[5] = Trig0; + VAFields[6] = Trig1; + VAFields[7] = Trig2; + VAFields[8] = FrTrigNb; + VAFields[9] = SpareU32; + + VRet = fwrite ( VAFields, 40 /* size = 10 x U32 */, 1 /* Elt nb */, VPtCont->PfDest ); + + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error writing record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + VRet = fflush ( VPtCont->PfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error flush record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPtCont->PfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose record %d => %s", EvId, _strerror ( "System says :" ) )); + } + + ++VPtCont->EltCnt; + + // Cpy file + // Rq : In case of error => log error BUT don't return < 0 error code because w/r conflict may happen + // on the cpy index file and must not stop run + + +#ifdef EFRIO__CREATE_INDEX_FILE_CPY + if ( 1 ) { +#else + if ( 0 ) { +#endif + + while (1) { + + VPtCont->PfDestCpy = fopen ( FIL__TEL_INDEX_FILE_CPY_NAME, "ab" ); + + if ( VPtCont->PfDestCpy == NULL ) { + err_warning (( ERR_OUT, "Destination file %s open for append failed => %s", FIL__TEL_INDEX_FILE_CPY_NAME, _strerror ( "System says :" ) )); + break; + } + + VRet = fwrite ( VAFields, 40 /* size = 10 x U32 */, 1 /* Elt nb */, VPtCont->PfDestCpy ); + + if ( VRet != 1 ) { + err_warning (( ERR_OUT, "Error writing record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + VRet = fflush ( VPtCont->PfDestCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT,"Error flush record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + VRet = fclose ( VPtCont->PfDestCpy ); + + if ( VRet != 0 ) { + err_warning (( ERR_OUT,"Error fclose record %d => %s", EvId, _strerror ( "System says :" ) )); + break; + } + + break; + } // End while (1) + + } + + return (0); + +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 09/07/2012 +Rev : 13/11/2012 + : - Fill destination buffer with 0 before reading file +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileTelRead ( char* FilePath, UInt32* PtDest, SInt32 DestSz ) { + + char VFuncName[] = "FIL_FIndexFileTelRead"; + + FILE* VPfDest; + SInt32 VFileSz; + UInt32 VAFields[9]; + SInt32 VRet; + + + // Measure file size + + VFileSz = FIL_FFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + err_retfail ( -1, (ERR_OUT,"Buffer size=%d < File size=%d", DestSz, VFileSz ) ); + } + + err_error (( ERR_OUT, "TRACE => FileSize=%d", VFileSz )); + + // Fill destination buffer with 0 + + memset ( PtDest, 0, DestSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + err_retnull ( VPfDest, (ERR_OUT,"Source file %s open failed => %s", FilePath, _strerror ( "System says :" ) )); + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error reading source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + // Return record nb + + return ( VFileSz / 40 ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 10/07/2012 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileSyncWrite ( char* FilePath, UInt8* PtSrc, SInt32 SrcSz ) { + + char VFuncName[] = "FIL_FIndexFileSyncWrite"; + SInt32 VRet; + FILE* VPf; + + + // Check param + + err_retnull ( PtSrc, (ERR_OUT,"PtSrc == NULL !") ); + + // try to create + + VPf = fopen ( FilePath, "wb" ); + + err_retnull ( VPf, (ERR_OUT,"Sync index file %s creation failed => %s", FilePath, _strerror ( "System says :" )) ); + + + // Try to write + + VRet = fwrite ( PtSrc, SrcSz, 1 /* Elt nb */, VPf ); + + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error writing sync file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fflush ( VPf ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error flush sync file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPf ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose sync file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 10/07/2012 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FIndexFileSyncRead ( char* FilePath, UInt8* PtDest, SInt32 DestSz ) { + + char VFuncName[] = "FIL_FIndexFileSyncRead"; + SInt32 VRet; + FILE* VPfDest; + SInt32 VFileSz; + + + // Check param + + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL !") ); + + // Measure file size + + VFileSz = FIL_FFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + err_retfail ( -1, (ERR_OUT,"Buffer size=%d < File size=%d", DestSz, VFileSz ) ); + } + + err_error (( ERR_OUT, "TRACE => FileSize=%d", VFileSz )); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + err_retnull ( VPfDest, (ERR_OUT,"Source file %s open failed => %s", FilePath, _strerror ( "System says :" ) )); + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + if ( VRet != 1 ) { + err_retfail ( -1, (ERR_OUT,"Error reading source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + err_retfail ( -1, (ERR_OUT,"Error fclose source file %s => %s", FilePath, _strerror ( "System says :" ) )); + } + + + // Return record nb + + return ( VFileSz / 76 ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/07/2012 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FMi32aBTIneffEvFileRead ( char* SrcFilePath, FIL__TMi32ABTIneffEvRec* PtDest, SInt32 DestEltSz ) { + + char VFuncName[] = "FIL_FMi32ABTIneffEvFileRead"; + SInt32 VRet; + FILE* VPf; + SInt32 ViLine; + char VStrCR[2]; + char VDataSep; + SInt8 VEndOfFileReached; + + + + /* Check parameters */ + + err_retnull ( SrcFilePath, (ERR_OUT,"SrcFilePath == NULL" ) ); + err_retnull ( PtDest , (ERR_OUT,"PtDest == NULL" ) ); + + + /* Try to open file */ + + VPf = fopen ( SrcFilePath, "rt" ); + err_retnull ( VPf, (ERR_OUT,"Open source file %s failed", SrcFilePath ) ); + + // err_trace (( ERR_OUT, "FIL_FTextFileToFloatVectors - 2" )); + + /* Read lines */ + + VEndOfFileReached = 0; + + for ( ViLine=0; ViLine < DestEltSz; ViLine++ ) { + + VRet = fscanf ( VPf, "%d%c%d\n", &PtDest[ViLine].EventNo, &VDataSep, &PtDest[ViLine].TrigLine ); + + if ( VRet == EOF ) { + VEndOfFileReached = 1; + fclose (VPf); + err_trace (( ERR_OUT, "End of file reached : %d lines = records read", ViLine + 1 )); + break; + } + + if ( VRet != 3 ) { + fclose (VPf); + break; + // err_retfail ( -1, (ERR_OUT,"Error reading line=%d in file=%s VRet=%d => %s => Abort", ViLine, SrcFilePath, VRet, _strerror ( "System says :" ) ) ); + } + + if ( VDataSep != '-' ) { + err_warning (( ERR_OUT, "Warning reading line=%d in file=%s => Bad separator = %c", ViLine, VDataSep )); + } + + + } + + + if ( VEndOfFileReached = 0 ) { + err_error (( ERR_OUT, "Reading of file %s stopped after %d lines = records because max buffer size reached", SrcFilePath, ViLine )); + } + + fclose (VPf); + + + // Return nb of lines = records + + return ( ViLine ); + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +: +Ouputs : The function returns +: = 0 ok +: < 0 in case of error +: +Globals : None +: +Remark : None +: +Level : This is a user level function. +Date : 24/07/2012 +Doc date : +Modif : +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 FIL_FMi32aBTIneffEvPrint ( FIL__TMi32ABTIneffEvRec* PtSrc, SInt32 RecordsNb ) { + + char VFuncName[] = "FIL_FMi32ABTIneffEvPrint"; + SInt32 VRet; + SInt32 ViRec; + + + msg (( MSG_OUT, "=====================================" )); + msg (( MSG_OUT, "Print list of ineff events : %d record", RecordsNb )); + msg (( MSG_OUT, "=====================================" )); + msg (( MSG_OUT, "" )); + + + + for ( ViRec=0; ViRec < RecordsNb; ViRec++ ) { + msg (( MSG_OUT, "Record[%.4d] : Event=%.6d - TrigLine=%.3d", ViRec, PtSrc[ViRec].EventNo, PtSrc[ViRec].TrigLine )); + } + + return (0); +} + + + + +#endif + + diff --git a/include/pxi_daq_lib_v.3.1/files.def b/include/pxi_daq_lib_v.3.1/files.def new file mode 100755 index 0000000..ed7c79d --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/files.def @@ -0,0 +1,105 @@ +/* 24/02/05 */ + + +#ifndef FIL_DEF +#define FIL_DEF + +#define FIL_DIR_FILES_LIST_MAX_CNT 100 + +#define FIL__TCBinFile_MEAS_TIME +#define FIL__TCStreamFile_MEAS_TIME + +#define FIL__TCBinFile_RWB_MODE_WRITE 0 +#define FIL__TCBinFile_RWB_MODE_READ 1 +#define FIL__TCBinFile_RWB_MODE_BOTH 2 + +// 07/03/2009 +// Macro removed because they are not supported under ROOT ... +// => Macro "calls" had been replaced by the macro code below in files.c +// => For new implementations : a copy paste of the macro code below must be done for each "flag test" +// +// #define FIL__TCBinFile_CHK_CONF_DONE {err_retfail ( ProConfDone , (ERR_OUT,"Abort => Conf not done !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_WR {err_retfail ( ProReadyToWrite, (ERR_OUT,"Abort => File not open in WB !") );} +// #define FIL__TCBinFile_CHK_RDY_TO_RD {err_retfail ( ProReadyToRead , (ERR_OUT,"Abort => File not open in RB !") );} + + +// #define FIL__TCStreamFile_MAX_BUFF_NB 4 // Before 09/10/2014 + +#define FIL__TCStreamFile_MAX_BUFF_NB 1 // 09/10/2014 WARNING ONLY for FSBB BT !!!!!!!!!!! => Max buffers limited to 1 + +// #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 // Before 07/11/12 => 50 000 - Maximum number of blocs in variable bloc size mode + +// #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 200000 // 200000 From 07/11/12 to 22/06/13 + +// #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 400000 // 400000 since 22/06/13 + +// -------------------------------------------------------------------------------------- +// 04/02/2014 GC : FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE selection by CC +// -------------------------------------------------------------------------------------- + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + + #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 50000 // Before 07/11/12 => 50 000 - Maximum number of blocs in variable bloc size mode + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + +#endif + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + + #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 200000 // 200000 From 07/11/12 to 22/06/13 + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + +#endif + + + +#ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_SINCE_220613 + + #define FIL__TCStreamFile_MAX_BLOC_NB_IN_VAR_BLOC_SZ_MODE 400000 // 400000 since 22/06/13 + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_BEFORE_071112 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + + #ifdef APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_071112_TO_220613 + #error NOT allowed => Only one APP_DLL__TELESCOPE_MI26_MI28_DATA_FORMAT_CC1_DDMMYY at a time !!! + #endif + +#endif + + + + +#define FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB 20 + + +#define FIL__TCStreamFile_LOG_GENERAL_MSG 0 +#define FIL__TCStreamFile_LOG_ERR_TRACE 1 +#define FIL__TCStreamFile_LOG_ERR_WARNING 2 +#define FIL__TCStreamFile_LOG_ERR_ERROR 3 + + +// Copy of DU & Telescope index files used to get on-line run status + +#define FIL__DUT_INDEX_FILE_CPY_NAME "s:/data/cur_run_dut_index.bin" +#define FIL__TEL_INDEX_FILE_CPY_NAME "s:/data/cur_run_tel_index.bin" + + + +#endif + diff --git a/include/pxi_daq_lib_v.3.1/files.typ b/include/pxi_daq_lib_v.3.1/files.typ new file mode 100755 index 0000000..bdf3ab7 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/files.typ @@ -0,0 +1,341 @@ +/* 24/02/05 */ + + +#ifndef FIL_TYP +#define FIL_TYP + +/* char FIL_TADirFilesList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; */ + + +typedef struct { + char AList [FIL_DIR_FILES_LIST_MAX_CNT][GLB_FILE_PATH_SZ]; +} FIL_TDirFilesList; + + +// 30/01/2009 + +class FIL__TCBinFile { + + + private : + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + // Parameters from conf + + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParMaxBlocSz; + SInt32 ProParBlocSz; + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + // Variables for internal processing + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + + SInt32 ProCurRdEltId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrEltId; + UInt64 ProCurWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + UInt64 ProTotWrSz; // Moved from SInt32 to UInt64 on 08/11/2010 + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + FILE* ProPtFile; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + + + public : + + FIL__TCBinFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~FIL__TCBinFile (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + SInt32 PubFConf ( char* DataFile, SInt8 RWBMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz ); + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + +// 01/05/2010 + +typedef struct { + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + UInt32 ABlocSz[1]; + +} FIL__TCStreamFile_Old_TRecInfFile; + +// 05/11/10 + +typedef struct { + + UInt64 Offset; + + // UInt32 Sz; + + SInt32 Sz; // NEW 12/01/2012 + + SInt32 SpareW32InfoFormat; // Number which identifies the meaning ASpareW32Info + SInt32 SpareW32InfoNb; // Number of spare parameters + SInt32 ASpareW32Info[FIL__TCStreamFile_BLOC_INF_MAX_SPARE_W32_INFO_NB]; // Array for user parameters + + UInt32 Dummy; // For alignment + +} FIL__TCStreamFile_TBlocInf; + + +// 05/11/10 + +typedef struct { + + + SInt32 Version; + TIME__TUDateL DateCreate; + TIME__TUTime TimeCreate; + TIME__TUDateL DateClose; + TIME__TUTime TimeClose; + SInt32 FixedBlocSz; + UInt32 MaxBlocSz; + UInt32 BlocSz; + UInt32 BlocNb; + + UInt32 Dummy; // For alignment + + FIL__TCStreamFile_TBlocInf ABlocInf[1]; + + +} FIL__TCStreamFile_TRecInfFile; + + +class FIL__TCStreamFile { + + + private : + + FIL__TCStreamFile* PriPtMyself; + + protected : + + SInt8 ProConfDone; // -1 => not done / +1 => done / 0 IS NOT allowed + + // Parameters from constructor + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + SInt32 ProParDiskBlocSz; + SInt8 ProParFixedBlocSzMode; + + // Parameters from conf + + SInt8 ProUseThread; + char ProParDataFile[GLB_FILE_PATH_SZ]; + SInt8 ProParRWBMode; + SInt32 ProParRequestedMaxBlocSz; // Bloc size value asked by user + SInt32 ProParMaxBlocSz; // Adjusted depending on ProParBlocSz + + SInt32 ProParRequestedBlocSz; // Bloc size value asked by user + SInt32 ProParBlocSz; // Bloc size value used ( multiple of disk bloc size ) + SInt8 ProParFlushAfterWrite; + SInt8 ProParMeasTime; + + SInt32 ProAParBlocSz[FIL__TCStreamFile_MAX_BUFF_NB]; // 11/01/2012 NEW DBG + + // Variables for internal processing + + SInt8 ProFileHasBeenClosed; // 13/01/2012 + + HANDLE ProFileHnd; + +#ifdef CC_UNIX + FILE* ProFilePtUx; // Pointer to data file for Linux / Unix +#endif + + // 12/01/2012 - Now two index table are used + char ProInfFileName[GLB_FILE_PATH_SZ]; // Store updated index table file = table with non saved blocs info removed + char ProInfFileNameAll[GLB_FILE_PATH_SZ]; // Store default index table file = table with ALL blocs info = included non saved + FILE* ProPtInfFile; + FILE* ProPtInfFileAll; + + FIL__TCStreamFile_TRecInfFile* ProPtRecInfFile; + FIL__TCStreamFile_TRecInfFile* ProPtRecInfFileCpy; // NEW 12/01/2012 copy of RecInfFile record used to update table = to remove blocs on which saved has failed + SInt32 ProRecInfSz; + + SInt8 ProReadyToWrite; // -1 no / +1 yes / 0 IS NOT allowed + SInt8 ProReadyToRead; // -1 no / +1 yes / 0 IS NOT allowed + +#ifndef CC_UNIX + + #ifndef FILE__NO_CRITICAL_SECTION_HANDLING + CRITICAL_SECTION ProCsPrintMsg; + #endif + +#endif + + HANDLE ProThreadHnd; + DWORD ProThreadId; + + HANDLE ProSemWrBuffHnd; + HANDLE ProSemRdBuffHnd; + + SInt16 ProIndexWrBuff; + SInt16 ProIndexRdBuff; + + UInt8* ProABuff[FIL__TCStreamFile_MAX_BUFF_NB]; + SInt32 ProBuffSz; + + SInt32* ProAPtBlocSz[FIL__TCStreamFile_MAX_BUFF_NB]; // Pointer to the "sz" field of FIL__TCStreamFile_TBlocInf + // PubFSeqWrite fill the field of FIL__TCStreamFile_TBlocInf with size of block + // If writing to disk in thread functions failed, a "-" is added to this size + // This will be used by the function which updates the index file table in order + // to skip blocs not saved and ajust offset list + + + SInt32 ProCurRdBlocId; + SInt32 ProCurRdSz; + + SInt32 ProCurWrBlocId; + SInt32 ProCurWrSz; + SInt64 ProTotWrSz; + + void* ProPtrBuffRdData; + SInt32 ProSzBuffRdData; + + UInt32 ProTime1; + UInt32 ProTime2; + UInt32 ProTimeExec; + + // Results + + SInt32 ProResWrBlocFailCnt; + + SInt32 ProFCalcProParBlocSz ( SInt32 DataSz ); + + SInt32 ProFUpdateIndexTable (); + + public : + + FIL__TCStreamFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + ~FIL__TCStreamFile (); + + friend DWORD WINAPI FIL__TCStreamFile_FThread ( LPVOID lpParam ); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 DiskBlocSz ); + SInt32 PubFSetDiskSectorSz ( SInt32 DiskBlocSz ); + SInt32 PubFGetDiskSectorSz (); + + void PubFPrintMsg ( char* Msg, SInt8 MsgLevel ); + SInt32 PubFConf ( FIL__TCStreamFile* PtMyself, SInt8 UseThread, char* DataFile, SInt8 RWBMode, SInt8 FixedBlocSzMode, SInt32 MaxBlocSz, SInt32 BlocSz, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFPrintInfFileRec ( FIL__TCStreamFile_TRecInfFile* Pt, char* Cmt, char* TagStr ); + SInt32 PubFPrintInfFile (); + SInt32 PubFGetFileSz (); + SInt32 PubFGetBlocNb (); + + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + // SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 SpareInfo ); + + SInt32 PubFSeqWrite ( void* PtrData, SInt32 DataSz, SInt32 DbgCallPar, SInt32 SpareW32InfoFormat, SInt32* PtSpareW32Info, SInt16 SpareW32InfoNb ); + + SInt32 PubFSeqRead ( void* DestPtr, SInt32 MaxDestSz, SInt32 DataSzToRead ); + void* PubFSeqRead ( SInt32 DataSzToRead ); + SInt32 PubFGotoBloc ( SInt32 BlocNo ); + SInt32 PubFBlocRead ( SInt32 BlocNo, void* DestPtr, SInt32 MaxDestSz, SInt32* PtSpareW32InfoFormat, SInt16 MaxSpareW32InfoNb, SInt32* PtSpareW32Info ); + void* PubFBlocRead ( SInt32 BlocNo ); + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + + + +// 09/07/2012 + +typedef struct { + + char FilePath[GLB_FILE_PATH_SZ]; + FILE* PfDest; + FILE* PfDestCpy; + + SInt32 EltCnt; + + +} FIL__TIndexFileDut; + + +// 09/07/2012 + +typedef struct { + + char FilePath[GLB_FILE_PATH_SZ]; + FILE* PfDest; + FILE* PfDestCpy; + + SInt32 EltCnt; + + +} FIL__TIndexFileTel; + + +// 24/07/2012 + +typedef struct { + + SInt32 EventNo; + SInt32 TrigLine; + +} FIL__TMi32ABTIneffEvRec; + + + +#endif + + diff --git a/include/pxi_daq_lib_v.3.1/files.var b/include/pxi_daq_lib_v.3.1/files.var new file mode 100755 index 0000000..a7432e1 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/files.var @@ -0,0 +1,21 @@ +/* 24/02/05 */ + + +#ifndef FIL_VAR +#define FIL_VAR + +/* 07/04/2007 - New macros VAR_DCL and VAR_DCL_INIT for variable declaration to solve a ROOT CINT limitation on macros */ +/* CINT doesn't handle macros like #define EMPTY_MACRO ... EMPTY_MACRO IS NOT replaced by empty space BUT LET as si = not replaced */ + +// Examples +// +// VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 ERR_VGLogClosed , 0); +// VAR_DCL ( EXTERN, VAR_STATIC, char ERR_OUT[ERR_TOT_MSG_SZ] ); + + +EXTERN VAR_STATIC FIL__TIndexFileDut FIL__VGIndexFileDut; +EXTERN VAR_STATIC FIL__TIndexFileTel FIL__VGIndexFileTel; + +#endif + + diff --git a/include/pxi_daq_lib_v.3.1/fsbb0.def b/include/pxi_daq_lib_v.3.1/fsbb0.def new file mode 100755 index 0000000..1f79998 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/fsbb0.def @@ -0,0 +1,204 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_DEF +#define FSBB0_DEF + +#define FSBB0__APP_IGNORE_GC_MOD_220514 + +#define FSBB0__MI26_MI28_CODE_MUST_BE_UPDATED + +#ifdef FSBB0__APP_DLL_TEST_ULT1 + #include "fsbb0_test_ult1.def" +#else + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define FSBB0__REG_DISCRI_BIT_SZ 416 // Ult1 = 960 // Mi26 = 1152 +#define FSBB0__REG_DISCRI_W32_SZ 13 // Ult1 = 30 // Mi26 = 36 + + + + + // Size in CLK unit of the frame which contains the readout of ONE line + #define FSBB0__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 832 // Single line = nop scanning mode + #define FSBB0__DISCRI_RO_SCAN_FRAME_CLK_NB 836 // Scanning mode + + + + + +// This register is not implemented on Ultimate +// +// #define FSBB0__REG_AFTER_ZS_BIT_SZ 160 +// #define FSBB0__REG_AFTER_ZS_W32_SZ 5 + +#define FSBB0__REG_AFTER_MUX_BIT_SZ 160 // Mi26 = 160 +#define FSBB0__REG_AFTER_MUX_W32_SZ 5 // Mi26 = 5 + +#define FSBB0__MAT_DISCRI_COL_NB 416 // 23/01/2013 +#define FSBB0__MAT_DISCRI_LINES_NB 424 // +#define FSBB0__MAT_DISCRI_USEFUL_LINES_NB 416 // 23/01/2013 - Without the two markers lines + + +#define FSBB0__ZS_FFRAME_MODE0_1X80MHZ 0 +#define FSBB0__ZS_FFRAME_MODE1_2X80MHZ 1 +#define FSBB0__ZS_FFRAME_MODE2_1X160MHZ 2 +#define FSBB0__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 13312 // 832 W16 // Ult1 = 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 13312 // 832 W16 // Ult1 = 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 13312 //26624 // 1772 W16 // Ult1 = 29696 // 1856 W16 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 13312 //26624 // 1772 W16 // Ult1 = 29696 // 1856 W16 + + + +// #define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +/* +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 416 // Ult1 = 928 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 416 // Ult1 = 928 // Mi26 = 576 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 832 // Ult1 = 1856 // Mi26 = 576 + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 208// Ult1 = 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 208// Ult1 = 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 416// Ult1 = 928 // Mi26 = 144 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 416// Ult1 = 928 // Mi26 = 288*/ + + +// Id to select FSBB0 register + +#define FSBB0__REG_DISCRI 0 +// #define FSBB0__REG_AFTER_ZS 1 -> Not implemented on Ultimate +//#define FSBB0__REG_AFTER_MUX 1 -> not implemented on fsbb +#define FSBB0__REG_DISCRI_SCAN 1 + +#define FSBB0__REG_DISCRI_SCAN__SRC_CLK_160MHZ 2 // 23/06/2010 + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define FSBB0__REG_BIAS_NB 19 + +// $ #define FSBB0__REG_BIAS_ICLPDISC 0 +// $ #define FSBB0__REG_BIAS_IPWRSW 1 +// $ #define FSBB0__REG_BIAS_IBUF 2 +// $ #define FSBB0__REG_BIAS_ID1PWRS 3 +// $ #define FSBB0__REG_BIAS_ID2PWRS 4 +// $ #define FSBB0__REG_BIAS_ILVDSTX 5 +// $ #define FSBB0__REG_BIAS_ILVDSRX 6 +// $ #define FSBB0__REG_BIAS_IVTST1 7 +// $ #define FSBB0__REG_BIAS_IVTST2 8 +// $ #define FSBB0__REG_BIAS_IANABUF 9 +// $ #define FSBB0__REG_BIAS_IVDREF1D 10 +// $ #define FSBB0__REG_BIAS_IVDREF1C 11 +// $ #define FSBB0__REG_BIAS_IVDREF1B 12 +// $ #define FSBB0__REG_BIAS_IVDREF1A 13 +// $ #define FSBB0__REG_BIAS_IVDREF2 14 +// $ #define FSBB0__REG_BIAS_IDIS1 15 +// $ #define FSBB0__REG_BIAS_IDIS2 16 +// $ #define FSBB0__REG_BIAS_IPXI 17 +// $ #define FSBB0__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define FSBB0__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define FSBB0__DIS_MEAS_STEP_PAR_FIRST 0 +#define FSBB0__DIS_MEAS_STEP_PAR_LAST (FSBB0__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define FSBB0__DIS_TEST_MAX_STEP_NB 50 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define FSBB0__NB_MAX_FSBB0_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define FSBB0__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define FSBB0__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define FSBB0__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// FSBB0__TCTelMon +// -------------------- + +#define FSBB0__COLOR_BROWN 0x000066CC +#define FSBB0__COLOR_ORANGE 0x0000A5FF +#define FSBB0__COLOR_YELLOW 0x0000FFFF +#define FSBB0__COLOR_GREEN 0x0000FF00 +#define FSBB0__COLOR_BLUE 0x00FF0000 +#define FSBB0__COLOR_VIOLET 0x00990066 + +#define FSBB0__TCTelMon__COL_PLANE_0 (TColor) FSBB0__COLOR_ORANGE +#define FSBB0__TCTelMon__COL_PLANE_1 (TColor) FSBB0__COLOR_BLUE +#define FSBB0__TCTelMon__COL_PLANE_2 (TColor) FSBB0__COLOR_BROWN +#define FSBB0__TCTelMon__COL_PLANE_3 (TColor) FSBB0__COLOR_YELLOW +#define FSBB0__TCTelMon__COL_PLANE_4 (TColor) FSBB0__COLOR_GREEN +#define FSBB0__TCTelMon__COL_PLANE_5 (TColor) FSBB0__COLOR_VIOLET + + +#define FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.3.1/fsbb0.typ b/include/pxi_daq_lib_v.3.1/fsbb0.typ new file mode 100755 index 0000000..c464c9f --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/fsbb0.typ @@ -0,0 +1,1233 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_TYP +#define FSBB0_TYP + +#ifdef ROOT_ROOT + typedef UInt32 FSBB0__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor FSBB0__TColor; +#endif + + + + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +// $ typedef struct { +// $ +// $ SInt8 FileErrLogLvl; +// $ char FileErrFile[GLB_FILE_PATH_SZ]; +// $ +// $} FSBB0__TContext; + +/* ============================================================================ */ +/* Discri register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[FSBB0__REG_DISCRI_W32_SZ]; + SInt8 ADataBit[FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TRegDiscri; + +/* ============================================================================ */ +/* Discri register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[FSBB0__REG_DISCRI_W32_SZ]; + +} FSBB0__TRegDiscriW32; + + +/* ============================================================================ */ +/* Discri register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TRegDiscriBit; + + +/* ============================================================================ */ +/* Discri matrix dual view : W32 or Bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + FSBB0__TRegDiscri ALine[FSBB0__MAT_DISCRI_LINES_NB]; + +} FSBB0__TMatDiscri; + +/* ============================================================================ */ +/* Discri matrix view as W32 array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AALineW32[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_W32_SZ]; + +} FSBB0__TMatDiscriW32; + +/* ============================================================================ */ +/* Discri matrix view as bit array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriBit; + + +typedef struct { + + float AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriBitf; + + +/* ============================================================================ */ +/* Discri matrix view as bit array - BUT scale 1/4 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 23/07/2009 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[FSBB0__MAT_DISCRI_LINES_NB / 2][FSBB0__REG_DISCRI_BIT_SZ / 2]; + +} FSBB0__TMatDiscriBitHalfScale; + + + +/* ============================================================================ */ +/* After Zero Sup register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + UInt32 ADataW32[FSBB0__REG_AFTER_ZS_W32_SZ]; + SInt8 ADataBit[FSBB0__REG_AFTER_ZS_BIT_SZ]; + +} FSBB0__TRegAfterZs; +*/ + +/* ============================================================================ */ +/* After Zero Sup register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + UInt32 AW32[FSBB0__REG_AFTER_ZS_W32_SZ]; + +} FSBB0__TRegAfterZsW32; +*/ + +/* ============================================================================ */ +/* After Zero Sup register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + SInt8 ABit[FSBB0__REG_AFTER_ZS_BIT_SZ]; + +} FSBB0__TRegAfterZsBit; +*/ + +/* ============================================================================ */ +/* After Mux register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[FSBB0__REG_AFTER_MUX_W32_SZ]; + SInt8 ADataBit[FSBB0__REG_AFTER_MUX_BIT_SZ]; + +} FSBB0__TRegAfterMux; + +/* ============================================================================ */ +/* After Mux register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[FSBB0__REG_AFTER_MUX_W32_SZ]; + +} FSBB0__TRegAfterMuxW32; + + +/* ============================================================================ */ +/* After Mux register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[FSBB0__REG_AFTER_MUX_BIT_SZ]; + +} FSBB0__TRegAfterMuxBit; + + + +/* ======================================================= */ +/* Frame provided by FSBB0 DAQ, it's independent of output */ +/* mode BUT data are not organized as in FSBB0__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by FSBB0__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +/* typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + + + UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + + } FSBB0__TZsFFrameRaw; */ + + + + + + //typedef struct { + // + // ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + // UInt32 Header; // Header of Mimosa 26 frame + // UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + // UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + // UInt32 Trailer; // Trailer of Mimosa 26 frame + + // UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + // UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + //} FSBB0__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + + //typedef union { + + // UInt16 W16; + + // struct { + + // UInt16 StateNb : 4; + // UInt16 LineAddr : 11; + // UInt16 Ovf : 1; + + // } F; + + //} FSBB0__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +// typedef union { + +// UInt16 W16; + +// struct { + +// UInt16 HitNb : 2; +// UInt16 ColAddr : 11; +// UInt16 NotUsed : 3; + +// } F; + +// } FSBB0__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +// typedef struct { + +// FSBB0__TStatesLine StatesLine; +// FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +// } FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by FSBB0, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +//typedef struct { + +//ASIC__TFrameStatus SStatus; + +//UInt32 Header; +//UInt32 FrameCnt; +//UInt32 DataLength; +// SInt16 TrigSignalLine; +//SInt8 TrigSignalClk; +// SInt16 TrigLine; + +// UInt32 StatesRecNb; // It's NOT a FSBB0 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + +// FSBB0__TZsFStatesRec AStatesRec[FSBB0__ZS_FFRAME_MAX_STATES_REC]; + +// UInt32 Trailer; +// UInt32 Zero; +// UInt32 Zero2; + +// } FSBB0__TZsFFrame; // F in FFrame means Fixed size frame + + + + +#ifndef APP__RMV_FSBB0__TCDiscriFile +#ifndef APP__RMV_CLASSES + +// 31/01/2009 + +class FSBB0__TCDiscriFile : public FIL__TCBinFile { + + + private : + + protected : + + + public : + + FSBB0__TCDiscriFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~FSBB0__TCDiscriFile (); + + SInt32 PubFConf ( char* DataFile, SInt8 WriteRead, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetEvNb (); + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + SInt32 PubFWriteEv ( FSBB0__TMatDiscriW32* PtSrcMat ); + SInt32 PubFReadNextEv ( FSBB0__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + FSBB0__TMatDiscriW32* PubFReadNextEv (); + SInt32 PubFGotoEv ( SInt32 EvNo ); + SInt32 PubFReadEv ( SInt32 EvNo, FSBB0__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + FSBB0__TMatDiscriW32* PubFReadEv ( SInt32 EvNo ); + + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + +#endif +#endif + +/* ==================================================== */ +/* Discriminators test information file record */ +/* */ +/* - Test no */ +/* - Chip no / comment */ +/* - Number of steps */ +/* - Events nb / step */ +/* - Run no associated to each step */ +/* - Bias used for each step */ +/* - User defined parameters for each step */ +/* The can be used to convert udac / mv etc ... */ +/* */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.cnf contains the structure */ +/* FSBB0__TDisTestCnfFile */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + +// A copy of bias used for the current run +// 10/02/2009 + +typedef struct { + + UInt8 ABias[FSBB0__REG_BIAS_NB]; + +} FSBB0__TBiasCnf; + + +// All information about current discri measurement step +// 10/02/2009 + +typedef struct { + + SInt32 RunNo; + FSBB0__TBiasCnf Bias; + float APar[FSBB0__DIS_MEAS_STEP_MAX_PAR_NB]; + +} FSBB0__TDisMeasStep; + + +// Format of file discri_test_NNNN.cnf +// 10/02/2009 + +/*typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to FSBB0__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + +} FSBB0__TDisMeasHeader; + +typedef struct { + FSBB0__TDisMeasHeader Head; + FSBB0__TDisMeasStep AStep[FSBB0__DIS_TEST_MAX_STEP_NB]; +}FSBB0__TDisTestCnfFile;*/ + + +typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to FSBB0__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + + FSBB0__TDisMeasStep AStep[FSBB0__DIS_TEST_MAX_STEP_NB]; + + +} FSBB0__TDisTestCnfFile; + + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in sub matrices view mode => sub A, B, C, D */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 3D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED per submatrix. */ +/* => Header.SubMatView = 1 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* FSBB0__TDisHitCntAllSubMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of FSBB0__TDisHitCntAllSubMatStepData */ +/* - init a FSBB0__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + SInt32 TestNo; + SInt8 SubMatView; // 0 => whole matrix as single data piece + // 1 => submatrices A, B, C, D + SInt32 StepNb; + char CnfFileName[GLB_FILE_PATH_SZ]; + + +} FSBB0__TDisHitCntHeader; + + +typedef struct { + + float AAASubMat[FSBB0__SUB_MAT_NB][FSBB0__MAT_DISCRI_LINES_NB/ FSBB0__SUB_MAT_NB][FSBB0__REG_DISCRI_BIT_SZ ]; + +} FSBB0__TDisHitCntAllSubMatStepData; + +typedef struct { + + float AAAASubMat [FSBB0__DIS_TEST_MAX_STEP_NB][FSBB0__SUB_MAT_NB][FSBB0__MAT_DISCRI_LINES_NB / FSBB0__SUB_MAT_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TDisHitCntAllSubMatStepDataMG; + +typedef struct { + + FSBB0__TDisHitCntHeader Header; + FSBB0__TDisHitCntAllSubMatStepData FirstStepData; + +} FSBB0__TDisHitCntAllSubMatFile; + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in whole matrix view mode */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 2D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED as ONE matrix. */ +/* => Header.SubMatView = 0 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* FSBB0__TDisHitCntMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of FSBB0__TDisHitCntMatStepData */ +/* - init a FSBB0__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + float AAMat[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TDisHitCntMatStepData; + + +typedef struct { + + FSBB0__TDisHitCntHeader Header; + FSBB0__TDisHitCntMatStepData FirstStepData; + +} FSBB0__TDisHitCntMatFile; + + + +typedef struct { + + SInt8 AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ/ FSBB0__SUB_MAT_NB ]; + +} FSBB0__TSubMatDiscriBit; + +typedef struct { + + FSBB0__TColor AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriColor; + + +typedef struct { + + FSBB0__TColor AALineCol[FSBB0__MAT_DISCRI_LINES_NB / 2][FSBB0__REG_DISCRI_BIT_SZ / 2]; + +} FSBB0__TMatDiscriColorHalfScale; + + +typedef struct { + + FSBB0__TColor AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ / FSBB0__SUB_MAT_NB]; + +} FSBB0__TSubMatDiscriColor; + + +// To store "1" count on each discri for N events + +typedef struct { + + SInt32 ABit[FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TRegDiscriCumul; + + +// To store % of "1" on each discri for N events + +typedef struct { + + float ABit[FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TRegDiscriPerCent; + +// To store "1" count on whole matrix for N events + +typedef struct { + + UInt16 AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriCumul; + + +typedef struct { + + UInt16 AALineCol[FSBB0__MAT_DISCRI_LINES_NB / 2][FSBB0__REG_DISCRI_BIT_SZ / 2]; + +} FSBB0__TMatDiscriCumulHalfScale; + + +// To store % of "1" on whole matrix for N events + +typedef struct { + + float AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ]; + +} FSBB0__TMatDiscriPerCent; + + +typedef struct { + + float AALineCol[FSBB0__MAT_DISCRI_LINES_NB][FSBB0__REG_DISCRI_BIT_SZ/ FSBB0__SUB_MAT_NB]; + +} FSBB0__TSubMatDiscriPerCent; + + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + + +// DPXI__FSBB0_NB_MAX_FSBB0_PER_DAQ + +typedef FSBB0__TZsFFrame FSBB0__TAZsFFrame[FSBB0__NB_MAX_FSBB0_PER_DAQ]; + + + +typedef struct { + + // Date & Time + + UInt32 StartDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StartTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Asic conf + + UInt8 AsicName; // Value of enumerated ASIC__TEAsicName defined in asic.def + SInt8 AsicNb; // Number of Asic read by DAQ + + // Trigger mode + + SInt8 SwTrigEnabled; // Enable automatic start of acquisition on first trigger of a spill + // - 0 => Board starts upon acquisition request command, don't care about trigger + // - 1 => After acquisition request command, board wait on first trigger to start + // Trigger detection is done by sw, therefore it has a latency of N x 15 ms + + SInt8 HwTrigModeSavedData; // Trigger mode + // - 0 => Run contains all frames : with OR without trigger + // - 1 => Run contains ONLY frames with a trigger + // - More trigger modes may be defined later + + SInt32 HwTrigPar[FSBB0__TZSRunCnf__HW_TRIG_PAR_NB]; // Parameter about trigger handling -> enumerated DPXI__TEHwTrigPar in daq_pix.def + // - DPXI__HW_TRIG_PAR__OFFSET -> Offset which must be added to trigger position to get real position + // - DPXI__HW_TRIG_PAR__WINDOW -> Number of frame acquired after trigger + // - DPXI__HW_TRIG_PAR_NB -> Max parameters number + + + // Run parameters + + SInt32 RunNo; // Run number + SInt8 RunSave; // Save (1) or Not (0) data + SInt8 RunSaveMode; // Save mode -> Reserved for future use + SInt32 RunEvNb; // Event number in run + SInt32 RunFileEvNb; // Event number per file + +} FSBB0__TZSRunCnf; + + +typedef struct { + + // Date & Time + + UInt32 StopDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StopTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Status + + SInt32 EvNbTaken; // Real number of events taken must be <= FSBB0__TZSRunCnf.RunEvNb + SInt32 RejAcqNb; // Number of acquistion rejected in case of Mimosa 26 data error ( bad header, trailer etc ... ) + + SInt32 ARejAcqList[FSBB0__TZSRunRes__MAX_ACQ_REJ_NB]; // List of rejected acquisition + +} FSBB0__TZSRunRes; + + +// 09/07/2009 + +#ifndef APP__RMV_CLASSES + +class FSBB0__TCZsRunRW { + + private: + + SInt32 PrivFInitForNewRunLoading (); + + // Object + + FIL__TCBinFile* ProPtBinFile; + + protected: + + // Parameters + + char ProParRunDir[GLB_FILE_PATH_SZ]; + SInt32 ProParRunNo; + SInt32 ProParCurFSBB0No; + SInt32 ProParCurEvNo; + + SInt8 ProParMeasTime; + SInt8 ProParPrintMsg; + SInt8 ProParPrintEvHeader; + + // Informations from run conf file OR calculated + + char ProRunCnfFile[GLB_FILE_PATH_SZ]; + char ProRunResFile[GLB_FILE_PATH_SZ]; + + FSBB0__TZSRunCnf ProRecZSRunCnf; + FSBB0__TZSRunRes ProRecZSRunRes; + + SInt32 ProInfRunFSBB0Nb; + SInt32 ProInfRunEvNb; + SInt32 ProInfRunFileSz; + SInt32 ProInfRunEvNbPerFile; + SInt32 ProInfRunBlocNbPerFile; + SInt32 ProInfZsFFrameRawSz; + + // Intermediate variables for processing + + SInt8 ProConfDone; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + + + SInt8 ProLastEvAccessDoneInOneFSBB0Mode; + SInt32 ProCurBlocNoInRun; + SInt32 ProCurFileNo; + SInt32 ProCurBlocNoInFile; + char ProCurFileName[GLB_FILE_PATH_SZ]; + + FSBB0__TZsFFrameRaw* ProPtFFrameRaw; + + + public: + + FSBB0__TCZsRunRW (); + ~FSBB0__TCZsRunRW (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + SInt32 PubFSetMeasTime ( SInt8 Yes ); + SInt32 PubFSetPrintMsg ( SInt8 Print ); + SInt32 PubFSetPrintEvHeader ( SInt8 Print ); + + SInt32 PubFGetMeasTime (); + SInt32 PubFGetPrintMsg (); + SInt32 PubFGetPrintEvHeader (); + + SInt32 PubFGetFSBB0Nb (); + SInt32 PubFGetEvNb (); + SInt32 PubFGetEvNbPerFile (); + + SInt32 PubFLoadRun ( char* RunDir, UInt32 RunNo ); + + FSBB0__TZsFFrameRaw* PubFGotoEvOneFSBB0 ( SInt8 FSBB0No, SInt32 EvNo ); + FSBB0__TZsFFrameRaw* PubFGotoEvAllFSBB0 ( SInt32 EvNo ); + + SInt32 PubFCloseRun (); + +}; + +#endif + +// 01/08/09 + +typedef struct { + + UInt32 IndexInEvWithHitList; + ASIC__TFrameStatus FrStatus; + +} FSBB0__TCTelMon_TEltListEvWithHitAllPlanes; + + +// 02/08/09 + +typedef struct { + + SInt16 x; + SInt16 y; + +} FSBB0__TCTelMon_THit; + +// 02/08/09 + +typedef struct { + + FSBB0__TCTelMon_THit AAHits[MAPS__TCDigTelMon_MAX_PLANE_NB][MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE]; + SInt32 AHitsNbPerPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + SInt32 EvNoInRun; + +} FSBB0__TCTelMon_TTrack; + +// 02/08/09 + +typedef struct { + + SInt8 Full; + SInt8 PlaneNb; + SInt32 EvNb; + FSBB0__TCTelMon_TTrack ATracks[MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB]; + + +} FSBB0__TCTelMon_TResRun; + + +// 17/07/09 + +#ifndef ROOT_ROOT + +#ifndef APP__RMV_CLASSES + +class FSBB0__TCTelMon : public MAPS__TCDigTelMon { + + private: + + SInt8 PrivStopProc; + + // ------------------------------------------- + // Plot colors of planes for coincidence mode + // ------------------------------------------- + + FSBB0__TColor PrivAPlanePlotColor[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // ------------------------------------------------------ + // Variables to store frames : pixel, cumul, plot color + // ------------------------------------------------------ + + FSBB0__TZsFFrameRaw* PrivPtAcqData; // Copy of Acq data, enabled if MakeLocalCpy parameter of PubFAddEvents (...) is set + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, FSBB0__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + SInt32 PrivAcqEvNb; // Event nb of current Acq = parameter EvNb of last PubFAddEvents (...) call + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, FSBB0__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + + FSBB0__TZsFFrame PrivZsFFrame; // Tmp var to store ZsFFrameRaw converted to ZsFFrame + // Used for each frame converted + + FSBB0__TMatDiscriBit PrivMatDiscriCoin; // Result for planeS coin plot AS PIXELS full scale matrix + FSBB0__TMatDiscriCumul PrivMatDiscriCoinCum; // Result for planeS coin cumul plot AS COUNT full scale matrix + + FSBB0__TMatDiscriBitHalfScale PrivMatDiscriBitHalfScale; // Result for planeS coin plot AS PIXELS 1/2 scale matrix + FSBB0__TMatDiscriCumulHalfScale PrivMatDiscriCumHalfScale; // Result for planeS coin cumul plot AS COUNT 1/2 scale matrix + + FSBB0__TMatDiscriColor PrivMatDispColor; // Result in matrix color data for ALL KINDS of plots + FSBB0__TMatDiscriColorHalfScale PrivMatDispColorHalfScale; // Result in 1/2 scale matrix color data for ALL KINDS of plots + + // ===================================================================== + // Lists to store informations results of events processing + // ===================================================================== + + // Flag to enable / disable list update + // It's useful to disable list update for data re-processing ( off-line ) with information of list + // because list informations should not been updates while using them for current data processing ... + // + // The following methods set this flag to one + // - PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ) + + SInt8 PriEnListEvWitHitUpdate; + SInt8 PriEnListEvWithTrigUpdate; + + // --------------------------- + // List of events with trigger + // --------------------------- + + SInt32 PrivListEvWithTrigIndex; // Current elt index + SInt8 PrivListEvWithTrigFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithTrig[FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB]; + + // --------------------------- + // List of events with hit(s) + // --------------------------- + + SInt32 PrivListEvWithHitIndex; // Current elt index + SInt8 PrivListEvWithHitFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithHit[FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB]; // List + + // ----------------------------------------- + // List of events with hit(s) on all planes + // ----------------------------------------- + + SInt32 PrivListEvWithHitAllPlanesIndex; // Currenr elt index + SInt8 PrivListEvWithHitAllPlanesFull; // Full flag + SInt8 PrivListEvWithHitAllPlanesCurProcMode; // Current processing mode + // Uses to know if data must be reprocessed in cas user + // has changed list mode via ProPar.ListHitAllPlanesMode + + // The list array ( dynamic allocation ) + + FSBB0__TCTelMon_TEltListEvWithHitAllPlanes* PrivAListEvWithHitAllPlanes; + + // --------------------------------------------------------------------- + // Result run after data processing + // --------------------------------------------------------------------- + + FSBB0__TCTelMon_TResRun* PrivPtResRun; + + // --------------------------------------------------------------------- + // General init function : reset all variables, called by constructor + // --------------------------------------------------------------------- + + SInt32 PrivFInit (); + + // --------------------------------------------------------------------- + // Processing function + // --------------------------------------------------------------------- + + SInt32 PrivFConvZsFFrameToMatDiscriBitAndCumul ( SInt32 DbgEvNo, SInt8 Mode, SInt8 PlaneNo, SInt8 PlaneSelForCoin, SInt8 EvNo, SInt8 EvSelForPlot, FSBB0__TZsFFrame* PtSrc, FSBB0__TMatDiscriBit* PtDestFrameBit, FSBB0__TMatDiscriBit* PtDestCoinBit, FSBB0__TMatDiscriCumul* PtDestFrameCum, FSBB0__TMatDiscriCumul* PtDestCoinCum, SInt8 PrintLvl ); + + + // --------------------------------------------------------------------- + // Lists ( events with trigger / hit ) add events functions + // --------------------------------------------------------------------- + + SInt32 PrivFAddEvInListEvWithTrig ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt ); + SInt32 PrivFAddEvInListEvWithHit ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt, SInt8 HitOnAllPlanes, SInt8 SingleHitOnEachPlane ); + + protected: + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Process one frame = one event of plane specified by Id (0..5) + + SInt32 ProFProcessPlane ( SInt32 DbdEvNo, SInt8 Id, FSBB0__TZsFFrameRaw* PtSrc ); + + + + public: + + // -------------------------------------------------------------------------- + // Flag to select one Acq off-line processing / full RUN off-line processing + // -------------------------------------------------------------------------- + // Will be done via a method later + // 06/08/2009 + // -------------------------------------------------------------------------- + + SInt8 PubAcqOffLineProcOrRunOffLineProc; + + // ------------------------------------------- + // Constructor & Destructor + // ------------------------------------------- + + FSBB0__TCTelMon (); + ~FSBB0__TCTelMon (); + + // ------------------------------------------------------------ + // Begin method => MUST be called before ANY other function ! + // ------------------------------------------------------------ + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 MaxBuffEvNb ); + + // ------------------------------------------- + // GUI handling methods + // ------------------------------------------- + + #ifndef ROOT_ROOT + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGetGuiPar (); + + #endif + + // ------------------------------------------- + // Run control methods + // ------------------------------------------- + // Allocate / free buffers + // ------------------------------------------- + + SInt32 PubFStartRun ( SInt8 MapsNb ); + SInt32 PubFStopRun (); + + // ------------------------------------------- + // Monitoring control methods + // ------------------------------------------- + + SInt32 PubFStartMon (); + SInt32 PubFStopMon (); + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Add events in on-line monitoring mode and call data processing methods ( protected ) + + SInt32 PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt32 EvNb, FSBB0__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + // Off-line processing of data + // WARNING : NOW - 26/07/2009 - IT'S ONLY data of LAST acquisition ( data provided by last call to PubFAddEvents ) + // => Uses as events number the one of last acq + // => Force mode to "Process one Acq" AND update GUI parameters + + SInt32 PubFProcessOffLineCurAcq (); + SInt32 PubFProcessOffLineCurAcq2 (); + + // Select frame to plot + + SInt32 PubFGotoFirstFrame (); + SInt32 PubFGotoPrevFrame (); + SInt32 PubFGotoNextFrame (); + SInt32 PubFGotoLastFrame (); + + // ------------------------------------------- + // Results print methods + // ------------------------------------------- + + // Print list of events with a trigger detected => print SStatus record + + SInt32 PubPrintListEvWithTrig ( SInt8 Verbose ); + + // Print list of events with at least one hit in one plane => print SStatus record + + SInt32 PubPrintListEvWithHit ( SInt8 Verbose ); + + // Print list of events with hit on ALL planes => print SStatus record + + SInt32 PubPrintListEvWithHitOnAllPlanes ( SInt8 Verbose ); + + // Print res run + + SInt32 PubAllocResRun (); + SInt32 PubFreeResRun (); + SInt32 PubPrintResRun (); + SInt32 PubSaveResRun ( char* FileName ); + + + SInt32 PubFIsEvInListEvWithHitOnAllPlanes ( SInt32 EvNo ); + SInt32 PubFIsEvLastOfListEvWithHitOnAllPlanes ( SInt32 EvNo ); + + SInt32 PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ); + + + // ------------------------------------------- + // Results plot methods + // ------------------------------------------- + + // There is NO plot method in class. + // + // Because a call of a plot function ( from plot lib ) in DAQ supervisor thread doesn't work + // - nothing is displayed ! + // - this may crash the application + // I don't know why and have no time to study and understand this bug. I have found a workarround + // by calling the plot function in an application timer. + // + // The class request plot by setting the flag ProRequestPlot to 1 + // plot is done by "plot timer" callback in application which + // reset the flag ProRequestPlot after plot. + + // The application "plot timer" must know : + // - when he must plot --> Test variable pointed by PubFGetPtPlotRq () + // - the matrix to plot : full / half scale --> Test variable pointed by PubFGetPtDispFullMatrix () + // - the data to plot --> Read via pointer given by PubFGetPtFullMatCol () / PubFGetPtHalfMatCol () + // + // Polling of plot request and access to data is NOT DONE via method calls because + // - calling class methods in timer while other methods may be called in DAQ supervisor thread MAY cause problems => No detailed understanding, no time ... + // - it will save execution time by avoiding function call + + SInt8* PubFGetPtDispFullMatrix (); + FSBB0__TMatDiscriColor* PubFGetPtFullMatCol (); + FSBB0__TMatDiscriColorHalfScale* PubFGetPtHalfMatCol (); + + +}; + + + +enum { +FSBB0_EMUL_HITS, FSBB0_EMUL_ALL_ZERO,FSBB0_EMUL_ALL_ONE, FSBB0_EMUL_CROSS, FSBB0_EMUL_BORDER +} FSBB0_EHitEmulType; + + + + + +#endif + + +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/fsbb0_test_ult1.def b/include/pxi_daq_lib_v.3.1/fsbb0_test_ult1.def new file mode 100755 index 0000000..4d7602b --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/fsbb0_test_ult1.def @@ -0,0 +1,214 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_TEST_ULT1_DEF +#define FSBB0_TEST_ULT1_DEF + + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define FSBB0__REG_DISCRI_BIT_SZ 960 +#define FSBB0__REG_DISCRI_W32_SZ 30 + + +#ifdef FSBB0__APP_DLL_TEST_WITH_PATTERN_GENERATOR + + // Size in CLK unit of the frame which contains the readout of ONE line + + #define FSBB0__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 1858 // Single line = nop scanning mode + #define FSBB0__DISCRI_RO_SCAN_FRAME_CLK_NB 1858 // Scanning mode + +#else + + // Size in CLK unit of the frame which contains the readout of ONE line + + #define FSBB0__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 1856 // Single line = nop scanning mode + #define FSBB0__DISCRI_RO_SCAN_FRAME_CLK_NB 1858 // Scanning mode + +#endif + + + + +// This register is not implemented on Ultimate +// +// #define FSBB0__REG_AFTER_ZS_BIT_SZ 160 +// #define FSBB0__REG_AFTER_ZS_W32_SZ 5 + +#define FSBB0__REG_AFTER_MUX_BIT_SZ 160 +#define FSBB0__REG_AFTER_MUX_W32_SZ 5 + +#define FSBB0__MAT_DISCRI_COL_NB 960 // 23/01/2013 +#define FSBB0__MAT_DISCRI_LINES_NB 930 +#define FSBB0__MAT_DISCRI_USEFUL_LINES_NB 928 // 23/01/2013 - Without the two markers lines + +#define FSBB0__ZS_FFRAME_RAW_MAX_W16 3700 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define FSBB0__ZS_FFRAME_RAW_MAX_W32 1850 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 +#define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 1856 // Total frame size ( sum of 2 links ) in W32 - Mi26 = 576 + +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define FSBB0__ZS_FFRAME_MAX_STATES_REC 928 // Mi26 = 576 - one per line + +#define FSBB0__ZS_FFRAME_MODE0_1X80MHZ 0 +#define FSBB0__ZS_FFRAME_MODE1_2X80MHZ 1 +#define FSBB0__ZS_FFRAME_MODE2_1X160MHZ 2 +#define FSBB0__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 14848 // 928 W16 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 29696 // 1856 W16 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 29696 // 1856 W16 + +// $ #define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 928 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 928 // Mi26 = 576 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 1856 // Mi26 = 576 +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 1856 // Mi26 = 576 => Moved in fsbb0_usr.def + +#define FSBB0__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 464 // Mi26 = 288 +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 928 // Mi26 = 144 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 928 // Mi26 = 288 + + +// Id to select FSBB0 register + +#define FSBB0__REG_DISCRI 0 +// #define FSBB0__REG_AFTER_ZS 1 -> Not implemented on Ultimate +#define FSBB0__REG_AFTER_MUX 1 +#define FSBB0__REG_DISCRI_SCAN 2 + +#define FSBB0__REG_DISCRI_SCAN__SRC_CLK_160MHZ 3 // 23/06/2010 + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + +// Submatrices number + +#define FSBB0__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define FSBB0__REG_BIAS_NB 19 + +// $ #define FSBB0__REG_BIAS_ICLPDISC 0 +// $ #define FSBB0__REG_BIAS_IPWRSW 1 +// $ #define FSBB0__REG_BIAS_IBUF 2 +// $ #define FSBB0__REG_BIAS_ID1PWRS 3 +// $ #define FSBB0__REG_BIAS_ID2PWRS 4 +// $ #define FSBB0__REG_BIAS_ILVDSTX 5 +// $ #define FSBB0__REG_BIAS_ILVDSRX 6 +// $ #define FSBB0__REG_BIAS_IVTST1 7 +// $ #define FSBB0__REG_BIAS_IVTST2 8 +// $ #define FSBB0__REG_BIAS_IANABUF 9 +// $ #define FSBB0__REG_BIAS_IVDREF1D 10 +// $ #define FSBB0__REG_BIAS_IVDREF1C 11 +// $ #define FSBB0__REG_BIAS_IVDREF1B 12 +// $ #define FSBB0__REG_BIAS_IVDREF1A 13 +// $ #define FSBB0__REG_BIAS_IVDREF2 14 +// $ #define FSBB0__REG_BIAS_IDIS1 15 +// $ #define FSBB0__REG_BIAS_IDIS2 16 +// $ #define FSBB0__REG_BIAS_IPXI 17 +// $ #define FSBB0__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define FSBB0__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define FSBB0__DIS_MEAS_STEP_PAR_FIRST 0 +#define FSBB0__DIS_MEAS_STEP_PAR_LAST (FSBB0__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define FSBB0__DIS_TEST_MAX_STEP_NB 50 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define FSBB0__NB_MAX_FSBB0_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define FSBB0__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define FSBB0__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define FSBB0__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// FSBB0__TCTelMon +// -------------------- + +#define FSBB0__COLOR_BROWN 0x000066CC +#define FSBB0__COLOR_ORANGE 0x0000A5FF +#define FSBB0__COLOR_YELLOW 0x0000FFFF +#define FSBB0__COLOR_GREEN 0x0000FF00 +#define FSBB0__COLOR_BLUE 0x00FF0000 +#define FSBB0__COLOR_VIOLET 0x00990066 + +#define FSBB0__TCTelMon__COL_PLANE_0 (TColor) FSBB0__COLOR_ORANGE +#define FSBB0__TCTelMon__COL_PLANE_1 (TColor) FSBB0__COLOR_BLUE +#define FSBB0__TCTelMon__COL_PLANE_2 (TColor) FSBB0__COLOR_BROWN +#define FSBB0__TCTelMon__COL_PLANE_3 (TColor) FSBB0__COLOR_YELLOW +#define FSBB0__TCTelMon__COL_PLANE_4 (TColor) FSBB0__COLOR_GREEN +#define FSBB0__TCTelMon__COL_PLANE_5 (TColor) FSBB0__COLOR_VIOLET + + +#define FSBB0__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define FSBB0__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define FSBB0__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.3.1/fsbb0_usr.def b/include/pxi_daq_lib_v.3.1/fsbb0_usr.def new file mode 100755 index 0000000..17b868f --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/fsbb0_usr.def @@ -0,0 +1,210 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_DEF +#define FSBB0_USR_DEF + +#ifdef FSBB0__APP_DLL_TEST_ULT1 + #include "fsbb0_usr_test_ult1.def" +#else + + +/* ================= */ +/* Macro example */ +/* ================= */ + + + + +// 27/05/2014 - GC : Rename cst & update values +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 892 //ult = 1856 // Mi26 = 576 +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1784 //ult=3712 // +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 886 // Add on 11/05/2011 - value per link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1772 // Add on 11/05/2011 - value per link + +// ----------------------------------------------------------------------------- +// Frame total size & data part size (per link) FSBB0 in mode 1 link @ 160 MHz +// ----------------------------------------------------------------------------- + +// 27/08/2014 - GC : Update cst values : +// +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 443 => BAD value +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 886 => BAD value +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ 1772 => BAD value +// +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 886 // FSBB0 = 886 W16 / frame / link including ... +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ 1772 // FSBB0 = 1772 W8 / frame / link including ... + +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 440 // FSBB0 = 440 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 880 // FSBB0 = 880 W16 / frame / link including ... +#define FSBB0__ZS_FFRAME_MODE_1X160MHZ_W8_SZ 1760 // FSBB0 = 1760 W8 / frame / link including ... + + + +// 27/08/2014 - GC : Update cst values : +// +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W32_SZ 436 => OK +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 878 => BAD value +// - FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1756 => BAD value +// +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 878 // FSBB0 = 878 = Number of W16 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1756 // FSBB0 = 1756 = Number of W8 in data part / frame / link + +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W32_SZ 436 // FSBB0 = 436 = Number of W30 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 872 // FSBB0 = 436 * 2 = Number of W16 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1744 // FSBB0 = 436 * 4 = Number of W8 in data part / frame / link + +// 20/09/2014 - GC : New update of cst value because MAW W30 nb in data part is 433 and not 436 +// => More explanation in mail "... FSBB .. Question No 12" 20/09/2014 +// + + #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W32_SZ 433 // FSBB0 = 433 = Number of W30 in data part / frame / link + #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W16_SZ 866 // FSBB0 = 433 * 2 = Number of W16 in data part / frame / link + #define FSBB0__ZS_FFRAME_MODE_1X160MHZ_MAX_DATA_PART_W8_SZ 1732 // FSBB0 = 433 * 4 = Number of W8 in data part / frame / link + + + +// ----------------------------------------------------------------------------- +// Frame total size & data part size (per link) FSBB0 in mode 2 links @ 160 MHz +// ----------------------------------------------------------------------------- +// The value are the same as for 1 link mode ... if there is no erros in doc +// that's why I prefer to keep two sets of constants +// ----------------------------------------------------------------------------- + +// 27/08/2014 - GC : Update cst values : +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 443 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 886 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1772 => BAD value +// +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 => BAD value +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 886 // FSBB0 = 886 W16 / frame / link including ... +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1772 // FSBB0 = 1772 W8 / frame / link including ... + +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 // FSBB0 = 439 = Number of W30 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 // FSBB0 = 878 = Number of W16 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 // FSBB0 = 1756 = Number of W8 in data part / frame / link + + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 440 // FSBB0 = 440 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 880 // FSBB0 = 880 W16 / frame / link including ... +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 1760 // FSBB0 = 1760 W8 / frame / link including ... + + + +// 27/08/2014 - GC : Update cst values : +// +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 => OK +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 => BAD value +// - FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 => BAD value +// +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 878 // FSBB0 = 878 = Number of W16 in data part / frame / link +// #define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1756 // FSBB0 = 1756 = Number of W8 in data part / frame / link + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W32_SZ 436 // FSBB0 = 436 = Number of W30 in data part / frame / link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 872 // FSBB0 = 436 * 2 = Number of W16 in data part / frame / link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 1744 // FSBB0 = 436 * 4 = Number of W8 in data part / frame / link + +// Before 27/08/2014 - GC => Update cst values on 27/08/2014 +// +// FSBB0 will be used with only one link for beam test +// 22/05/2014 - GC : Redefine cst values +// 27/05/2014 - GC : Cst removed in fsbb0_usr.def, they were in the two files before ... with different values ... +// +// #define FSBB0__ZS_FFRAME_RAW_MAX_W8 1756 // FSBB0 = 1756 = Maximum data part number of W8 / frame / link +// #define FSBB0__ZS_FFRAME_RAW_MAX_W16 878 // FSBB0 = 878 = Maximum data part number of W16 / frame / link +// #define FSBB0__ZS_FFRAME_RAW_MAX_W32 439 // FSBB0 = 439 = Maximum data part number of W30 / frame / link +// #define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 443 // FSBB0 = 443 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer + +// 27/08/2014 - GC : New cts values + +#define FSBB0__ZS_FFRAME_RAW_MAX_W8 1744 // FSBB0 = 1744 = Maximum data part number of W8 / frame / link +#define FSBB0__ZS_FFRAME_RAW_MAX_W16 872 // FSBB0 = 872 = Maximum data part number of W16 / frame / link +#define FSBB0__ZS_FFRAME_RAW_MAX_W32 436 // FSBB0 = 436 = Maximum data part number of W30 / frame / link +#define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 440 // FSBB0 = 440 = Total number of W30 / frame / link including Header, Trigger, FrCntDataLength, Trailer + + +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 18 // 28/05/14 - GC : 9 on G + 9 on G1 +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP 9 // 05/06/14 - GC : Max 9 Windows on each group G0, G1 +#define FSBB0__ZS_FFRAME_MAX_STATES_REC 104 // 28/05/14 - GC : One per S-line => 416 lines / 4 = 104 S-lines + + + +// ----------------------------------------------------------------------------- +// Special constant for FSBB0 (Not needed on Mi26, Mi28) +// +// Due to FSBB0 integration time (41,6 us) and ro frequency (DDR @ 160 MHz) +// the total number of bits sent on each link is NOT a multiple of the maximum +// frame length in W30 (FSBB0__ZS_FFRAME_MODE_1X160MHZ_W32_SZ), there are 112 bits more. +// This value is defined by the following constant +// ----------------------------------------------------------------------------- + +// 27/08/2014 - GC : Value used before 27/08/14, new value is 112, it's connected to others cst update on 27/08/14 +// +// #define FSBB0__ZS_HW_FRAME_PADDING_BITS_AT_END 22 // Padding bits at end of frame + +#define FSBB0__ZS_HW_FRAME_PADDING_BITS_AT_END 112 // Padding bits at end of frame + + +#define FSBB0__TEST_FILES_NAME_MAX_SZ 256 +#define FSBB0__TEST_MAX_NUMBER 40 + + + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + +// Submatrices number + +#define FSBB0__SUB_MAT_NB 2 + +// -------------------- +// Bias registers index +// -------------------- + +#define FSBB0__REG_BIAS_NB 15 + +#define FSBB0__REG_BIAS_ILVDSTX 0 +#define FSBB0__REG_BIAS_IDISCLP 1 +#define FSBB0__REG_BIAS_IBUFREF 2 +#define FSBB0__REG_BIAS_IVTST1 3 +#define FSBB0__REG_BIAS_IVTST2B 4 +#define FSBB0__REG_BIAS_IVTST2A 5 +#define FSBB0__REG_BIAS_IANABUF 6 +#define FSBB0__REG_BIAS_IVDREF1B 7 +#define FSBB0__REG_BIAS_IVDREF2B 8 +#define FSBB0__REG_BIAS_IVDREF1A 9 +#define FSBB0__REG_BIAS_IVDREF2A 10 +#define FSBB0__REG_BIAS_IDIS1 11 +#define FSBB0__REG_BIAS_IDIS2 12 +#define FSBB0__REG_BIAS_IPIX 13 +#define FSBB0__REG_BIAS_IPIXCLP 14 + + +#endif + +#endif + diff --git a/include/pxi_daq_lib_v.3.1/fsbb0_usr.typ b/include/pxi_daq_lib_v.3.1/fsbb0_usr.typ new file mode 100755 index 0000000..e4c9dac --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/fsbb0_usr.typ @@ -0,0 +1,414 @@ + +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_TYP +#define FSBB0_USR_TYP + +/* ================================= */ +/* Lib context */ +/* Contain all global variables */ +/* --------------------------------- */ +/* Date : 24/11/2008 - GC */ +/* ================================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} FSBB0__TContext; + + +/* ================================= */ +/* Union to extract */ +/* Header 0,1 from header 30 bits */ +/* fro frame field */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 H0 : 15; // B00..B14 + UInt32 H1 : 15; // B15..B29 + UInt32 Nu : 2; // B30..B31 + } F; + +} FSBB0__THeader; + +/* ================================= */ +/* Union to extract */ +/* Trailer 0,1 from trailer 30 bits */ +/* fro frame field */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 T0 : 15; // B00..B14 + UInt32 T1 : 15; // B15..B29 + UInt32 Nu : 2; // B30..B31 + } F; + +} FSBB0__TTrailer; + + +/* ================================= */ +/* Union to extract */ +/* Trigger fields from 30 bits word */ +/* */ +/* --------------------------------- */ +/* Date : 23/05/2014 - GC */ +/* ================================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 Mode : 3; // B00..B02 + UInt32 NbLine : 8; // B03..B10 + UInt32 Nu : 21; // B11..B31 + } F; + +} FSBB0__TTriger; + + +/* ============================= */ +/* Union to extract */ +/* Data length, rem, frames cnt */ +/* fro frame field */ +/* ----------------------------- */ +/* Date : 22/05/2014 */ +/* ============================= */ + +typedef union { + + UInt32 W32; + + struct { + UInt32 DataLength : 8; // B00..B07 + UInt32 Rem : 2; // B08..B09 + UInt32 FrameCnt : 20; // B10..B29 + } F; + +} FSBB0__TDataLengthRemFrCnt; + +/* ======================================================= */ +/* Frame provided by FSBB0 DAQ, it's independent of output */ +/* mode BUT data are not organized as in FSBB0__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by FSBB0__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 23/05/2014 - GC : Upd fields + THeader, TTRailer */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + FSBB0__THeader Header; // Header of FSBB0 frame + FSBB0__TTriger Trigger; // Trigger of FSBB0 frame - 22/05/14 GC + + FSBB0__TDataLengthRemFrCnt DataLengthRemFrCnt; // 22/05/14 GC + // Field from FSBB0 frame which contains + // - DataLength B00..B07 + // - Rem B08..B09 + // - FrCnt B10..B29 + + // UInt32 FrameCnt; // 22/05/14 GC => Replaced by DataLengthRemFrCnt + // Frame counter of FSBB0 frame + + +UInt8 TrigLine; + UInt8 TrigMode; + + // 22/05/14 GC => Replaced by CalcDataLength + // + // UInt32 DataLength; // Useful length in W32 unit of data contains in ADataW32 array + // Calculation to be defined + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + UInt8 FsbbFieldDataLength; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + UInt8 FsbbFieldRem; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + UInt32 UsefulDataLengthW30; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + UInt32 TotalDataLengthW30; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + SInt8 BugFieldDataLengthEqual0; // 28/08/14 - GC : New fields to handle FSBB0 datalength bugs + + UInt32 CalcDataLength; // 22/05/14 GC - Replace fields "DataLength" but it has not the same meaning + // + // - "DataLength" (Mi26, 28) contains the fields data length from Mi26/28 frame + // - "CalcDataLength" = W32 nb in ADataW32 array calculated from DataLengthRemFrCnt + + + FSBB0__TTrailer Trailer; // Trailer of FSBB0 frame + +// 22/05/14 GC +// Set zeo fields in comments +// +// UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw +// UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + +// 22/05/14 GC +// U16 -> U32 because data are serialized on U30 words on FSBB +// +// UInt16 ADataW16[FSBB0__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + UInt32 ADataW32[FSBB0__ZS_FFRAME_RAW_MAX_W32]; // MUST BE AT END OF RECORD ! + + +} FSBB0__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 22/05/2014 - GC */ +/* =================================================== */ + +typedef union { + + UInt32 W32; + + struct { + + UInt32 HitNbG0 : 8; + UInt32 HitNbG1 : 8; + UInt32 SLineAddr : 9; + UInt32 NU : 7; + + } F; + +} FSBB0__TStatesLine; + +/* =================================================== */ +/* Hit window of Zero Sup frame, 2 views */ +/* - W32 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 22/05/2014 - GC */ +/* =================================================== */ + +typedef union { + + UInt32 W32; + + struct { + + UInt32 Delta : 2; + UInt32 Code : 20; + UInt32 ColAddr : 8; + UInt32 NU : 2; + + } F; + +} FSBB0__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 05/06/2014 - GC : Update fields list to handle */ +/* easily groups G0, G1 */ +/* ======================================================= */ + +typedef struct { + + // Before 05/06/2014 - GC + // + // FSBB0__TStatesLine StatesLine; + // FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + + // Since 05/06/2014 - GC + + FSBB0__TStatesLine StatesLine; + FSBB0__TState AStatesG0[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP]; + FSBB0__TState AStatesG1[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_GROUP]; + + SInt8 NbWinTot; + SInt8 NbWinG0; + SInt8 NbWinG1; + +} FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +// typedef struct { +// +// FSBB0__TStatesLine StatesLine; +// FSBB0__TState AStates[FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; +// +// } FSBB0__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by FSBB0, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* Rev : XX/05/2014 - MS : Mi28 -> FSBB0 */ +/* Rev : 23/05/2014 - GC : Upd fields + THeader, TTRailer */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + FSBB0__THeader Header; + UInt32 FrameCnt; + FSBB0__TTriger Trigger; // Trigger of FSBB0 frame - 22/05/14 GC + + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a FSBB0 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + FSBB0__TZsFStatesRec AStatesRec[FSBB0__ZS_FFRAME_MAX_STATES_REC]; + + FSBB0__TTrailer Trailer; + + // 22/05/14 GC + // Set zero fields in comments + // + // UInt32 Zero; + // UInt32 Zero2; + +} FSBB0__TZsFFrame; // F in FFrame means Fixed size frame + + + +/* ======================================================= */ +/* Structure containing the pattern to be set via the JTAG */ +/* link to perform the automatic tests of the FSBB0 */ +/* structure */ +/* ------------------------------------------------------- */ +/* Date : 17/06/2014 */ +/* ------------------------------------------------------- */ + +typedef struct { + + SInt16 ConfigIndex; + SInt16 FileNumberMajor; + SInt16 FileNumberMinor; + UInt32 Pattern[8][13]; + SInt16 Zone11; + SInt16 Zone10; + SInt16 Zone01; + SInt16 Zone00; + + +} FSBB0__TTestPattern; // F in FFrame means Fixed size frame + + + + + +typedef struct { + + char ConfigFile[FSBB0__TEST_FILES_NAME_MAX_SZ]; + char ResultFileBit[FSBB0__TEST_FILES_NAME_MAX_SZ]; + char ResultFileW32[FSBB0__TEST_FILES_NAME_MAX_SZ]; + SInt16 FileNumberMajor; + SInt16 FileNumberMinor; + + +} FSBB0__TTestFiles; // F in FFrame means Fixed size frame + + + +/* ======================================================= */ +/* Structure containing the test parameters : */ +/* files name for all the tests to be done */ +/* structure */ +/* ------------------------------------------------------- */ +/* Date : 20/06/2014 */ +/* ------------------------------------------------------- */ + +typedef struct { + + FSBB0__TTestFiles Files[FSBB0__TEST_MAX_NUMBER]; + +} FSBB0__TTestParams; // F in FFrame means Fixed size frame + + + + + +#endif + diff --git a/include/pxi_daq_lib_v.3.1/fsbb0_usr_test_ult1.def b/include/pxi_daq_lib_v.3.1/fsbb0_usr_test_ult1.def new file mode 100755 index 0000000..9d4c44b --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/fsbb0_usr_test_ult1.def @@ -0,0 +1,80 @@ +/******************************************************************************* +File : x:\lib\com\maps\fsbb0\fsbb0_usr.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef FSBB0_USR_TEST_ULT1_DEF +#define FSBB0_USR_TEST_ULT1_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 1856 +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 3712 // + + +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 1850 // Add on 11/05/2011 - value per link +#define FSBB0__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 3700 // Add on 11/05/2011 - value per link + +#define FSBB0__ZS_FFRAME_RAW_MAX_W8 7400 // Data part size ( sum of 2 links ) in W8 +#define FSBB0__ZS_FFRAME_RAW_MAX_W16 3700 // Data part size ( sum of 2 links ) in W16 +#define FSBB0__ZS_FFRAME_RAW_MAX_W32 1850 // Data part size ( sum of 2 links ) in W32 + +#define FSBB0__ZS_FFRAME_RAW_TOTAL_SZ_W32 1856 // Mi26 = 576 + + +#define FSBB0__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 +#define FSBB0__ZS_FFRAME_MAX_STATES_REC 828 + +// ====================================== +// For FSBB0 discri analysis tools +// ====================================== + +// Submatrices number + +#define FSBB0__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define FSBB0__REG_BIAS_NB 19 + +#define FSBB0__REG_BIAS_ICLPDISC 0 +#define FSBB0__REG_BIAS_IPWRSW 1 +#define FSBB0__REG_BIAS_IBUF 2 +#define FSBB0__REG_BIAS_ID1PWRS 3 +#define FSBB0__REG_BIAS_ID2PWRS 4 +#define FSBB0__REG_BIAS_ILVDSTX 5 +#define FSBB0__REG_BIAS_ILVDSRX 6 +#define FSBB0__REG_BIAS_IVTST1 7 +#define FSBB0__REG_BIAS_IVTST2 8 +#define FSBB0__REG_BIAS_IANABUF 9 +#define FSBB0__REG_BIAS_IVDREF1D 10 +#define FSBB0__REG_BIAS_IVDREF1C 11 +#define FSBB0__REG_BIAS_IVDREF1B 12 +#define FSBB0__REG_BIAS_IVDREF1A 13 +#define FSBB0__REG_BIAS_IVDREF2 14 +#define FSBB0__REG_BIAS_IDIS1 15 +#define FSBB0__REG_BIAS_IDIS2 16 +#define FSBB0__REG_BIAS_IPXI 17 +#define FSBB0__REG_BIAS_VPIXCLP 18 + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/globals.def b/include/pxi_daq_lib_v.3.1/globals.def new file mode 100755 index 0000000..0e2bdc4 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/globals.def @@ -0,0 +1,39 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_DEF +#define GLOBALS_DEF + +#ifndef CC_UNIX + #include "globals_root.def" +#endif + +#ifndef ROOT_ROOT + #define GLB_READ_CR { while ( getchar () != '\n' ); }; +#endif + + +#ifndef ROOT_ROOT + #define GLB_KEYB_CR { while ( getchar () != '\n' ); } +#endif + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/globals_root.def b/include/pxi_daq_lib_v.3.1/globals_root.def new file mode 100755 index 0000000..26466d2 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/globals_root.def @@ -0,0 +1,44 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/globals.def +Goal : Globals things : constants, conditional compilation, + : variables, functions. +Remark : It should be splitted in separate files, but ... +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/*************************************************************/ + + +#ifndef GLOBALS_ROOT_DEF +#define GLOBALS_ROOT_DEF + +/* CONDITIONNAL COMPILATION */ + +#define GLB_GC_CASCADE +#define GLB_FIRST_REC_FORMAT + +/* MACROS */ + +#define GLB_FILE_PATH_SZ 256 +#define GLB_CMT_SZ 256 +#define GLB_HOST_NAME_SZ 50 + +#define GLB_SEQ 0 + +#define GLB_RMP_FILE_PATH "/common/rmp/RMP" +#define GLB_RMPS_FILE_PATH "/common/rmp/RUN" + + +#define GLB_DEF_BYTE_SEX 0x3615ABCD + + +// #define GLB_DESY_VME_A32_BASE 0xd0000000 /* By default it's LEPSI config base address 0xd0000000*/ + + + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/maps.def b/include/pxi_daq_lib_v.3.1/maps.def new file mode 100755 index 0000000..a829d9d --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/maps.def @@ -0,0 +1,59 @@ +/******************************************************************************* +File : x:\lib\com\maps\maps.def +Goal : Macros definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_DEF +#define MAPS_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define MAPS__TCDigTelMon_MAX_EV_NB 300 +#define MAPS__TCDigTelMon_MAX_PLANE_NB 6 +#define MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB 10000 +#define MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE 1000 + +#define MAPS__TCDigTelMon_CHK_PLANE_ID(Id) { if ( (Id < 0) || (Id >= MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Id, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + +#define MAPS__TCDigTelMon_CHK_PLANE_NB(Nb) { if ( (Nb <= 0) || (Nb > MAPS__TCDigTelMon_MAX_PLANE_NB) ) err_retfail ( -1, (ERR_OUT,"Bad Id=%d MUST be 0..%d", Nb, MAPS__TCDigTelMon_MAX_PLANE_NB-1) ); } + + +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME 0 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL 1 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS 2 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR 3 +#define MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS 4 + +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__HIT_ALL_PLANES 0 +#define MAPS__TCDigTelMon_LIST_HIT_ALL_PLANES_MODE__SINGLE_EACH_PLANE 1 + + +typedef enum { + + MAPS__MAPS_READ_MODE_A_FR0_FR1, + MAPS__MAPS_READ_MODE_A_READ_CALIB, + + MAPS__MAPS_READ_MODE_NB + +} MAPS__TMapsReadMode; + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/maps.typ b/include/pxi_daq_lib_v.3.1/maps.typ new file mode 100755 index 0000000..63e1342 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/maps.typ @@ -0,0 +1,383 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.typ +Goal : Types definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_TYP +#define MAPS_TYP + + +#ifdef ROOT_ROOT + typedef UInt32 MAPS__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor MAPS__TColor; +#endif + + + +// 17/07/2009 + +typedef struct { + + SInt32 MaxBuffEvNb; + + // Hard coded parameters in next classes + + SInt8 MapsNb; // Nb of MAPS acquired by DAQ + SInt8 MapsName; + SInt8 PlaneNb; + + // Parameters from GUI + + SInt8 MonEnabled; + + SInt32 AcqFrNb; // Nb of frame in current acq to process + + SInt8 ProcOneAcq; // 1 => Process current ONLY acq + // 0 => Process ProcEvNb coming from GUI + // It can be more or less than one acq + + SInt32 ProcEvNb; // Ev nb to process, either + // - if ProcOneAcq = 1 => ev nb of one acq + // - if ProcOneAcq = 0 => from GUI + + SInt8 ProcOnlyFrWithHitOnAllPlanes; + + SInt8 ListHitAllPlanesMode; + + SInt8 ProcOnlyFrWithTrig; // Process only frames with hit + SInt8 HandleTrigPos; // Use trigger position to extract events + SInt8 StopAtEndOfProc; // Stop at end of processing, no automatic processing of next acq + SInt8 StoreEvents; // Store events + + SInt8 DispFrNbWithTrigOrFrNbWithHit; // Display in PubPt_ADispFrNbWithTrigOrHit & PubPt_ADispFrPCentWithTrigOrHit trig or hit nb + // 0 => Display frame nb & % with trigger + // 1 => Display frame nb & % with at least one hit + + SInt8 DispFullMatrix; // 0 => Display 1/2 scale matrix + // 1 => Display full matrix + + SInt8 ProcMode; // Processing mode + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_FRAME + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_CUMUL + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_PER_FRAME_6_COLORS + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_1_COLOR + // MAPS__TCDigTelMon_MODE_PLOT_PLANE_COIN_CUMUL_6_COLORS + + SInt8 CumPlotGrayOrBlueLevels; // Cumul plot + // 0 => in gray levels + // 1 => in blue levels + + SInt8 CumPlotHitOrHitCnt; // Cumul plot + // 0 => binary display : count > 0 => set pixel in black / blue + // 1 => gray or blue levels display + + + SInt32 GotoRawFrNo; // Plot raw data of frame No + +} MAPS__TDigTelPar; + + +// 17/07/2009 + +typedef struct { + + SInt8 RunInProgress; + SInt8 LastPlaneSelForCoin; // Index of last plane selected for coincidence + + SInt32 CurEvNo; // Index of last event buffered + SInt32 FirstEvToProc; // Index of first event to process + SInt32 LastEvToProc; // Index of last event to process + SInt32 CurEvToProc; // Index of event to process + SInt32 EvNbToProc; // Ev nb to process + +} MAPS__TDigTelInf; + + +// 17/07/2009 + +typedef struct { + + SInt32 AcqFrNb; // Frame nb received from current acq + SInt32 ProFrNo; // Index of currently processed frame + SInt32 ProTimeMs; // Processing time + +} MAPS__TDigTelRes; + + +// 17/07/2009 + +typedef struct { + + SInt8 MapsId; // Id of the MAPS + MAPS__TColor PlotColor; + + SInt8 Process; // Process data of this plane + SInt8 RevertXDir; // Revert numbering of X direction ( columns ) in case planes are mounted back to back + SInt8 PlotCum; // Plot cumulated hit count over N events + SInt8 PlotCoin; // Plot coincidence + SInt8 PlotFrame; // Plot frame raw data + +} MAPS__TDigTelPlanePar; + + +// 22/07/2009 + +typedef struct { + + SInt8 PrevProcState; // Not used on 22/07/2009 + SInt8 CurProcState; // Not used on 22/07/2009 + + +} MAPS__TDigPlaneInf; + + +// 17/07/2009 + +typedef struct { + + void* AEvPt[MAPS__TCDigTelMon_MAX_EV_NB]; + void* CurEvPt; + +} MAPS__TDigTelPlaneData; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add CumTotTrigNb & CumFrameTrigNb + +typedef struct { + + void* PtMatDiscriBit; // Flat view of matrix X col x Y lines + void* PtMatCumTotHitCnt; // Hit count of each pixel over all events + + SInt32 FrameNbWithTrig; // Nb of frame with trigger + float FramePCentWithTrig; // % of frame with trigger + SInt32 CumTotTrigNb; // Total number of triggers + float CumFrameTrigNb; // Cumul MEAN trigger nb on frames WITH trigger + + SInt32 FrameNbWithHit; // Nb of frame with at least one hit + float FramePCentWithHit; // % of frame with at least one hit + SInt32 CumTotHitNb; // Total cumul hit nb over ALL frames ( with and without hit ) + float CumFrHitNb; // Cumul MEAN hit nb on frames WITH hit + +} MAPS__TDigTelPlaneRes; + + +// 17/07/2009 +// 20/05/2010 +// - Calculation of mean trig nb / frame => Add PubPt_ADispCumFrTrigNb + +#ifndef ROOT_ROOT + +class MAPS__TCDigTelMon { + + private: + + SInt8 PrivGuiConnected; + SInt8 PrivSetGuiParDontRead; + + SInt32 PrivFInit (); + + SInt32 PrivChkPlaneId ( SInt8 Id ); + + SInt32 PrivFSetGuiLabelsDispFrNbWithTrigOrFrNbWithHit (); + + protected: + + SInt8 ProRequestPlot; // Request plot from sw external to object + + MAPS__TDigTelPar ProPar; + MAPS__TDigTelInf ProInf; + MAPS__TDigTelRes ProRes; + MAPS__TDigTelPlanePar ProAPlanePar[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigPlaneInf ProAPlaneInf[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneData ProAPlaneData[MAPS__TCDigTelMon_MAX_PLANE_NB]; + MAPS__TDigTelPlaneRes ProAPlaneRes[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + public: + + // ---------------------------------- + // Fields to connect GUI components + // ---------------------------------- + + // Group + + TGroupBox* PubPt_GrpTelMon; + + // Label + + TLabel* PubPt_LbFrNbWithTrigOrHit; + TLabel* PubPt_LbFrPCentWithTrigOrHit; + + // Controls + + TCheckBox* PubPt_ChkEnableMonitor; + + TCheckBox* PubPt_AChkProc[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkRevertXDir[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TCheckBox* PubPt_ChkProcOneAcq; + TEdit* PubPt_EdFrNbToProc; + TCheckBox* PubPt_ChkProcOnlyFrWithTrig; + + TComboBox* PubPt_CbListHitAllPlanesMode; + + TCheckBox* PubPt_ChkTrigPosHanling; + TCheckBox* PubPt_ChkStopAtEndOfProc; + TCheckBox* PubPt_ChkStoreFr; + + TCheckBox* PubPt_ChkDispFrNbWithTrigOrFrNbWithHit; + TCheckBox* PubPt_ChkDispFullMatrix; + + TComboBox* PubPt_CbProcMode; + TCheckBox* PubPt_ChkCumPlotGrayOrBlueLevels; + TCheckBox* PubPt_ChkCumPlotHitOrHitCnt; + + TEdit* PubPt_EdGotoFr; + + TLabel* PubPt_ALbPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TRadioButton* PubPt_ARbPlotCum[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TCheckBox* PubPt_AChkPlotCoin[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TRadioButton* PubPt_ARdPlotFr[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // Indicators + + TEdit* PubPt_DispAcqFrNb; + TEdit* PubPt_DispCurProcFr; + + TEdit* PubPt_ADispFrNbWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispFrPCentWithTrigOrHit[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_ADispCumFrTrigNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumTotHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + TEdit* PubPt_ADispCumFrHitNb[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + TEdit* PubPt_DispProFrNo; + TEdit* PubPt_DispProcTimeMs; + + // Display + + TImage* PubPt_ImgMiniMatrix; + TImage* PubPt_ImgFullMatrix; + + + // ------------- + // Methods + // ------------- + + + MAPS__TCDigTelMon (); + ~MAPS__TCDigTelMon (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGuiEnablePlane ( SInt8 Id, SInt8 Enable ); + + SInt32 PubFSetGuiPar (); + SInt32 PubFSetGuiParGotoFr (); + + SInt32 PubFGetGuiPar (); + SInt32 PubFOnGuiParDispModeChangeFrNbWithTrigOrFrNbWithHit (); // Specific GUI behaviour + SInt32 PubFSetGuiStatus (); + SInt32 PubFSetGuiRes (); + + + // Set parameters + + SInt32 PubFSetPar ( MAPS__TDigTelPar* Pt ); + SInt32 PubFSetPlanePar ( SInt8 Id, MAPS__TDigTelPlanePar* Pt ); + + // Get parameters + + MAPS__TDigTelPar* PubFGetPar (); + MAPS__TDigTelPlanePar* PubFGetPlanePar ( SInt8 Id ); + MAPS__TDigTelPlaneData* PubFGetPlaneData ( SInt8 Id ); + + // Disable all planes processing + + SInt32 PubFDisAllPlanesProcessing (); + + // Disable group + + SInt32 PubFDisCumPlot (); + SInt32 PubFDisCoinPlot (); + SInt32 PubFDisFramePlot (); + + // Set results + + MAPS__TDigTelPlaneRes* PubFSetPlaneRes ( SInt8 Id ); + + // Poll plot request + + SInt32 PubFGetPlotRqStatus (); + SInt32 PubFResetPlotRqStatus (); + + SInt8* PubFGetPtPlotRq (); + SInt8* PubFGetPtMonEnabled (); + + + // Debug print + + SInt32 PubFPrintPar (); + SInt32 PubFPrintInf (); + + SInt32 PubFPrintPlanePar ( SInt8 Id ); + SInt32 PubFPrintAllPlanesPar (); + + SInt32 PubFPrintPlaneInf ( SInt8 Id ); + SInt32 PubFPrintAllPlanesInf (); + + SInt32 PubFPrintPlaneData ( SInt8 Id ); + SInt32 PubFPrintAllPlanesData (); + + SInt32 PubFPrintPlaneRes ( SInt8 Id ); + SInt32 PubFPrintAllPlanesRes (); + + +}; + +#endif + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 17/07/2009 */ +/* ============================= */ + +typedef struct { + + SInt8 Dummy; + +} MAPS__TContext; + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/maps.var b/include/pxi_daq_lib_v.3.1/maps.var new file mode 100755 index 0000000..cd0d91a --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/maps.var @@ -0,0 +1,33 @@ + +/******************************************************************************* +File : x:\lib\com\maps\maps.var +Goal : Variables definition of MAPS library. + : It provides MAPS types definition and data handling functions. +Prj date : 17/07/2009 +File date : 17/07/2009 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MAPS_VAR +#define MAPS_VAR + + + +/* ============== */ +/* */ +/* ============== */ + +EXTERN VAR_STATIC MAPS__TContext MAPS__VGContext; + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/math.c b/include/pxi_daq_lib_v.3.1/math.c new file mode 100755 index 0000000..c25ad6f --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/math.c @@ -0,0 +1,4350 @@ + +/******************************************************************************* +File : x:\lib\com\math.c +Goal : Functions of +Prj date : //200 +File date : //200 +Doc date : //200 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MATH_C +#define MATH_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 MATH_FSInt32Ceil ( SInt32 Src ) { + return ( ceil ( (double) Src ) ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2008 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_FFloatPow ( float x, float y ) { + return ( pow ( x, y ) ); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* 03/05/04 */ + +SInt32 MATH_FCpySInt32ToSInt16Array ( SInt32* PtSrc, SInt32 SrcEltSz, SInt16* PtDest, SInt32 DestEltSz ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( SrcEltSz > DestEltSz ) { + err_retfail ( -1, (ERR_OUT,"SrcEltSz=%d > DestEltSz=%d", SrcEltSz, DestEltSz) ); + } + + for ( Vi=0; Vi < SrcEltSz; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + +} + +// 14/08/2007 + +float MATH_FUInt8Avg ( UInt8* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +float MATH_FSInt8Avg ( SInt8* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +float MATH_FUInt16Avg ( UInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +float MATH_FSInt16Avg ( SInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +// 09/11/2010 +// Reject item == 0 from average calculation + +float MATH_FSInt16AvgNonZero ( SInt16* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + SInt32 VGoodEltCnt; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + VGoodEltCnt = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( Src[Vi] != 0 ) { + VSum = VSum + Src[Vi]; + ++VGoodEltCnt; + } + + } + + if ( VGoodEltCnt == 0 ) { + err_warning (( ERR_OUT, "No elt <> 0 to calculate average !" )); + return (0); + } + + return ( VSum / (float) VGoodEltCnt ); +} + + + +/* 21/06/2006 */ +/* Calculates the mean value of Src array selected elements */ +/* SelList[i] == 1 if the corresponding item must be used for processing */ + +float MATH_FSInt16DataListAvg ( SInt16* Src, SInt8* SelList, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VEltCnt; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( SelList, (ERR_OUT,"SelList == NULL") ); + + VEltCnt = 0; + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( SelList[Vi] != 1 ) { + continue; + } + + ++VEltCnt; + + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) VEltCnt ); +} + +// 14/08/2007 + +float MATH_FUInt32Avg ( UInt32* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + + +float MATH_FSInt32Avg ( SInt32* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + + +float MATH_FSInt32AvgNo1 ( SInt32 Src, SInt8 StartSearch, SInt8 DoCalc ) { + + static SInt64 VSum; + static SInt32 VEltCnt; + float VAvg = 0; + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VSum = 0; + return (0); + } + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Calculation not possible => bad elt nb = %d", VEltCnt) ); + } + + VAvg = (float) VSum / (float) VEltCnt; + err_retval ( VAvg, ( ERR_OUT, "Average of %d value = %.3f", VEltCnt, VAvg ) ); + } + + VSum += Src; + ++VEltCnt; + + + return (0); +} + + +// 21/05/2010 +// Calculation is done by setting DoCalc at 1 +// - current value of Src is added to sum before calculation +// - if one wants to calculate average "later", set Src=0 and DoCalc=1 + + +float MATH_FSInt32AvgNo2 ( SInt32 Src, SInt8 StartSearch, SInt8 DoCalc ) { + + static SInt64 VSum; + static SInt32 VEltCnt; + float VAvg = 0; + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VSum = 0; + } + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Calculation not possible => bad elt nb = %d", VEltCnt) ); + } + + VAvg = (float) VSum / (float) VEltCnt; + err_retval ( VAvg, ( ERR_OUT, "Average of %d value = %.3f", VEltCnt, VAvg ) ); + } + + VSum += Src; + ++VEltCnt; + + return (0); +} + + +// 11/08/2007 + +SInt32 MATH_FFloatMinMaxAvg ( float* Src, SInt32 EltNb, float* PtResMin, float* PtResMax, float* PtResAvg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + float VMin; + float VMax; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( PtResMin, (ERR_OUT,"PtResMin == NULL") ); + err_retnull ( PtResMax, (ERR_OUT,"PtResMax == NULL") ); + err_retnull ( PtResAvg, (ERR_OUT,"PtResAvg == NULL") ); + + VSum = 0; + VMin = Src[0]; + VMax = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + + VSum = VSum + Src[Vi]; + } + + *PtResMin = VMin; + *PtResMax = VMax; + *PtResAvg = ( VSum / (float) EltNb ); + + return (0); +} + + +float MATH_FFloatAvg ( float* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum = VSum + Src[Vi]; + } + + return ( VSum / (float) EltNb ); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + + +float MATH_FFloatAvgNo1 ( float Src, SInt8 StartSearch, SInt8 DoCalc ) { + + static double VSum; + static SInt32 VEltCnt; + float VAvg = 0; + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VSum = 0; + return (0); + } + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Calculation not possible => bad elt nb = %d", VEltCnt) ); + } + + VAvg = (float) VSum / (float) VEltCnt; + err_retval ( VAvg, ( ERR_OUT, "Average of %d value = %.3f", VEltCnt, VAvg ) ); + } + + VSum += Src; + ++VEltCnt; + + + return (0); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + + +float MATH_FFloatAvgNo2 ( float Src, SInt8 StartSearch, SInt8 DoCalc ) { + + static double VSum; + static SInt32 VEltCnt; + float VAvg = 0; + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VSum = 0; + return (0); + } + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Calculation not possible => bad elt nb = %d", VEltCnt) ); + } + + VAvg = (float) VSum / (float) VEltCnt; + err_retval ( VAvg, ( ERR_OUT, "Average of %d value = %.3f", VEltCnt, VAvg ) ); + } + + VSum += Src; + ++VEltCnt; + + + return (0); +} + + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// The mean value = Avg parameters MUST be given on first call ! +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + +float MATH_FFloatSigma1No1 ( float Src, float Avg, SInt8 StartSearch, SInt8 DoCalc ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + static SInt32 VEltCnt; + static float VAvg; + static double VPrevSum2; + static double VSum2; + + + // Init + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VAvg = Avg; + VSum2 = 0; + VPrevSum2 = 0; + return (0); + } + + // Calculates sigma + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_error (( ERR_OUT, "Bad elt counter = %d", VEltCnt )); + return (-1); + } + + return ( sqrt ( VSum2 / (float) VEltCnt ) ); + } + + + // Process data + + VSum2 = VSum2 + ( (Src - VAvg) * (Src - VAvg) ); + + if ( VSum2 < VPrevSum2 ) { + err_error (( ERR_OUT, "VSum2 overflow !" )); + return (-1); + } + + VPrevSum2 = VSum2; + + ++VEltCnt; + + return (0); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// The mean value = Avg parameters MUST be given on first call ! +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + +float MATH_FFloatSigma1No2 ( float Src, float Avg, SInt8 StartSearch, SInt8 DoCalc ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + static SInt32 VEltCnt; + static float VAvg; + static double VPrevSum2; + static double VSum2; + + + // Init + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VAvg = Avg; + VSum2 = 0; + VPrevSum2 = 0; + return (0); + } + + // Calculates sigma + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_error (( ERR_OUT, "Bad elt counter = %d", VEltCnt )); + return (-1); + } + + return ( sqrt ( VSum2 / (float) VEltCnt ) ); + } + + + // Process data + + VSum2 = VSum2 + ( (Src - VAvg) * (Src - VAvg) ); + + if ( VSum2 < VPrevSum2 ) { + err_error (( ERR_OUT, "VSum2 overflow !" )); + return (-1); + } + + VPrevSum2 = VSum2; + + ++VEltCnt; + + return (0); +} + + + +float MATH_FFloatMinAndMinIndex ( float* Src, SInt32 EltNb, SInt32* PtMinIndex ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMinIndex; + float VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMinIndex = -1; + VMin = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + VMinIndex = Vi; + } + } + + if ( PtMinIndex != NULL ) { + *PtMinIndex = VMinIndex; + } + + return (VMin); +} + +float MATH_FFloatMin ( float* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + float VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + +float MATH_FFloatMaxAndMaxIndex ( float* Src, SInt32 EltNb, SInt32* PtMaxIndex ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + SInt32 VMaxIndex; + float VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMaxIndex = -1; + VMax = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + VMaxIndex = Vi; + } + } + + if ( PtMaxIndex != NULL ) { + *PtMaxIndex = VMaxIndex; + } + + return (VMax); +} + + +float MATH_FFloatMax ( float* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + float VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +float MATH_FFloatMinNo1 ( float Src, SInt8 StartSearch ) { + + static SInt8 VGetFirstElt = 0; + static float VMin; + + if ( StartSearch == 1 ) { + VGetFirstElt = 1; + return (0); + } + + if ( VGetFirstElt == 1 ) { + VGetFirstElt = 0; + VMin = Src; + return (VMin); + } + + if ( Src < VMin ) { + VMin = Src; + } + + return (VMin); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +float MATH_FFloatMinNo2 ( float Src, SInt8 StartSearch ) { + + static SInt8 VGetFirstElt = 0; + static float VMin; + + if ( StartSearch == 1 ) { + VGetFirstElt = 1; + return (0); + } + + if ( VGetFirstElt == 1 ) { + VGetFirstElt = 0; + VMin = Src; + return (VMin); + } + + if ( Src < VMin ) { + VMin = Src; + } + + return (VMin); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +float MATH_FFloatMaxNo1 ( float Src, SInt8 StartSearch ) { + + static SInt8 VGetFirstElt = 0; + static float VMax; + + if ( StartSearch == 1 ) { + VGetFirstElt = 1; + return (0); + } + + if ( VGetFirstElt == 1 ) { + VGetFirstElt = 0; + VMax = Src; + return (VMax); + } + + if ( Src > VMax ) { + VMax = Src; + } + + return (VMax); +} + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +float MATH_FFloatMaxNo2 ( float Src, SInt8 StartSearch ) { + + static SInt8 VGetFirstElt = 0; + static float VMax; + + if ( StartSearch == 1 ) { + VGetFirstElt = 1; + return (0); + } + + if ( VGetFirstElt == 1 ) { + VGetFirstElt = 0; + VMax = Src; + return (VMax); + } + + if ( Src > VMax ) { + VMax = Src; + } + + return (VMax); +} + + + +// 09/08/2007 + +SInt32 MATH_FUInt32Min ( UInt32* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + UInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 0xFFFFFFFF; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + + +// 09/08/2007 + +SInt32 MATH_FUInt32Max ( UInt32* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + UInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = 0; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + + +SInt32 MATH_FSInt32Min ( SInt32* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 0x7FFFFFFF; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +SInt32 MATH_FSInt32MinNo1 ( SInt32 Src, SInt8 StartSearch ) { + + static SInt32 VMin; + + if ( StartSearch == 1 ) { + VMin = TYP_MAX_SINT32; + return (0); + } + + if ( Src < VMin ) { + VMin = Src; + } + + return (VMin); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +SInt32 MATH_FSInt32MinNo2 ( SInt32 Src, SInt8 StartSearch ) { + + static SInt32 VMin; + + if ( StartSearch == 1 ) { + VMin = TYP_MAX_SINT32; + return (0); + } + + if ( Src < VMin ) { + VMin = Src; + } + + return (VMin); +} + + + +SInt32 MATH_FSInt32Max ( SInt32* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = ( ~ 0x7FFFFFFF ); + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +SInt32 MATH_FSInt32MaxNo1 ( SInt32 Src, SInt8 StartSearch ) { + + static SInt32 VMax; + + if ( StartSearch == 1 ) { + VMax = TYP_MIN_SINT32; + return (0); + } + + if ( Src > VMax ) { + VMax = Src; + } + + return (VMax); +} + +// 21/05/2010 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call + +SInt32 MATH_FSInt32MaxNo2 ( SInt32 Src, SInt8 StartSearch ) { + + static SInt32 VMax; + + if ( StartSearch == 1 ) { + VMax = TYP_MIN_SINT32; + return (0); + } + + if ( Src > VMax ) { + VMax = Src; + } + + return (VMax); +} + + +// 09/08/2007 + +SInt32 MATH_FUInt16Min ( UInt16* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + UInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 65535; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + +// 09/08/2007 + +SInt32 MATH_FUInt16Max ( UInt16* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + UInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = 0; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + +/* -------------------- */ + +SInt32 MATH_FSInt16Min ( SInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 32767; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + +/* 20/06/2006 */ +/* Calculates the min value Src array selected elements */ +/* SelList[i] == 1 if the corresponding item must be used for min processing */ + +SInt32 MATH_FSInt16DataListMin ( SInt16* SrcData, SInt8* SelList, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( SelList, (ERR_OUT,"SelList == NULL") ); + + VMin = 32767; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( (SelList[Vi] == 1) && (SrcData[Vi] < VMin) ) { + VMin = SrcData[Vi]; + } + } + + return (VMin); +} + + + +SInt32 MATH_FSInt16Max ( SInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = -32768; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + +/* 20/06/2006 */ +/* Calculates the max value Src array selected elements */ +/* SelList[i] == 1 if the corresponding item must be used for max processing */ + +SInt32 MATH_FSInt16DataListMax ( SInt16* SrcData, SInt8* SelList, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( SelList, (ERR_OUT,"SelList == NULL") ); + + VMax = -32768; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( (SelList[Vi] == 1) && (SrcData[Vi] > VMax) ) { + VMax = SrcData[Vi]; + } + } + + return (VMax); +} + + + + + + + +/* ---- */ +// 12/04/2006 + +UInt8 MATH_FUInt8Min ( UInt8* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + UInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 255; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + +// 12/04/2006 + + +UInt8 MATH_FUInt8Max ( UInt8* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + UInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = 0; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + +/* ---- */ +// 07/08/2007 + +SInt8 MATH_FSInt8Min ( SInt8* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + SInt32 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = 127; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + +// 07/08/2007 + + +SInt8 MATH_FSInt8Max ( SInt8* Src, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + SInt32 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = -128; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + + + +float MATH_FSInt32Sigma1 ( SInt32* Src, SInt32 EltNb, float Avg ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + for ( Vi=0; Vi < EltNb; Vi++) { + + /* VSum2 = VSum2 + ( (Src[Vi] *Src[Vi]) - VAvg2 ); */ + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + + +// 19/01/2012 +// First call must be done with StartSearch = 1 and Src of this call IS NOT processed +// => Processing starts on next call +// The mean value = Avg parameters MUST be given on first call ! +// Calculation is done by setting DoCalc at 1 +// - current value of Src is not processed => use previous list of values + +float MATH_FSInt32Sigma1No1 ( SInt32 Src, float Avg, SInt8 StartSearch, SInt8 DoCalc ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + static SInt32 VEltCnt; + static float VAvg; + static double VPrevSum2; + static double VSum2; + + + // Init + + if ( StartSearch == 1 ) { + VEltCnt = 0; + VAvg = Avg; + VSum2 = 0; + VPrevSum2 = 0; + return (0); + } + + // Calculates sigma + + if ( DoCalc == 1 ) { + + if ( VEltCnt <= 0 ) { + err_error (( ERR_OUT, "Bad elt counter = %d", VEltCnt )); + return (-1); + } + + return ( sqrt ( VSum2 / (float) VEltCnt ) ); + } + + + // Process data + + VSum2 = VSum2 + ( (Src - VAvg) * (Src - VAvg) ); + + if ( VSum2 < VPrevSum2 ) { + err_error (( ERR_OUT, "VSum2 overflow !" )); + return (-1); + } + + VPrevSum2 = VSum2; + + return (0); +} + + +float MATH_FSInt16Sigma1 ( SInt16* Src, SInt32 EltNb, float Avg ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + SInt32 VOutOfRangeCnt; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + VOutOfRangeCnt = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( ( Src[Vi] < (Avg-6) ) || (Src[Vi] > (Avg+6) ) ) { + ++VOutOfRangeCnt; + } + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + +// 14/08/2007 + +float MATH_FSInt8Sigma1 ( SInt8* Src, SInt32 EltNb, float Avg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + + for ( Vi=0; Vi < EltNb; Vi++) { + + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + + +// 14/08/2007 + +float MATH_FUInt32Sigma1 ( UInt32* Src, SInt32 EltNb, float Avg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + + for ( Vi=0; Vi < EltNb; Vi++) { + + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + +// 14/08/2007 + +float MATH_FUInt16Sigma1 ( UInt16* Src, SInt32 EltNb, float Avg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + + for ( Vi=0; Vi < EltNb; Vi++) { + + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + +// 14/08/2007 + +float MATH_FUInt8Sigma1 ( UInt8* Src, SInt32 EltNb, float Avg ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + double VPrevSum2; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + + for ( Vi=0; Vi < EltNb; Vi++) { + + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + + +/* 21/06/2006 */ +/* Calculates the sigma value of Src array selected elements */ +/* SelList[i] == 1 if the corresponding item must be used for processing */ + +float MATH_FSInt16DataListSigma1 ( SInt16* Src, SInt8* SelList, SInt32 EltNb, float Avg ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + SInt32 VEltCnt; + double VPrevSum2; + double VSum2; + double VAvg2; + SInt32 VOutOfRangeCnt; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( SelList, (ERR_OUT,"SelList == NULL") ); + + VSum2 = 0; + VPrevSum2 = 0; + VAvg2 = Avg * Avg; + + VEltCnt = 0; + VOutOfRangeCnt = 0; + + for ( Vi=0; Vi < EltNb; Vi++) { + + if ( SelList[Vi] != 1 ) { + continue; + } + + ++VEltCnt; + + if ( ( Src[Vi] < (Avg-6) ) || (Src[Vi] > (Avg+6) ) ) { + ++VOutOfRangeCnt; + } + + VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); + + if ( VSum2 < VPrevSum2 ) { + return (-1); + } + + VPrevSum2 = VSum2; + + } /* End for */ + + // return ( VOutOfRangeCnt ); + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + return ( sqrt ( VSum2 / (float) VEltCnt ) ); +} + + + + +float MATH_FFloatSigma1 ( float* Src, SInt32 EltNb, float Avg ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + double VSum2; + double VAvg2; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VSum2 = 0; + VAvg2 = Avg * Avg; + + for ( Vi=0; Vi < EltNb; Vi++) { + VSum2 = VSum2 + ( (Src[Vi] *Src[Vi]) - VAvg2 ); + /* VSum2 = VSum2 + ( (Src[Vi] - Avg) * (Src[Vi] - Avg) ); */ + } + + if ( VSum2 <= 0 ) { + err_warning (( ERR_OUT, "Sigma calc error : Sum2=%.3f <= 0 => Sigma=0", VSum2 )); + return (0); + } + + + return ( sqrt ( VSum2 / (float) EltNb ) ); +} + + +void MATH_FDiffPedest ( SInt32* Src, float Pedest, float* Dest, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_error (( ERR_OUT, "Bad EltNb=%d => must be > 0", EltNb )); + return; + } + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Src[Vi] - Pedest; + } + +} + + + +void MATH_FDiffPedestUInt8FloatFloat ( UInt8* Src, float* Pedest, float* Dest, SInt32 EltNb ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_error (( ERR_OUT, "Bad EltNb=%d => must be > 0", EltNb )); + return; + } + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Src[Vi] - Pedest[Vi]; + } + +} + + +/* 07/12/04 */ + +SInt32 MATH_FScaleFloatVect ( float* Src, float* Dest, SInt32 EltNb, float Offset, float Slope ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = ( Src[Vi] * Slope ) + Offset; + } + + +} + +/* 02/01/05 */ + +SInt32 MATH_FIntInRange ( SInt32 Min, SInt32 Max, SInt32 Val ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + if ( (Val >= Min) && (Val <= Max)) { + return (1); + } + + err_retfail ( -1, (ERR_OUT,"Value = %d out of range <%d..%d> ", Val, Min, Max) ); +} + +/* 02/01/05 */ + +SInt32 MATH_FFloatInRange ( float Min, float Max, float Val ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + if ( (Val >= Min) && (Val <= Max)) { + return (1); + } + + err_retfail ( -1, (ERR_OUT,"Value = %d out of range <%d..%d> ", Val, Min, Max) ); +} + + +/* 26/04/06 */ + +SInt32 MATH_FOffsetSInt16Vect ( SInt16* Src, SInt16* Dest, SInt32 EltNb, SInt16 Offset ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Src[Vi] + Offset; + } + + return (0); +} + + +/* 26/04/06 */ + +SInt32 MATH_FTranslateSInt16ToUInt16Vect ( SInt16* Src, UInt16* Dest, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Src[Vi] + 32768; + } + + return (0); +} + +/* 30/04/06 */ + + +SInt32 MATH_FScaleSInt32Vect ( SInt32* Src, SInt32* Dest, SInt32 EltNb, SInt32 Offset, SInt32 Slope ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + err_retnull ( Src , (ERR_OUT,"Src == NULL") ); + err_retnull ( Dest, (ERR_OUT,"Dest == NULL") ); + + for ( Vi=0; Vi < EltNb; Vi++ ) { + Dest[Vi] = Offset + ( Src[Vi] * Slope ); + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 26/04/2006 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoSInt16Book ( SInt16 HistoId, SInt16 Min, SInt16 Max, SInt16 BinW ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + err_warning (( ERR_OUT, "Do nothing for the moment : reserved for future use" )); + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 26/04/2006 +Modif : 04/05/2006 + : - Add a test on BinNb <= MATH_HISTO_MAX_BIN_NB +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoSInt16Build ( SInt16 HistoId, SInt16* PtSrc, SInt32 EltNb, SInt16 Min, SInt16 Max, SInt16 BinW, SInt16* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, SInt32** PtPtDestX, SInt32** PtPtDestY, SInt8 DbgPlot ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + SInt16 VMin; + SInt16 VMax; + SInt16 VBinW; + SInt16 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + static SInt32 VADestX [MATH_HISTO_MAX_ID_NB][MATH_HISTO_MAX_BIN_NB + 1]; + static SInt32 VADestY [MATH_HISTO_MAX_ID_NB][MATH_HISTO_MAX_BIN_NB + 1]; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + /* Check histo ID */ + + err_retfail ( HistoId, (ERR_OUT,"HistoId=%d MUST be > 0", HistoId) ); + + if ( HistoId >= MATH_HISTO_MAX_ID_NB ) { + err_retfail ( -1, (ERR_OUT,"HistoId=%d >= MATH_HISTO_MAX_ID_NB=%d", HistoId, MATH_HISTO_MAX_ID_NB ) ); + } + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtPtDestX, (ERR_OUT,"PtPtDestX == NULL") ); + err_retnull ( PtPtDestY, (ERR_OUT,"PtPtDestY == NULL") ); + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + VADestX[HistoId][Vi] = 0; + VADestY[HistoId][Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ); + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * VBinNb ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++VADestY[HistoId][VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + VADestX[HistoId][Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + /* ---------------------------------------- */ + /* Init paramters pointers to result arrays */ + /* ---------------------------------------- */ + + *PtPtDestX = VADestX[HistoId]; + *PtPtDestY = VADestY[HistoId]; + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, VADestX[HistoId][Vi], VADestX[HistoId][Vi+1], VADestY[HistoId][Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, VADestX[HistoId][Vi], Vi, VADestY[HistoId][Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* 30/04/06 */ + +SInt32 MATH_FCpyUInt16ArrayToSInt32Array ( UInt16* PtSrc, SInt32 SrcEltSz, SInt32* PtDest, SInt32 DestEltSz ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + + if ( SrcEltSz > DestEltSz ) { + err_retfail ( -1, (ERR_OUT,"SrcEltSz=%d > DestEltSz=%d", SrcEltSz, DestEltSz) ); + } + + for ( Vi=0; Vi < SrcEltSz; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + +} + + +/* 30/04/06 */ + +SInt32 MATH_FCpySInt16ArrayToSInt32Array ( SInt16* PtSrc, SInt32 SrcEltSz, SInt32* PtDest, SInt32 DestEltSz ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + + SInt32 Vi; + + if ( SrcEltSz > DestEltSz ) { + err_retfail ( -1, (ERR_OUT,"SrcEltSz=%d > DestEltSz=%d", SrcEltSz, DestEltSz) ); + } + + for ( Vi=0; Vi < SrcEltSz; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + +} + + +/* TO REMOVE ONE DAY - Following lines are in comment */ + +/* + +UInt16 MATH_FSInt16Min ( UInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + UInt16 VMin; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMin = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] < VMin ) { + VMin = Src[Vi]; + } + } + + return (VMin); +} + + + + +UInt16 MATH_FSInt16Max ( UInt16* Src, SInt32 EltNb ) { + +#ifdef APP_ROOT + static char VFuncName[] = ""; +#endif + + SInt32 Vi; + UInt16 VMax; + + if ( EltNb <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Bad EltNb=%d => must be > 0", EltNb) ); + } + + VMax = Src[0]; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + if ( Src[Vi] > VMax ) { + VMax = Src[Vi]; + } + } + + return (VMax); +} + +*/ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FVoltageGain2dB ( float Gain ) { + + float VdB; + + if ( Gain <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Gain = %.3f must be > 0", Gain) ); + } + + VdB = 20 * log10 ( Gain ); + + return (VdB); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdB2VoltageGain ( float dB ) { + + float VGain; + + VGain = MATH_FFloatPow ( 10, ((float) dB / (float) 20) ); + + return (VGain); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FPowerGain2dB ( float Gain ) { + + float VdB; + + if ( Gain <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Gain = %.3f must be > 0", Gain) ); + } + + VdB = 10 * log10 ( Gain ); + + return (VdB); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdB2PowerGain ( float dB ) { + + float VGain; + + + VGain = MATH_FFloatPow ( 10, ((float) dB / (float) 10) ); + + return (VGain); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FV2dBV ( float Volt ) { + + float VdBV; + + if ( Volt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Vlot = %.3f must be > 0", Volt) ); + } + + VdBV = MATH_UCONV_FVoltageGain2dB ( Volt ); + + return (VdBV); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBV2V ( float dBV ) { + + float Volt; + + + Volt = MATH_UCONV_FdB2VoltageGain ( dBV ); + + return (Volt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FmV2dBV ( float mV ) { + + float VdBV; + + VdBV = MATH_UCONV_FV2dBV ( (float) mV / (float) 1000 ); + + return (VdBV); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBV2mV ( float dBV ) { + + float VmV; + + VmV = 1000 * MATH_UCONV_FdBV2V ( dBV ); + + return (VmV); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FV2dBmV ( float Volt ) { + + float VdBmV; + + if ( Volt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Vlot = %.3f must be > 0", Volt) ); + } + + VdBmV = MATH_UCONV_FVoltageGain2dB ( (float) Volt / (float) 0.001 ); + + return (VdBmV); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBmV2V ( float dBmV ) { + + float Volt; + + + Volt = 0.001 * MATH_UCONV_FdB2VoltageGain ( dBmV ); + + return (Volt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FV2dBm600 ( float Volt ) { + + float VPowerW; + float VdBm600; + + if ( Volt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Vlot = %.3f must be > 0", Volt) ); + } + + VPowerW = (float) (( Volt * Volt )) / (float) 600; + + VdBm600 = 10 * log10 ( VPowerW / 0.001 ); + + err_trace (( ERR_OUT, "V = %.3f - Power mW = %.3f - dBm = %.3f ", Volt, VPowerW, VdBm600 )); + + return (VdBm600); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBm600_2V ( float dBm600 ) { + + float VPowerW; + float VVolt; + + VPowerW = 0.001 * MATH_UCONV_FdB2PowerGain ( dBm600 ); + + VVolt = sqrt ( VPowerW * 600 ); + + return (VVolt); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FmV2dBm600 ( float mV ) { + + float VdBm600; + + VdBm600 = MATH_UCONV_FV2dBm600 ( (float) mV / (float) 1000 ); + + err_trace (( ERR_OUT, "mV = %.3f - dBm = %.3f ", mV, VdBm600 )); + + return (VdBm600); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FV2dBm50 ( float Volt ) { + + float VPowerW; + float VdBm50; + + if ( Volt <= 0 ) { + err_retfail ( -1, (ERR_OUT,"Vlot = %.3f must be > 0", Volt) ); + } + + VPowerW = (float) (( Volt * Volt )) / (float) 50; + + VdBm50 = 10 * log10 ( VPowerW / 0.001 ); + + return (VdBm50); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FdBm50_2V ( float dBm50 ) { + + float VPowerW; + float VVolt; + + VPowerW = 0.001 * MATH_UCONV_FdB2PowerGain ( dBm50 ); + + VVolt = sqrt ( VPowerW * 50 ); + + return (VVolt); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 01/08/2007 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +float MATH_UCONV_FmV2dBm50 ( float mV ) { + + float VdBm50; + + VdBm50 = MATH_UCONV_FV2dBm50 ( (float) mV / (float) 1000 ) ; + + return (VdBm50); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/08/2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 DAM_FAllocResizeFloatBuffer ( SInt32 NewBuffESz, SInt32* PtCurBuffESz, float LowAdjustTheresholdRatio, float** PtPtBuff ) { + + float VBuffESzRatio; + + if ( (*PtCurBuffESz) != 0 ) { + VBuffESzRatio = (float) NewBuffESz / (float) (*PtCurBuffESz); + } + + else { + VBuffESzRatio = 1.1; + } + + if ( (NewBuffESz > (*PtCurBuffESz)) || (VBuffESzRatio < LowAdjustTheresholdRatio) ) { + + if ( (*PtPtBuff) != NULL ) { + free (*PtPtBuff); + } + + (*PtPtBuff) = (float*) malloc ( NewBuffESz * (sizeof (float)) ); + + err_retnull ( (*PtPtBuff), (ERR_OUT,"Allocation of %d SInt32 failed !", NewBuffESz) ); + + err_trace (( ERR_OUT, "Buffer size adjusted : Previous = %d SInt32 - New = %d SInt32", (*PtCurBuffESz), NewBuffESz )); + + (*PtCurBuffESz) = NewBuffESz; + } + + return (0); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 08/08/2007 +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +// 08/08/2007 + +SInt32 DAM_FCpyVectUInt8ToFloat ( UInt8* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectSInt8ToFloat ( SInt8* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectUInt16ToFloat ( UInt16* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectSInt16ToFloat ( SInt16* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectUInt32ToFloat ( UInt32* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + +// 08/08/2007 + +SInt32 DAM_FCpyVectSInt32ToFloat ( SInt32* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + + +// 08/08/2007 + +SInt32 DAM_FCpyVectFloatToFloat ( float* PtSrc, float* PtDest, SInt32 NbElt ) { + + SInt32 Vi; + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtDest, (ERR_OUT,"PtDest == NULL") ); + + for ( Vi=0; Vi < NbElt; Vi++ ) { + PtDest[Vi] = PtSrc[Vi]; + } + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectUInt8 ( UInt8* PtSrc, SInt32 EltNb, UInt8 Min, UInt8 Max, UInt8 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + UInt8 VMin; + UInt8 VMax; + UInt8 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + err_trace (( ERR_OUT, "Min=%d - Max=%d - BinW=%d - BinNb=%d", VMin, VMax, VBinW, VBinNb )); + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectUInt16 ( UInt16* PtSrc, SInt32 EltNb, UInt16 Min, UInt16 Max, UInt16 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + UInt16 VMin; + UInt16 VMax; + UInt16 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectUInt32 ( UInt32* PtSrc, SInt32 EltNb, UInt32 Min, UInt32 Max, UInt32 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + UInt32 VMin; + UInt32 VMax; + UInt32 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +SInt32 MATH_FHistoVectSInt8 ( SInt8* PtSrc, SInt32 EltNb, SInt8 Min, SInt8 Max, UInt8 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + SInt8 VMin; + SInt8 VMax; + UInt8 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectSInt16 ( SInt16* PtSrc, SInt32 EltNb, SInt16 Min, SInt16 Max, UInt16 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + SInt16 VMin; + SInt16 VMax; + UInt16 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectSInt32 ( SInt32* PtSrc, SInt32 EltNb, SInt32 Min, SInt32 Max, UInt32 BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + SInt32 VMin; + SInt32 VMax; + UInt32 VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 14/08/2007 +Modif : +Doc date : //2007 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + +SInt32 MATH_FHistoVectFloat ( float* PtSrc, SInt32 EltNb, float Min, float Max, float BinW, float* PtCalcMax, SInt32* PtUdf, SInt32* PtOvf, float* PtDestX, float* PtDestY, SInt32 DestESz, SInt8 DbgPlot ) { + + #ifdef APP_ROOT + static char VFuncName[] = ""; + #endif + + SInt32 VRet; + SInt32 VUdfCnt; + SInt32 VOvfCnt; + float VMin; + float VMax; + float VBinW; + SInt32 VBinNb; + SInt32 Vi; + SInt32 VBinSIndex; + SInt32 VFirstBinSIndex; + SInt32 VBinUIndex; + + /* ------------------------- */ + /* Check function parameters */ + /* ------------------------- */ + + + /* Check pointers parameters */ + + err_retnull ( PtSrc , (ERR_OUT,"PtSrc == NULL") ); + err_retnull ( PtCalcMax, (ERR_OUT,"PtCalcMax == NULL") ); + err_retnull ( PtDestX , (ERR_OUT,"PtDestX == NULL") ); + err_retnull ( PtDestY , (ERR_OUT,"PtDestY == NULL") ); + + if ( DestESz < MATH_HISTO_MAX_BIN_NB + 1 ) { + err_retfail ( -1, (ERR_OUT,"Destination array too small %d elt < MATH_HISTO_MAX_BIN_NB + 1 = %d", DestESz, MATH_HISTO_MAX_BIN_NB + 1 ) ); + } + + /* ------------------------ */ + /* Reset result arrays */ + /* ------------------------ */ + + for ( Vi = 0; Vi < MATH_HISTO_MAX_BIN_NB + 1; Vi++ ) { + PtDestX[Vi] = 0; + PtDestY[Vi] = 0; + } + + + /* ------------------------ */ + /* Calculate histo bounds */ + /* ------------------------ */ + + VMin = Min; + VBinW = BinW; + + VBinNb = MATH_FSInt32Ceil ( ( Max - Min ) / VBinW ) + 1; + + if ( VBinNb > MATH_HISTO_MAX_BIN_NB ) { + err_retfail ( -1, (ERR_OUT,"Too much bin nb = %d > MATH_HISTO_MAX_BIN_NB = %d", VBinNb, MATH_HISTO_MAX_BIN_NB) ); + } + + VMax = VMin + ( VBinW * (VBinNb - 1) ); + *PtCalcMax = VMax; + + if ( VMax > Max ) { + err_warning (( ERR_OUT, "Max recalculated Set value=%d - Calculated value=%d", Max, VMax )); + } + + /* ------------------------ */ + /* Build bin content */ + /* ------------------------ */ + + VUdfCnt = 0; + VOvfCnt = 0; + + VFirstBinSIndex = VMin / VBinW; + + for ( Vi=0; Vi < EltNb; Vi++ ) { + + if (PtSrc[Vi] < VMin) { + ++VUdfCnt; + continue; + } + + if (PtSrc[Vi] > VMax) { + ++VOvfCnt; + continue; + } + + VBinSIndex = PtSrc[Vi] / VBinW; + + if ( VBinSIndex < 0 ) { + --VBinSIndex; + } + + VBinUIndex = VBinSIndex - VFirstBinSIndex; + + ++PtDestY[VBinUIndex]; + + } /* End for */ + + /* ------------------------ */ + /* Update Udf & Ovf */ + /* ------------------------ */ + + if ( PtUdf != NULL ) { + *PtUdf = VUdfCnt; + } + + if ( PtOvf != NULL ) { + *PtOvf = VOvfCnt; + } + + + /* ------------------------ */ + /* Build X array content */ + /* ------------------------ */ + + for ( Vi=0; Vi < (VBinNb + 1); Vi++ ) { + + PtDestX[Vi] = VMin + ( Vi * VBinW ); + + } /* End for */ + + + /* ------------------------ */ + /* Plot arrays */ + /* ------------------------ */ + + if ( DbgPlot ) { + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "Bin [Index=%4d] [Range=%4d..%4d] Count = %4d", Vi, PtDestX[Vi], PtDestX[Vi+1], PtDestY[Vi] )); + } /* End for */ + + for ( Vi=0; Vi < VBinNb; Vi++ ) { + msg (( MSG_OUT, "X[%4d]=%4d - Y[%4d]=%4d", Vi, PtDestX[Vi], Vi, PtDestY[Vi] )); + } /* End for */ + + + } /* End if */ + + return (VBinNb); +} + + + +// 14/08/2007 + +SInt8 MATH_FChkUInt8Range ( float Data ) { + + if ( (Data < 0) || (Data > 255) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [0..255]") ); + } + + return (0); +} + + +// 14/08/2007 + +SInt8 MATH_FChkUInt16Range ( float Data ) { + + if ( (Data < 0) || (Data > 65535) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [0..65535]") ); + } + + return (0); +} + +// 14/08/2007 + +SInt8 MATH_FChkUInt32Range ( float Data ) { + + if ( (Data < 0) || (Data > 0xFFFFFFFF) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [0..%d]", 0xFFFFFFFF) ); + } + + return (0); +} + + + + +// 14/08/2007 + +SInt8 MATH_FChkSInt8Range ( float Data ) { + + if ( (Data < -128) || (Data > 127) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [-128..127]") ); + } + + return (0); +} + + +// 14/08/2007 + +SInt8 MATH_FChkSInt16Range ( float Data ) { + + if ( (Data < -32768) || (Data > 32767) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [-32768..32767]") ); + } + + return (0); +} + +// 14/08/2007 + +SInt8 MATH_FChkSInt32Range ( float Data ) { + + +#ifdef INT_MAX + if ( (Data < (-INT_MAX-1)) || (Data > INT_MAX) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [%d..%d]", (-INT_MAX-1), INT_MAX) ); + } +#else + if ( (Data < (-MaxInt-1)) || (Data > MaxInt) ) { + err_retfail ( -1, (ERR_OUT,"Data=%.3f is out of UInt8 range [%d..%d]", (-MaxInt-1), MaxInt) ); + } +#endif + + return (0); +} + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : //2004 +Doc date : //2004 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + +#endif + +// msg (( MSG_OUT, "Msg" )); diff --git a/include/pxi_daq_lib_v.3.1/math.def b/include/pxi_daq_lib_v.3.1/math.def new file mode 100755 index 0000000..f6e521a --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/math.def @@ -0,0 +1,27 @@ + +/* 03/05/2004 */ + +#ifndef MATH_DEF +#define MATH_DEF + + +#define MATH_HISTO_MAX_ID_NB 10 +#define MATH_HISTO_MAX_BIN_NB 4096 + + +typedef enum { + + DAM_DATA_TYPE_NOT_SET, + DAM_DATA_TYPE_UINT8, + DAM_DATA_TYPE_UINT16, + DAM_DATA_TYPE_UINT32, + DAM_DATA_TYPE_SINT8, + DAM_DATA_TYPE_SINT16, + DAM_DATA_TYPE_SINT32, + DAM_DATA_TYPE_FLOAT, + +} DAM_EDataTypes; + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/math.typ b/include/pxi_daq_lib_v.3.1/math.typ new file mode 100755 index 0000000..7d10179 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/math.typ @@ -0,0 +1,8 @@ +/* 03/05/2004 */ + +#ifndef MATH_TYP +#define MATH_TYP + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/math.var b/include/pxi_daq_lib_v.3.1/math.var new file mode 100755 index 0000000..98cc61a --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/math.var @@ -0,0 +1,7 @@ + +/* 03/05/2004 */ + +#ifndef MATH_VAR +#define MATH_VAR + +#endif diff --git a/include/pxi_daq_lib_v.3.1/mi26_usr.def b/include/pxi_daq_lib_v.3.1/mi26_usr.def new file mode 100755 index 0000000..7771c7f --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/mi26_usr.def @@ -0,0 +1,75 @@ +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.def +Goal : Macros definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_DEF +#define MI26_USR_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 +#define MI26__ZS_FFRAME_MODE_2X80MHZ_W8_SZ 1152 + +#define MI26__ZS_FFRAME_RAW_MAX_W8 2280 +#define MI26__ZS_FFRAME_RAW_MAX_W16 1140 // 1142 +#define MI26__ZS_FFRAME_RAW_MAX_W32 570 +#define MI26__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 + + +#define MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 +#define MI26__ZS_FFRAME_MAX_STATES_REC 576 // one per line + +// ====================================== +// For MI26 discri analysis tools +// ====================================== + +// Submatrices number + +#define MI26__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define MI26__REG_BIAS_NB 19 + +#define MI26__REG_BIAS_ICLPDISC 0 +#define MI26__REG_BIAS_IPWRSW 1 +#define MI26__REG_BIAS_IBUF 2 +#define MI26__REG_BIAS_ID1PWRS 3 +#define MI26__REG_BIAS_ID2PWRS 4 +#define MI26__REG_BIAS_ILVDSTX 5 +#define MI26__REG_BIAS_ILVDS 6 +#define MI26__REG_BIAS_IVTST1 7 +#define MI26__REG_BIAS_IVTST2 8 +#define MI26__REG_BIAS_IANABUF 9 +#define MI26__REG_BIAS_IVDREF1D 10 +#define MI26__REG_BIAS_IVDREF1C 11 +#define MI26__REG_BIAS_IVDREF1B 12 +#define MI26__REG_BIAS_IVDREF1A 13 +#define MI26__REG_BIAS_IVDREF2 14 +#define MI26__REG_BIAS_IDIS1 15 +#define MI26__REG_BIAS_IDIS2 16 +#define MI26__REG_BIAS_IPXI 17 +#define MI26__REG_BIAS_IKIMO 18 + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/mi26_usr.typ b/include/pxi_daq_lib_v.3.1/mi26_usr.typ new file mode 100755 index 0000000..006161a --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/mi26_usr.typ @@ -0,0 +1,193 @@ + +/******************************************************************************* +File : x:\lib\com\maps\mi26\mi26_usr.typ +Goal : Types definition of Mi26 library. + : It provides Mi26 types definition and data handling functions. +Prj date : 05/08/2010 +File date : 05/08/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef MI26_USR_TYP +#define MI26_USR_TYP + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} MI26__TContext; + + +/* ======================================================= */ +/* Frame provided by Mi26 DAQ, it's independent of output */ +/* mode BUT data are not organized as in MI26__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by MI26__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + UInt32 Header; // Header of Mimosa 26 frame + UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 Trailer; // Trailer of Mimosa 26 frame + + UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + UInt16 ADataW16[MI26__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} MI26__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} MI26__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} MI26__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + MI26__TStatesLine StatesLine; + MI26__TState AStates[MI26__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} MI26__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by Mi26, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max MI26__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a MI26 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + MI26__TZsFStatesRec AStatesRec[MI26__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} MI26__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/msg.c b/include/pxi_daq_lib_v.3.1/msg.c new file mode 100755 index 0000000..7dd5585 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/msg.c @@ -0,0 +1,230 @@ + +/******************************************************************************* +File : x:\lib\com\msg\msg.c +Goal : Implement user messages print ( screen ) or log ( file ) functions. + : It's usefull to send debug messages. + : +Remark : The way it works is controlled by 3 globals variables + : MSG_VGLogClosed = 0 ( disable ) / 1 ( enable ) user messages + : MSG_VGLogPath = '/msg/msg.txt' = path of messages logfile + : MSG_VGLogFile = NULL ( output = file ) / stdout ( use stdout ) + : There is the same variables with RMSG_ instead of MSG_ they are + : used for on-line remote monitoring messages. + : The default state off these variable is set here, but you can + : overwrite it at the beginning of a program +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_C +#define MSG_C + + +SInt32 MSG_FGenEnableLog ( SInt8 Chan, SInt8 Enable ) { + MSG_VGALogClosed[Chan] = Enable; + MSG_VGALogEnabled[Chan] = Enable; + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGenGetLogEnabled ( SInt8 Chan ) { + return (MSG_VGALogEnabled[Chan]); +} + + +SInt32 MSG_FGenSetLogFilePath ( SInt8 Chan, char* LogFilePath ) { + sprintf ( MSG_VGALogPath[Chan], "%s", LogFilePath ); + return (0); +} + +char* MSG_FGenGetLogFilePath ( SInt8 Chan ) { + return ( MSG_VGALogPath[Chan] ); +} + +SInt32 MSG_FGenStopLog ( SInt8 Chan, SInt8 Stop ) { + MSG_VGADontLog[Chan] = Stop; + return (0); +} + + +SInt32 MSG_FGenBegin ( SInt8 Chan, SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( Chan, Enable ); + MSG_FGenSetLogFilePath ( Chan, FilePath ); + + return (0); +} + +SInt32 MSG_FBegin ( SInt8 Enable, char* FilePath ) { + + MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable ); + MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, FilePath ); + + return (0); +} + + +SInt32 MSG_FEnd () { + + return (0); +} + + +SInt32 MSG_FEnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt32 MSG_EnableLog ( SInt8 Enable ) { + return ( MSG_FGenEnableLog ( MSG_CHAN_MSG, Enable) ); +} + +SInt8 MSG_FGetLogEnabled () { + return ( MSG_FGenGetLogEnabled ( MSG_CHAN_MSG ) ); +} + +SInt32 MSG_FSetLogFilePath ( char* LogFilePath ) { + return ( MSG_FGenSetLogFilePath ( MSG_CHAN_MSG, LogFilePath ) ); +} + +/* 11/06/2005 */ + +SInt32 MSG_FSetFileLogLevel ( SInt8 Level ) { + + MSG_VGFileLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_GSetFileLogLevel () { + return (MSG_VGFileLogLevel); +} + + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserLogLevel ( SInt8 Level ) { + + MSG_VGUserLogLevel = Level; + + return (0); +} + +/* 07/04/2007 */ + +SInt8 MSG_FGetUserLogLevel () { + return (MSG_VGUserLogLevel); +} + +char* MSG_FGetLogFilePath ( void ) { + return ( MSG_FGenGetLogFilePath ( MSG_CHAN_MSG ) ); +} + + +/* 11/06/2005 */ + +SInt32 MSG_FSetUserMsgFunc ( TUserMsgFunc Func ) { + + MSG_VGUserMsgFunc = Func; + + return (0); +} + + +/* 07/04/2007 */ + +char* MSG_FGenGetMsgLogConfStr ( SInt8 Chan ) { + + static char VStr[MSG_CMT_SZ+1]; + + sprintf ( VStr, "Messages log configuration \n\n - Log enabled = %d \n - Stop log = %d \n - File log level = %d \n - Log file name = %s \n - User log level = %d \n\n ", MSG_VGALogEnabled[Chan], MSG_VGADontLog[Chan], MSG_VGFileLogLevel, MSG_VGALogPath[Chan], MSG_VGUserLogLevel ); + + return (VStr); +} + +/* 07/04/2007 */ + +char* MSG_FGetMsgLogConfStr () { + return ( MSG_FGenGetMsgLogConfStr (MSG_CHAN_MSG) ); +} + +SInt32 MSG_FGenMsg ( SInt8 Chan, SInt8 Level ) { + + static char VMsg[256 /* MSG_CMT_SZ include file not visble from ROOT => must be solved */]; + + if ( (MSG_VGFileLogLevel == 0) && (MSG_VGUserLogLevel == 0) ) { + return (0); + } + + sprintf ( VMsg, "MSG %.7d => %s \n", MSG_VGAMsgCnt[Chan]++, MSG_VGAStrMsg[Chan]); + + if ( (MSG_VGFileLogLevel != 0) && (MSG_VGFileLogLevel >= Level) ) { + + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + + // 29/10/2010 => Alway overwrite log file + + // if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + // MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + // } + + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "%s", VMsg ); + fflush ( MSG_VGALogFile[Chan] ); + } + + } /* End if ( Level >= MSG_VGFileLogLevel ) */ + + if ( (MSG_VGUserLogLevel != 0) && (MSG_VGUserLogLevel >= Level) ) { + + if ( MSG_VGUserMsgFunc != NULL ) { + MSG_VGUserMsgFunc ( VMsg ); + } + + } /* End if ( Level >= MSG_VGUserLogLevel ) */ + + + return (0); + +/* + if ( MSG_VGALogClosed[Chan] && (MSG_VGALogFile[Chan] != stdout ) ) { + MSG_VGALogClosed[Chan] = 0; + if ( ( MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "a" ) ) == NULL ) { + MSG_VGALogFile[Chan] = fopen ( MSG_VGALogPath[Chan], "w" ); + } + } + + if ( (MSG_VGADontLog[Chan] == 0) && (MSG_VGALogFile[Chan] != NULL) ) { + fprintf ( MSG_VGALogFile[Chan], "MSG %.4d =>", MSG_VGAMsgCnt[Chan]++ ); + fprintf ( MSG_VGALogFile[Chan], MSG_VGAStrMsg[Chan] ); + fprintf ( MSG_VGALogFile[Chan], "\n" ); + fflush ( MSG_VGALogFile[Chan] ); + } + + return (0); + +*/ + +} + + +#endif + diff --git a/include/pxi_daq_lib_v.3.1/msg.def b/include/pxi_daq_lib_v.3.1/msg.def new file mode 100755 index 0000000..c709cc1 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/msg.def @@ -0,0 +1,63 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.def +Goal : Macros definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_DEF +#define MSG_DEF + + + +#define MSG_CMT_SZ 1024 + +#define MSG_CHAN_NB 2 +#define MSG_CHAN_MSG 0 +#define MSG_CHAN_RMSG 1 + + +/* Must be after variables definition, instead CINT will be unable to handle these macros */ + +#define MSG_VGLogFile MSG_VGALogFile[MSG_CHAN_MSG] +#define MSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_MSG] +#define MSG_VGDontLog MSG_VGADontLog[MSG_CHAN_MSG] +#define MSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_MSG] +#define MSG_VGLogPath MSG_VGALogPath[MSG_CHAN_MSG] + +#define RMSG_VGLogFile MSG_VGALogFile[MSG_CHAN_RMSG] +#define RMSG_VGLogClosed MSG_VGALogClosed[MSG_CHAN_RMSG] +#define RMSG_VGMsgCnt MSG_VGAMsgCnt[MSG_CHAN_RMSG] +#define RMSG_VGLogPath MSG_VGALogPath[MSG_CHAN_RMSG] + +/* 07/04/2007 MSG_VGAStrMsg identifier replaced by MSG_OUT because of ROOT CINT macros limitations */ +/* #define MSG_OUT MSG_VGAStrMsg[MSG_CHAN_MSG] */ + +#define RMSG_OUT MSG_VGAStrMsg[MSG_CHAN_RMSG] + +#define MSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,127);} +#define msg(Msg) MSG_PRINTF(Msg) + +#define MSG_PRINTF_LVL(Msg,Lvl) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_MSG,Lvl); } +#define msgl(Msg,Lvl) MSG_PRINTF_LVL(Msg,Lvl) + + +#define RMSG_PRINTF(Msg) { sprintf Msg; MSG_FGenMsg (MSG_CHAN_RMSG,127); } +#define msgr(Msg) RMSG_PRINTF(Msg) +#define rmsg(Msg) RMSG_PRINTF(Msg) + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/msg.typ b/include/pxi_daq_lib_v.3.1/msg.typ new file mode 100755 index 0000000..0f62f1d --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/msg.typ @@ -0,0 +1,27 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.typ +Goal : Types definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + + +#ifndef MSG_TYP +#define MSG_TYP + +typedef SInt32 (*TUserMsgFunc) ( char* Msg ); + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/msg.var b/include/pxi_daq_lib_v.3.1/msg.var new file mode 100755 index 0000000..2e8fc8b --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/msg.var @@ -0,0 +1,59 @@ +/******************************************************************************* +File : x:\lib\com\msg\msg.var +Goal : Variables definition of user messages logging library +Prj date : 2000 - 2002 +File date : 20/02/2005 +Doc date : +Remark : Library exists since 2000, but split in files .def, .typ, .var, .h, .c + : was done on 20/02/2005. +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*******************************************************************************/ + +#ifndef MSG_VAR +#define MSG_VAR + +/* + +EXTERN VAR_STATIC FILE* MSG_VGALogFile[MSG_CHAN_NB] VAR_INIT_A2(NULL,NULL); +EXTERN VAR_STATIC SInt8 MSG_VGALogClosed[MSG_CHAN_NB] VAR_INIT_A2(1,1); +EXTERN VAR_STATIC SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt8 MSG_VGADontLog[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] VAR_INIT_A2(0,0); +EXTERN VAR_STATIC char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ] VAR_INIT_A2("/dd/tmp/pc/msg.txt","/dev/rmsg"); +EXTERN VAR_STATIC char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ]; +EXTERN VAR_STATIC SInt8 MSG_VGFileLogLevel VAR_INIT (0); +EXTERN VAR_STATIC SInt8 MSG_VGUserLogLevel VAR_INIT (0); +EXTERN VAR_STATIC TUserMsgFunc MSG_VGUserMsgFunc VAR_INIT (NULL); + +*/ + +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, FILE* MSG_VGALogFile[MSG_CHAN_NB] , NULL, NULL ); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogClosed[MSG_CHAN_NB] , 1, 1); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGALogEnabled[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt8 MSG_VGADontLog[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, SInt32 MSG_VGAMsgCnt[MSG_CHAN_NB] , 0, 0); +VAR_DCL_INIT_A2 ( EXTERN, VAR_STATIC, char MSG_VGALogPath[MSG_CHAN_NB][GLB_FILE_PATH_SZ], "/dd/tmp/pc/msg.txt","/dev/rmsg" ); + + +VAR_DCL ( EXTERN, VAR_STATIC, char MSG_VGAStrMsg[MSG_CHAN_NB][MSG_CMT_SZ] ); + +/* 07/04/2007 Replace macro MSG_OUT by a variable which points to MSG_VGAStrMsg[MSG_CHAN_MSG] because of ROOT CINT macros limitations */ + + +VAR_DCL_INIT ( EXTERN, VAR_STATIC, char* MSG_OUT , MSG_VGAStrMsg[MSG_CHAN_MSG] ); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGFileLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, SInt8 MSG_VGUserLogLevel , 0); +VAR_DCL_INIT ( EXTERN, VAR_STATIC, TUserMsgFunc MSG_VGUserMsgFunc , NULL); + + +#endif + + diff --git a/include/pxi_daq_lib_v.3.1/sync_index_rec.c b/include/pxi_daq_lib_v.3.1/sync_index_rec.c new file mode 100755 index 0000000..9ae3f53 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/sync_index_rec.c @@ -0,0 +1,163 @@ +/******************************************************************************* +File : sync_index_rec.c +Goal : Functions to synchronized two DAQ files +Prj date : 18/07/2012 +File date : 18/07/2012 +Doc date : 18/07/2012 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef SYNC_INDEX_REC_C +#define SYNC_INDEX_REC_C + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Return file size or negative value upon failure. + Author : Gilles CLAUS +*/ + /* =================================================================================== */ +/* DOC_FUNC_END */ +int GetFileSize ( char* FilePath ) { + + FILE* VPf; + int VFileSz = 0; + + if ( ( VPf = fopen ( FilePath, "rb" ) ) == NULL ) { + printf( "GetFileSize: fopen fail !\n" ); + return -1; + } + + /* Calculate file size */ + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + printf( "GetFileSize: fseek SEEK_SET fail !\n" ); + return -1; + } + + if ( fseek ( VPf, 0, SEEK_END ) != 0 ) { + printf( "GetFileSize: fseek SEEK_END fail !\n" ); + return -1; + } + + if ( (VFileSz = ftell ( VPf )) == -1 ) { + printf( "GetFileSize: ftell fail !" ); + return -1; + } + + if ( fseek ( VPf, 0, SEEK_SET ) != 0 ) { + printf( "GetFileSize: fseek SEEK_SET fail !"); + return -1; + } + + if ( fclose (VPf) != 0 ) { + printf( "GetFileSize: fclose fail !" ); + return -1; + } + + return VFileSz; +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== + Prototype : + : + Goal : Read the file containing the synchronization information + : between two boards, each with its data file. + : For instance a board reading binary sensors + : and another board reading analog sensors. + : + Inputs : + : + : + Ouputs : The function returns + : = 0 ok + : < 0 in case of error + : + Globals : None + : + Remark : None + : + Level : This is a user level function. + Date : 10/07/2012 + Doc date : + Modif : + Author : Gilles CLAUS + E-mail : claus@lepsi.in2p3.fr + Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +int GetSyncPointer ( char* FilePath, unsigned char* PtDest, int DestSz ) { + + int VRet; + FILE* VPfDest; + int VFileSz; + + + // Check param + + if( PtDest==NULL ) { + printf( "GetSyncPointer: PtDest == NULL !\n"); + return -1; + } + + // Measure file size + + VFileSz = GetFileSize ( FilePath ); + + // Check buffer size / file size + + if ( DestSz < VFileSz ) { + printf( "GetSyncPointer: Buffer size=%d < File size=%d.\n", DestSz, VFileSz ); + return -1; + } + + printf( "GetSyncPointer: TRACE => FileSize=%d\n", VFileSz ); + + // Open file + + VPfDest = fopen ( FilePath, "rb" ); + + if( VPfDest == NULL ) { + printf( "GetSyncPointer: Source file %s open failed.\n", FilePath ); + return -1; + } + + // Load file in buffer + + VRet = fread ( PtDest, VFileSz /* size */, 1 /* Elt nb */, VPfDest ); + + printf("SYNC Version is %d\n", ((APP__TSyncIndexRec*)PtDest)->Version); + + if ( VRet != 1 ) { + printf( "GetSyncPointer: Error reading source file %s.\n", FilePath ); + return -1; + } + + VRet = fclose ( VPfDest ); + + if ( VRet != 0 ) { + printf( "GetSyncPointer: Error fclose source file %s.\n", FilePath ); + return -1; + } + + + // Return record nb + + return ( VFileSz / sizeof (APP__TSyncIndexRec) ); + +} + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.3.1/sync_index_rec.typ b/include/pxi_daq_lib_v.3.1/sync_index_rec.typ new file mode 100755 index 0000000..bd3bcd8 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/sync_index_rec.typ @@ -0,0 +1,57 @@ +/* ============== */ +/* 10/07/2012 */ +/* -------------- */ +/* Doc 18/07/2012 */ +/* ============== */ + +#ifndef SYNC_INDEX_REC_TYP +#define SYNC_INDEX_REC_TYP + +#define CC_UNIX // Specify operating system +#include "types.typ" + +typedef struct { + + // The fields needed to synchronize DUT & Telescope run are marked with a * + // The other fields are extra information, which may be use to make cross-check + + UInt32 Version; // Record version + + // DUT events information + + UInt32 DutEvId; // * Event identifier from 0 to NbMaxEventsInRun - 1 + UInt32 DutEvTag; // Event tag = Mi26 sync signal pulses count = Mi26 frames counter + UInt32 DutTrigLine; // Line read by DAQ when trigger has occurred + UInt32 DutTrigFrame; // Frame read by DAQ when trigger has occurred + UInt32 DutTrigNbTot; // Total number of triggers seen by DAQ since beginning of run + UInt32 DutTrigNbAccepted; // Number of triggers accepted by DAQ since beginning of run = number of events taken by DAQ + UInt32 DutSpareU32; // Reserved + + // Telescope information + + UInt32 TelBegEvFrId; // * First frame corresponding to DUT event + + // Frame which contains trigger info + // + UInt32 TelTrigFrId; // Frame id since begining of run => 0 .. NbMaxFramesInRun - 1 + UInt32 TelTrigAcqId; // Acquisition id since begining of run + UInt32 TelTrigFrIdInAcq; // Frame id in current acquisition => 0 .. NbMaxFramesPerAcq + UInt32 TelTrigEvTag; // Event tag = Mi26 frames counter + + // Three first triggers of the frame (TelTrigFrId) + // Unit is Mi26 clock TS => divide by 16 to get trigger line + // + UInt32 TelTrig0; // First trigger + UInt32 TelTrig1; // Second trigger + UInt32 TelTrig2; // Third trigger + + UInt32 TelFrTrigNb; // Total number of trigger of the frame (TelTrigFrId) + + UInt32 TelTrigSpareU32; // Reserved + + UInt32 TelEndEvFrId; // * Last frame corresponding to DUT event + +} APP__TSyncIndexRec; + +#endif + diff --git a/include/pxi_daq_lib_v.3.1/time.c b/include/pxi_daq_lib_v.3.1/time.c new file mode 100755 index 0000000..1e98424 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/time.c @@ -0,0 +1,623 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.c +Goal : Functions of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_C +#define TIME_C + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateL TIME_FConvDateS2DateL ( TIME__TUDateS DateS ) { + + TIME__TUDateL VDateL; + + VDateL.Date.Day = DateS.Date.Day; + VDateL.Date.Month = DateS.Date.Month; + VDateL.Date.Year = 2000 + DateS.Date.Year; + + return (VDateL); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 28/02/2010 +Doc date : 28/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +TIME__TUDateS TIME_FConvDateL2DateS ( TIME__TUDateL DateL ) { + + TIME__TUDateS VDateS; + + VDateS.Date.Day = DateL.Date.Day; + VDateS.Date.Month = DateL.Date.Month; + VDateS.Date.Year = DateL.Date.Year % 2000; + + return (VDateS); +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 23/05/2010 +Doc date : 23/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateS2Str ( TIME__TUDateS Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.2d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( UInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + +// 23/05/2010 + +char* TIME__FDateS2Str ( SInt32 Date, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUDateS VDate; + + VDate.W32 = (UInt32) Date; + + return ( TIME__FDateS2Str ( VDate, PtDestStr, DestStrSz ) ); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ + : +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FDateL2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2Str ( TIME__TUDateL Date, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d/%.2d/%.4d", Date.Date.Day, Date.Date.Month, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done +: after each TIME__FDateL2Str () call otherwise the string content will be the one of +: last call because all pointers will point to last string stored in local variable +: of function. +: +Level : +Date : 06/03/2010 +Doc date : 06/03/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FDateL2StrExt ( TIME__TUDateL Date, char SepChar, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrDate[TIME__STR_DATE_SZ]; + + sprintf ( VStrDate, "%.2d%c%.2d%c%.4d", Date.Date.Day, SepChar, Date.Date.Month, SepChar, Date.Date.Year ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_DATE_SZ) ) { + sprintf ( PtDestStr, "%s", VStrDate ); + } + + return (VStrDate); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FConvDateTime2DateL ( TDateTime Src ) { + + TIME__TUDateL VDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + Src.DecodeDate ( &VYear, &VMonth, &VDay ); + + VDate.Date.Year = VYear; + VDate.Date.Month = VMonth; + VDate.Date.Day = VDay; + + return (VDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 22/02/2010 +Doc date : 22/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUDateL TIME__FGetDateLOfNextDay ( TIME__TUDateL Cur ) { + + TDateTime VCurDate ( Cur.Date.Year, Cur.Date.Month, Cur.Date.Day ); + TIME__TUDateL VNextDate; + unsigned short VYear; + unsigned short VMonth; + unsigned short VDay; + + ++VCurDate; + + VCurDate.DecodeDate ( &VYear, &VMonth, &VDay ); + + VNextDate.Date.Year = VYear; + VNextDate.Date.Month = VMonth; + VNextDate.Date.Day = VDay; + + return (VNextDate); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : + : +Goal : + : +Inputs : + : +Ouputs : + : +Globals : + : +Remark : + : +WARNING : If return pointer to list is used, a copy of LIST ( not pointer ) must be done + : after each TIME__FFillListDatesLOfWeek () call otherwise the list content will be + : the one of last call because all pointers will point to last list stored in local + : variable of function. + : + : +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + +#ifndef ROOT_ROOT + +TIME__TListDatesLOfWeek* TIME__FFillListDatesLOfWeek ( TIME__TUDateL MondayDate, TIME__TListDatesLOfWeek* PtList ) { + + static TIME__TListDatesLOfWeek VList; + TIME__TUDateL VDayDate; + SInt8 ViDay; + + + VDayDate = MondayDate; + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + VList.ADates[ViDay] = VDayDate; + VDayDate = TIME__FGetDateLOfNextDay ( VDayDate ); + } + + if ( PtList != NULL ) { + *PtList = VList; + } + + return (&VList); +} + +#endif + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 23/02/2010 +Doc date : 23/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +SInt32 TIME__FPrintListDatesLOfWeek ( TIME__TListDatesLOfWeek* PtList ) { + + SInt8 ViDay; + + + err_retnull ( PtList, (ERR_OUT,"PtList == NULL") ); + + + for ( ViDay=0; ViDay < 7; ViDay++ ) { + msg (( MSG_OUT, "Date : %s", TIME__FDateL2Str ( PtList->ADates[ViDay], NULL /* PtDestStr */, 0 /* DestStrSz */ ) )); + } + + + err_retok (( ERR_OUT, "" )); +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +WARNING : A copy of return STRING ( not pointer ) must be done after each TIME_FGetDayName call + : otherwise the string content will be the one of last call because all pointers will + : point to last string stored in local variable of function. +: +Level : +Date : 27/02/2010 +Doc date : 27/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME_FGetDayName ( UInt8 DayIndex, SInt8 Language ) { + + static char* VAStrDayNameFr[8] = {"Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi", "Dimanche" }; + static char* VAStrDayNameEn[8] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; + + if ( DayIndex > 7 ) { + err_error (( ERR_OUT, "Bad day index = %d out of rnage 0..7", DayIndex )); + return ( "?" ); + } + + switch ( Language ) { + + case TIME__LANG_FRENCH : { + return ( VAStrDayNameFr[DayIndex] ); + break; } + + case TIME__LANG_ENGLISH : { + return ( VAStrDayNameEn[DayIndex] ); + break; } + + + default : { + err_error (( ERR_OUT, "Bad language = %d out of range", Language )); + return ( "?"); + } + + } + +} + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +#ifndef ROOT_ROOT + +TIME__TUTime TIME__FConvDateTime2Time ( TDateTime Src ) { + + TIME__TUTime VTime; + unsigned short VHour; + unsigned short VMin; + unsigned short VSec; + unsigned short VMSec; + + Src.DecodeTime ( &VHour, &VMin, &VSec, &VMSec ); + + VTime.Time.Hour = VHour; + VTime.Time.Min = VMin; + VTime.Time.Sec = VSec; + VTime.Time.Cent = VMSec / 10; + + return (VTime); +} + +#endif + + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : Optional return parameter PtDestStr, not used if NULL or DestStrSz < TIME__STR_DATE_SZ +: +WARNING : If return pointer to string is used, a copy OF STRING ( not pointer ) must be done + : after each TIME__FTime2Str () call otherwise the string content will be the one of + : last call because all pointers will point to last string stored in local variable + : of function. + : +Level : +Date : 21/05/2010 +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + +char* TIME__FTime2Str ( TIME__TUTime Time, char* PtDestStr, SInt32 DestStrSz ) { + + static char VStrTime[TIME__STR_TIME_SZ]; + + sprintf ( VStrTime, "%.2d:%.2d:%.2d|%.2d", Time.Time.Hour, Time.Time.Min, Time.Time.Sec, Time.Time.Cent ); + + if ( (PtDestStr != NULL) && (DestStrSz >= TIME__STR_TIME_SZ) ) { + sprintf ( PtDestStr, "%s", VStrTime ); + } + + return (VStrTime); +} + + +// 23/05/2010 + +char* TIME__FTime2Str ( UInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + +// 23/05/2010 + +char* TIME__FTime2Str ( SInt32 Time, char* PtDestStr, SInt32 DestStrSz ) { + + TIME__TUTime VTime; + + VTime.W32 = (UInt32) Time; + + return ( TIME__FTime2Str ( VTime, PtDestStr, DestStrSz ) ); + +} + + +/* DOC_FUNC_BEGIN */ +/* =================================================================================== +Prototype : +: +Goal : +: +Inputs : +: +Ouputs : +: +Globals : +: +Remark : +: +Level : +Date : 21/02/2010 +Doc date : 21/02/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +Labo : LEPSI */ +/* =================================================================================== */ +/* DOC_FUNC_END */ + + + + + +#endif + diff --git a/include/pxi_daq_lib_v.3.1/time.def b/include/pxi_daq_lib_v.3.1/time.def new file mode 100755 index 0000000..a4ec9f1 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/time.def @@ -0,0 +1,40 @@ + + +/******************************************************************************* +File : x:\lib\com\time\time.def +Goal : Macros definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_DEF +#define TIME_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define TIME__STR_DATE_SZ 11 +#define TIME__STR_TIME_SZ 11 + +#define TIME__LANG_FRENCH 0 +#define TIME__LANG_ENGLISH 1 + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/time.typ b/include/pxi_daq_lib_v.3.1/time.typ new file mode 100755 index 0000000..3d88f0e --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/time.typ @@ -0,0 +1,140 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.typ +Goal : Types definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_TYP +#define TIME_TYP + + +/* =========================== */ +/* Date S => Short date format */ +/* Eg : 01/01/10 */ +/* =========================== */ + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aa in W32 + // B31B24 B23B16 B15B08 B07B00 + // 00 Day Month Year + + SInt8 Year; + SInt8 Month; + SInt8 Day; + SInt8 NotUsed; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateS; + + +typedef union { + + UInt32 W32; + + TIME__TSDateS Date; + +} TIME__TUDateS; + + + +/* ========================== */ +/* Date L => Long date format */ +/* Eg : 01/01/2010 */ +/* ========================== */ + + +typedef struct { + + // Fields order MUST be Year, Month, Day -> Don't modify it + // Because with this order date is in French format jj/mm/aaaa in W32 + // B31B24 B23B16 B15B00 + // Day Month Year + + SInt16 Year; + SInt8 Month; + SInt8 Day; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSDateL; + + +typedef union { + + UInt32 W32; + + TIME__TSDateL Date; + +} TIME__TUDateL; + + + +/* ============== */ +/* */ +/* ============== */ + + +typedef struct { + + TIME__TUDateL ADates[7]; + +} TIME__TListDatesLOfWeek; + + +/* =============================== */ +/* Time : Hour - Min - Sec - 1/100 */ +/* Eg : 21/05/2010 */ +/* =============================== */ + + +typedef struct { + + // Fields order MUST be Hour - Min - Sec - 1/100 -> Don't modify it + // B31B24 B23B16 B15B08 B07B00 + // Hour Min Sec Cent + + SInt8 Cent; + SInt8 Sec; + SInt8 Min; + SInt8 Hour; + + // Signed values are used rather than unsigned because they allow to + // tag dates by setting negatives values in fields + +} TIME__TSTime; + + +typedef union { + + UInt32 W32; + + TIME__TSTime Time; + +} TIME__TUTime; + + + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/time.var b/include/pxi_daq_lib_v.3.1/time.var new file mode 100755 index 0000000..3b0fee6 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/time.var @@ -0,0 +1,35 @@ + +/******************************************************************************* +File : x:\lib\com\time\time.var +Goal : Variables definition of time lib. +Prj date : 21/02/2010 +File date : 21/02/2010 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef TIME_VAR +#define TIME_VAR + + +/* ================= */ +/* Variable example */ +/* ================= */ + +EXTERN SInt8 TIME_VGMyVar; + +/* ============== */ +/* */ +/* ============== */ + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/types.def b/include/pxi_daq_lib_v.3.1/types.def new file mode 100755 index 0000000..05619d9 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/types.def @@ -0,0 +1,34 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.def +Goal : Limits of types. + : +Prj date : 2000 - 2002 +File date : +Doc date : 21/05/2010 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*************************************************************/ + + +/*H**************************************************************************** +FILE : Types.def +BUT : Define types limts. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_DEF +#define TYPES_DEF + + +#define TYP_MIN_SINT32 0x80000000 +#define TYP_MAX_SINT32 0x7FFFFFFF + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/types.typ b/include/pxi_daq_lib_v.3.1/types.typ new file mode 100755 index 0000000..f39ce8d --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/types.typ @@ -0,0 +1,187 @@ +/************************************************************* +File : /dd/sdev_src/c/work/common/include/types.typ +Goal : Common basic types definitions. + : I never use default C types names ( char, int ... ) + : i redefined them here ( SInt8, UInt32 ... ). + : + : If something go wong on you'r plateform with C types + : definition you need to update this file. +Prj date : 2000 - 2002 +File date : +Doc date : 23/11/2002 +Author : Gilles CLAUS +E-mail : claus@lepsi.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : LEPSI */ +/*************************************************************/ + + +/*H**************************************************************************** +FILE : Types.Typ +BUT : Define types. +AUTEUR : G.CLAUS +****************************************************************************H*/ + +#ifndef TYPES_TYP +#define TYPES_TYP + + // typedef enum ELang { ELang_FRENCH, ELang_ENGLISH, ELang_GERMAN, ELang_LANG_NB } TLang; + +#ifndef NODEFTYPCHAR + +/* +17/11/04 GC + +BCPPB declares an identfier with the same name " Char " +this problem happens while compiling Mimo* JTAG application (MP). +This Char identifier is used in SpinEdit object. + +MP used conditionnal compilation, i decided to remove this Char +type definition, because i believe i never use it. +Wait and see ... + +*/ + +/* typedef unsigned char Char; */ + +#endif + +#ifndef UInt8 + typedef unsigned char UInt8; +#endif + +#ifndef UByte + typedef UInt8 UByte; +#endif + +#ifndef SInt8 + typedef char SInt8; +#endif + +#ifndef SByte + typedef SInt8 SByte; +#endif + +#ifndef UInt16 + typedef unsigned short UInt16; +#endif + +#ifndef UWord + typedef UInt16 UWord; +#endif + +#ifndef SInt16 + typedef short SInt16; +#endif + +#ifndef SWord + typedef SInt16 SWord; +#endif +#ifndef CC_64B +// 32 bits +#ifndef UInt32 + typedef unsigned long int UInt32; +// typedef unsigned int UInt32; // correction for 64bits, JB 2011/10/28 +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + typedef long int SInt32; +// typedef int SInt32; // correction for 64bits, JB 2014/10/16 +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif +#else +// 64 bits + +#ifndef UInt32 + typedef unsigned int UInt32; +#endif + +#ifndef ULong + typedef UInt32 ULong; +#endif + +#ifndef SInt32 + typedef int SInt32; +#endif + +#ifndef SLong + typedef SInt32 SLong; +#endif +#endif + + +#ifdef CC_UNIX + +#ifndef UInt64 + typedef int64_t UInt64; +#endif + +#ifndef SInt64 + //typedef uint64_t SInt64; + typedef ULong64_t SInt64; +#endif + +#else + +#ifndef UInt64 + typedef unsigned __int64 UInt64; +#endif + +#ifndef SInt64 + typedef __int64 SInt64; +#endif + + +#endif + + +/* ROOT ! +typedef single Real32; +typedef double Real64; +typedef extended Real80; +*/ + + +/* Pointeurs */ + +typedef char* TPChar; + +typedef UInt8* TPUInt8; +typedef TPUInt8 TPUByte; + +typedef SInt8* TPSInt8; +typedef TPSInt8 TPSByte; + +typedef UInt16* TPUInt16; +typedef TPUInt16 TPUWord; + +typedef SInt16* TPSInt16; +typedef TPSInt16 TPSWord; + +typedef UInt32* TPUInt32; +typedef TPUInt32 TPULong; + +typedef SInt32* TPSInt32; +typedef TPSInt32 TPSLong; + +/* ROOT ! +typedef Real32* TPReal32; +typedef Real64* TPReal64; +typedef Real80* TPReal80; +*/ + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/ult1.def b/include/pxi_daq_lib_v.3.1/ult1.def new file mode 100755 index 0000000..f6d4cfb --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/ult1.def @@ -0,0 +1,221 @@ +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_DEF +#define ULT1_DEF + + +#ifdef ULT1__APP_DLL_TEST_MI26 + #include "ult1_test_mi26.def" +#else + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define ULT1__REG_DISCRI_BIT_SZ 960 // Mi26 = 1152 +#define ULT1__REG_DISCRI_W32_SZ 30 // Mi26 = 36 + + +#ifdef ULT1__APP_DLL_TEST_WITH_PATTERN_GENERATOR + + // Size in CLK unit of the frame which contains the readout of ONE line + + #define ULT1__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 1858 // Single line = nop scanning mode + #define ULT1__DISCRI_RO_SCAN_FRAME_CLK_NB 1858 // Scanning mode + +#else + + // Size in CLK unit of the frame which contains the readout of ONE line + + #define ULT1__DISCRI_RO_NO_SCAN_FRAME_CLK_NB 1856 // Single line = nop scanning mode + #define ULT1__DISCRI_RO_SCAN_FRAME_CLK_NB 1858 // Scanning mode + +#endif + + + + +// This register is not implemented on Ultimate +// +// #define ULT1__REG_AFTER_ZS_BIT_SZ 160 +// #define ULT1__REG_AFTER_ZS_W32_SZ 5 + +#define ULT1__REG_AFTER_MUX_BIT_SZ 160 // Mi26 = 160 +#define ULT1__REG_AFTER_MUX_W32_SZ 5 // Mi26 = 5 + +#define ULT1__MAT_DISCRI_COL_NB 960 // 23/01/2013 +#define ULT1__MAT_DISCRI_LINES_NB 930 +#define ULT1__MAT_DISCRI_USEFUL_LINES_NB 928 // 23/01/2013 - Without the two markers lines + +#define ULT1__ZS_FFRAME_RAW_MAX_W16 3700 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define ULT1__ZS_FFRAME_RAW_MAX_W32 1850 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 +#define ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 1856 // Total frame size ( sum of 2 links ) in W32 - Mi26 = 576 + +// 11/09/2014 GC - Removed because defined in ult1_usr.def +// +// #define ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +// #define ULT1__ZS_FFRAME_MAX_STATES_REC 928 // Mi26 = 576 - one per line + + +#define ULT1__ZS_FFRAME_MODE0_1X80MHZ 0 +#define ULT1__ZS_FFRAME_MODE1_2X80MHZ 1 +#define ULT1__ZS_FFRAME_MODE2_1X160MHZ 2 +#define ULT1__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 14848 // 928 W16 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 14848 // 928 W16 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 29696 // 1856 W16 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 29696 // 1856 W16 + +// $ #define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 928 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 928 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 1856 // Mi26 = 576 +// #define ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 1856 // Mi26 = 576 => Moved in ult1_usr.def + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 464 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 464 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 928 // Mi26 = 144 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 928 // Mi26 = 288 + + +// Id to select ULT1 register + +#define ULT1__REG_DISCRI 0 +// #define ULT1__REG_AFTER_ZS 1 -> Not implemented on Ultimate +#define ULT1__REG_AFTER_MUX 1 +#define ULT1__REG_DISCRI_SCAN 2 + +#define ULT1__REG_DISCRI_SCAN__SRC_CLK_160MHZ 3 // 23/06/2010 + +// ====================================== +// For ULT1 discri analysis tools +// ====================================== + +// Submatrices number + +#define ULT1__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define ULT1__REG_BIAS_NB 19 + +// $ #define ULT1__REG_BIAS_ICLPDISC 0 +// $ #define ULT1__REG_BIAS_IPWRSW 1 +// $ #define ULT1__REG_BIAS_IBUF 2 +// $ #define ULT1__REG_BIAS_ID1PWRS 3 +// $ #define ULT1__REG_BIAS_ID2PWRS 4 +// $ #define ULT1__REG_BIAS_ILVDSTX 5 +// $ #define ULT1__REG_BIAS_ILVDSRX 6 +// $ #define ULT1__REG_BIAS_IVTST1 7 +// $ #define ULT1__REG_BIAS_IVTST2 8 +// $ #define ULT1__REG_BIAS_IANABUF 9 +// $ #define ULT1__REG_BIAS_IVDREF1D 10 +// $ #define ULT1__REG_BIAS_IVDREF1C 11 +// $ #define ULT1__REG_BIAS_IVDREF1B 12 +// $ #define ULT1__REG_BIAS_IVDREF1A 13 +// $ #define ULT1__REG_BIAS_IVDREF2 14 +// $ #define ULT1__REG_BIAS_IDIS1 15 +// $ #define ULT1__REG_BIAS_IDIS2 16 +// $ #define ULT1__REG_BIAS_IPXI 17 +// $ #define ULT1__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define ULT1__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define ULT1__DIS_MEAS_STEP_PAR_FIRST 0 +#define ULT1__DIS_MEAS_STEP_PAR_LAST (ULT1__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define ULT1__DIS_TEST_MAX_STEP_NB 50 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define ULT1__NB_MAX_ULT1_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define ULT1__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define ULT1__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define ULT1__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// ULT1__TCTelMon +// -------------------- + +#define ULT1__COLOR_BROWN 0x000066CC +#define ULT1__COLOR_ORANGE 0x0000A5FF +#define ULT1__COLOR_YELLOW 0x0000FFFF +#define ULT1__COLOR_GREEN 0x0000FF00 +#define ULT1__COLOR_BLUE 0x00FF0000 +#define ULT1__COLOR_VIOLET 0x00990066 + +#define ULT1__TCTelMon__COL_PLANE_0 (TColor) ULT1__COLOR_ORANGE +#define ULT1__TCTelMon__COL_PLANE_1 (TColor) ULT1__COLOR_BLUE +#define ULT1__TCTelMon__COL_PLANE_2 (TColor) ULT1__COLOR_BROWN +#define ULT1__TCTelMon__COL_PLANE_3 (TColor) ULT1__COLOR_YELLOW +#define ULT1__TCTelMon__COL_PLANE_4 (TColor) ULT1__COLOR_GREEN +#define ULT1__TCTelMon__COL_PLANE_5 (TColor) ULT1__COLOR_VIOLET + + +#define ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define ULT1__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.3.1/ult1.typ b/include/pxi_daq_lib_v.3.1/ult1.typ new file mode 100755 index 0000000..9016166 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/ult1.typ @@ -0,0 +1,1223 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_TYP +#define ULT1_TYP + +#ifdef ROOT_ROOT + typedef UInt32 ULT1__TColor; + #define clWhite 0 + #define clBlack 0 + #define clBlue 0 + #define clRed 0 +#else + typedef TColor ULT1__TColor; +#endif + + + + + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +// $ typedef struct { +// $ +// $ SInt8 FileErrLogLvl; +// $ char FileErrFile[GLB_FILE_PATH_SZ]; +// $ +// $} ULT1__TContext; + +/* ============================================================================ */ +/* Discri register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[ULT1__REG_DISCRI_W32_SZ]; + SInt8 ADataBit[ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TRegDiscri; + +/* ============================================================================ */ +/* Discri register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[ULT1__REG_DISCRI_W32_SZ]; + +} ULT1__TRegDiscriW32; + + +/* ============================================================================ */ +/* Discri register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TRegDiscriBit; + + +/* ============================================================================ */ +/* Discri matrix dual view : W32 or Bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + ULT1__TRegDiscri ALine[ULT1__MAT_DISCRI_LINES_NB]; + +} ULT1__TMatDiscri; + +/* ============================================================================ */ +/* Discri matrix view as W32 array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AALineW32[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_W32_SZ]; + +} ULT1__TMatDiscriW32; + +/* ============================================================================ */ +/* Discri matrix view as bit array */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriBit; + + +typedef struct { + + float AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriBitf; + + +/* ============================================================================ */ +/* Discri matrix view as bit array - BUT scale 1/4 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 23/07/2009 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 AALineCol[ULT1__MAT_DISCRI_LINES_NB / 2][ULT1__REG_DISCRI_BIT_SZ / 2]; + +} ULT1__TMatDiscriBitHalfScale; + + + +/* ============================================================================ */ +/* After Zero Sup register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + UInt32 ADataW32[ULT1__REG_AFTER_ZS_W32_SZ]; + SInt8 ADataBit[ULT1__REG_AFTER_ZS_BIT_SZ]; + +} ULT1__TRegAfterZs; +*/ + +/* ============================================================================ */ +/* After Zero Sup register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + UInt32 AW32[ULT1__REG_AFTER_ZS_W32_SZ]; + +} ULT1__TRegAfterZsW32; +*/ + +/* ============================================================================ */ +/* After Zero Sup register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +/* Not implemented on Ultimate + +typedef struct { + + SInt8 ABit[ULT1__REG_AFTER_ZS_BIT_SZ]; + +} ULT1__TRegAfterZsBit; +*/ + +/* ============================================================================ */ +/* After Mux register, 2 views */ +/* - Array of W32 words */ +/* - Array of bits */ +/* ---------------------------------------------------------------------------- */ +/* WARNING : It is not a bit mapping but conversion must be done by a function */ +/* ---------------------------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 ADataW32[ULT1__REG_AFTER_MUX_W32_SZ]; + SInt8 ADataBit[ULT1__REG_AFTER_MUX_BIT_SZ]; + +} ULT1__TRegAfterMux; + +/* ============================================================================ */ +/* After Mux register as array of W32 */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + UInt32 AW32[ULT1__REG_AFTER_MUX_W32_SZ]; + +} ULT1__TRegAfterMuxW32; + + +/* ============================================================================ */ +/* After Mux register as array of bit */ +/* ---------------------------------------------------------------------------- */ +/* Date : 25/11/2008 */ +/* ============================================================================ */ + +typedef struct { + + SInt8 ABit[ULT1__REG_AFTER_MUX_BIT_SZ]; + +} ULT1__TRegAfterMuxBit; + + + +/* ======================================================= */ +/* Frame provided by ULT1 DAQ, it's independent of output */ +/* mode BUT data are not organized as in ULT1__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by ULT1__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + + typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + + + UInt16 ADataW16[ULT1__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + + } xxx__TZsFFrameRaw; + + + + + + //typedef struct { + // + // ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + // UInt32 Header; // Header of Mimosa 26 frame + // UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + // UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + // UInt32 Trailer; // Trailer of Mimosa 26 frame + + // UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + // UInt16 ADataW16[ULT1__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + + //} ULT1__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + + //typedef union { + + // UInt16 W16; + + // struct { + + // UInt16 StateNb : 4; + // UInt16 LineAddr : 11; + // UInt16 Ovf : 1; + + // } F; + + //} ULT1__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +// typedef union { + +// UInt16 W16; + +// struct { + +// UInt16 HitNb : 2; +// UInt16 ColAddr : 11; +// UInt16 NotUsed : 3; + +// } F; + +// } ULT1__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max ULT1__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +// typedef struct { + +// ULT1__TStatesLine StatesLine; +// ULT1__TState AStates[ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +// } ULT1__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by ULT1, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max ULT1__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +//typedef struct { + +//ASIC__TFrameStatus SStatus; + +//UInt32 Header; +//UInt32 FrameCnt; +//UInt32 DataLength; +// SInt16 TrigSignalLine; +//SInt8 TrigSignalClk; +// SInt16 TrigLine; + +// UInt32 StatesRecNb; // It's NOT a ULT1 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + +// ULT1__TZsFStatesRec AStatesRec[ULT1__ZS_FFRAME_MAX_STATES_REC]; + +// UInt32 Trailer; +// UInt32 Zero; +// UInt32 Zero2; + +// } ULT1__TZsFFrame; // F in FFrame means Fixed size frame + + + + +#ifndef APP__RMV_ULT1__TCDiscriFile +#ifndef APP__RMV_CLASSES + +// 31/01/2009 + +class ULT1__TCDiscriFile : public FIL__TCBinFile { + + + private : + + protected : + + + public : + + ULT1__TCDiscriFile ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + ~ULT1__TCDiscriFile (); + + SInt32 PubFConf ( char* DataFile, SInt8 WriteRead, SInt8 FlushAfterWrite, SInt8 MeasTime ); + + SInt32 PubFSetFileName ( char* DataFile ); + SInt32 PubFSetFlushMode ( SInt8 FlushAfterWrite ); + + SInt32 PubFGetFileSz (); + SInt32 PubFGetEvNb (); + + SInt32 PubFCreate (); + SInt32 PubFOpen (); + + SInt32 PubFWriteEv ( ULT1__TMatDiscriW32* PtSrcMat ); + SInt32 PubFReadNextEv ( ULT1__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + ULT1__TMatDiscriW32* PubFReadNextEv (); + SInt32 PubFGotoEv ( SInt32 EvNo ); + SInt32 PubFReadEv ( SInt32 EvNo, ULT1__TMatDiscriW32* PtDestMat, SInt32 MaxDestSz ); + ULT1__TMatDiscriW32* PubFReadEv ( SInt32 EvNo ); + + SInt32 PubFFlush (); + SInt32 PubFClose (); + +}; + +#endif +#endif + +/* ==================================================== */ +/* Discriminators test information file record */ +/* */ +/* - Test no */ +/* - Chip no / comment */ +/* - Number of steps */ +/* - Events nb / step */ +/* - Run no associated to each step */ +/* - Bias used for each step */ +/* - User defined parameters for each step */ +/* The can be used to convert udac / mv etc ... */ +/* */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.cnf contains the structure */ +/* ULT1__TDisTestCnfFile */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + +// A copy of bias used for the current run +// 10/02/2009 + +typedef struct { + + UInt8 ABias[ULT1__REG_BIAS_NB]; + +} ULT1__TBiasCnf; + + +// All information about current discri measurement step +// 10/02/2009 + +typedef struct { + + SInt32 RunNo; + ULT1__TBiasCnf Bias; + float APar[ULT1__DIS_MEAS_STEP_MAX_PAR_NB]; + +} ULT1__TDisMeasStep; + + +// Format of file discri_test_NNNN.cnf +// 10/02/2009 + +/*typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to ULT1__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + +} ULT1__TDisMeasHeader; + +typedef struct { + ULT1__TDisMeasHeader Head; + ULT1__TDisMeasStep AStep[ULT1__DIS_TEST_MAX_STEP_NB]; +}ULT1__TDisTestCnfFile;*/ + + +typedef struct { + + SInt32 TestNo; // No of test + char ChipNoCmt[GLB_CMT_SZ]; // Comment about mimosa : name, number ... + SInt32 StepNb; // Number of threshold steps used to perform this test = number of run + SInt32 EvNbPerStep; // Number of events per step = nb of events per run + + // Information about each step + // - No of run + // - Bias values used for this run + // - An array of float user parameters, up to ULT1__DIS_MEAS_STEP_MAX_PAR_NB + // Parameters can be used to store threshold in mv or convertion ratio udac / mv etc ... + + ULT1__TDisMeasStep AStep[ULT1__DIS_TEST_MAX_STEP_NB]; + + +} ULT1__TDisTestCnfFile; + + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in sub matrices view mode => sub A, B, C, D */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 3D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED per submatrix. */ +/* => Header.SubMatView = 1 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* ULT1__TDisHitCntAllSubMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of ULT1__TDisHitCntAllSubMatStepData */ +/* - init a ULT1__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + SInt32 TestNo; + SInt8 SubMatView; // 0 => whole matrix as single data piece + // 1 => submatrices A, B, C, D + SInt32 StepNb; + char CnfFileName[GLB_FILE_PATH_SZ]; + + +} ULT1__TDisHitCntHeader; + + +typedef struct { + + float AAASubMat[ULT1__SUB_MAT_NB][ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ / 4]; + +} ULT1__TDisHitCntAllSubMatStepData; + +typedef struct { + + float AAAASubMat [ULT1__DIS_TEST_MAX_STEP_NB][ULT1__SUB_MAT_NB][ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ / 4]; + +} ULT1__TDisHitCntAllSubMatStepDataMG; + +typedef struct { + + ULT1__TDisHitCntHeader Header; + ULT1__TDisHitCntAllSubMatStepData FirstStepData; + +} ULT1__TDisHitCntAllSubMatFile; + + +/* ==================================================== */ +/* Discriminators data processing output file record */ +/* in whole matrix view mode */ +/* */ +/* - Header */ +/* -- No of test */ +/* -- Step number = thresholds number */ +/* -- Path of config file to get more informations */ +/* Config file is discri_test_NNNN.cnf */ +/* */ +/* - Data */ +/* It's a 2D array which contains hit count in % for */ +/* each pixel. It's ORGANIZED as ONE matrix. */ +/* => Header.SubMatView = 0 */ +/* ---------------------------------------------------- */ +/* The file discri_test_NNNN.dat contains the structure */ +/* ULT1__TDisHitCntMatFile */ +/* ---------------------------------------------------- */ +/* WARNING : This structure AS IS allows only to access */ +/* to file header and FIRST test data. */ +/* In order to acces to next test data : */ +/* - init a BYTE pointer VPtB to FirstStepData addr */ +/* - increment with size of ULT1__TDisHitCntMatStepData */ +/* - init a ULT1__TDisHitCntStepData pointer to VPtB */ +/* - and so on for next step ... */ +/* */ +/* ---------------------------------------------------- */ +/* Date : 10/02/2009 */ +/* ==================================================== */ + + +typedef struct { + + float AAMat[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TDisHitCntMatStepData; + + +typedef struct { + + ULT1__TDisHitCntHeader Header; + ULT1__TDisHitCntMatStepData FirstStepData; + +} ULT1__TDisHitCntMatFile; + + + +typedef struct { + + SInt8 AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ / 4]; + +} ULT1__TQuaterMatDiscriBit; + +typedef struct { + + ULT1__TColor AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriColor; + + +typedef struct { + + ULT1__TColor AALineCol[ULT1__MAT_DISCRI_LINES_NB / 2][ULT1__REG_DISCRI_BIT_SZ / 2]; + +} ULT1__TMatDiscriColorHalfScale; + + +typedef struct { + + ULT1__TColor AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ / 4]; + +} ULT1__TQuaterMatDiscriColor; + + +// To store "1" count on each discri for N events + +typedef struct { + + SInt32 ABit[ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TRegDiscriCumul; + + +// To store % of "1" on each discri for N events + +typedef struct { + + float ABit[ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TRegDiscriPerCent; + +// To store "1" count on whole matrix for N events + +typedef struct { + + UInt16 AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriCumul; + + +typedef struct { + + UInt16 AALineCol[ULT1__MAT_DISCRI_LINES_NB / 2][ULT1__REG_DISCRI_BIT_SZ / 2]; + +} ULT1__TMatDiscriCumulHalfScale; + + +// To store % of "1" on whole matrix for N events + +typedef struct { + + float AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TMatDiscriPerCent; + + +typedef struct { + + float AALineCol[ULT1__MAT_DISCRI_LINES_NB][ULT1__REG_DISCRI_BIT_SZ]; + +} ULT1__TQuaterMatDiscriPerCent; + + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + + +// DPXI__ULT1_NB_MAX_ULT1_PER_DAQ + +typedef ULT1__TZsFFrame ULT1__TAZsFFrame[ULT1__NB_MAX_ULT1_PER_DAQ]; + + + +typedef struct { + + // Date & Time + + UInt32 StartDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StartTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Asic conf + + UInt8 AsicName; // Value of enumerated ASIC__TEAsicName defined in asic.def + SInt8 AsicNb; // Number of Asic read by DAQ + + // Trigger mode + + SInt8 SwTrigEnabled; // Enable automatic start of acquisition on first trigger of a spill + // - 0 => Board starts upon acquisition request command, don't care about trigger + // - 1 => After acquisition request command, board wait on first trigger to start + // Trigger detection is done by sw, therefore it has a latency of N x 15 ms + + SInt8 HwTrigModeSavedData; // Trigger mode + // - 0 => Run contains all frames : with OR without trigger + // - 1 => Run contains ONLY frames with a trigger + // - More trigger modes may be defined later + + SInt32 HwTrigPar[ULT1__TZSRunCnf__HW_TRIG_PAR_NB]; // Parameter about trigger handling -> enumerated DPXI__TEHwTrigPar in daq_pix.def + // - DPXI__HW_TRIG_PAR__OFFSET -> Offset which must be added to trigger position to get real position + // - DPXI__HW_TRIG_PAR__WINDOW -> Number of frame acquired after trigger + // - DPXI__HW_TRIG_PAR_NB -> Max parameters number + + + // Run parameters + + SInt32 RunNo; // Run number + SInt8 RunSave; // Save (1) or Not (0) data + SInt8 RunSaveMode; // Save mode -> Reserved for future use + SInt32 RunEvNb; // Event number in run + SInt32 RunFileEvNb; // Event number per file + +} ULT1__TZSRunCnf; + + +typedef struct { + + // Date & Time + + UInt32 StopDate; // DD-MM-YY = D23D16 - D15D08 - D07D00 + UInt32 StopTime; // HH-MM-SS-CC = D31D24 - D23D16 - D15D08 - D07D00 + + // Status + + SInt32 EvNbTaken; // Real number of events taken must be <= ULT1__TZSRunCnf.RunEvNb + SInt32 RejAcqNb; // Number of acquistion rejected in case of Mimosa 26 data error ( bad header, trailer etc ... ) + + SInt32 ARejAcqList[ULT1__TZSRunRes__MAX_ACQ_REJ_NB]; // List of rejected acquisition + +} ULT1__TZSRunRes; + + +// 09/07/2009 + +#ifndef APP__RMV_CLASSES + +class ULT1__TCZsRunRW { + + private: + + SInt32 PrivFInitForNewRunLoading (); + + // Object + + FIL__TCBinFile* ProPtBinFile; + + protected: + + // Parameters + + char ProParRunDir[GLB_FILE_PATH_SZ]; + SInt32 ProParRunNo; + SInt32 ProParCurULT1No; + SInt32 ProParCurEvNo; + + SInt8 ProParMeasTime; + SInt8 ProParPrintMsg; + SInt8 ProParPrintEvHeader; + + // Informations from run conf file OR calculated + + char ProRunCnfFile[GLB_FILE_PATH_SZ]; + char ProRunResFile[GLB_FILE_PATH_SZ]; + + ULT1__TZSRunCnf ProRecZSRunCnf; + ULT1__TZSRunRes ProRecZSRunRes; + + SInt32 ProInfRunULT1Nb; + SInt32 ProInfRunEvNb; + SInt32 ProInfRunFileSz; + SInt32 ProInfRunEvNbPerFile; + SInt32 ProInfRunBlocNbPerFile; + SInt32 ProInfZsFFrameRawSz; + + // Intermediate variables for processing + + SInt8 ProConfDone; + SInt8 ProParEnableErrLog; + SInt8 ProParErrLogLvl; + + char ProParErrLogFile[GLB_FILE_PATH_SZ]; + + + SInt8 ProLastEvAccessDoneInOneULT1Mode; + SInt32 ProCurBlocNoInRun; + SInt32 ProCurFileNo; + SInt32 ProCurBlocNoInFile; + char ProCurFileName[GLB_FILE_PATH_SZ]; + + ULT1__TZsFFrameRaw* ProPtFFrameRaw; + + + public: + + ULT1__TCZsRunRW (); + ~ULT1__TCZsRunRW (); + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl ); + + SInt32 PubFSetMeasTime ( SInt8 Yes ); + SInt32 PubFSetPrintMsg ( SInt8 Print ); + SInt32 PubFSetPrintEvHeader ( SInt8 Print ); + + SInt32 PubFGetMeasTime (); + SInt32 PubFGetPrintMsg (); + SInt32 PubFGetPrintEvHeader (); + + SInt32 PubFGetULT1Nb (); + SInt32 PubFGetEvNb (); + SInt32 PubFGetEvNbPerFile (); + + SInt32 PubFLoadRun ( char* RunDir, UInt32 RunNo ); + + ULT1__TZsFFrameRaw* PubFGotoEvOneULT1 ( SInt8 ULT1No, SInt32 EvNo ); + ULT1__TZsFFrameRaw* PubFGotoEvAllULT1 ( SInt32 EvNo ); + + SInt32 PubFCloseRun (); + +}; + +#endif + +// 01/08/09 + +typedef struct { + + UInt32 IndexInEvWithHitList; + ASIC__TFrameStatus FrStatus; + +} ULT1__TCTelMon_TEltListEvWithHitAllPlanes; + + +// 02/08/09 + +typedef struct { + + SInt16 x; + SInt16 y; + +} ULT1__TCTelMon_THit; + +// 02/08/09 + +typedef struct { + + ULT1__TCTelMon_THit AAHits[MAPS__TCDigTelMon_MAX_PLANE_NB][MAPS__TCDigTelMon_MAX_RES_RUN_HIT_NB_PER_PLANE]; + SInt32 AHitsNbPerPlane[MAPS__TCDigTelMon_MAX_PLANE_NB]; + SInt32 EvNoInRun; + +} ULT1__TCTelMon_TTrack; + +// 02/08/09 + +typedef struct { + + SInt8 Full; + SInt8 PlaneNb; + SInt32 EvNb; + ULT1__TCTelMon_TTrack ATracks[MAPS__TCDigTelMon_MAX_RES_RUN_EV_NB]; + + +} ULT1__TCTelMon_TResRun; + + +// 17/07/09 + +#ifndef ROOT_ROOT + +#ifndef APP__RMV_CLASSES + +class ULT1__TCTelMon : public MAPS__TCDigTelMon { + + private: + + SInt8 PrivStopProc; + + // ------------------------------------------- + // Plot colors of planes for coincidence mode + // ------------------------------------------- + + ULT1__TColor PrivAPlanePlotColor[MAPS__TCDigTelMon_MAX_PLANE_NB]; + + // ------------------------------------------------------ + // Variables to store frames : pixel, cumul, plot color + // ------------------------------------------------------ + + ULT1__TZsFFrameRaw* PrivPtAcqData; // Copy of Acq data, enabled if MakeLocalCpy parameter of PubFAddEvents (...) is set + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, ULT1__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + SInt32 PrivAcqEvNb; // Event nb of current Acq = parameter EvNb of last PubFAddEvents (...) call + // PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt16 EvNb, ULT1__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + + ULT1__TZsFFrame PrivZsFFrame; // Tmp var to store ZsFFrameRaw converted to ZsFFrame + // Used for each frame converted + + ULT1__TMatDiscriBit PrivMatDiscriCoin; // Result for planeS coin plot AS PIXELS full scale matrix + ULT1__TMatDiscriCumul PrivMatDiscriCoinCum; // Result for planeS coin cumul plot AS COUNT full scale matrix + + ULT1__TMatDiscriBitHalfScale PrivMatDiscriBitHalfScale; // Result for planeS coin plot AS PIXELS 1/2 scale matrix + ULT1__TMatDiscriCumulHalfScale PrivMatDiscriCumHalfScale; // Result for planeS coin cumul plot AS COUNT 1/2 scale matrix + + ULT1__TMatDiscriColor PrivMatDispColor; // Result in matrix color data for ALL KINDS of plots + ULT1__TMatDiscriColorHalfScale PrivMatDispColorHalfScale; // Result in 1/2 scale matrix color data for ALL KINDS of plots + + // ===================================================================== + // Lists to store informations results of events processing + // ===================================================================== + + // Flag to enable / disable list update + // It's useful to disable list update for data re-processing ( off-line ) with information of list + // because list informations should not been updates while using them for current data processing ... + // + // The following methods set this flag to one + // - PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ) + + SInt8 PriEnListEvWitHitUpdate; + SInt8 PriEnListEvWithTrigUpdate; + + // --------------------------- + // List of events with trigger + // --------------------------- + + SInt32 PrivListEvWithTrigIndex; // Current elt index + SInt8 PrivListEvWithTrigFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithTrig[ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB]; + + // --------------------------- + // List of events with hit(s) + // --------------------------- + + SInt32 PrivListEvWithHitIndex; // Current elt index + SInt8 PrivListEvWithHitFull; // Full flag + + // The list array ( dynamic allocation ) + // Rq : AA and only one dimention because dynamic allocation of each elt of this array is done in PrivFInit () + + ASIC__TFrameStatus* PrivAAListEvWithHit[ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB]; // List + + // ----------------------------------------- + // List of events with hit(s) on all planes + // ----------------------------------------- + + SInt32 PrivListEvWithHitAllPlanesIndex; // Currenr elt index + SInt8 PrivListEvWithHitAllPlanesFull; // Full flag + SInt8 PrivListEvWithHitAllPlanesCurProcMode; // Current processing mode + // Uses to know if data must be reprocessed in cas user + // has changed list mode via ProPar.ListHitAllPlanesMode + + // The list array ( dynamic allocation ) + + ULT1__TCTelMon_TEltListEvWithHitAllPlanes* PrivAListEvWithHitAllPlanes; + + // --------------------------------------------------------------------- + // Result run after data processing + // --------------------------------------------------------------------- + + ULT1__TCTelMon_TResRun* PrivPtResRun; + + // --------------------------------------------------------------------- + // General init function : reset all variables, called by constructor + // --------------------------------------------------------------------- + + SInt32 PrivFInit (); + + // --------------------------------------------------------------------- + // Processing function + // --------------------------------------------------------------------- + + SInt32 PrivFConvZsFFrameToMatDiscriBitAndCumul ( SInt32 DbgEvNo, SInt8 Mode, SInt8 PlaneNo, SInt8 PlaneSelForCoin, SInt8 EvNo, SInt8 EvSelForPlot, ULT1__TZsFFrame* PtSrc, ULT1__TMatDiscriBit* PtDestFrameBit, ULT1__TMatDiscriBit* PtDestCoinBit, ULT1__TMatDiscriCumul* PtDestFrameCum, ULT1__TMatDiscriCumul* PtDestCoinCum, SInt8 PrintLvl ); + + + // --------------------------------------------------------------------- + // Lists ( events with trigger / hit ) add events functions + // --------------------------------------------------------------------- + + SInt32 PrivFAddEvInListEvWithTrig ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt ); + SInt32 PrivFAddEvInListEvWithHit ( SInt8 PlaneNo, ASIC__TFrameStatus* PtFrStatus, SInt32 HitCnt, SInt8 HitOnAllPlanes, SInt8 SingleHitOnEachPlane ); + + protected: + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Process one frame = one event of plane specified by Id (0..5) + + SInt32 ProFProcessPlane ( SInt32 DbdEvNo, SInt8 Id, ULT1__TZsFFrameRaw* PtSrc ); + + + + public: + + // -------------------------------------------------------------------------- + // Flag to select one Acq off-line processing / full RUN off-line processing + // -------------------------------------------------------------------------- + // Will be done via a method later + // 06/08/2009 + // -------------------------------------------------------------------------- + + SInt8 PubAcqOffLineProcOrRunOffLineProc; + + // ------------------------------------------- + // Constructor & Destructor + // ------------------------------------------- + + ULT1__TCTelMon (); + ~ULT1__TCTelMon (); + + // ------------------------------------------------------------ + // Begin method => MUST be called before ANY other function ! + // ------------------------------------------------------------ + + SInt32 PubFBegin ( char* ErrLogFile, SInt8 EnableErrLog, SInt8 ErrLogLvl, SInt32 MaxBuffEvNb ); + + // ------------------------------------------- + // GUI handling methods + // ------------------------------------------- + + #ifndef ROOT_ROOT + + // GUI interface + + SInt32 PubFConnectGui (); + + SInt32 PubFGetGuiPar (); + + #endif + + // ------------------------------------------- + // Run control methods + // ------------------------------------------- + // Allocate / free buffers + // ------------------------------------------- + + SInt32 PubFStartRun ( SInt8 MapsNb ); + SInt32 PubFStopRun (); + + // ------------------------------------------- + // Monitoring control methods + // ------------------------------------------- + + SInt32 PubFStartMon (); + SInt32 PubFStopMon (); + + // ------------------------------------------- + // Data processing methods + // ------------------------------------------- + + // Add events in on-line monitoring mode and call data processing methods ( protected ) + + SInt32 PubFAddEvents ( SInt8 MapsName, SInt8 MapsNb, SInt32 EvNb, ULT1__TZsFFrameRaw* PtSrc, SInt8 MakeLocalCpy, SInt8 OffLineCall ); + + // Off-line processing of data + // WARNING : NOW - 26/07/2009 - IT'S ONLY data of LAST acquisition ( data provided by last call to PubFAddEvents ) + // => Uses as events number the one of last acq + // => Force mode to "Process one Acq" AND update GUI parameters + + SInt32 PubFProcessOffLineCurAcq (); + SInt32 PubFProcessOffLineCurAcq2 (); + + // Select frame to plot + + SInt32 PubFGotoFirstFrame (); + SInt32 PubFGotoPrevFrame (); + SInt32 PubFGotoNextFrame (); + SInt32 PubFGotoLastFrame (); + + // ------------------------------------------- + // Results print methods + // ------------------------------------------- + + // Print list of events with a trigger detected => print SStatus record + + SInt32 PubPrintListEvWithTrig ( SInt8 Verbose ); + + // Print list of events with at least one hit in one plane => print SStatus record + + SInt32 PubPrintListEvWithHit ( SInt8 Verbose ); + + // Print list of events with hit on ALL planes => print SStatus record + + SInt32 PubPrintListEvWithHitOnAllPlanes ( SInt8 Verbose ); + + // Print res run + + SInt32 PubAllocResRun (); + SInt32 PubFreeResRun (); + SInt32 PubPrintResRun (); + SInt32 PubSaveResRun ( char* FileName ); + + + SInt32 PubFIsEvInListEvWithHitOnAllPlanes ( SInt32 EvNo ); + SInt32 PubFIsEvLastOfListEvWithHitOnAllPlanes ( SInt32 EvNo ); + + SInt32 PubFProcOnlyEvWithHitOnAllPlanes ( SInt8 Yes ); + + + // ------------------------------------------- + // Results plot methods + // ------------------------------------------- + + // There is NO plot method in class. + // + // Because a call of a plot function ( from plot lib ) in DAQ supervisor thread doesn't work + // - nothing is displayed ! + // - this may crash the application + // I don't know why and have no time to study and understand this bug. I have found a workarround + // by calling the plot function in an application timer. + // + // The class request plot by setting the flag ProRequestPlot to 1 + // plot is done by "plot timer" callback in application which + // reset the flag ProRequestPlot after plot. + + // The application "plot timer" must know : + // - when he must plot --> Test variable pointed by PubFGetPtPlotRq () + // - the matrix to plot : full / half scale --> Test variable pointed by PubFGetPtDispFullMatrix () + // - the data to plot --> Read via pointer given by PubFGetPtFullMatCol () / PubFGetPtHalfMatCol () + // + // Polling of plot request and access to data is NOT DONE via method calls because + // - calling class methods in timer while other methods may be called in DAQ supervisor thread MAY cause problems => No detailed understanding, no time ... + // - it will save execution time by avoiding function call + + SInt8* PubFGetPtDispFullMatrix (); + ULT1__TMatDiscriColor* PubFGetPtFullMatCol (); + ULT1__TMatDiscriColorHalfScale* PubFGetPtHalfMatCol (); + + +}; + +#endif + + +#endif + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/ult1_test_mi26.def b/include/pxi_daq_lib_v.3.1/ult1_test_mi26.def new file mode 100755 index 0000000..1cd7556 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/ult1_test_mi26.def @@ -0,0 +1,191 @@ +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_test_mi26.def +Goal : Macros definition of Ultimate 1 library => for lib test with Mi26. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 01/03/2011 +File date : 01/03/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_TEST_MI26_DEF +#define ULT1_TEST_MI26_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + + +#define ULT1__REG_DISCRI_BIT_SZ 1152 // Mi26 = 1152 +#define ULT1__REG_DISCRI_W32_SZ 36 // Mi26 = 36 + +// This register is not implemented on Ultimate +// +// #define ULT1__REG_AFTER_ZS_BIT_SZ 160 +// #define ULT1__REG_AFTER_ZS_W32_SZ 5 + +#define ULT1__REG_AFTER_MUX_BIT_SZ 160 // Mi26 = 160 +#define ULT1__REG_AFTER_MUX_W32_SZ 5 // Mi26 = 5 + +#define ULT1__MAT_DISCRI_LINES_NB 578 // 578 + +#define ULT1__ZS_FFRAME_RAW_MAX_W16 1140 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define ULT1__ZS_FFRAME_RAW_MAX_W32 570 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 +#define ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 // Total frame size ( sum of 2 links ) in W32 - Mi26 = 576 + +#define ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define ULT1__ZS_FFRAME_MAX_STATES_REC 576 // Mi26 = 576 - one per line + +#define ULT1__ZS_FFRAME_MODE0_1X80MHZ 0 +#define ULT1__ZS_FFRAME_MODE1_2X80MHZ 1 +#define ULT1__ZS_FFRAME_MODE2_1X160MHZ 2 +#define ULT1__ZS_FFRAME_MODE3_2X160MHZ 3 + + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_BIT_SZ 0 // 0 => Not used for this test +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_BIT_SZ 0 // 0 => Not used for this test +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_BIT_SZ 0 // 0 => Not used for this test +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_BIT_SZ 9216 // = Mi26 2 x 80 MHz + +// $ #define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_W16_SZ 288 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_W16_SZ 576 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 576 // Mi26 = 576 + +#define ULT1__ZS_FFRAME_MODE_1X80MHZ_W32_SZ 288 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W32_SZ 288 // Mi26 = 288 +#define ULT1__ZS_FFRAME_MODE_1X160MHZ_W32_SZ 144 // Mi26 = 144 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W32_SZ 288 // Mi26 = 288 + + +// Id to select ULT1 register + +#define ULT1__REG_DISCRI 0 +// #define ULT1__REG_AFTER_ZS 1 -> Not implemented on Ultimate +#define ULT1__REG_AFTER_MUX 1 +#define ULT1__REG_DISCRI_SCAN 2 + +#define ULT1__REG_DISCRI_SCAN__SRC_CLK_160MHZ 3 // 23/06/2010 + +// ====================================== +// For ULT1 discri analysis tools +// ====================================== + +// Submatrices number + +#define ULT1__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +// $ #define ULT1__REG_BIAS_NB 19 + +// $ #define ULT1__REG_BIAS_ICLPDISC 0 +// $ #define ULT1__REG_BIAS_IPWRSW 1 +// $ #define ULT1__REG_BIAS_IBUF 2 +// $ #define ULT1__REG_BIAS_ID1PWRS 3 +// $ #define ULT1__REG_BIAS_ID2PWRS 4 +// $ #define ULT1__REG_BIAS_ILVDSTX 5 +// $ #define ULT1__REG_BIAS_ILVDSRX 6 +// $ #define ULT1__REG_BIAS_IVTST1 7 +// $ #define ULT1__REG_BIAS_IVTST2 8 +// $ #define ULT1__REG_BIAS_IANABUF 9 +// $ #define ULT1__REG_BIAS_IVDREF1D 10 +// $ #define ULT1__REG_BIAS_IVDREF1C 11 +// $ #define ULT1__REG_BIAS_IVDREF1B 12 +// $ #define ULT1__REG_BIAS_IVDREF1A 13 +// $ #define ULT1__REG_BIAS_IVDREF2 14 +// $ #define ULT1__REG_BIAS_IDIS1 15 +// $ #define ULT1__REG_BIAS_IDIS2 16 +// $ #define ULT1__REG_BIAS_IPXI 17 +// $ #define ULT1__REG_BIAS_VPIXCLP 18 + + +// --------------------------------------------------------------------------------- +// User defined parameters for each step ( threshold = run ) of discri measurement +// --------------------------------------------------------------------------------- + +// Maximum parameters number + +#define ULT1__DIS_MEAS_STEP_MAX_PAR_NB 20 + +// Index of each parameter to access them in array +// User can create new parameters here + +#define ULT1__DIS_MEAS_STEP_PAR_FIRST 0 +#define ULT1__DIS_MEAS_STEP_PAR_LAST (ULT1__DIS_MEAS_STEP_MAX_PAR_NB - 1) + +// Maximum number of steps + +#define ULT1__DIS_TEST_MAX_STEP_NB 30 + + +/* ============================================================================ */ +/* */ +/* */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* */ +/* ---------------------------------------------------------------------------- */ +/* Date : */ +/* ============================================================================ */ + +#define ULT1__NB_MAX_ULT1_PER_DAQ 8 + + +// -------------------- +// ZS Run info record +// -------------------- + +#define ULT1__TZSRunCnf__HW_TRIG_PAR_NB 10 // WARNING !!! MUST be >= DPXI__HW_TRIG_PAR_NB + +#define ULT1__TZSRunRes__MAX_ACQ_REJ_NB 1000 + +#define ULT1__TCZsRunRW__CHK_INIT() {err_retfail ( ProConfDone, (ERR_OUT,"Conf NOT done => Abort") ); } + + + + + +// -------------------- +// ULT1__TCTelMon +// -------------------- + +#define ULT1__COLOR_BROWN 0x000066CC +#define ULT1__COLOR_ORANGE 0x0000A5FF +#define ULT1__COLOR_YELLOW 0x0000FFFF +#define ULT1__COLOR_GREEN 0x0000FF00 +#define ULT1__COLOR_BLUE 0x00FF0000 +#define ULT1__COLOR_VIOLET 0x00990066 + +#define ULT1__TCTelMon__COL_PLANE_0 (TColor) ULT1__COLOR_ORANGE +#define ULT1__TCTelMon__COL_PLANE_1 (TColor) ULT1__COLOR_BLUE +#define ULT1__TCTelMon__COL_PLANE_2 (TColor) ULT1__COLOR_BROWN +#define ULT1__TCTelMon__COL_PLANE_3 (TColor) ULT1__COLOR_YELLOW +#define ULT1__TCTelMon__COL_PLANE_4 (TColor) ULT1__COLOR_GREEN +#define ULT1__TCTelMon__COL_PLANE_5 (TColor) ULT1__COLOR_VIOLET + + +#define ULT1__TCTelMon__EV_LIST_MAX_CHAN_NB (MAPS__TCDigTelMon_MAX_PLANE_NB + 1) // 1 channel = 1 plane + // Last channel = cumul hit nb of all planes + +#define ULT1__TCTelMon__EV_LIST_CHAN_ID_CUMUL MAPS__TCDigTelMon_MAX_PLANE_NB // Channel for cumul hit nb of all planes + + +#define ULT1__TCTelMon__EV_LIST_MAX_ELT_NB 200000 + + +#endif \ No newline at end of file diff --git a/include/pxi_daq_lib_v.3.1/ult1_usr.def b/include/pxi_daq_lib_v.3.1/ult1_usr.def new file mode 100755 index 0000000..20ecdd7 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/ult1_usr.def @@ -0,0 +1,86 @@ +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.def +Goal : Macros definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_DEF +#define ULT1_USR_DEF + +#ifdef ULT1__APP_DLL_TEST_MI26 + #include "ult1_usr_test_mi26.def" +#else + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W16_SZ 1856 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_W8_SZ 3712 // + + +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W16_SZ 1850 // Add on 11/05/2011 - value per link +#define ULT1__ZS_FFRAME_MODE_2X160MHZ_MAX_DATA_PART_W8_SZ 3700 // Add on 11/05/2011 - value per link + +#define ULT1__ZS_FFRAME_RAW_MAX_W8 7400 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 +#define ULT1__ZS_FFRAME_RAW_MAX_W16 3700 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define ULT1__ZS_FFRAME_RAW_MAX_W32 1850 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 + +#define ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 1856 // Mi26 = 576 + + +#define ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define ULT1__ZS_FFRAME_MAX_STATES_REC 828 // Mi26 = 576 - one per line + +// ====================================== +// For ULT1 discri analysis tools +// ====================================== + +// Submatrices number + +#define ULT1__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define ULT1__REG_BIAS_NB 19 + +#define ULT1__REG_BIAS_ICLPDISC 0 +#define ULT1__REG_BIAS_IPWRSW 1 +#define ULT1__REG_BIAS_IBUF 2 +#define ULT1__REG_BIAS_ID1PWRS 3 +#define ULT1__REG_BIAS_ID2PWRS 4 +#define ULT1__REG_BIAS_ILVDSTX 5 +#define ULT1__REG_BIAS_ILVDSRX 6 +#define ULT1__REG_BIAS_IVTST1 7 +#define ULT1__REG_BIAS_IVTST2 8 +#define ULT1__REG_BIAS_IANABUF 9 +#define ULT1__REG_BIAS_IVDREF1D 10 +#define ULT1__REG_BIAS_IVDREF1C 11 +#define ULT1__REG_BIAS_IVDREF1B 12 +#define ULT1__REG_BIAS_IVDREF1A 13 +#define ULT1__REG_BIAS_IVDREF2 14 +#define ULT1__REG_BIAS_IDIS1 15 +#define ULT1__REG_BIAS_IDIS2 16 +#define ULT1__REG_BIAS_IPXI 17 +#define ULT1__REG_BIAS_VPIXCLP 18 + + +#endif + +#endif diff --git a/include/pxi_daq_lib_v.3.1/ult1_usr.typ b/include/pxi_daq_lib_v.3.1/ult1_usr.typ new file mode 100755 index 0000000..04f1914 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/ult1_usr.typ @@ -0,0 +1,193 @@ + +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.typ +Goal : Types definition of Ultimate 1 library. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 28/02/2011 +File date : 28/02/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_TYP +#define ULT1_USR_TYP + +/* ============================= */ +/* Lib context */ +/* Contain all global variables */ +/* ----------------------------- */ +/* Date : 24/11/2008 */ +/* ============================= */ + +typedef struct { + + SInt8 FileErrLogLvl; + char FileErrFile[GLB_FILE_PATH_SZ]; + +} ULT1__TContext; + + +/* ======================================================= */ +/* Frame provided by ULT1 DAQ, it's independent of output */ +/* mode BUT data are not organized as in ULT1__TZsFFrame */ +/* The format is : */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at end of frame ) */ +/* - Array of W16 data */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains the maximum */ +/* possible W16 defined by ULT1__ZS_FFRAME_RAW_MAX_W16 */ +/* ------------------------------------------------------- */ +/* Date : 08/12/2008 */ +/* ======================================================= */ + + +typedef struct { + + ASIC__TFrameStatus SStatus; // Informations about frame, see ASIC__TFrameStatus in asic.typ + + UInt32 Header; // Header of Mimosa 26 frame + UInt32 FrameCnt; // Frame counter of Mimosa 26 frame + + UInt32 DataLength; // Useful length in W16 unit of data contains in ADataW16 array + // - B00B16 -> Length on first output + // - B17B23 -> Length on second output + // + // Add the two values to get the total length + + UInt32 Trailer; // Trailer of Mimosa 26 frame + + UInt32 Zero; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + UInt32 Zero2; // Zero at end of Mimosa 26 frame -> But NOW they are set to 0xFFFFFFFF by DAQ sw + // + // It's strange ... please don't ask why it's sugar and it's written salt on the box ... + // + // At the beginning it was last fields of Mimosa 26 frame, which are set to 0, now it's + // overwritten by sw in order to mark the end of information fields before data fields + // and 0xFFFFFFFF is a better value than zero for this purpose. + + + UInt16 ADataW16[ULT1__ZS_FFRAME_RAW_MAX_W16]; // MUST BE AT END OF RECORD ! + +} ULT1__TZsFFrameRaw; // F in FFrameRaw means Fixed size frame + + + +/* =================================================== */ +/* Field States/Line of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 StateNb : 4; + UInt16 LineAddr : 11; + UInt16 Ovf : 1; + + } F; + +} ULT1__TStatesLine; + +/* =================================================== */ +/* Field State of Zero Sup frame, 2 views */ +/* - W16 word */ +/* - Fields */ +/* --------------------------------------------------- */ +/* It's bit mapping => No conversion function required */ +/* --------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* =================================================== */ + +typedef union { + + UInt16 W16; + + struct { + + UInt16 HitNb : 2; + UInt16 ColAddr : 11; + UInt16 NotUsed : 3; + + } F; + +} ULT1__TState; + + +/* ======================================================= */ +/* One list of states associated to one line */ +/* - States/Lines information */ +/* - States list */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max ULT1__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ======================================================= */ + +typedef struct { + + ULT1__TStatesLine StatesLine; + ULT1__TState AStates[ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC]; + +} ULT1__TZsFStatesRec; // F in FStatesRec means Fixed size record + + +/* ======================================================= */ +/* Frame provided by ULT1, this is the final result after */ +/* data processing depending of output mode selected */ +/* - Header */ +/* - Frames counter */ +/* - Data length = W16 number of useful data ( excluding */ +/* trailer and bits at zero at enbd of frame ) */ +/* ------------------------------------------------------- */ +/* This is a FIXED size record which contains all states */ +/* of one line, max ULT1__ZS_FFRAME_MAX_STATES_NB_PER_LINE */ +/* ------------------------------------------------------- */ +/* Date : 24/11/2008 */ +/* ------------------------------------------------------- */ + +typedef struct { + + ASIC__TFrameStatus SStatus; + + UInt32 Header; + UInt32 FrameCnt; + UInt32 DataLength; + SInt16 TrigSignalLine; + SInt8 TrigSignalClk; + SInt16 TrigLine; + + UInt32 StatesRecNb; // It's NOT a ULT1 frame field, it's calculated by sw + // It's the number of valid record in AStatesRec + + ULT1__TZsFStatesRec AStatesRec[ULT1__ZS_FFRAME_MAX_STATES_REC]; + + UInt32 Trailer; + UInt32 Zero; + UInt32 Zero2; + +} ULT1__TZsFFrame; // F in FFrame means Fixed size frame + + + +#endif diff --git a/include/pxi_daq_lib_v.3.1/ult1_usr_test_mi26.def b/include/pxi_daq_lib_v.3.1/ult1_usr_test_mi26.def new file mode 100755 index 0000000..310b227 --- /dev/null +++ b/include/pxi_daq_lib_v.3.1/ult1_usr_test_mi26.def @@ -0,0 +1,76 @@ +/******************************************************************************* +File : x:\lib\com\maps\ult1\ult1_usr.def +Goal : Macros definition of Ultimate 1 library => for lib test with Mi26. + : It provides Ultimate 1 types definition and data handling functions. +Prj date : 01/03/2011 +File date : 01/03/2011 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@ires.in2p3.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long +: as it stays in a public research context. You are not allowed to use it +: for commercial purpose. You must put this header with laboratory and +: authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef ULT1_USR_TEST_MI26_DEF +#define ULT1_USR_TEST_MI26_DEF + + +/* ================= */ +/* Macro example */ +/* ================= */ + +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W16_SZ 576 // Mi26 = 576 +#define ULT1__ZS_FFRAME_MODE_2X80MHZ_W8_SZ 1152 // Mi26 = 1152 + +#define ULT1__ZS_FFRAME_RAW_MAX_W8 2280 // Data part size ( sum of 2 links ) in W8 - Mi26 = 2280 +#define ULT1__ZS_FFRAME_RAW_MAX_W16 1140 // Data part size ( sum of 2 links ) in W16 - Mi26 = 1140 +#define ULT1__ZS_FFRAME_RAW_MAX_W32 570 // Data part size ( sum of 2 links ) in W32 - Mi26 = 570 + +#define ULT1__ZS_FFRAME_RAW_TOTAL_SZ_W32 576 // Mi26 = 576 + + +#define ULT1__ZS_FFRAME_MAX_STATES_NB_PER_STATES_REC 9 // Mi26 = 9 +#define ULT1__ZS_FFRAME_MAX_STATES_REC 576 // Mi26 = 576 - one per line + +// ====================================== +// For ULT1 discri analysis tools +// ====================================== + +// Submatrices number + +#define ULT1__SUB_MAT_NB 4 + +// -------------------- +// Bias registers index +// -------------------- + +#define ULT1__REG_BIAS_NB 19 + +#define ULT1__REG_BIAS_ICLPDISC 0 +#define ULT1__REG_BIAS_IPWRSW 1 +#define ULT1__REG_BIAS_IBUF 2 +#define ULT1__REG_BIAS_ID1PWRS 3 +#define ULT1__REG_BIAS_ID2PWRS 4 +#define ULT1__REG_BIAS_ILVDSTX 5 +#define ULT1__REG_BIAS_ILVDSRX 6 +#define ULT1__REG_BIAS_IVTST1 7 +#define ULT1__REG_BIAS_IVTST2 8 +#define ULT1__REG_BIAS_IANABUF 9 +#define ULT1__REG_BIAS_IVDREF1D 10 +#define ULT1__REG_BIAS_IVDREF1C 11 +#define ULT1__REG_BIAS_IVDREF1B 12 +#define ULT1__REG_BIAS_IVDREF1A 13 +#define ULT1__REG_BIAS_IVDREF2 14 +#define ULT1__REG_BIAS_IDIS1 15 +#define ULT1__REG_BIAS_IDIS2 16 +#define ULT1__REG_BIAS_IPXI 17 +#define ULT1__REG_BIAS_VPIXCLP 18 + + +#endif diff --git a/include/spiralNumerotation.h b/include/spiralNumerotation.h new file mode 100755 index 0000000..7847a3a --- /dev/null +++ b/include/spiralNumerotation.h @@ -0,0 +1,43 @@ +Shor_t spiralMatrix[20][20]; + +spiralMatrix[ 0][ 0] = 0; +spiralMatrix[ 0][ 1] = 1; +spiralMatrix[ 1][ 1] = 2; +spiralMatrix[ 1][ 0] = 3; +spiralMatrix[ 1][ 0] = 4; +spiralMatrix[ 1][ 0] = 5; +spiralMatrix[ 1][ 0] = 6; +spiralMatrix[ 1][ 0] = 7; +spiralMatrix[ 1][ 0] = 8; +spiralMatrix[ 1][ 0] = 9; +spiralMatrix[ 1][ 0] = 10; +spiralMatrix[ 1][ 0] = 11; +spiralMatrix[ 1][ 0] = 12; +spiralMatrix[ 1][ 0] = 13; +spiralMatrix[ 1][ 0] = 14; +spiralMatrix[ 1][ 0] = 15; +spiralMatrix[ 1][ 0] = 16; +spiralMatrix[ 1][ 0] = 17; +spiralMatrix[ 1][ 0] = 18; +spiralMatrix[ 1][ 0] = 19; +spiralMatrix[ 1][ 0] = 20; +spiralMatrix[ 1][ 0] = 21; +spiralMatrix[ 1][ 0] = 22; +spiralMatrix[ 1][ 0] = 23; +spiralMatrix[ 1][ 0] = 24; +spiralMatrix[ 1][ 0] = 25; +spiralMatrix[ 1][ 0] = 26; +spiralMatrix[ 1][ 0] = 27; +spiralMatrix[ 1][ 0] = 28; +spiralMatrix[ 1][ 0] = 29; +spiralMatrix[ 1][ 0] = 30; +spiralMatrix[ 1][ 0] = 31; +spiralMatrix[ 1][ 0] = 32; +spiralMatrix[ 1][ 0] = 33; +spiralMatrix[ 1][ 0] = 34; +spiralMatrix[ 1][ 0] = 35; +spiralMatrix[ 1][ 0] = 36; +spiralMatrix[ 1][ 0] = 37; +spiralMatrix[ 1][ 0] = 38; +spiralMatrix[ 1][ 0] = 39; +spiralMatrix[ 1][ 0] = 40; diff --git a/include/sup_exp.typ b/include/sup_exp.typ new file mode 100755 index 0000000..0081fc0 --- /dev/null +++ b/include/sup_exp.typ @@ -0,0 +1,212 @@ + +/******************************************************************************* +File : X:\prj\win\Beast\supervisor\lib\sup_exp\sup_exp.typ +Goal : Types definition of supervisor sw export library +Prj date : 06/09/2017 +File date : 17/01/2018 +Doc date : //200 +Author : Gilles CLAUS +E-mail : gilles.claus@iphc.cnrs.fr +---------------------------------------------------------------------------------- +License : You are free to use this source files for your own development as long + : as it stays in a public research context. You are not allowed to use it + : for commercial purpose. You must put this header with laboratory and + : authors names in all development based on this library. +---------------------------------------------------------------------------------- +Labo : IPHC */ +/*******************************************************************************/ + + +#ifndef SEXP_TYP +#define SEXP_TYP + +#define CC_UNIX + +#ifndef GLB_CMT_SZ +#define GLB_CMT_SZ 256 +#endif + +#define fTimeRefRecordSize 540 + +/* ======================================================================== */ +/* If NOT compiled in DAQ src architecture => Standard types redefinition */ +/* ======================================================================== */ + + + #ifndef CC__NOT_EXPORT_SW + + #ifndef UInt8 + typedef unsigned char UInt8; + #endif + + #ifndef UByte + typedef UInt8 UByte; + #endif + + #ifndef SInt8 + // typedef char SInt8; + typedef signed char SInt8; // ZE 2021/05/26 + #endif + + #ifndef SByte + typedef SInt8 SByte; + #endif + + #ifndef UInt16 + typedef unsigned short UInt16; + #endif + + #ifndef UWord + typedef UInt16 UWord; + #endif + + #ifndef SInt16 + typedef short SInt16; + #endif + + #ifndef SWord + typedef SInt16 SWord; + #endif + + #ifndef UInt32 + //typedef unsigned long int UInt32; + typedef unsigned int UInt32; + #endif + + #ifndef ULong + typedef UInt32 ULong; + #endif + + #ifndef SInt32 + //typedef long int SInt32; + typedef int SInt32; + #endif + + #ifndef SLong + typedef SInt32 SLong; + #endif + + + #ifdef CC_UNIX + + #ifndef UInt64 + //typedef int64_t UInt64; + #endif + + #ifndef SInt64 + //typedef uint64_t SInt64; + //typedef ULong64_t SInt64; + #endif + + #else + + #ifndef UInt64 + typedef unsigned __int64 UInt64; + #endif + + #ifndef SInt64 + typedef __int64 SInt64; + #endif + + #endif + + #endif + + +/* ================= */ +/* Type example */ +/* ================= */ + +typedef struct { + char name[20]; + SInt8 age; +} SEXP__TMyStruct; + + +/* ============== */ +/* Latchup types */ +/* ============== */ + +// 17/01/2018 + +typedef struct { + + UInt8 Day; + UInt8 Month; + UInt8 Year; + UInt8 Reserved; + +} SEXP__TDate; + + +// 17/01/2018 + +typedef struct { + + UInt8 Ms; + UInt8 Sec; + UInt8 Min; + UInt8 Hour; + +} SEXP__TTime; + + +// 17/01/2018 + +typedef struct { + + union { + + UInt32 DateAsInt32; + SEXP__TDate Date; + + }; + + union { + + UInt32 TimeAsInt32; + SEXP__TTime Time; + + }; + + +} SEXP__TDateTime; + + +// 17/01/2018 + +typedef struct { + + UInt32 FormatVersionDate; // Date of the record format + // B31B25 = Version + // B24B16 = Year + // B15B08 = Month + // B07B00 = Day + + SInt16 RecCnt; // Record counter = Time stamp counter, starting at 1 + + SInt16 ReStartCnt; // Ladder (Mi26) restart counter, must be equal to RecCnt + // used to detect errors in case ReStartCnt <> RecCnt + + // Cyclic time stamping flag + // + SInt16 InfoCyclicTS; // = 0 on for first TS = the one taken when Mi26 is started at beginning of the run + // = 1 on following TS if automatic time stamping is enabled during the run + // = 0 on a TS which is not thje first one => This TS correspond to a Mi26 restart after a latchup + + UInt8 RtcTimeAvailable; // 0 = RTC time is NOT available in RtcDateTime field, 1 = RTC time is available + + UInt8 NtpTimeAvailable; // 0 = NTP time is NOT available in NtpDateTime field, 1 = NTP time is available + + SEXP__TDateTime RtcDateTime; // RTC date and time record + + SEXP__TDateTime NtpDateTime; // NTP date and time record + + char RtcDateTimeStr[GLB_CMT_SZ]; // RTC date and time converted in a string + + char NtpDateTimeStr[GLB_CMT_SZ]; // NTP date and time converted in a string + +} SEXP_TTsRec; + + +#endif diff --git a/include/tiff.h b/include/tiff.h new file mode 100755 index 0000000..ecf2d19 --- /dev/null +++ b/include/tiff.h @@ -0,0 +1,437 @@ +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFF_ +#define _TIFF_ +/* + * Tag Image File Format (TIFF) + * + * Based on Rev 6.0 from: + * Developer's Desk + * Aldus Corporation + * 411 First Ave. South + * Suite 200 + * Seattle, WA 98104 + * 206-622-5500 + */ +#define TIFF_VERSION 42 + +#define TIFF_BIGENDIAN 0x4d4d +#define TIFF_LITTLEENDIAN 0x4949 + +#ifndef _TIFF_DATA_TYPEDEFS_ +#define _TIFF_DATA_TYPEDEFS_ +/* + * Intrinsic data types required by the file format: + * + * 8-bit quantities int8/uint8 + * 16-bit quantities int16/uint16 + * 32-bit quantities int32/uint32 + * strings unsigned char* + */ +#ifdef __STDC__ +typedef signed char int8; /* NB: non-ANSI compilers may not grok */ +#else +typedef char int8; +#endif +typedef unsigned char uint8; +typedef short int16; +typedef unsigned short uint16; /* sizeof (uint16) must == 2 */ +#if defined(__alpha) || (defined(_MIPS_SZLONG) && _MIPS_SZLONG == 64) +typedef int int32; +typedef unsigned int uint32; /* sizeof (uint32) must == 4 */ +#else +typedef long int32; +typedef unsigned long uint32; /* sizeof (uint32) must == 4 */ +#endif +#endif /* _TIFF_DATA_TYPEDEFS_ */ + +/* For TIFFReassignTagToIgnore */ +enum TIFFIgnoreSense /* IGNORE tag table */ +{ + TIS_STORE, + TIS_EXTRACT, + TIS_EMPTY +}; + +typedef struct { + uint16 tiff_magic; /* magic number (defines byte order) */ + uint16 tiff_version; /* TIFF version number */ + uint32 tiff_diroff; /* byte offset to first directory */ +} TIFFHeader; + +/* + * TIFF Image File Directories are comprised of + * a table of field descriptors of the form shown + * below. The table is sorted in ascending order + * by tag. The values associated with each entry + * are disjoint and may appear anywhere in the file + * (so long as they are placed on a word boundary). + * + * If the value is 4 bytes or less, then it is placed + * in the offset field to save space. If the value + * is less than 4 bytes, it is left-justified in the + * offset field. + */ +typedef struct { + uint16 tdir_tag; /* see below */ + uint16 tdir_type; /* data type; see below */ + uint32 tdir_count; /* number of items; length in spec */ + uint32 tdir_offset; /* byte offset to field data */ +} TIFFDirEntry; + +/* + * NB: In the comments below, + * - items marked with a + are obsoleted by revision 5.0, + * - items marked with a ! are introduced in revision 6.0. + * - items marked with a % are introduced post revision 6.0. + * - items marked with a $ are obsoleted by revision 6.0. + */ + +/* + * Tag data type information. + * + * Note: RATIONALs are the ratio of two 32-bit integer values. + */ +typedef enum { + TIFF_NOTYPE = 0, /* placeholder */ + TIFF_BYTE = 1, /* 8-bit unsigned integer */ + TIFF_ASCII = 2, /* 8-bit bytes w/ last byte null */ + TIFF_SHORT = 3, /* 16-bit unsigned integer */ + TIFF_LONG = 4, /* 32-bit unsigned integer */ + TIFF_RATIONAL = 5, /* 64-bit unsigned fraction */ + TIFF_SBYTE = 6, /* !8-bit signed integer */ + TIFF_UNDEFINED = 7, /* !8-bit untyped data */ + TIFF_SSHORT = 8, /* !16-bit signed integer */ + TIFF_SLONG = 9, /* !32-bit signed integer */ + TIFF_SRATIONAL = 10, /* !64-bit signed fraction */ + TIFF_FLOAT = 11, /* !32-bit IEEE floating point */ + TIFF_DOUBLE = 12 /* !64-bit IEEE floating point */ +} TIFFDataType; + +/* + * TIFF Tag Definitions. + */ +#define TIFFTAG_SUBFILETYPE 254 /* subfile data descriptor */ +#define FILETYPE_REDUCEDIMAGE 0x1 /* reduced resolution version */ +#define FILETYPE_PAGE 0x2 /* one page of many */ +#define FILETYPE_MASK 0x4 /* transparency mask */ +#define TIFFTAG_OSUBFILETYPE 255 /* +kind of data in subfile */ +#define OFILETYPE_IMAGE 1 /* full resolution image data */ +#define OFILETYPE_REDUCEDIMAGE 2 /* reduced size image data */ +#define OFILETYPE_PAGE 3 /* one page of many */ +#define TIFFTAG_IMAGEWIDTH 256 /* image width in pixels */ +#define TIFFTAG_IMAGELENGTH 257 /* image height in pixels */ +#define TIFFTAG_BITSPERSAMPLE 258 /* bits per channel (sample) */ +#define TIFFTAG_COMPRESSION 259 /* data compression technique */ +#define COMPRESSION_NONE 1 /* dump mode */ +#define COMPRESSION_CCITTRLE 2 /* CCITT modified Huffman RLE */ +#define COMPRESSION_CCITTFAX3 3 /* CCITT Group 3 fax encoding */ +#define COMPRESSION_CCITTFAX4 4 /* CCITT Group 4 fax encoding */ +#define COMPRESSION_LZW 5 /* Lempel-Ziv & Welch */ +#define COMPRESSION_OJPEG 6 /* !6.0 JPEG */ +#define COMPRESSION_JPEG 7 /* %JPEG DCT compression */ +#define COMPRESSION_NEXT 32766 /* NeXT 2-bit RLE */ +#define COMPRESSION_CCITTRLEW 32771 /* #1 w/ word alignment */ +#define COMPRESSION_PACKBITS 32773 /* Macintosh RLE */ +#define COMPRESSION_THUNDERSCAN 32809 /* ThunderScan RLE */ +/* codes 32895-32898 are reserved for ANSI IT8 TIFF/IT <dkelly@etsinc.com) */ +#define COMPRESSION_IT8CTPAD 32895 /* IT8 CT w/padding */ +#define COMPRESSION_IT8LW 32896 /* IT8 Linework RLE */ +#define COMPRESSION_IT8MP 32897 /* IT8 Monochrome picture */ +#define COMPRESSION_IT8BL 32898 /* IT8 Binary line art */ +/* compression codes 32908-32911 are reserved for Pixar */ +#define COMPRESSION_PIXARFILM 32908 /* Pixar companded 10bit LZW */ +#define COMPRESSION_PIXARLOG 32909 /* Pixar companded 11bit ZIP */ +#define COMPRESSION_DEFLATE 32946 /* Deflate compression */ +#define COMPRESSION_ADOBE_DEFLATE 8 /* Deflate compression, as recognized by Adobe */ +/* compression code 32947 is reserved for Oceana Matrix <dev@oceana.com> */ +#define COMPRESSION_DCS 32947 /* Kodak DCS encoding */ +#define COMPRESSION_JBIG 34661 /* ISO JBIG */ +#define COMPRESSION_SGILOG 34676 /* SGI Log Luminance RLE */ +#define COMPRESSION_SGILOG24 34677 /* SGI Log 24-bit packed */ +#define TIFFTAG_PHOTOMETRIC 262 /* photometric interpretation */ +#define PHOTOMETRIC_MINISWHITE 0 /* min value is white */ +#define PHOTOMETRIC_MINISBLACK 1 /* min value is black */ +#define PHOTOMETRIC_RGB 2 /* RGB color model */ +#define PHOTOMETRIC_PALETTE 3 /* color map indexed */ +#define PHOTOMETRIC_MASK 4 /* $holdout mask */ +#define PHOTOMETRIC_SEPARATED 5 /* !color separations */ +#define PHOTOMETRIC_YCBCR 6 /* !CCIR 601 */ +#define PHOTOMETRIC_CIELAB 8 /* !1976 CIE L*a*b* */ +#define PHOTOMETRIC_LOGL 32844 /* CIE Log2(L) */ +#define PHOTOMETRIC_LOGLUV 32845 /* CIE Log2(L) (u',v') */ +#define TIFFTAG_THRESHHOLDING 263 /* +thresholding used on data */ +#define THRESHHOLD_BILEVEL 1 /* b&w art scan */ +#define THRESHHOLD_HALFTONE 2 /* or dithered scan */ +#define THRESHHOLD_ERRORDIFFUSE 3 /* usually floyd-steinberg */ +#define TIFFTAG_CELLWIDTH 264 /* +dithering matrix width */ +#define TIFFTAG_CELLLENGTH 265 /* +dithering matrix height */ +#define TIFFTAG_FILLORDER 266 /* data order within a byte */ +#define FILLORDER_MSB2LSB 1 /* most significant -> least */ +#define FILLORDER_LSB2MSB 2 /* least significant -> most */ +#define TIFFTAG_DOCUMENTNAME 269 /* name of doc. image is from */ +#define TIFFTAG_IMAGEDESCRIPTION 270 /* info about image */ +#define TIFFTAG_MAKE 271 /* scanner manufacturer name */ +#define TIFFTAG_MODEL 272 /* scanner model name/number */ +#define TIFFTAG_STRIPOFFSETS 273 /* offsets to data strips */ +#define TIFFTAG_ORIENTATION 274 /* +image orientation */ +#define ORIENTATION_TOPLEFT 1 /* row 0 top, col 0 lhs */ +#define ORIENTATION_TOPRIGHT 2 /* row 0 top, col 0 rhs */ +#define ORIENTATION_BOTRIGHT 3 /* row 0 bottom, col 0 rhs */ +#define ORIENTATION_BOTLEFT 4 /* row 0 bottom, col 0 lhs */ +#define ORIENTATION_LEFTTOP 5 /* row 0 lhs, col 0 top */ +#define ORIENTATION_RIGHTTOP 6 /* row 0 rhs, col 0 top */ +#define ORIENTATION_RIGHTBOT 7 /* row 0 rhs, col 0 bottom */ +#define ORIENTATION_LEFTBOT 8 /* row 0 lhs, col 0 bottom */ +#define TIFFTAG_SAMPLESPERPIXEL 277 /* samples per pixel */ +#define TIFFTAG_ROWSPERSTRIP 278 /* rows per strip of data */ +#define TIFFTAG_STRIPBYTECOUNTS 279 /* bytes counts for strips */ +#define TIFFTAG_MINSAMPLEVALUE 280 /* +minimum sample value */ +#define TIFFTAG_MAXSAMPLEVALUE 281 /* +maximum sample value */ +#define TIFFTAG_XRESOLUTION 282 /* pixels/resolution in x */ +#define TIFFTAG_YRESOLUTION 283 /* pixels/resolution in y */ +#define TIFFTAG_PLANARCONFIG 284 /* storage organization */ +#define PLANARCONFIG_CONTIG 1 /* single image plane */ +#define PLANARCONFIG_SEPARATE 2 /* separate planes of data */ +#define TIFFTAG_PAGENAME 285 /* page name image is from */ +#define TIFFTAG_XPOSITION 286 /* x page offset of image lhs */ +#define TIFFTAG_YPOSITION 287 /* y page offset of image lhs */ +#define TIFFTAG_FREEOFFSETS 288 /* +byte offset to free block */ +#define TIFFTAG_FREEBYTECOUNTS 289 /* +sizes of free blocks */ +#define TIFFTAG_GRAYRESPONSEUNIT 290 /* $gray scale curve accuracy */ +#define GRAYRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define GRAYRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define GRAYRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define GRAYRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define GRAYRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_GRAYRESPONSECURVE 291 /* $gray scale response curve */ +#define TIFFTAG_GROUP3OPTIONS 292 /* 32 flag bits */ +#define GROUP3OPT_2DENCODING 0x1 /* 2-dimensional coding */ +#define GROUP3OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define GROUP3OPT_FILLBITS 0x4 /* fill to byte boundary */ +#define TIFFTAG_GROUP4OPTIONS 293 /* 32 flag bits */ +#define GROUP4OPT_UNCOMPRESSED 0x2 /* data not compressed */ +#define TIFFTAG_RESOLUTIONUNIT 296 /* units of resolutions */ +#define RESUNIT_NONE 1 /* no meaningful units */ +#define RESUNIT_INCH 2 /* english */ +#define RESUNIT_CENTIMETER 3 /* metric */ +#define TIFFTAG_PAGENUMBER 297 /* page numbers of multi-page */ +#define TIFFTAG_COLORRESPONSEUNIT 300 /* $color curve accuracy */ +#define COLORRESPONSEUNIT_10S 1 /* tenths of a unit */ +#define COLORRESPONSEUNIT_100S 2 /* hundredths of a unit */ +#define COLORRESPONSEUNIT_1000S 3 /* thousandths of a unit */ +#define COLORRESPONSEUNIT_10000S 4 /* ten-thousandths of a unit */ +#define COLORRESPONSEUNIT_100000S 5 /* hundred-thousandths */ +#define TIFFTAG_TRANSFERFUNCTION 301 /* !colorimetry info */ +#define TIFFTAG_SOFTWARE 305 /* name & release */ +#define TIFFTAG_DATETIME 306 /* creation date and time */ +#define TIFFTAG_ARTIST 315 /* creator of image */ +#define TIFFTAG_HOSTCOMPUTER 316 /* machine where created */ +#define TIFFTAG_PREDICTOR 317 /* prediction scheme w/ LZW */ +#define TIFFTAG_WHITEPOINT 318 /* image white point */ +#define TIFFTAG_PRIMARYCHROMATICITIES 319 /* !primary chromaticities */ +#define TIFFTAG_COLORMAP 320 /* RGB map for pallette image */ +#define TIFFTAG_HALFTONEHINTS 321 /* !highlight+shadow info */ +#define TIFFTAG_TILEWIDTH 322 /* !rows/data tile */ +#define TIFFTAG_TILELENGTH 323 /* !cols/data tile */ +#define TIFFTAG_TILEOFFSETS 324 /* !offsets to data tiles */ +#define TIFFTAG_TILEBYTECOUNTS 325 /* !byte counts for tiles */ +#define TIFFTAG_BADFAXLINES 326 /* lines w/ wrong pixel count */ +#define TIFFTAG_CLEANFAXDATA 327 /* regenerated line info */ +#define CLEANFAXDATA_CLEAN 0 /* no errors detected */ +#define CLEANFAXDATA_REGENERATED 1 /* receiver regenerated lines */ +#define CLEANFAXDATA_UNCLEAN 2 /* uncorrected errors exist */ +#define TIFFTAG_CONSECUTIVEBADFAXLINES 328 /* max consecutive bad lines */ +#define TIFFTAG_SUBIFD 330 /* subimage descriptors */ +#define TIFFTAG_INKSET 332 /* !inks in separated image */ +#define INKSET_CMYK 1 /* !cyan-magenta-yellow-black */ +#define TIFFTAG_INKNAMES 333 /* !ascii names of inks */ +#define TIFFTAG_NUMBEROFINKS 334 /* !number of inks */ +#define TIFFTAG_DOTRANGE 336 /* !0% and 100% dot codes */ +#define TIFFTAG_TARGETPRINTER 337 /* !separation target */ +#define TIFFTAG_EXTRASAMPLES 338 /* !info about extra samples */ +#define EXTRASAMPLE_UNSPECIFIED 0 /* !unspecified data */ +#define EXTRASAMPLE_ASSOCALPHA 1 /* !associated alpha data */ +#define EXTRASAMPLE_UNASSALPHA 2 /* !unassociated alpha data */ +#define TIFFTAG_SAMPLEFORMAT 339 /* !data sample format */ +#define SAMPLEFORMAT_UINT 1 /* !unsigned integer data */ +#define SAMPLEFORMAT_INT 2 /* !signed integer data */ +#define SAMPLEFORMAT_IEEEFP 3 /* !IEEE floating point data */ +#define SAMPLEFORMAT_VOID 4 /* !untyped data */ +#define TIFFTAG_SMINSAMPLEVALUE 340 /* !variable MinSampleValue */ +#define TIFFTAG_SMAXSAMPLEVALUE 341 /* !variable MaxSampleValue */ +#define TIFFTAG_JPEGTABLES 347 /* %JPEG table stream */ +/* + * Tags 512-521 are obsoleted by Technical Note #2 + * which specifies a revised JPEG-in-TIFF scheme. + */ +#define TIFFTAG_JPEGPROC 512 /* !JPEG processing algorithm */ +#define JPEGPROC_BASELINE 1 /* !baseline sequential */ +#define JPEGPROC_LOSSLESS 14 /* !Huffman coded lossless */ +#define TIFFTAG_JPEGIFOFFSET 513 /* !pointer to SOI marker */ +#define TIFFTAG_JPEGIFBYTECOUNT 514 /* !JFIF stream length */ +#define TIFFTAG_JPEGRESTARTINTERVAL 515 /* !restart interval length */ +#define TIFFTAG_JPEGLOSSLESSPREDICTORS 517 /* !lossless proc predictor */ +#define TIFFTAG_JPEGPOINTTRANSFORM 518 /* !lossless point transform */ +#define TIFFTAG_JPEGQTABLES 519 /* !Q matrice offsets */ +#define TIFFTAG_JPEGDCTABLES 520 /* !DCT table offsets */ +#define TIFFTAG_JPEGACTABLES 521 /* !AC coefficient offsets */ +#define TIFFTAG_YCBCRCOEFFICIENTS 529 /* !RGB -> YCbCr transform */ +#define TIFFTAG_YCBCRSUBSAMPLING 530 /* !YCbCr subsampling factors */ +#define TIFFTAG_YCBCRPOSITIONING 531 /* !subsample positioning */ +#define YCBCRPOSITION_CENTERED 1 /* !as in PostScript Level 2 */ +#define YCBCRPOSITION_COSITED 2 /* !as in CCIR 601-1 */ +#define TIFFTAG_REFERENCEBLACKWHITE 532 /* !colorimetry info */ +/* tags 32952-32956 are private tags registered to Island Graphics */ +#define TIFFTAG_REFPTS 32953 /* image reference points */ +#define TIFFTAG_REGIONTACKPOINT 32954 /* region-xform tack point */ +#define TIFFTAG_REGIONWARPCORNERS 32955 /* warp quadrilateral */ +#define TIFFTAG_REGIONAFFINE 32956 /* affine transformation mat */ +/* tags 32995-32999 are private tags registered to SGI */ +#define TIFFTAG_MATTEING 32995 /* $use ExtraSamples */ +#define TIFFTAG_DATATYPE 32996 /* $use SampleFormat */ +#define TIFFTAG_IMAGEDEPTH 32997 /* z depth of image */ +#define TIFFTAG_TILEDEPTH 32998 /* z depth/data tile */ +/* tags 33300-33309 are private tags registered to Pixar */ +/* + * TIFFTAG_PIXAR_IMAGEFULLWIDTH and TIFFTAG_PIXAR_IMAGEFULLLENGTH + * are set when an image has been cropped out of a larger image. + * They reflect the size of the original uncropped image. + * The TIFFTAG_XPOSITION and TIFFTAG_YPOSITION can be used + * to determine the position of the smaller image in the larger one. + */ +#define TIFFTAG_PIXAR_IMAGEFULLWIDTH 33300 /* full image size in x */ +#define TIFFTAG_PIXAR_IMAGEFULLLENGTH 33301 /* full image size in y */ + /* Tags 33302-33306 are used to identify special image modes and data + * used by Pixar's texture formats. + */ +#define TIFFTAG_PIXAR_TEXTUREFORMAT 33302 /* texture map format */ +#define TIFFTAG_PIXAR_WRAPMODES 33303 /* s & t wrap modes */ +#define TIFFTAG_PIXAR_FOVCOT 33304 /* cotan(fov) for env. maps */ +#define TIFFTAG_PIXAR_MATRIX_WORLDTOSCREEN 33305 +#define TIFFTAG_PIXAR_MATRIX_WORLDTOCAMERA 33306 +/* tag 33405 is a private tag registered to Eastman Kodak */ +#define TIFFTAG_WRITERSERIALNUMBER 33405 /* device serial number */ +/* tag 33432 is listed in the 6.0 spec w/ unknown ownership */ +#define TIFFTAG_COPYRIGHT 33432 /* copyright string */ +/* IPTC TAG from RichTIFF specifications */ +#define TIFFTAG_RICHTIFFIPTC 33723 +/* 34016-34029 are reserved for ANSI IT8 TIFF/IT <dkelly@etsinc.com) */ +#define TIFFTAG_IT8SITE 34016 /* site name */ +#define TIFFTAG_IT8COLORSEQUENCE 34017 /* color seq. [RGB,CMYK,etc] */ +#define TIFFTAG_IT8HEADER 34018 /* DDES Header */ +#define TIFFTAG_IT8RASTERPADDING 34019 /* raster scanline padding */ +#define TIFFTAG_IT8BITSPERRUNLENGTH 34020 /* # of bits in short run */ +#define TIFFTAG_IT8BITSPEREXTENDEDRUNLENGTH 34021/* # of bits in long run */ +#define TIFFTAG_IT8COLORTABLE 34022 /* LW colortable */ +#define TIFFTAG_IT8IMAGECOLORINDICATOR 34023 /* BP/BL image color switch */ +#define TIFFTAG_IT8BKGCOLORINDICATOR 34024 /* BP/BL bg color switch */ +#define TIFFTAG_IT8IMAGECOLORVALUE 34025 /* BP/BL image color value */ +#define TIFFTAG_IT8BKGCOLORVALUE 34026 /* BP/BL bg color value */ +#define TIFFTAG_IT8PIXELINTENSITYRANGE 34027 /* MP pixel intensity value */ +#define TIFFTAG_IT8TRANSPARENCYINDICATOR 34028 /* HC transparency switch */ +#define TIFFTAG_IT8COLORCHARACTERIZATION 34029 /* color character. table */ +/* tags 34232-34236 are private tags registered to Texas Instruments */ +#define TIFFTAG_FRAMECOUNT 34232 /* Sequence Frame Count */ +/* tag 34750 is a private tag registered to Adobe? */ +#define TIFFTAG_ICCPROFILE 34675 /* ICC profile data */ +/* tag 34377 is private tag registered to Adobe for PhotoShop */ +#define TIFFTAG_PHOTOSHOP 34377 +/* tag 34750 is a private tag registered to Pixel Magic */ +#define TIFFTAG_JBIGOPTIONS 34750 /* JBIG options */ +/* tags 34908-34914 are private tags registered to SGI */ +#define TIFFTAG_FAXRECVPARAMS 34908 /* encoded Class 2 ses. parms */ +#define TIFFTAG_FAXSUBADDRESS 34909 /* received SubAddr string */ +#define TIFFTAG_FAXRECVTIME 34910 /* receive time (secs) */ +/* tags 37439-37443 are registered to SGI <gregl@sgi.com> */ +#define TIFFTAG_STONITS 37439 /* Sample value to Nits */ +/* tag 34929 is a private tag registered to FedEx */ +#define TIFFTAG_FEDEX_EDR 34929 /* unknown use */ +/* tag 65535 is an undefined tag used by Eastman Kodak */ +#define TIFFTAG_DCSHUESHIFTVALUES 65535 /* hue shift correction data */ + +/* + * The following are ``pseudo tags'' that can be + * used to control codec-specific functionality. + * These tags are not written to file. Note that + * these values start at 0xffff+1 so that they'll + * never collide with Aldus-assigned tags. + * + * If you want your private pseudo tags ``registered'' + * (i.e. added to this file), send mail to sam@sgi.com + * with the appropriate C definitions to add. + */ +#define TIFFTAG_FAXMODE 65536 /* Group 3/4 format control */ +#define FAXMODE_CLASSIC 0x0000 /* default, include RTC */ +#define FAXMODE_NORTC 0x0001 /* no RTC at end of data */ +#define FAXMODE_NOEOL 0x0002 /* no EOL code at end of row */ +#define FAXMODE_BYTEALIGN 0x0004 /* byte align row */ +#define FAXMODE_WORDALIGN 0x0008 /* word align row */ +#define FAXMODE_CLASSF FAXMODE_NORTC /* TIFF Class F */ +#define TIFFTAG_JPEGQUALITY 65537 /* Compression quality level */ +/* Note: quality level is on the IJG 0-100 scale. Default value is 75 */ +#define TIFFTAG_JPEGCOLORMODE 65538 /* Auto RGB<=>YCbCr convert? */ +#define JPEGCOLORMODE_RAW 0x0000 /* no conversion (default) */ +#define JPEGCOLORMODE_RGB 0x0001 /* do auto conversion */ +#define TIFFTAG_JPEGTABLESMODE 65539 /* What to put in JPEGTables */ +#define JPEGTABLESMODE_QUANT 0x0001 /* include quantization tbls */ +#define JPEGTABLESMODE_HUFF 0x0002 /* include Huffman tbls */ +/* Note: default is JPEGTABLESMODE_QUANT | JPEGTABLESMODE_HUFF */ +#define TIFFTAG_FAXFILLFUNC 65540 /* G3/G4 fill function */ +#define TIFFTAG_PIXARLOGDATAFMT 65549 /* PixarLogCodec I/O data sz */ +#define PIXARLOGDATAFMT_8BIT 0 /* regular u_char samples */ +#define PIXARLOGDATAFMT_8BITABGR 1 /* ABGR-order u_chars */ +#define PIXARLOGDATAFMT_11BITLOG 2 /* 11-bit log-encoded (raw) */ +#define PIXARLOGDATAFMT_12BITPICIO 3 /* as per PICIO (1.0==2048) */ +#define PIXARLOGDATAFMT_16BIT 4 /* signed short samples */ +#define PIXARLOGDATAFMT_FLOAT 5 /* IEEE float samples */ +/* 65550-65556 are allocated to Oceana Matrix <dev@oceana.com> */ +#define TIFFTAG_DCSIMAGERTYPE 65550 /* imager model & filter */ +#define DCSIMAGERMODEL_M3 0 /* M3 chip (1280 x 1024) */ +#define DCSIMAGERMODEL_M5 1 /* M5 chip (1536 x 1024) */ +#define DCSIMAGERMODEL_M6 2 /* M6 chip (3072 x 2048) */ +#define DCSIMAGERFILTER_IR 0 /* infrared filter */ +#define DCSIMAGERFILTER_MONO 1 /* monochrome filter */ +#define DCSIMAGERFILTER_CFA 2 /* color filter array */ +#define DCSIMAGERFILTER_OTHER 3 /* other filter */ +#define TIFFTAG_DCSINTERPMODE 65551 /* interpolation mode */ +#define DCSINTERPMODE_NORMAL 0x0 /* whole image, default */ +#define DCSINTERPMODE_PREVIEW 0x1 /* preview of image (384x256) */ +#define TIFFTAG_DCSBALANCEARRAY 65552 /* color balance values */ +#define TIFFTAG_DCSCORRECTMATRIX 65553 /* color correction values */ +#define TIFFTAG_DCSGAMMA 65554 /* gamma value */ +#define TIFFTAG_DCSTOESHOULDERPTS 65555 /* toe & shoulder points */ +#define TIFFTAG_DCSCALIBRATIONFD 65556 /* calibration file desc */ +/* Note: quality level is on the ZLIB 1-9 scale. Default value is -1 */ +#define TIFFTAG_ZIPQUALITY 65557 /* compression quality level */ +#define TIFFTAG_PIXARLOGQUALITY 65558 /* PixarLog uses same scale */ +/* 65559 is allocated to Oceana Matrix <dev@oceana.com> */ +#define TIFFTAG_DCSCLIPRECTANGLE 65559 /* area of image to acquire */ +#define TIFFTAG_SGILOGDATAFMT 65560 /* SGILog user data format */ +#define SGILOGDATAFMT_FLOAT 0 /* IEEE float samples */ +#define SGILOGDATAFMT_16BIT 1 /* 16-bit samples */ +#define SGILOGDATAFMT_RAW 2 /* uninterpreted data */ +#define SGILOGDATAFMT_8BIT 3 /* 8-bit RGB monitor values */ +#endif /* _TIFF_ */ \ No newline at end of file diff --git a/include/tiffio.h b/include/tiffio.h new file mode 100755 index 0000000..065c0fd --- /dev/null +++ b/include/tiffio.h @@ -0,0 +1,314 @@ +/* + * Copyright (c) 1988-1997 Sam Leffler + * Copyright (c) 1991-1997 Silicon Graphics, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that (i) the above copyright notices and this permission notice appear in + * all copies of the software and related documentation, and (ii) the names of + * Sam Leffler and Silicon Graphics may not be used in any advertising or + * publicity relating to the software without the specific, prior written + * permission of Sam Leffler and Silicon Graphics. + * + * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, + * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY + * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR + * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, + * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE + * OF THIS SOFTWARE. + */ + +#ifndef _TIFFIO_ +#define _TIFFIO_ + +/* + * TIFF I/O Library Definitions. + */ +#include "tiff.h" + +/* + * This define can be used in code that requires + * compilation-related definitions specific to a + * version or versions of the library. Runtime + * version checking should be done based on the + * string returned by TIFFGetVersion. + */ +#define TIFFLIB_VERSION 19970127 /* January 27, 1997 */ + +/* + * TIFF is defined as an incomplete type to hide the + * library's internal data structures from clients. + */ +typedef struct tiff TIFF; + +/* + * The following typedefs define the intrinsic size of + * data types used in the *exported* interfaces. These + * definitions depend on the proper definition of types + * in tiff.h. Note also that the varargs interface used + * to pass tag types and values uses the types defined in + * tiff.h directly. + * + * NB: ttag_t is unsigned int and not unsigned short because + * ANSI C requires that the type before the ellipsis be a + * promoted type (i.e. one of int, unsigned int, pointer, + * or double) and because we defined pseudo-tags that are + * outside the range of legal Aldus-assigned tags. + * NB: tsize_t is int32 and not uint32 because some functions + * return -1. + * NB: toff_t is not off_t for many reasons; TIFFs max out at + * 32-bit file offsets being the most important + */ +typedef uint32 ttag_t; /* directory tag */ +typedef uint16 tdir_t; /* directory index */ +typedef uint16 tsample_t; /* sample number */ +typedef uint32 tstrip_t; /* strip number */ +typedef uint32 ttile_t; /* tile number */ +typedef int32 tsize_t; /* i/o size in bytes */ +typedef void* tdata_t; /* image data ref */ +typedef int32 toff_t; /* file offset */ + +#if !defined(__WIN32__) && (defined(_WIN32) || defined(WIN32)) +#define __WIN32__ +#endif +#if defined(_WINDOWS) || defined(__WIN32__) || defined(_Windows) +#include +#ifdef __WIN32__ +DECLARE_HANDLE(thandle_t); /* Win32 file handle */ +#else +typedef HFILE thandle_t; /* client data handle */ +#endif +#else +typedef void* thandle_t; /* client data handle */ +#endif + +#ifndef NULL +#define NULL 0 +#endif + +/* + * Flags to pass to TIFFPrintDirectory to control + * printing of data structures that are potentially + * very large. Bit-or these flags to enable printing + * multiple items. + */ +#define TIFFPRINT_NONE 0x0 /* no extra info */ +#define TIFFPRINT_STRIPS 0x1 /* strips/tiles info */ +#define TIFFPRINT_CURVES 0x2 /* color/gray response curves */ +#define TIFFPRINT_COLORMAP 0x4 /* colormap */ +#define TIFFPRINT_JPEGQTABLES 0x100 /* JPEG Q matrices */ +#define TIFFPRINT_JPEGACTABLES 0x200 /* JPEG AC tables */ +#define TIFFPRINT_JPEGDCTABLES 0x200 /* JPEG DC tables */ + +/* + * RGBA-style image support. + */ +typedef unsigned char TIFFRGBValue; /* 8-bit samples */ +typedef struct _TIFFRGBAImage TIFFRGBAImage; +/* + * The image reading and conversion routines invoke + * ``put routines'' to copy/image/whatever tiles of + * raw image data. A default set of routines are + * provided to convert/copy raw image data to 8-bit + * packed ABGR format rasters. Applications can supply + * alternate routines that unpack the data into a + * different format or, for example, unpack the data + * and draw the unpacked raster on the display. + */ +typedef void (*tileContigRoutine) + (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, + unsigned char*); +typedef void (*tileSeparateRoutine) + (TIFFRGBAImage*, uint32*, uint32, uint32, uint32, uint32, int32, int32, + unsigned char*, unsigned char*, unsigned char*, unsigned char*); +/* + * RGBA-reader state. + */ +typedef struct { /* YCbCr->RGB support */ + TIFFRGBValue* clamptab; /* range clamping table */ + int* Cr_r_tab; + int* Cb_b_tab; + int32* Cr_g_tab; + int32* Cb_g_tab; + float coeffs[3]; /* cached for repeated use */ +} TIFFYCbCrToRGB; + +struct _TIFFRGBAImage { + TIFF* tif; /* image handle */ + int stoponerr; /* stop on read error */ + int isContig; /* data is packed/separate */ + int alpha; /* type of alpha data present */ + uint32 width; /* image width */ + uint32 height; /* image height */ + uint16 bitspersample; /* image bits/sample */ + uint16 samplesperpixel; /* image samples/pixel */ + uint16 orientation; /* image orientation */ + uint16 photometric; /* image photometric interp */ + uint16* redcmap; /* colormap pallete */ + uint16* greencmap; + uint16* bluecmap; + /* get image data routine */ + int (*get)(TIFFRGBAImage*, uint32*, uint32, uint32); + union { + void (*any)(TIFFRGBAImage*); + tileContigRoutine contig; + tileSeparateRoutine separate; + } put; /* put decoded strip/tile */ + TIFFRGBValue* Map; /* sample mapping array */ + uint32** BWmap; /* black&white map */ + uint32** PALmap; /* palette image map */ + TIFFYCbCrToRGB* ycbcr; /* YCbCr conversion state */ +}; + +/* + * Macros for extracting components from the + * packed ABGR form returned by TIFFReadRGBAImage. + */ +#define TIFFGetR(abgr) ((abgr) & 0xff) +#define TIFFGetG(abgr) (((abgr) >> 8) & 0xff) +#define TIFFGetB(abgr) (((abgr) >> 16) & 0xff) +#define TIFFGetA(abgr) (((abgr) >> 24) & 0xff) + +/* + * A CODEC is a software package that implements decoding, + * encoding, or decoding+encoding of a compression algorithm. + * The library provides a collection of builtin codecs. + * More codecs may be registered through calls to the library + * and/or the builtin implementations may be overridden. + */ +typedef int (*TIFFInitMethod)(TIFF*, int); +typedef struct { + char* name; + uint16 scheme; + TIFFInitMethod init; +} TIFFCodec; + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif +typedef void (*TIFFErrorHandler)(const char*, const char*, va_list); +typedef tsize_t (*TIFFReadWriteProc)(thandle_t, tdata_t, tsize_t); +typedef toff_t (*TIFFSeekProc)(thandle_t, toff_t, int); +typedef int (*TIFFCloseProc)(thandle_t); +typedef toff_t (*TIFFSizeProc)(thandle_t); +typedef int (*TIFFMapFileProc)(thandle_t, tdata_t*, toff_t*); +typedef void (*TIFFUnmapFileProc)(thandle_t, tdata_t, toff_t); +typedef void (*TIFFExtendProc)(TIFF*); + +extern const char* TIFFGetVersion(void); + +extern const TIFFCodec* TIFFFindCODEC(uint16); +extern TIFFCodec* TIFFRegisterCODEC(uint16, const char*, TIFFInitMethod); +extern void TIFFUnRegisterCODEC(TIFFCodec*); + +extern tdata_t _TIFFmalloc(tsize_t); +extern tdata_t _TIFFrealloc(tdata_t, tsize_t); +extern void _TIFFmemset(tdata_t, int, tsize_t); +extern void _TIFFmemcpy(tdata_t, const tdata_t, tsize_t); +extern int _TIFFmemcmp(const tdata_t, const tdata_t, tsize_t); +extern void _TIFFfree(tdata_t); + +extern void TIFFClose(TIFF*); +extern int TIFFFlush(TIFF*); +extern int TIFFFlushData(TIFF*); +extern int TIFFGetField(TIFF*, ttag_t, ...); +extern int TIFFVGetField(TIFF*, ttag_t, va_list); +extern int TIFFGetFieldDefaulted(TIFF*, ttag_t, ...); +extern int TIFFVGetFieldDefaulted(TIFF*, ttag_t, va_list); +extern int TIFFReadDirectory(TIFF*); +extern tsize_t TIFFScanlineSize(TIFF*); +extern tsize_t TIFFRasterScanlineSize(TIFF*); +extern tsize_t TIFFStripSize(TIFF*); +extern tsize_t TIFFVStripSize(TIFF*, uint32); +extern tsize_t TIFFTileRowSize(TIFF*); +extern tsize_t TIFFTileSize(TIFF*); +extern tsize_t TIFFVTileSize(TIFF*, uint32); +extern uint32 TIFFDefaultStripSize(TIFF*, uint32); +extern void TIFFDefaultTileSize(TIFF*, uint32*, uint32*); +extern int TIFFFileno(TIFF*); +extern int TIFFGetMode(TIFF*); +extern int TIFFIsTiled(TIFF*); +extern int TIFFIsByteSwapped(TIFF*); +extern int TIFFIsUpSampled(TIFF*); +extern int TIFFIsMSB2LSB(TIFF*); +extern uint32 TIFFCurrentRow(TIFF*); +extern tdir_t TIFFCurrentDirectory(TIFF*); +extern tdir_t TIFFNumberOfDirectories(TIFF*); +extern uint32 TIFFCurrentDirOffset(TIFF*); +extern tstrip_t TIFFCurrentStrip(TIFF*); +extern ttile_t TIFFCurrentTile(TIFF*); +extern int TIFFReadBufferSetup(TIFF*, tdata_t, tsize_t); +extern int TIFFWriteBufferSetup(TIFF*, tdata_t, tsize_t); +extern int TIFFLastDirectory(TIFF*); +extern int TIFFSetDirectory(TIFF*, tdir_t); +extern int TIFFSetSubDirectory(TIFF*, uint32); +extern int TIFFUnlinkDirectory(TIFF*, tdir_t); +extern int TIFFSetField(TIFF*, ttag_t, ...); +extern int TIFFVSetField(TIFF*, ttag_t, va_list); +extern int TIFFWriteDirectory(TIFF *); +#if defined(c_plusplus) || defined(__cplusplus) +extern void TIFFPrintDirectory(TIFF*, FILE*, long = 0); +extern int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t = 0); +extern int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t = 0); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int = 0); +#else +extern void TIFFPrintDirectory(TIFF*, FILE*, long); +extern int TIFFReadScanline(TIFF*, tdata_t, uint32, tsample_t); +extern int TIFFWriteScanline(TIFF*, tdata_t, uint32, tsample_t); +extern int TIFFReadRGBAImage(TIFF*, uint32, uint32, uint32*, int); +#endif +extern int TIFFRGBAImageOK(TIFF*, char [1024]); +extern int TIFFRGBAImageBegin(TIFFRGBAImage*, TIFF*, int, char [1024]); +extern int TIFFRGBAImageGet(TIFFRGBAImage*, uint32*, uint32, uint32); +extern void TIFFRGBAImageEnd(TIFFRGBAImage*); +extern TIFF* TIFFOpen(const char*, const char*); +extern TIFF* TIFFFdOpen(int, const char*, const char*); +extern TIFF* TIFFClientOpen(const char*, const char*, + thandle_t, + TIFFReadWriteProc, TIFFReadWriteProc, + TIFFSeekProc, TIFFCloseProc, + TIFFSizeProc, + TIFFMapFileProc, TIFFUnmapFileProc); +extern const char* TIFFFileName(TIFF*); +extern void TIFFError(const char*, const char*, ...); +extern void TIFFWarning(const char*, const char*, ...); +extern TIFFErrorHandler TIFFSetErrorHandler(TIFFErrorHandler); +extern TIFFErrorHandler TIFFSetWarningHandler(TIFFErrorHandler); +extern TIFFExtendProc TIFFSetTagExtender(TIFFExtendProc); +extern ttile_t TIFFComputeTile(TIFF*, uint32, uint32, uint32, tsample_t); +extern int TIFFCheckTile(TIFF*, uint32, uint32, uint32, tsample_t); +extern ttile_t TIFFNumberOfTiles(TIFF*); +extern tsize_t TIFFReadTile(TIFF*, + tdata_t, uint32, uint32, uint32, tsample_t); +extern tsize_t TIFFWriteTile(TIFF*, + tdata_t, uint32, uint32, uint32, tsample_t); +extern tstrip_t TIFFComputeStrip(TIFF*, uint32, tsample_t); +extern tstrip_t TIFFNumberOfStrips(TIFF*); +extern tsize_t TIFFReadEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFReadRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFReadEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFReadRawTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteEncodedStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteRawStrip(TIFF*, tstrip_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteEncodedTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern tsize_t TIFFWriteRawTile(TIFF*, ttile_t, tdata_t, tsize_t); +extern void TIFFSetWriteOffset(TIFF*, toff_t); +extern void TIFFSwabShort(uint16*); +extern void TIFFSwabLong(uint32*); +extern void TIFFSwabDouble(double*); +extern void TIFFSwabArrayOfShort(uint16*, unsigned long); +extern void TIFFSwabArrayOfLong(uint32*, unsigned long); +extern void TIFFSwabArrayOfDouble(double*, unsigned long); +extern void TIFFReverseBits(unsigned char *, unsigned long); +extern const unsigned char* TIFFGetBitRevTable(int); +#if defined(__cplusplus) +} +#endif +#endif /* _TIFFIO_ */ \ No newline at end of file diff --git a/include/vetoPixels.c b/include/vetoPixels.c new file mode 100644 index 0000000..3ab59a7 --- /dev/null +++ b/include/vetoPixels.c @@ -0,0 +1,3429 @@ +#ifndef _vetoPixels_included_ +#define _vetoPixels_included_ + +// +// The functions below identify bad pixels. +// The functions return 1 if the pixel is bad, +// 0 if it can be used for further analysis. +// +// The GlobalTool class has a function vetoPixel which points to the desired +// following function according to the value of the field "NoiseRun" in the +// config file. The matching between the run number and the function is done +// with the SetVetoFunction method. +// +// The user can define its own function below and shall also set the proper +// matchin in the SetVetoFunction method. +// BEWARE chipNb IS THE INPUT NOT THE PLANE INDEX! +// +// +// Mechanism setup on 2012/03/11 + +// ----------------------------------------------------------------------------- + +bool vetoPixel_IPNLtelescopeV01( int chipNb, int row, int col) //26166 +{ + // Noisy pixels filtering, called with NoiseRun = 26166 + // IPNL telescope configuration, + // DESY, march 2011 + // GANIL, July 2011 + + // GANIL 07.2012, RSB 8, 0.1% over 10.000 evnts (run26166 ) + + // Plane: 1 2 3 4 5 6 7 8 + // Input: 5 3 1 7 6 4 2 8 = chipNb+1 + + // List updated by VRe on March 14th 2012 + + return + (chipNb==4 && row==43 && col==200) + || (chipNb==2 && row==338 && 162837 && col<843) + || (chipNb==0 && row==535 && col==485) + || (chipNb==6 && row==512 && col==119) + || (chipNb==5 && row==253 && 99835 && col<845) + || (chipNb==0 && row==251 && col==14) + || (chipNb==0 && row==308 && col==1032) + || (chipNb==0 && row==237 && col==959) + || (chipNb==0 && row==62 && col==170) + || (chipNb==0 && row==77 && col==362) + || (chipNb==0 && row==29 && col==446) + || (chipNb==0 && row==535 && col==485) + // Plane 3 OK + || (chipNb==2 && row==338 && 172835 && col<845) +// RUN21 : 100kEv, 0.5%= occur min = 500 + || (chipNb==0 && row==535 && col==485) +// RUN21 : 1MEv, 0.1%= occur min = 1000 + || (chipNb==0 && 412=0 && col<=77) + || (row==423 && col>=0 && col<=300) + || (row==433 && col==843) + || (row==472 && col==817) + || (row==497 && col==683) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 2 ; name = 2Left ; InputNumber = 1 ; ChipNumber = 0 +////////////////////////////////////////// + + || (chipNb==0 && + (0 + //RUN51 + || (row==38 && col==166) + || (row==62 && col==170) + || (row==77 && col==362) + || (row==89 && col==325) + || (row==98 && col==1027) + || (row==101 && col==14) + || (row==115 && col==77) + || (row==121 && col==306) + || (row==124 && col==862) + || (row==155 && col==802) + || (row==161 && col==1035) + || (row==167 && col==1069) + || (row==183 && col==138) + || (row==236 && col==550) + || (row==237 && col==959) + || (row==251 && col==14) + || (row==257 && col==428) + || (row==308 && col==1032) + || (row==312 && col==1141) + || (row==331 && col==1031) + || (row==337 && col==1082) + || (row==344 && col==480) + || (row==369 && col==454) + || (row==371 && col==976) + || (row==394 && col==514) + || (row==411 && col==835) + || (row==417 && col==518) + || (row==419 && col>=824 && col<=827) + || (row==420 && col>=838 && col<=843) + || (row>=412 && row<=429 && col==835) + || (row==428 && col==330) + || (row==429 && col==215) + || (row==431 && col==155) + || (row==462 && col==303) + || (row==468 && col==936) + || (row==480 && col==571) + || (row==505 && col==11) + || (row==513 && col==569) + || (row==516 && col==1010) + || (row==526 && col==113) + || (row==535 && col==485) + || (row==561 && col==379) + || (row==561 && col==1050) + //RUN21 + || (row==137 && col==289) + || (row==302 && col==497) + || (row==385 && col==1006) + || (row==420 && col==844) + || (row==441 && col==898) + || (row==517 && col==167) + || (row==538 && col==310) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 6 ; name = 2Right ; InputNumber = 2 ; ChipNumber = 1 +////////////////////////////////////////// + + || (chipNb==1 && + (0 + //RUN51 + || (row==65 && col==537) + || (row==156 && col==1111) + || (row==296 && col==975) + || (row==342 && col==1023) + || (row==512 && col==899) + //RUN21 + || (row==14 && col==841) + || (row==252 && col==136) + || (row==288 && col==533) + || (row==483 && col==1142) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 3 ; name = 3Left ; InputNumber = 3 ; ChipNumber = 2 +////////////////////////////////////////// + + || (chipNb==2 && + (0 + //RUN51 + || (row==338 && col>=167 && col<=214) + || (row==339 && (col==45 || col==46 || col==264)) + || (row==405 && col==1143) + || (row>=448 && row<=463 && col==233) + || (row==486 && col==1033) + || (row==565 && col==1092) + || (row==566 && col==943) + || (row==572 && col==994) + //RUN21 + || (row==421 && col==1116) + || (row==460 && col==1037) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 7 ; name = 3Right ; InputNumber = 4 ; ChipNumber = 3 +////////////////////////////////////////// + + || (chipNb==3 && + (0 + //RUN51 + || (row==39 && col==1147) + || (row==54 && col==423) + || (row==91 && col==1094) + || (row==117 && col==994) + || (row==141 && col==1026) + || (row==214 && col==1035) + || (row==263 && col==511) + || (row==314 && col==808) + || (row==314 && col==811) + || (row==314 && col==815) + || (row==315 && col==816) + || (row==319 && col>=819 && col<= 824) + || (row==321 && col==818) + || (row==323 && col==818) + || (row==368 && col==977) + || (row==471 && col==911) + || (row==474 && col==1061) + //RUN21 + || (row==102 && col==397) + || (row==156 && col==881) + || (row==271 && col==969) + || (row==295 && col==949) + + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 4 ; name = 4Left ; InputNumber = 5 ; ChipNumber = 4 +////////////////////////////////////////// + + || (chipNb==4 && + (0 + //RUN51 + || (row==23 && col==1091) + || (row==38 && col==899) + || (row==43 && col==200) + || (row==50 && col==1006) + || (row==51 && col==242) + || (row==56 && col==51) + || (row==57 && col==1138) + || (row==69 && col==914) + || (row==74 && col==969) + || (row==75 && col==1107) + || (row==100 && col==1040) + || (row==108 && col==1018) + || (row==141 && col==799) + || (row==147 && col==121) + || (row==152 && col==948) + || (row==180 && col==291) + || (row==190 && col==947) + || (row==219 && col==1012) + || (row==220 && col==827) + || (row==228 && col==502) + || (row==245 && col==213) + || (row==248 && col==1006) + || (row==268 && col==65) + || (row==299 && col==1016) + || (row==331 && col==927) + || (row==334 && col==1095) + || (row==335 && col==1024) + || (row==376 && col==498) + || (row==378 && col==396) + || (row==393 && col==570) + || (row==404 && col==1005) + || (row==565 && col==877) + //RUN21 + || (row==107 && col==348) + || (row==141 && col==473) + || (row==257 && col==300) + || (row==260 && col==496) + || (row==564 && col==879) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 8 ; name = 4Right ; InputNumber = 6 ; ChipNumber = 5 +////////////////////////////////////////// + + || (chipNb==5 && + (0 + //RUN51 + || (row==45 && col==110) + || (row==253 && col>=225 && col <=330) + || (row==254 && col>=0 && col <=253) + || (row==431 && col==102) + || (row==471 && col==42) + || (row==507 && col==643) + //RUN21 + || (row==253 && col>=205 && col<= 225) + )) + +////////////////////////////////////////// + + ; +} + +bool vetoPixel_IPNLtelescopeV05 ( int chipNb, int row, int col) //26170 +{ +/////////////////////////////////////////////////// +// Veto Pixels List Code // +// Generated with MRax::GenerateVetoPixelsCode() // +/////////////////////////////////////////////////// +// Generated on 15/8/2014 at 0:25:49 +// * RUN: 53 +// * Events cumulated: 1000000 +// * Absolute threshold: 100 +// * Relative threshold: 1.000e-04 +/////////////////////////////////////////////////// + // Noisy pixels filtering, called with NoiseRun = 26170 + // IPNL telescope configuration, + // List made on 2014.08.15 for GSI-08/2012 with RUN 53 (IVI) with RSB=6 +/////////////////////////////////////////////////// +// !!!!!!!!!!!!!!!! +// Planes 1Left and 1Right are using the same veto as vetoPixel_IPNLtelescopeV04, because to much noise ! + + + return + 0 +////////////////////////////////////////// +// Plane 1 ; name = 1Left ; InputNumber = 7 ; ChipNumber = 6 +// * Relative threshold: 1.000e-02 for 1L + 1R RSB8 +////////////////////////////////////////// + + || (chipNb==6 && + (0 + || (row==23 && col==1033) + || (row==51 && col==210) + || (row==76 && col==54) + || (row==91 && col==18) + || (row==152 && col==94) + || (row==166 && col==38) + || (row==179 && col==892) + || (row==200 && col==211) + || (row==213 && col==1057) + || (row==227 && col==983) + || (row==241 && col==546) + || (row==252 && col==284) + || (row==257 && col==1028) + || (row==257 && col==1080) + || (row==259 && col==142) + || (row==259 && col==1081) + || (row==278 && col==123) + || (row==306 && col==100) + || (row==325 && col==260) + || (row==327 && col==480) + || (row==333 && col==68) + || (row==372 && col==331) + || (row==395 && col==381) + || (row==401 && col==486) + || (row==411 && col==517) + || (row==414 && col==230) + || (row==433 && col==977) + || (row==485 && col==1147) + || (row==512 && col==119) + || (row==526 && col==994) + || (row==547 && col==1030) + || (row==553 && col==1037) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 5 ; name = 1Right ; InputNumber = 8 ; ChipNumber = 7 +// * Relative threshold: 1.000e-02 for 1L + 1R RSB8 +////////////////////////////////////////// + + || (chipNb==7 && + (0 + || (row==46 && col==188) + || (row==50 && col==421) + || (row==61 && col==652) + || (row==69 && col==698) + || (row==69 && col==934) + || (row==93 && col==1071) + || (row==113 && col==52) + || (row==132 && col==11) + || (row==161 && col==1143) + || (row==173 && col==1022) + || (row==185 && col==846) + || (row==277 && col==1042) + || (row==293 && col==879) + || (row==317 && col==1133) + || (row==354 && col==16) + || (row==392 && col==1121) + || (row==412 && col==506) + || (row==422 && col>=0 && col<=77) + || (row==423 && col>=0 && col<=300) + || (row==433 && col==843) + || (row==472 && col==817) + || (row==497 && col==683) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 2 ; name = 2Left ; InputNumber = 1 ; ChipNumber = 0 +////////////////////////////////////////// + + || (chipNb==0 && + (0 + || (row==0 && col==165) + || (row==0 && col==349) + || (row==1 && col==1136) + || (row==2 && col==1093) + || (row==3 && col==1051) + || (row==5 && col==129) + || (row==8 && col==813) + || (row==9 && col==669) + || (row==10 && col==298) + || (row==10 && col==895) + || (row==11 && col==1115) + || (row==13 && col==521) + || (row==18 && col==1146) + || (row==19 && col==51) + || (row==20 && col==1033) + || (row==23 && col==53) + || (row==23 && col==1098) + || (row==24 && col==557) + || (row==25 && col==350) + || (row==25 && col==958) + || (row==25 && col==1012) + || (row==27 && col==199) + || (row==27 && col==400) + || (row==28 && col==737) + || (row==30 && col==331) + || (row==33 && col==1025) + || (row==33 && col==1124) + || (row==35 && col==956) + || (row==36 && col==70) + || (row==36 && col==174) + || (row==38 && col==166) + || (row==39 && col==83) + || (row==42 && col==50) + || (row==43 && col==470) + || (row==44 && col==391) + || (row==46 && col==860) + || (row==47 && col==13) + || (row==47 && col==632) + || (row==47 && col==855) + || (row==49 && col==842) + || (row==50 && col==1131) + || (row==50 && col==1142) + || (row==51 && col==495) + || (row==51 && col==1090) + || (row==52 && col==296) + || (row==54 && col==1148) + || (row==55 && col==206) + || (row==61 && col==751) + || (row==62 && col==170) + || (row==62 && col==878) + || (row==63 && col==29) + || (row==64 && col==23) + || (row==64 && col==400) + || (row==64 && col==439) + || (row==64 && col==828) + || (row==65 && col==1139) + || (row==66 && col==406) + || (row==66 && col==762) + || (row==67 && col==669) + || (row==67 && col==1109) + || (row==68 && col==957) + || (row==70 && col==429) + || (row==72 && col==317) + || (row==73 && col==777) + || (row==73 && col==1080) + || (row==74 && col==435) + || (row==74 && col==548) + || (row==74 && col==605) + || (row==76 && col==270) + || (row==76 && col==292) + || (row==76 && col==736) + || (row==77 && col==362) + || (row==78 && col==474) + || (row==78 && col==1138) + || (row==79 && col==341) + || (row==80 && col==13) + || (row==80 && col==942) + || (row==81 && col==438) + || (row==83 && col==304) + || (row==83 && col==1125) + || (row==84 && col==1018) + || (row==86 && col==1082) + || (row==87 && col==729) + || (row==89 && col==325) + || (row==89 && col==517) + || (row==90 && col==892) + || (row==93 && col==930) + || (row==95 && col==480) + || (row==96 && col==45) + || (row==98 && col==1027) + || (row==98 && col==1139) + || (row==100 && col==6) + || (row==100 && col==541) + || (row==100 && col==721) + || (row==101 && col==14) + || (row==101 && col==743) + || (row==105 && col==1053) + || (row==106 && col==499) + || (row==107 && col==221) + || (row==107 && col==353) + || (row==107 && col==1135) + || (row==108 && col==510) + || (row==109 && col==1038) + || (row==110 && col==732) + || (row==113 && col==471) + || (row==114 && col==1030) + || (row==115 && col==77) + || (row==115 && col==145) + || (row==115 && col==151) + || (row==119 && col==1094) + || (row==120 && col==547) + || (row==121 && col==306) + || (row==123 && col==667) + || (row==123 && col==1036) + || (row==124 && col==552) + || (row==124 && col==862) + || (row==125 && col==302) + || (row==126 && col==495) + || (row==127 && col==0) + || (row==128 && col==61) + || (row==129 && col==1093) + || (row==130 && col==415) + || (row==131 && col==367) + || (row==132 && col==435) + || (row==133 && col==94) + || (row==133 && col==391) + || (row==134 && col==87) + || (row==135 && col==861) + || (row==136 && col==305) + || (row==136 && col==1017) + || (row==137 && col==289) + || (row==138 && col==107) + || (row==138 && col==951) + || (row==139 && col==170) + || (row==139 && col==521) + || (row==140 && col==851) + || (row==141 && col==519) + || (row==141 && col==773) + || (row==144 && col==975) + || (row==146 && col==423) + || (row==148 && col==659) + || (row==151 && col==187) + || (row==152 && col==532) + || (row==154 && col==138) + || (row==154 && col==530) + || (row==154 && col==992) + || (row==155 && col==802) + || (row==156 && col==1125) + || (row==160 && col==86) + || (row==160 && col==478) + || (row==161 && col==1035) + || (row==163 && col==776) + || (row==163 && col==942) + || (row==165 && col==327) + || (row==166 && col==120) + || (row==166 && col==1036) + || (row==167 && col==1069) + || (row==168 && col==1147) + || (row==169 && col==157) + || (row==170 && col==838) + || (row==171 && col==386) + || (row==171 && col==954) + || (row==171 && col==1129) + || (row==175 && col==906) + || (row==176 && col==923) + || (row==177 && col==417) + || (row==177 && col==637) + || (row==178 && col==482) + || (row==179 && col==1056) + || (row==180 && col==506) + || (row==180 && col==1122) + || (row==181 && col==33) + || (row==181 && col==1026) + || (row==182 && col==3) + || (row==182 && col==845) + || (row==182 && col==1120) + || (row==183 && col==138) + || (row==184 && col==18) + || (row==184 && col==501) + || (row==185 && col==1129) + || (row==186 && col==842) + || (row==188 && col==509) + || (row==188 && col==722) + || (row==191 && col==315) + || (row==191 && col==651) + || (row==191 && col==1119) + || (row==192 && col==547) + || (row==195 && col==654) + || (row==196 && col==522) + || (row==196 && col==571) + || (row==197 && col==708) + || (row==197 && col==751) + || (row==201 && col==762) + || (row==201 && col==903) + || (row==204 && col==469) + || (row==206 && col==487) + || (row==209 && col==679) + || (row==209 && col==794) + || (row==209 && col==1129) + || (row==210 && col==1041) + || (row==213 && col==1104) + || (row==214 && col==428) + || (row==216 && col==395) + || (row==216 && col==1151) + || (row==217 && col==1117) + || (row==218 && col==705) + || (row==219 && col==318) + || (row==219 && col==987) + || (row==220 && col==429) + || (row==221 && col==511) + || (row==221 && col==849) + || (row==221 && col==1087) + || (row==225 && col==116) + || (row==225 && col==549) + || (row==225 && col==943) + || (row==226 && col==389) + || (row==227 && col==462) + || (row==227 && col==1108) + || (row==227 && col==1131) + || (row==228 && col==112) + || (row==228 && col==751) + || (row==229 && col==444) + || (row==229 && col==722) + || (row==230 && col==1107) + || (row==231 && col==117) + || (row==231 && col==224) + || (row==232 && col==407) + || (row==232 && col==1122) + || (row==233 && col==0) + || (row==234 && col==512) + || (row==236 && col==550) + || (row==237 && col==959) + || (row==239 && col==114) + || (row==240 && col==97) + || (row==240 && col==1143) + || (row==241 && col==179) + || (row==241 && col==663) + || (row==242 && col==54) + || (row==243 && col==339) + || (row==243 && col==378) + || (row==243 && col==559) + || (row==243 && col==984) + || (row==244 && col==193) + || (row==244 && col==1052) + || (row==245 && col==692) + || (row==246 && col==340) + || (row==247 && col==462) + || (row==247 && col==500) + || (row==247 && col==824) + || (row==247 && col==995) + || (row==248 && col==547) + || (row==248 && col==1038) + || (row==249 && col==230) + || (row==249 && col==1016) + || (row==249 && col==1087) + || (row==250 && col==938) + || (row==250 && col==1101) + || (row==251 && col==14) + || (row==251 && col==946) + || (row==252 && col==1123) + || (row==254 && col==733) + || (row==254 && col==1126) + || (row==257 && col==428) + || (row==260 && col==858) + || (row==261 && col==131) + || (row==261 && col==229) + || (row==261 && col==742) + || (row==262 && col==330) + || (row==266 && col==202) + || (row==266 && col==564) + || (row==266 && col==828) + || (row==267 && col==946) + || (row==267 && col==1052) + || (row==269 && col==921) + || (row==270 && col==1006) + || (row==273 && col==615) + || (row==273 && col==1129) + || (row==275 && col==473) + || (row==276 && col==547) + || (row==278 && col==300) + || (row==278 && col==1122) + || (row==279 && col==853) + || (row==280 && col==993) + || (row==282 && col==405) + || (row==282 && col==1076) + || (row==283 && col==1142) + || (row==285 && col==1138) + || (row==287 && col==151) + || (row==288 && col==94) + || (row==288 && col==437) + || (row==290 && col==555) + || (row==291 && col==970) + || (row==293 && col==289) + || (row==293 && col==444) + || (row==294 && col==1023) + || (row==295 && col==39) + || (row==295 && col==418) + || (row==296 && col==575) + || (row==296 && col==1012) + || (row==300 && col==391) + || (row==300 && col==419) + || (row==301 && col==845) + || (row==301 && col==1054) + || (row==302 && col==170) + || (row==302 && col==497) + || (row==302 && col==856) + || (row==305 && col==512) + || (row==306 && col==1119) + || (row==308 && col==1032) + || (row==308 && col==1043) + || (row==309 && col==285) + || (row==312 && col==1141) + || (row==313 && col==518) + || (row==314 && col==1062) + || (row==315 && col==859) + || (row==316 && col==410) + || (row==317 && col==1027) + || (row==318 && col==290) + || (row==318 && col==505) + || (row==318 && col==547) + || (row==321 && col==92) + || (row==321 && col==534) + || (row==323 && col==789) + || (row==324 && col==312) + || (row==326 && col==993) + || (row==329 && col==17) + || (row==330 && col==782) + || (row==330 && col==828) + || (row==331 && col==30) + || (row==331 && col==600) + || (row==331 && col==1031) + || (row==331 && col==1123) + || (row==332 && col==612) + || (row==333 && col==651) + || (row==333 && col==927) + || (row==333 && col==990) + || (row==333 && col==1036) + || (row==334 && col==188) + || (row==334 && col==437) + || (row==334 && col==582) + || (row==334 && col==1035) + || (row==335 && col==40) + || (row==337 && col==559) + || (row==337 && col==918) + || (row==337 && col==1082) + || (row==338 && col==396) + || (row==338 && col==1042) + || (row==339 && col==345) + || (row==339 && col==901) + || (row==340 && col==199) + || (row==341 && col==15) + || (row==342 && col==511) + || (row==343 && col==18) + || (row==344 && col==480) + || (row==344 && col==804) + || (row==345 && col==1125) + || (row==347 && col==561) + || (row==347 && col==1073) + || (row==348 && col==292) + || (row==349 && col==848) + || (row==349 && col==1090) + || (row==350 && col==1120) + || (row==351 && col==504) + || (row==353 && col==98) + || (row==354 && col==332) + || (row==354 && col==456) + || (row==356 && col==152) + || (row==357 && col==49) + || (row==358 && col==201) + || (row==359 && col==525) + || (row==361 && col==110) + || (row==361 && col==963) + || (row==361 && col==990) + || (row==362 && col==10) + || (row==363 && col==314) + || (row==363 && col==529) + || (row==363 && col==830) + || (row==363 && col==896) + || (row==364 && col==499) + || (row==364 && col==1054) + || (row==365 && col==173) + || (row==366 && col==426) + || (row==367 && col==142) + || (row==368 && col==468) + || (row==368 && col==969) + || (row==369 && col==423) + || (row==369 && col==454) + || (row==369 && col==1098) + || (row==371 && col==636) + || (row==371 && col==813) + || (row==371 && col==915) + || (row==371 && col==976) + || (row==372 && col==743) + || (row==374 && col==1082) + || (row==376 && col==267) + || (row==376 && col==530) + || (row==378 && col==279) + || (row==378 && col==1068) + || (row==379 && col==342) + || (row==380 && col==212) + || (row==381 && col==860) + || (row==381 && col==991) + || (row==382 && col==308) + || (row==385 && col==305) + || (row==385 && col==319) + || (row==385 && col==1006) + || (row==385 && col==1047) + || (row==386 && col==536) + || (row==387 && col==2) + || (row==387 && col==1034) + || (row==388 && col==370) + || (row==389 && col==669) + || (row==389 && col==1041) + || (row==391 && col==345) + || (row==391 && col==694) + || (row==393 && col==121) + || (row==393 && col==1074) + || (row==394 && col==514) + || (row==394 && col==863) + || (row==395 && col==503) + || (row==395 && col==667) + || (row==395 && col==818) + || (row==396 && col==781) + || (row==396 && col==1042) + || (row==397 && col==50) + || (row==397 && col==249) + || (row==397 && col==656) + || (row==398 && col==439) + || (row==398 && col==1023) + || (row==402 && col==548) + || (row==404 && col==360) + || (row==405 && col==668) + || (row==405 && col==998) + || (row==406 && col==15) + || (row==406 && col==1143) + || (row==407 && col==83) + || (row==407 && col==335) + || (row==409 && col==1004) + || (row==409 && col==1082) + || (row==411 && col==835) + || (row==412 && col==1117) + || (row==412 && col==1132) + || (row==414 && col==916) + || (row==416 && col==88) + || (row==416 && col==244) + || (row==417 && col==518) + || (row==417 && col==858) + || (row==418 && col==67) + || (row==418 && col==661) + || (row==418 && col==1090) + || (row==419 && col==824) + || (row==419 && col==825) + || (row==419 && col==826) + || (row==419 && col==827) + || (row==419 && col==857) + || (row==419 && col==1149) + || (row==420 && col==88) + || (row==420 && col==836) + || (row==420 && col==838) + || (row==420 && col==839) + || (row==420 && col==840) + || (row==420 && col==841) + || (row==420 && col==842) + || (row==420 && col==843) + || (row==420 && col==844) + || (row==421 && col==172) + || (row==421 && col==687) + || (row==421 && col==835) + || (row==421 && col==858) + || (row==422 && col==1049) + || (row==423 && col==835) + || (row==424 && col==645) + || (row==425 && col==796) + || (row==425 && col==835) + || (row==425 && col==1049) + || (row==425 && col==1060) + || (row==425 && col==1099) + || (row==427 && col==835) + || (row==427 && col==1116) + || (row==428 && col==330) + || (row==428 && col==1099) + || (row==429 && col==215) + || (row==429 && col==835) + || (row==431 && col==155) + || (row==432 && col==307) + || (row==433 && col==412) + || (row==433 && col==443) + || (row==433 && col==1117) + || (row==435 && col==662) + || (row==436 && col==720) + || (row==437 && col==559) + || (row==437 && col==718) + || (row==437 && col==782) + || (row==441 && col==898) + || (row==443 && col==1034) + || (row==444 && col==417) + || (row==445 && col==361) + || (row==445 && col==433) + || (row==445 && col==1061) + || (row==445 && col==1124) + || (row==448 && col==1114) + || (row==449 && col==555) + || (row==449 && col==791) + || (row==449 && col==952) + || (row==451 && col==1144) + || (row==452 && col==130) + || (row==454 && col==139) + || (row==454 && col==728) + || (row==454 && col==1078) + || (row==455 && col==60) + || (row==455 && col==643) + || (row==455 && col==995) + || (row==456 && col==760) + || (row==456 && col==825) + || (row==456 && col==910) + || (row==457 && col==1096) + || (row==458 && col==657) + || (row==460 && col==333) + || (row==461 && col==390) + || (row==461 && col==488) + || (row==461 && col==821) + || (row==461 && col==1027) + || (row==462 && col==226) + || (row==462 && col==303) + || (row==462 && col==734) + || (row==462 && col==848) + || (row==465 && col==1101) + || (row==466 && col==389) + || (row==466 && col==986) + || (row==466 && col==1127) + || (row==467 && col==274) + || (row==467 && col==427) + || (row==467 && col==649) + || (row==468 && col==100) + || (row==468 && col==338) + || (row==468 && col==459) + || (row==468 && col==525) + || (row==468 && col==936) + || (row==470 && col==494) + || (row==470 && col==785) + || (row==470 && col==1138) + || (row==471 && col==679) + || (row==475 && col==486) + || (row==476 && col==347) + || (row==476 && col==488) + || (row==477 && col==860) + || (row==479 && col==87) + || (row==480 && col==571) + || (row==481 && col==322) + || (row==481 && col==986) + || (row==481 && col==1126) + || (row==482 && col==605) + || (row==487 && col==528) + || (row==487 && col==848) + || (row==488 && col==259) + || (row==488 && col==848) + || (row==488 && col==1061) + || (row==490 && col==1133) + || (row==494 && col==481) + || (row==494 && col==557) + || (row==497 && col==311) + || (row==499 && col==863) + || (row==500 && col==559) + || (row==502 && col==3) + || (row==502 && col==960) + || (row==503 && col==288) + || (row==504 && col==214) + || (row==504 && col==1018) + || (row==504 && col==1051) + || (row==504 && col==1077) + || (row==505 && col==11) + || (row==505 && col==43) + || (row==505 && col==977) + || (row==505 && col==1127) + || (row==506 && col==181) + || (row==507 && col==1093) + || (row==507 && col==1144) + || (row==508 && col==451) + || (row==509 && col==508) + || (row==511 && col==959) + || (row==511 && col==1067) + || (row==513 && col==569) + || (row==513 && col==960) + || (row==514 && col==402) + || (row==515 && col==1104) + || (row==516 && col==790) + || (row==516 && col==1010) + || (row==517 && col==167) + || (row==517 && col==226) + || (row==517 && col==1007) + || (row==518 && col==1119) + || (row==519 && col==845) + || (row==520 && col==120) + || (row==520 && col==1060) + || (row==521 && col==418) + || (row==521 && col==1066) + || (row==521 && col==1115) + || (row==522 && col==862) + || (row==523 && col==603) + || (row==523 && col==830) + || (row==524 && col==1016) + || (row==525 && col==136) + || (row==525 && col==1042) + || (row==526 && col==113) + || (row==526 && col==119) + || (row==526 && col==885) + || (row==529 && col==483) + || (row==531 && col==140) + || (row==532 && col==116) + || (row==532 && col==842) + || (row==533 && col==442) + || (row==533 && col==545) + || (row==533 && col==556) + || (row==535 && col==294) + || (row==535 && col==485) + || (row==537 && col==1095) + || (row==537 && col==1113) + || (row==537 && col==1121) + || (row==538 && col==29) + || (row==538 && col==310) + || (row==538 && col==436) + || (row==541 && col==335) + || (row==541 && col==434) + || (row==541 && col==449) + || (row==541 && col==572) + || (row==542 && col==1070) + || (row==542 && col==1136) + || (row==542 && col==1141) + || (row==545 && col==35) + || (row==545 && col==52) + || (row==546 && col==14) + || (row==547 && col==23) + || (row==547 && col==959) + || (row==548 && col==123) + || (row==549 && col==925) + || (row==549 && col==1074) + || (row==550 && col==932) + || (row==551 && col==1070) + || (row==552 && col==39) + || (row==553 && col==237) + || (row==553 && col==927) + || (row==553 && col==953) + || (row==553 && col==1118) + || (row==554 && col==534) + || (row==555 && col==181) + || (row==555 && col==1079) + || (row==556 && col==71) + || (row==557 && col==328) + || (row==557 && col==1104) + || (row==558 && col==1112) + || (row==561 && col==379) + || (row==561 && col==1050) + || (row==562 && col==313) + || (row==562 && col==568) + || (row==562 && col==1142) + || (row==563 && col==691) + || (row==563 && col==1100) + || (row==564 && col==61) + || (row==564 && col==341) + || (row==568 && col==1026) + || (row==568 && col==1038) + || (row==569 && col==55) + || (row==570 && col==538) + || (row==571 && col==728) + || (row==571 && col==845) + || (row==571 && col==1063) + || (row==571 && col==1128) + || (row==571 && col==1141) + || (row==573 && col==981) + || (row==574 && col==203) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 6 ; name = 2Right ; InputNumber = 2 ; ChipNumber = 1 +////////////////////////////////////////// + + || (chipNb==1 && + (0 + || (row==0 && col==53) + || (row==0 && col==1133) + || (row==3 && col==80) + || (row==4 && col==48) + || (row==4 && col==862) + || (row==11 && col==433) + || (row==11 && col==842) + || (row==14 && col==841) + || (row==14 && col==1006) + || (row==19 && col==811) + || (row==21 && col==350) + || (row==22 && col==433) + || (row==22 && col==651) + || (row==37 && col==873) + || (row==42 && col==728) + || (row==52 && col==246) + || (row==65 && col==537) + || (row==74 && col==72) + || (row==75 && col==946) + || (row==76 && col==972) + || (row==90 && col==383) + || (row==92 && col==1015) + || (row==94 && col==926) + || (row==98 && col==428) + || (row==102 && col==1064) + || (row==107 && col==873) + || (row==109 && col==996) + || (row==113 && col==1063) + || (row==114 && col==1044) + || (row==118 && col==474) + || (row==118 && col==507) + || (row==129 && col==1101) + || (row==137 && col==490) + || (row==140 && col==929) + || (row==145 && col==527) + || (row==148 && col==510) + || (row==152 && col==428) + || (row==156 && col==1111) + || (row==158 && col==57) + || (row==164 && col==1148) + || (row==177 && col==869) + || (row==181 && col==835) + || (row==185 && col==197) + || (row==194 && col==1040) + || (row==196 && col==539) + || (row==203 && col==942) + || (row==208 && col==302) + || (row==211 && col==850) + || (row==216 && col==469) + || (row==216 && col==541) + || (row==217 && col==531) + || (row==220 && col==32) + || (row==226 && col==970) + || (row==229 && col==488) + || (row==230 && col==499) + || (row==232 && col==856) + || (row==239 && col==66) + || (row==248 && col==23) + || (row==250 && col==930) + || (row==251 && col==1031) + || (row==252 && col==136) + || (row==263 && col==379) + || (row==268 && col==361) + || (row==269 && col==962) + || (row==269 && col==984) + || (row==270 && col==835) + || (row==287 && col==1025) + || (row==288 && col==533) + || (row==288 && col==1073) + || (row==290 && col==1089) + || (row==291 && col==1025) + || (row==294 && col==453) + || (row==296 && col==975) + || (row==297 && col==451) + || (row==300 && col==1039) + || (row==302 && col==119) + || (row==302 && col==854) + || (row==307 && col==272) + || (row==308 && col==437) + || (row==314 && col==1130) + || (row==316 && col==977) + || (row==321 && col==518) + || (row==325 && col==1091) + || (row==328 && col==557) + || (row==330 && col==510) + || (row==331 && col==1128) + || (row==332 && col==968) + || (row==336 && col==507) + || (row==342 && col==740) + || (row==342 && col==1023) + || (row==346 && col==492) + || (row==348 && col==751) + || (row==348 && col==1056) + || (row==348 && col==1142) + || (row==350 && col==1131) + || (row==353 && col==570) + || (row==359 && col==466) + || (row==370 && col==445) + || (row==371 && col==867) + || (row==371 && col==1043) + || (row==372 && col==700) + || (row==374 && col==354) + || (row==376 && col==666) + || (row==377 && col==1040) + || (row==386 && col==39) + || (row==386 && col==450) + || (row==389 && col==1061) + || (row==400 && col==1078) + || (row==407 && col==534) + || (row==409 && col==400) + || (row==411 && col==524) + || (row==411 && col==1086) + || (row==413 && col==717) + || (row==420 && col==1004) + || (row==425 && col==1072) + || (row==428 && col==746) + || (row==430 && col==1130) + || (row==433 && col==810) + || (row==435 && col==502) + || (row==443 && col==971) + || (row==444 && col==557) + || (row==446 && col==444) + || (row==451 && col==1090) + || (row==459 && col==839) + || (row==465 && col==742) + || (row==472 && col==1124) + || (row==476 && col==55) + || (row==481 && col==327) + || (row==483 && col==1142) + || (row==484 && col==199) + || (row==488 && col==564) + || (row==489 && col==760) + || (row==490 && col==436) + || (row==494 && col==51) + || (row==501 && col==510) + || (row==504 && col==843) + || (row==504 && col==1033) + || (row==505 && col==906) + || (row==507 && col==1086) + || (row==509 && col==695) + || (row==512 && col==899) + || (row==519 && col==301) + || (row==519 && col==856) + || (row==520 && col==334) + || (row==521 && col==349) + || (row==530 && col==85) + || (row==534 && col==854) + || (row==538 && col==519) + || (row==538 && col==1031) + || (row==541 && col==744) + || (row==545 && col==502) + || (row==545 && col==822) + || (row==547 && col==970) + || (row==549 && col==341) + || (row==549 && col==1005) + || (row==549 && col==1101) + || (row==558 && col==1143) + || (row==566 && col==924) + || (row==567 && col==742) + || (row==568 && col==933) + || (row==570 && col==182) + || (row==570 && col==1131) + || (row==571 && col==1126) + || (row==574 && col==421) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 3 ; name = 3Left ; InputNumber = 3 ; ChipNumber = 2 +////////////////////////////////////////// + + || (chipNb==2 && + (0 + || (row==3 && col==983) + || (row==5 && col==1107) + || (row==7 && col==1126) + || (row==11 && col==885) + || (row==23 && col==1077) + || (row==23 && col==1082) + || (row==24 && col==797) + || (row==29 && col==982) + || (row==39 && col==1088) + || (row==42 && col==775) + || (row==42 && col==890) + || (row==59 && col==967) + || (row==69 && col==1008) + || (row==71 && col==1089) + || (row==77 && col==1020) + || (row==85 && col==155) + || (row==89 && col==995) + || (row==90 && col==547) + || (row==90 && col==877) + || (row==92 && col==1148) + || (row==98 && col==1132) + || (row==99 && col==1151) + || (row==104 && col==782) + || (row==105 && col==1070) + || (row==112 && col==1117) + || (row==112 && col==1126) + || (row==118 && col==1064) + || (row==120 && col==789) + || (row==120 && col==1135) + || (row==131 && col==708) + || (row==135 && col==809) + || (row==157 && col==1019) + || (row==169 && col==995) + || (row==177 && col==304) + || (row==180 && col==473) + || (row==204 && col==890) + || (row==208 && col==1046) + || (row==218 && col==1089) + || (row==219 && col==1012) + || (row==220 && col==1004) + || (row==220 && col==1035) + || (row==230 && col==866) + || (row==251 && col==1101) + || (row==254 && col==970) + || (row==257 && col==981) + || (row==261 && col==611) + || (row==267 && col==824) + || (row==269 && col==1005) + || (row==276 && col==1017) + || (row==281 && col==1088) + || (row==282 && col==1120) + || (row==283 && col==1076) + || (row==283 && col==1143) + || (row==284 && col==1087) + || (row==292 && col==1099) + || (row==297 && col==960) + || (row==300 && col==56) + || (row==309 && col==1082) + || (row==309 && col==1147) + || (row==311 && col==998) + || (row==312 && col==1103) + || (row==312 && col==1105) + || (row==313 && col==998) + || (row==315 && col==1141) + || (row==317 && col==1142) + || (row==321 && col==1132) + || (row==323 && col==938) + || (row==326 && col==820) + || (row==326 && col==1147) + || (row==329 && col==1036) + || (row==329 && col==1047) + || (row==330 && col==1149) + || (row==331 && col==1101) + || (row==336 && col==42) + || (row==338 && col>172 && col<215) + || (row==339 && col>=0 && col<381) + || (row==339 && col==405) + || (row==339 && col==419) + || (row==339 && col==453) + || (row==340 && col==858) + || (row==348 && col==1113) + || (row==363 && col==1018) + || (row==366 && col==1076) + || (row==371 && col==957) + || (row==371 && col==1027) + || (row==374 && col==959) + || (row==377 && col==1005) + || (row==378 && col==995) + || (row==378 && col==1113) + || (row==380 && col==798) + || (row==383 && col==980) + || (row==390 && col==852) + || (row==390 && col==1027) + || (row==390 && col==1123) + || (row==394 && col==881) + || (row==401 && col==1116) + || (row==405 && col==1143) + || (row==408 && col==1092) + || (row==414 && col==1109) + || (row==419 && col==1090) + || (row==419 && col==1143) + || (row==421 && col==1116) + || (row==424 && col==977) + || (row==424 && col==1046) + || (row==426 && col==900) + || (row==427 && col==1017) + || (row==445 && col==985) + || (row==447 && col==1147) + || (row==448 && col==233) + || (row==449 && col==233) + || (row==449 && col==1021) + || (row==450 && col==233) + || (row==451 && col==233) + || (row==452 && col==233) + || (row==453 && col==233) + || (row==454 && col==233) + || (row==455 && col==233) + || (row==456 && col==233) + || (row==457 && col==233) + || (row==458 && col==233) + || (row==459 && col==233) + || (row==460 && col==233) + || (row==460 && col==1037) + || (row==461 && col==233) + || (row==461 && col==1151) + || (row==462 && col==233) + || (row==463 && col==233) + || (row==465 && col==784) + || (row==466 && col==1012) + || (row==466 && col==1069) + || (row==469 && col==1039) + || (row==471 && col==1030) + || (row==472 && col==960) + || (row==473 && col==629) + || (row==475 && col==1134) + || (row==476 && col==1123) + || (row==478 && col==1147) + || (row==486 && col==1033) + || (row==487 && col==1116) + || (row==489 && col==1008) + || (row==489 && col==1148) + || (row==499 && col==968) + || (row==499 && col==1146) + || (row==508 && col==1044) + || (row==509 && col==928) + || (row==510 && col==833) + || (row==514 && col==1060) + || (row==518 && col==1022) + || (row==521 && col==499) + || (row==523 && col==855) + || (row==530 && col==916) + || (row==540 && col==1006) + || (row==540 && col==1121) + || (row==548 && col==606) + || (row==552 && col==1060) + || (row==555 && col==932) + || (row==561 && col==1148) + || (row==562 && col==482) + || (row==563 && col==953) + || (row==565 && col==1092) + || (row==566 && col==943) + || (row==572 && col==994) + || (row==572 && col==1102) + || (row==573 && col==927) + || (row==573 && col==975) + || (row==573 && col==1020) + || (row==574 && col==995) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 7 ; name = 3Right ; InputNumber = 4 ; ChipNumber = 3 +////////////////////////////////////////// + + || (chipNb==3 && + (0 + || (row==2 && col==824) + || (row==3 && col==573) + || (row==4 && col==457) + || (row==5 && col==996) + || (row==6 && col==360) + || (row==6 && col==467) + || (row==6 && col==795) + || (row==7 && col==574) + || (row==7 && col==876) + || (row==10 && col==946) + || (row==10 && col==992) + || (row==12 && col==1150) + || (row==13 && col==973) + || (row==17 && col==864) + || (row==17 && col==1117) + || (row==33 && col==1025) + || (row==35 && col==1099) + || (row==39 && col==1147) + || (row==41 && col==929) + || (row==42 && col==1103) + || (row==52 && col==1089) + || (row==53 && col==575) + || (row==54 && col==423) + || (row==54 && col==746) + || (row==54 && col==1010) + || (row==55 && col==1021) + || (row==65 && col==837) + || (row==66 && col==394) + || (row==68 && col==903) + || (row==70 && col==500) + || (row==74 && col==1149) + || (row==75 && col==1041) + || (row==82 && col==68) + || (row==91 && col==1094) + || (row==94 && col==1133) + || (row==98 && col==537) + || (row==102 && col==397) + || (row==117 && col==994) + || (row==119 && col==1100) + || (row==124 && col==561) + || (row==127 && col==703) + || (row==131 && col==792) + || (row==131 && col==1137) + || (row==135 && col==414) + || (row==135 && col==1002) + || (row==141 && col==1026) + || (row==145 && col==1036) + || (row==145 && col==1121) + || (row==150 && col==764) + || (row==152 && col==978) + || (row==154 && col==836) + || (row==155 && col==321) + || (row==155 && col==821) + || (row==156 && col==747) + || (row==156 && col==881) + || (row==156 && col==1049) + || (row==163 && col==538) + || (row==165 && col==1029) + || (row==166 && col==311) + || (row==167 && col==956) + || (row==168 && col==1003) + || (row==171 && col==438) + || (row==177 && col==1142) + || (row==178 && col==1007) + || (row==178 && col==1038) + || (row==179 && col==574) + || (row==181 && col==781) + || (row==183 && col==1083) + || (row==186 && col==1104) + || (row==189 && col==1100) + || (row==193 && col==927) + || (row==193 && col==1039) + || (row==193 && col==1100) + || (row==196 && col==541) + || (row==201 && col==1017) + || (row==206 && col==1090) + || (row==207 && col==838) + || (row==207 && col==1111) + || (row==214 && col==1035) + || (row==220 && col==1109) + || (row==222 && col==677) + || (row==227 && col==1017) + || (row==228 && col==809) + || (row==234 && col==457) + || (row==234 && col==1000) + || (row==239 && col==1142) + || (row==242 && col==990) + || (row==242 && col==1058) + || (row==243 && col==541) + || (row==243 && col==800) + || (row==243 && col==1125) + || (row==249 && col==773) + || (row==254 && col==990) + || (row==258 && col==658) + || (row==262 && col==1133) + || (row==263 && col==511) + || (row==267 && col==796) + || (row==268 && col==1118) + || (row==271 && col==969) + || (row==273 && col==175) + || (row==276 && col==902) + || (row==286 && col==516) + || (row==291 && col==215) + || (row==291 && col==1064) + || (row==294 && col==1107) + || (row==295 && col==949) + || (row==299 && col==722) + || (row==301 && col==543) + || (row==302 && col==598) + || (row==304 && col==826) + || (row==310 && col==818) + || (row==310 && col==928) + || (row==312 && col==962) + || (row==314 && col==808) + || (row==314 && col==811) + || (row==314 && col==815) + || (row==315 && col==523) + || (row==315 && col==572) + || (row==315 && col==816) + || (row==319 && col>=819 && col<=826) + || (row==320 && col==726) + || (row==320 && col==1141) + || (row==321 && col==818) + || (row==323 && col==818) + || (row==331 && col==1071) + || (row==331 && col==1109) + || (row==333 && col==905) + || (row==335 && col==955) + || (row==337 && col==1048) + || (row==339 && col==1108) + || (row==340 && col==461) + || (row==340 && col==986) + || (row==345 && col==664) + || (row==346 && col==965) + || (row==354 && col==1084) + || (row==360 && col==911) + || (row==361 && col==431) + || (row==361 && col==948) + || (row==368 && col==977) + || (row==370 && col==857) + || (row==375 && col==1105) + || (row==382 && col==1131) + || (row==384 && col==850) + || (row==388 && col==1094) + || (row==392 && col==783) + || (row==393 && col==553) + || (row==395 && col==941) + || (row==402 && col==1029) + || (row==408 && col==1101) + || (row==413 && col==1122) + || (row==414 && col==37) + || (row==425 && col==469) + || (row==432 && col==757) + || (row==433 && col==851) + || (row==435 && col==1063) + || (row==438 && col==1067) + || (row==443 && col==1086) + || (row==446 && col==1106) + || (row==450 && col==672) + || (row==453 && col==1020) + || (row==454 && col==1068) + || (row==462 && col==356) + || (row==462 && col==992) + || (row==468 && col==981) + || (row==471 && col==289) + || (row==471 && col==393) + || (row==471 && col==911) + || (row==471 && col==1004) + || (row==474 && col==1061) + || (row==478 && col==339) + || (row==479 && col==9) + || (row==483 && col==838) + || (row==488 && col==952) + || (row==489 && col==1087) + || (row==492 && col==1033) + || (row==492 && col==1104) + || (row==494 && col==407) + || (row==500 && col==816) + || (row==502 && col==968) + || (row==504 && col==1049) + || (row==509 && col==1047) + || (row==517 && col==351) + || (row==518 && col==659) + || (row==519 && col==499) + || (row==519 && col==729) + || (row==519 && col==950) + || (row==519 && col==1079) + || (row==520 && col==1139) + || (row==524 && col==453) + || (row==534 && col==363) + || (row==536 && col==719) + || (row==538 && col==876) + || (row==542 && col==415) + || (row==542 && col==742) + || (row==545 && col==1111) + || (row==547 && col==884) + || (row==548 && col==325) + || (row==548 && col==1140) + || (row==550 && col==638) + || (row==551 && col==907) + || (row==552 && col==153) + || (row==560 && col==282) + || (row==568 && col==1025) + || (row==569 && col==1023) + || (row==570 && col==657) + || (row==571 && col==1106) + || (row==573 && col==569) + || (row==573 && col==667) + || (row==574 && col==448) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 4 ; name = 4Left ; InputNumber = 5 ; ChipNumber = 4 +////////////////////////////////////////// + + || (chipNb==4 && + (0 + || (row==1 && col==1146) + || (row==7 && col==1028) + || (row==11 && col==1) + || (row==12 && col==522) + || (row==13 && col==62) + || (row==16 && col==1023) + || (row==17 && col==887) + || (row==17 && col==1138) + || (row==18 && col==405) + || (row==21 && col==1049) + || (row==22 && col==831) + || (row==22 && col==1056) + || (row==23 && col==1091) + || (row==24 && col==264) + || (row==28 && col==1004) + || (row==28 && col==1146) + || (row==30 && col==34) + || (row==31 && col==980) + || (row==33 && col==912) + || (row==34 && col==973) + || (row==34 && col==1104) + || (row==35 && col==18) + || (row==35 && col==337) + || (row==35 && col==881) + || (row==35 && col==1001) + || (row==38 && col==899) + || (row==41 && col==761) + || (row==43 && col==200) + || (row==49 && col==855) + || (row==49 && col==1047) + || (row==50 && col==1006) + || (row==50 && col==1109) + || (row==50 && col==1151) + || (row==51 && col==242) + || (row==52 && col==1003) + || (row==56 && col==51) + || (row==57 && col==115) + || (row==57 && col==1003) + || (row==57 && col==1138) + || (row==61 && col==1132) + || (row==62 && col==975) + || (row==62 && col==1124) + || (row==66 && col==1037) + || (row==66 && col==1045) + || (row==68 && col==1) + || (row==68 && col==1002) + || (row==69 && col==737) + || (row==69 && col==914) + || (row==70 && col==74) + || (row==74 && col==969) + || (row==75 && col==1107) + || (row==76 && col==85) + || (row==77 && col==1145) + || (row==79 && col==445) + || (row==80 && col==56) + || (row==80 && col==111) + || (row==82 && col==157) + || (row==88 && col==988) + || (row==89 && col==726) + || (row==91 && col==1149) + || (row==98 && col==44) + || (row==98 && col==644) + || (row==100 && col==1040) + || (row==101 && col==275) + || (row==103 && col==69) + || (row==104 && col==1026) + || (row==104 && col==1106) + || (row==106 && col==1074) + || (row==107 && col==348) + || (row==108 && col==1018) + || (row==109 && col==702) + || (row==109 && col==1025) + || (row==112 && col==1012) + || (row==115 && col==620) + || (row==116 && col==383) + || (row==121 && col==282) + || (row==121 && col==1126) + || (row==124 && col==115) + || (row==125 && col==1098) + || (row==128 && col==891) + || (row==129 && col==72) + || (row==129 && col==400) + || (row==131 && col==1146) + || (row==135 && col==781) + || (row==138 && col==872) + || (row==140 && col==706) + || (row==141 && col==74) + || (row==141 && col==473) + || (row==141 && col==799) + || (row==144 && col==92) + || (row==145 && col==277) + || (row==145 && col==951) + || (row==147 && col==121) + || (row==147 && col==693) + || (row==150 && col==878) + || (row==152 && col==948) + || (row==153 && col==233) + || (row==156 && col==1132) + || (row==157 && col==261) + || (row==157 && col==1100) + || (row==162 && col==526) + || (row==162 && col==1012) + || (row==164 && col==429) + || (row==164 && col==685) + || (row==168 && col==947) + || (row==170 && col==1112) + || (row==171 && col==986) + || (row==171 && col==1126) + || (row==172 && col==1129) + || (row==174 && col==1005) + || (row==178 && col==7) + || (row==178 && col==943) + || (row==179 && col==827) + || (row==180 && col==291) + || (row==181 && col==1043) + || (row==184 && col==25) + || (row==184 && col==847) + || (row==187 && col==273) + || (row==187 && col==933) + || (row==189 && col==747) + || (row==190 && col==947) + || (row==192 && col==1004) + || (row==196 && col==305) + || (row==197 && col==931) + || (row==200 && col==106) + || (row==200 && col==1025) + || (row==201 && col==1055) + || (row==202 && col==522) + || (row==202 && col==701) + || (row==203 && col==1056) + || (row==206 && col==482) + || (row==206 && col==1091) + || (row==211 && col==961) + || (row==212 && col==199) + || (row==212 && col==817) + || (row==212 && col==1104) + || (row==213 && col==987) + || (row==213 && col==1044) + || (row==214 && col==605) + || (row==215 && col==9) + || (row==215 && col==224) + || (row==216 && col==1084) + || (row==217 && col==990) + || (row==217 && col==1090) + || (row==219 && col==1012) + || (row==219 && col==1137) + || (row==220 && col==827) + || (row==222 && col==1029) + || (row==222 && col==1107) + || (row==225 && col==928) + || (row==226 && col==257) + || (row==227 && col==279) + || (row==227 && col==394) + || (row==227 && col==898) + || (row==228 && col==502) + || (row==231 && col==965) + || (row==231 && col==1035) + || (row==231 && col==1057) + || (row==232 && col==296) + || (row==232 && col==513) + || (row==232 && col==942) + || (row==234 && col==40) + || (row==234 && col==307) + || (row==236 && col==255) + || (row==240 && col==560) + || (row==243 && col==733) + || (row==243 && col==848) + || (row==245 && col==213) + || (row==245 && col==844) + || (row==246 && col==203) + || (row==248 && col==1006) + || (row==249 && col==967) + || (row==249 && col==1089) + || (row==250 && col==1069) + || (row==252 && col==121) + || (row==254 && col==814) + || (row==257 && col==300) + || (row==259 && col==128) + || (row==260 && col==496) + || (row==260 && col==861) + || (row==261 && col==921) + || (row==262 && col==528) + || (row==264 && col==457) + || (row==265 && col==1086) + || (row==266 && col==468) + || (row==267 && col==191) + || (row==268 && col==65) + || (row==268 && col==1107) + || (row==269 && col==1137) + || (row==270 && col==99) + || (row==271 && col==25) + || (row==274 && col==233) + || (row==274 && col==944) + || (row==279 && col==985) + || (row==284 && col==119) + || (row==284 && col==1150) + || (row==285 && col==521) + || (row==285 && col==1119) + || (row==286 && col==1143) + || (row==290 && col==1006) + || (row==290 && col==1111) + || (row==291 && col==966) + || (row==292 && col==1065) + || (row==293 && col==879) + || (row==293 && col==1042) + || (row==294 && col==1107) + || (row==296 && col==96) + || (row==298 && col==1021) + || (row==299 && col==657) + || (row==299 && col==1016) + || (row==300 && col==8) + || (row==300 && col==871) + || (row==300 && col==884) + || (row==300 && col==1065) + || (row==302 && col==156) + || (row==304 && col==448) + || (row==308 && col==162) + || (row==309 && col==1012) + || (row==310 && col==483) + || (row==311 && col==1026) + || (row==315 && col==407) + || (row==317 && col==613) + || (row==321 && col==965) + || (row==322 && col==301) + || (row==322 && col==864) + || (row==326 && col==1019) + || (row==328 && col==125) + || (row==329 && col==726) + || (row==331 && col==927) + || (row==331 && col==1101) + || (row==333 && col==35) + || (row==333 && col==858) + || (row==334 && col==347) + || (row==334 && col==1076) + || (row==334 && col==1095) + || (row==335 && col==1024) + || (row==336 && col==10) + || (row==337 && col==1053) + || (row==338 && col==84) + || (row==339 && col==216) + || (row==342 && col==1097) + || (row==344 && col==91) + || (row==344 && col==336) + || (row==344 && col==446) + || (row==345 && col==1022) + || (row==350 && col==770) + || (row==351 && col==538) + || (row==353 && col==1143) + || (row==357 && col==952) + || (row==358 && col==1142) + || (row==360 && col==1043) + || (row==361 && col==171) + || (row==362 && col==757) + || (row==362 && col==844) + || (row==362 && col==992) + || (row==363 && col==101) + || (row==363 && col==976) + || (row==363 && col==1147) + || (row==368 && col==883) + || (row==371 && col==1134) + || (row==373 && col==503) + || (row==375 && col==314) + || (row==375 && col==450) + || (row==376 && col==498) + || (row==377 && col==273) + || (row==378 && col==396) + || (row==378 && col==937) + || (row==382 && col==1150) + || (row==387 && col==834) + || (row==389 && col==917) + || (row==389 && col==985) + || (row==390 && col==89) + || (row==390 && col==172) + || (row==390 && col==1139) + || (row==391 && col==932) + || (row==392 && col==383) + || (row==392 && col==542) + || (row==393 && col==570) + || (row==394 && col==645) + || (row==395 && col==860) + || (row==397 && col==1053) + || (row==398 && col==957) + || (row==401 && col==795) + || (row==403 && col==968) + || (row==404 && col==1005) + || (row==405 && col==1143) + || (row==406 && col==862) + || (row==408 && col==1033) + || (row==408 && col==1109) + || (row==409 && col==1124) + || (row==412 && col==940) + || (row==415 && col==1128) + || (row==416 && col==764) + || (row==417 && col==818) + || (row==417 && col==1108) + || (row==421 && col==1043) + || (row==423 && col==41) + || (row==423 && col==1001) + || (row==424 && col==545) + || (row==433 && col==1128) + || (row==436 && col==59) + || (row==437 && col==1132) + || (row==440 && col==499) + || (row==446 && col==542) + || (row==448 && col==865) + || (row==448 && col==1113) + || (row==452 && col==57) + || (row==452 && col==208) + || (row==452 && col==276) + || (row==452 && col==1000) + || (row==453 && col==549) + || (row==454 && col==550) + || (row==455 && col==955) + || (row==456 && col==991) + || (row==460 && col==296) + || (row==460 && col==620) + || (row==460 && col==828) + || (row==466 && col==32) + || (row==467 && col==1109) + || (row==467 && col==1113) + || (row==468 && col==1118) + || (row==470 && col==828) + || (row==474 && col==1028) + || (row==476 && col==598) + || (row==477 && col==499) + || (row==477 && col==601) + || (row==478 && col==1150) + || (row==481 && col==269) + || (row==482 && col==1094) + || (row==486 && col==810) + || (row==487 && col==1073) + || (row==487 && col==1115) + || (row==487 && col==1142) + || (row==489 && col==415) + || (row==489 && col==714) + || (row==489 && col==817) + || (row==489 && col==979) + || (row==490 && col==147) + || (row==490 && col==1040) + || (row==491 && col==765) + || (row==491 && col==1095) + || (row==491 && col==1124) + || (row==494 && col==1116) + || (row==496 && col==993) + || (row==498 && col==957) + || (row==499 && col==978) + || (row==501 && col==1064) + || (row==502 && col==977) + || (row==503 && col==133) + || (row==504 && col==219) + || (row==505 && col==828) + || (row==506 && col==1089) + || (row==509 && col==400) + || (row==510 && col==1043) + || (row==512 && col==849) + || (row==512 && col==1047) + || (row==513 && col==759) + || (row==515 && col==1016) + || (row==516 && col==1095) + || (row==517 && col==1075) + || (row==518 && col==544) + || (row==521 && col==190) + || (row==524 && col==754) + || (row==528 && col==52) + || (row==531 && col==86) + || (row==531 && col==940) + || (row==533 && col==1011) + || (row==535 && col==70) + || (row==535 && col==530) + || (row==535 && col==661) + || (row==536 && col==1027) + || (row==536 && col==1104) + || (row==537 && col==899) + || (row==537 && col==1105) + || (row==539 && col==43) + || (row==546 && col==917) + || (row==547 && col==860) + || (row==553 && col==1006) + || (row==554 && col==59) + || (row==554 && col==886) + || (row==554 && col==1048) + || (row==558 && col==1029) + || (row==560 && col==1077) + || (row==562 && col==1075) + || (row==563 && col==1133) + || (row==564 && col==879) + || (row==564 && col==958) + || (row==565 && col==877) + || (row==569 && col==803) + || (row==569 && col==811) + || (row==569 && col==958) + || (row==573 && col==1024) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 8 ; name = 4Right ; InputNumber = 6 ; ChipNumber = 5 +////////////////////////////////////////// + + || (chipNb==5 && + (0 + || (row==6 && col==204) + || (row==28 && col==834) + || (row==33 && col==951) + || (row==34 && col==80) + || (row==45 && col==110) + || (row==50 && col==923) + || (row==65 && col==786) + || (row==79 && col==16) + || (row==84 && col==1005) + || (row==86 && col==565) + || (row==86 && col==1055) + || (row==86 && col==1068) + || (row==88 && col==472) + || (row==91 && col==372) + || (row==93 && col==1066) + || (row==106 && col==980) + || (row==135 && col==14) + || (row==135 && col==1016) + || (row==148 && col==843) + || (row==155 && col==713) + || (row==156 && col==42) + || (row==160 && col==182) + || (row==162 && col==1002) + || (row==163 && col==145) + || (row==197 && col==486) + || (row==208 && col==110) + || (row==208 && col==241) + || (row==228 && col==53) + || (row==228 && col==1001) + || (row==230 && col==169) + || (row==231 && col==1120) + || (row==242 && col==840) + || (row==250 && col==157) + || (row==253 && col==225) + || (row==253 && col>=230 && col<=330) + || (row==254 && col>=0 && col<=165) + || (row==254 && col==212) + || (row==257 && col==154) + || (row==265 && col==853) + || (row==266 && col==231) + || (row==274 && col==806) + || (row==292 && col==902) + || (row==293 && col==114) + || (row==305 && col==557) + || (row==308 && col==255) + || (row==317 && col==702) + || (row==319 && col==374) + || (row==327 && col==116) + || (row==333 && col==214) + || (row==377 && col==210) + || (row==378 && col==1131) + || (row==387 && col==345) + || (row==388 && col==7) + || (row==390 && col==1130) + || (row==395 && col==233) + || (row==397 && col==350) + || (row==408 && col==950) + || (row==431 && col==102) + || (row==437 && col==97) + || (row==440 && col==130) + || (row==452 && col==765) + || (row==468 && col==133) + || (row==469 && col==720) + || (row==470 && col==59) + || (row==471 && col==42) + || (row==474 && col==413) + || (row==478 && col==21) + || (row==505 && col==203) + || (row==507 && col==643) + || (row==510 && col==325) + || (row==511 && col==45) + || (row==513 && col==688) + || (row==524 && col==308) + || (row==528 && col==18) + || (row==529 && col==1141) + || (row==533 && col==715) + || (row==547 && col==1137) + || (row==549 && col==15) + || (row==550 && col==16) + || (row==557 && col==146) + || (row==557 && col==153) + || (row==561 && col==195) + || (row==563 && col==388) + )) + +////////////////////////////////////////// + + ; +} + +bool vetoPixel_IPNLtelescopeV06 ( int chipNb, int row, int col) //26171 +{ +/////////////////////////////////////////////////// +// Veto Pixels List Code // +// Generated with MRax::GenerateVetoPixelsCode() // +/////////////////////////////////////////////////// + // Noisy pixels filtering, called with NoiseRun = 26171 +// Generated on 17/8/2014 at 0:55:6 +// * RUN: 55 RSB=8 HIT2 after use of noise 26169 (V04) +// * Events cumulated: 1000000 +// * Absolute threshold: 100 +// * Relative threshold: 1.000e-04 for all except 1L + 1R +// * Relative threshold: 1.000e-02 for 1L + 1R +/////////////////////////////////////////////////// + + return + 0 +////////////////////////////////////////// +// Plane 1 ; name = 1Left ; InputNumber = 7 ; ChipNumber = 6 +////////////////////////////////////////// + + || (chipNb==6 && + (0 + //RUN51 GSI + || (row==23 && col==1033) + || (row==51 && col==210) + || (row==76 && col==54) + || (row==91 && col==18) + || (row==152 && col==94) + || (row==166 && col==38) + || (row==179 && col==892) + || (row==200 && col==211) + || (row==213 && col==1057) + || (row==227 && col==983) + || (row==241 && col==546) + || (row==252 && col==284) + || (row==257 && col==1028) + || (row==257 && col==1080) + || (row==259 && col==142) + || (row==259 && col==1081) + || (row==278 && col==123) + || (row==306 && col==100) + || (row==325 && col==260) + || (row==327 && col==480) + || (row==333 && col==68) + || (row==372 && col==331) + || (row==395 && col==381) + || (row==401 && col==486) + || (row==411 && col==517) + || (row==414 && col==230) + || (row==433 && col==977) + || (row==485 && col==1147) + || (row==512 && col==119) + || (row==526 && col==994) + || (row==547 && col==1030) + || (row==553 && col==1037) + //RUN55 HIT2 + || (row==17 && col==187) + || (row==17 && col==508) + || (row==17 && col==570) + || (row==49 && col==780) + || (row==71 && col==530) + || (row==76 && col==111) + || (row==92 && col==215) + || (row==107 && col==434) + || (row==109 && col==1062) + || (row==113 && col==666) + || (row==134 && col==730) + || (row==144 && col==1014) + || (row==194 && col==1) + || (row==211 && col==531) + || (row==213 && col==328) + || (row==218 && col==873) + || (row==258 && col==1098) + || (row==261 && col==1082) + || (row==267 && col==990) + || (row==287 && col==994) + || (row==302 && col==1004) + || (row==334 && col==1093) + || (row==341 && col==225) + || (row==344 && col==1068) + || (row==370 && col==446) + || (row==371 && col==529) + || (row==379 && col==328) + || (row==402 && col==1053) + || (row==410 && col==1061) + || (row==412 && col==54) + || (row==526 && col==505) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 5 ; name = 1Right ; InputNumber = 8 ; ChipNumber = 7 +////////////////////////////////////////// + + || (chipNb==7 && + (0 + //RUN51 GSI + || (row==46 && col==188) + || (row==50 && col==421) + || (row==61 && col==652) + || (row==69 && col==698) + || (row==69 && col==934) + || (row==93 && col==1071) + || (row==113 && col==52) + || (row==132 && col==11) + || (row==161 && col==1143) + || (row==173 && col==1022) + || (row==185 && col==846) + || (row==277 && col==1042) + || (row==293 && col==879) + || (row==317 && col==1133) + || (row==354 && col==16) + || (row==392 && col==1121) + || (row==412 && col==506) + || (row==422 && col>=0 && col<=77) + || (row==423 && col>=0 && col<=300) + || (row==433 && col==843) + || (row==472 && col==817) + || (row==497 && col==683) + //RUN55 HIT2 + || (row==20 && col==1102) + || (row==21 && col==84) + || (row==81 && col==676) + || (row==123 && col==443) + || (row==208 && col==797) + || (row==231 && col==1107) + || (row==271 && col==859) + || (row==531 && col==1031) + || (row==536 && col==879) + || (row==541 && col==783) + || (row==565 && col==817) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 2 ; name = 2Left ; InputNumber = 1 ; ChipNumber = 0 +////////////////////////////////////////// + + || (chipNb==0 && + (0 + //RUN51 GSI + || (row==38 && col==166) + || (row==62 && col==170) + || (row==77 && col==362) + || (row==89 && col==325) + || (row==98 && col==1027) + || (row==101 && col==14) + || (row==115 && col==77) + || (row==121 && col==306) + || (row==124 && col==862) + || (row==155 && col==802) + || (row==161 && col==1035) + || (row==167 && col==1069) + || (row==183 && col==138) + || (row==236 && col==550) + || (row==237 && col==959) + || (row==251 && col==14) + || (row==257 && col==428) + || (row==308 && col==1032) + || (row==312 && col==1141) + || (row==331 && col==1031) + || (row==337 && col==1082) + || (row==344 && col==480) + || (row==369 && col==454) + || (row==371 && col==976) + || (row==394 && col==514) + || (row==411 && col==835) + || (row==417 && col==518) + || (row==419 && col>=824 && col<=827) + || (row==420 && col>=838 && col<=843) + || (row>=412 && row<=429 && col==835) + || (row==428 && col==330) + || (row==429 && col==215) + || (row==431 && col==155) + || (row==462 && col==303) + || (row==468 && col==936) + || (row==480 && col==571) + || (row==505 && col==11) + || (row==513 && col==569) + || (row==516 && col==1010) + || (row==526 && col==113) + || (row==535 && col==485) + || (row==561 && col==379) + || (row==561 && col==1050) + //RUN21 GSI + || (row==137 && col==289) + || (row==302 && col==497) + || (row==385 && col==1006) + || (row==420 && col==844) + || (row==441 && col==898) + || (row==517 && col==167) + || (row==538 && col==310) + //RUN55 HIT2 + || (row==5 && col==129) + || (row==13 && col==521) + || (row==26 && col==19) + || (row==27 && col==400) + || (row==47 && col==632) + || (row==96 && col==95) + || (row==102 && col==1109) + || (row==133 && col==94) + || (row==138 && col==107) + || (row==141 && col==910) + || (row==148 && col==659) + || (row==179 && col==1056) + || (row==196 && col==522) + || (row==204 && col==469) + || (row==243 && col==559) + || (row==288 && col==94) + || (row==321 && col==534) + || (row==354 && col==332) + || (row==405 && col==998) + || (row==407 && col==335) + || (row==411 && col==1124) + || (row==418 && col==1090) + || (row==420 && col==836) + || (row==444 && col==417) + || (row==449 && col==476) + || (row==461 && col==390) + || (row==467 && col==649) + || (row==473 && col==272) + || (row==479 && col==87) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 6 ; name = 2Right ; InputNumber = 2 ; ChipNumber = 1 +////////////////////////////////////////// + + || (chipNb==1 && + (0 + //RUN51 GSI + || (row==65 && col==537) + || (row==156 && col==1111) + || (row==296 && col==975) + || (row==342 && col==1023) + || (row==512 && col==899) + //RUN21 GSI + || (row==14 && col==841) + || (row==252 && col==136) + || (row==288 && col==533) + || (row==483 && col==1142) + //RUN55 HIT2 + || (row==18 && col==916) + || (row==22 && col==651) + || (row==45 && col==613) + || (row==114 && col==1044) + || (row==181 && col==835) + || (row==203 && col==942) + || (row==230 && col==499) + || (row==242 && col==28) + || (row==307 && col==272) + || (row==314 && col==1130) + || (row==371 && col==1043) + || (row==372 && col==700) + || (row==400 && col==1078) + || (row==413 && col==717) + || (row==420 && col==1004) + || (row==453 && col==558) + || (row==454 && col==28) + || (row==454 && col==1134) + || (row==504 && col==1001) + || (row==535 && col==842) + || (row==551 && col==1119) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 3 ; name = 3Left ; InputNumber = 3 ; ChipNumber = 2 +////////////////////////////////////////// + + || (chipNb==2 && + (0 + //RUN51 GSI + || (row==338 && col>=167 && col<=214) + || (row==339 && (col==45 || col==46 || col==264)) + || (row==405 && col==1143) + || (row>=448 && row<=463 && col==233) + || (row==486 && col==1033) + || (row==565 && col==1092) + || (row==566 && col==943) + || (row==572 && col==994) + //RUN21 GSI + || (row==421 && col==1116) + || (row==460 && col==1037) + //RUN55 HIT2 + || (row==338 && col==163) + || (row==338 && col==164) + || (row==338 && col==165) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 7 ; name = 3Right ; InputNumber = 4 ; ChipNumber = 3 +////////////////////////////////////////// + + || (chipNb==3 && + (0 + //RUN51 GSI + || (row==39 && col==1147) + || (row==54 && col==423) + || (row==91 && col==1094) + || (row==117 && col==994) + || (row==141 && col==1026) + || (row==214 && col==1035) + || (row==263 && col==511) + || (row==314 && col==808) + || (row==314 && col==811) + || (row==314 && col==815) + || (row==315 && col==816) + || (row==319 && col>=819 && col<= 824) + || (row==321 && col==818) + || (row==323 && col==818) + || (row==368 && col==977) + || (row==471 && col==911) + || (row==474 && col==1061) + //RUN21 GSI + || (row==102 && col==397) + || (row==156 && col==881) + || (row==271 && col==969) + || (row==295 && col==949) + //RUN55 HIT2 + || (row==131 && col==792) + || (row==131 && col==1137) + || (row==135 && col==1002) + || (row==141 && col==1073) + || (row==158 && col==797) + || (row==168 && col==1003) + || (row==171 && col==961) + || (row==177 && col==1142) + || (row==178 && col==1007) + || (row==190 && col==453) + || (row==193 && col==927) + || (row==196 && col==541) + || (row==207 && col==838) + || (row==207 && col==1111) + || (row==218 && col==935) + || (row==234 && col==1000) + || (row==243 && col==1125) + || (row==266 && col==1013) + || (row==274 && col==1136) + || (row==286 && col==1006) + || (row==294 && col==1107) + || (row==296 && col==929) + || (row==304 && col==826) + || (row==305 && col==818) + || (row==308 && col==815) + || (row==314 && col==810) + || (row==320 && col==1141) + || (row==340 && col==986) + || (row==399 && col==920) + || (row==408 && col==1101) + || (row==440 && col==876) + || (row==450 && col==672) + || (row==453 && col==1020) + || (row==454 && col==1068) + || (row==471 && col==1004) + || (row==472 && col==588) + || (row==474 && col==918) + || (row==484 && col==26) + || (row==489 && col==955) + || (row==492 && col==1104) + || (row==502 && col==968) + || (row==507 && col==1081) + || (row==511 && col==910) + || (row==518 && col==1098) + || (row==534 && col==363) + || (row==546 && col==1018) + || (row==548 && col==325) + || (row==560 && col==282) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 4 ; name = 4Left ; InputNumber = 5 ; ChipNumber = 4 +////////////////////////////////////////// + + || (chipNb==4 && + (0 + //RUN51 GSI + || (row==23 && col==1091) + || (row==38 && col==899) + || (row==43 && col==200) + || (row==50 && col==1006) + || (row==51 && col==242) + || (row==56 && col==51) + || (row==57 && col==1138) + || (row==69 && col==914) + || (row==74 && col==969) + || (row==75 && col==1107) + || (row==100 && col==1040) + || (row==108 && col==1018) + || (row==141 && col==799) + || (row==147 && col==121) + || (row==152 && col==948) + || (row==180 && col==291) + || (row==190 && col==947) + || (row==219 && col==1012) + || (row==220 && col==827) + || (row==228 && col==502) + || (row==245 && col==213) + || (row==248 && col==1006) + || (row==268 && col==65) + || (row==299 && col==1016) + || (row==331 && col==927) + || (row==334 && col==1095) + || (row==335 && col==1024) + || (row==376 && col==498) + || (row==378 && col==396) + || (row==393 && col==570) + || (row==404 && col==1005) + || (row==565 && col==877) + //RUN21 GSI + || (row==107 && col==348) + || (row==141 && col==473) + || (row==257 && col==300) + || (row==260 && col==496) + || (row==564 && col==879) + //RUN55 HIT2 + || (row==75 && col==335) + || (row==204 && col==384) + || (row==215 && col==224) + || (row==228 && col==22) + || (row==232 && col==296) + || (row==293 && col==879) + || (row==315 && col==407) + || (row==344 && col==91) + || (row==344 && col==446) + || (row==363 && col==101) + || (row==518 && col==544) + || (row==536 && col==213) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 8 ; name = 4Right ; InputNumber = 6 ; ChipNumber = 5 +////////////////////////////////////////// + + || (chipNb==5 && + (0 + //RUN51 GSI + || (row==45 && col==110) + || (row==253 && col>=225 && col <=330) + || (row==254 && col>=0 && col <=253) + || (row==431 && col==102) + || (row==471 && col==42) + || (row==507 && col==643) + //RUN21 GSI + //|| (row==253 && col==206) + //|| (row==253 && col==217) + //|| (row==253 && col==219) + //|| (row==253 && col==222) + //RUN55 HIT2 + || (row==253 && col>=159 && col <=227) + || (row==305 && col==557) + || (row==376 && col==155) + || (row==524 && col==308) + )) + +////////////////////////////////////////// + + ; +} + +bool vetoPixel_IPNLtelescopeV10 ( int chipNb, int row, int col) //26180 +{ +/////////////////////////////////////////////////// +// Veto Pixels List Code // +// Generated with MRax::GenerateVetoPixelsCode() // +/////////////////////////////////////////////////// +// Noisy pixels filtering, called with NoiseRun = 26180 +// Generated on 17/8/2014 at 1:52:48 +// * GANIL 04/2014 with RSB=8 (news sensors) with RUN100-103 +// * Events cumulated: 179999 +// * Absolute threshold: 18 +// * Relative threshold: 1.000e-04 +/////////////////////////////////////////////////// + + + return + + 0 +////////////////////////////////////////// +// Plane 1 ; name = 1Left ; InputNumber = 4 ; ChipNumber = 3 +////////////////////////////////////////// + + || (chipNb==3 && + (0 + || (row==14 && col==124) + || (row==38 && col==964) + || (row==54 && col==1000) + || (row==64 && col==1026) + || (row==83 && col==1073) + || (row==90 && col==1111) + || (row==93 && col==788) + || (row==140 && col==113) + || (row==211 && col==1122) + || (row==244 && col==525) + || (row==269 && col==955) + || (row==320 && col==1115) + || (row==338 && col==872) + || (row==376 && col==1094) + || (row==385 && col==1069) + || (row==420 && col==979) + || (row==422 && col==1025) + || (row==485 && col==1070) + || (row>=525 && row<=560 && col>=845 && col<=870) + || (row==533 && col>=0 && col<=50) + || (row==533 && col>=50 && col<=80) + || (row==542 && col>=200 && col<=350) + || (row==543 && col>=170 && col<=290) + || (row==547 && col>=75 && col<=220) + || (row==548 && col>=60 && col<=220) + || (row==549 && col>=80 && col<=230) + || (row==555 && col==946) + || (row==556 && col>=105 && col<=160) + || (row==556 && 185<=col && col<=210) + || (row==560 && col==1059) + + )) +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 5 ; name = 1Right ; InputNumber = 8 ; ChipNumber = 7 +////////////////////////////////////////// + + || (chipNb==7 && + (0 + || (row==33 && col==1119) + || (row==52 && col==275) + || (row==67 && col==7) + || (row==71 && col==1145) + || (row==88 && col==1019) + || (row==92 && col==1039) + || (row==99 && col==1138) + || (row==140 && col==946) + || (row==159 && col==262) + || (row==166 && col==1109) + || (row==174 && col==949) + || (row==196 && col==74) + || (row==212 && col==1051) + || (row==216 && col==1068) + || (row==229 && col==99) + || (row==230 && col==760) + || (row==261 && col==395) + || (row==263 && col==1090) + || (row==269 && col==1011) + || (row==286 && col==911) + || (row==299 && col==996) + || (row==326 && col==1108) + || (row==337 && col==1020) + || (row==343 && col==887) + || (row==350 && col==1113) + || (row==364 && col==1048) + || (row==378 && col==1040) + || (row==382 && col==835) + || (row==423 && col==411) + || (row==443 && col==470) + || (row==447 && col==329) + || (row==474 && col==1040) + || (row==496 && col==533) + || (row==498 && col==993) + || (row==502 && col==96) + || (row==506 && col==452) + || (row==531 && col==176) + || (row==538 && col==549) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 2 ; name = 2Left ; InputNumber = 2 ; ChipNumber = 1 +////////////////////////////////////////// + + || (chipNb==1 && + (0 + || (row==31 && col==1087) + || (row==40 && col==1145) + || (row==68 && col==1032) + || (row==128 && col==536) + || (row==134 && col==1052) + || (row==157 && col==486) + || (row==237 && col==922) + || (row==247 && col==948) + || (row==249 && col==929) + || (row==257 && col==1149) + || (row==308 && col==527) + || (row==397 && col==966) + || (row==420 && col==473) + || (row==430 && col==1006) + || (row==446 && col==530) + || (row==446 && col==1014) + || (row==454 && col==316) + || (row==476 && col==1086) + || (row==484 && col==412) + || (row==529 && col==560) + || (row==538 && col==410) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 6 ; name = 2Right ; InputNumber = 6 ; ChipNumber = 5 +////////////////////////////////////////// + + || (chipNb==5 && + (0 + || (row==19 && col==969) + || (row==32 && col==855) + || (row==55 && col==539) + || (row==70 && col==899) + || (row==81 && col==1097) + || (row==98 && col==1108) + || (row==104 && col==871) + || (row==105 && col==1113) + || (row==112 && col==891) + || (row==114 && col==76) + || (row==129 && col==926) + || (row==143 && col==1123) + || (row==165 && col==951) + || (row==224 && col==1018) + || (row==234 && col==1147) + || (row==252 && col==1105) + || (row==257 && col==512) + || (row==275 && col==1125) + || (row==275 && col==1129) + || (row==279 && col==950) + || (row==285 && col==293) + || (row==297 && col==1076) + || (row==324 && col==850) + || (row==354 && col==850) + || (row==378 && col==1120) + || (row==379 && col==802) + || (row==380 && col==928) + || (row==383 && col==859) + || (row==393 && col==1124) + || (row==404 && col==983) + || (row==451 && col==135) + || (row==465 && col==916) + || (row==472 && col==1075) + || (row==562 && col==32) + || (row==570 && col==860) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 3 ; name = 3Left ; InputNumber = 3 ; ChipNumber = 2 +////////////////////////////////////////// + + || (chipNb==2 && + (0 + || (row==14 && col==841) + || (row==22 && col==651) + || (row==45 && col==613) + || (row==114 && col==1044) + || (row==156 && col==1111) + || (row==181 && col==835) + || (row==230 && col==499) + || (row==252 && col==136) + || (row==288 && col==533) + || (row==296 && col==975) + || (row==314 && col==1130) + || (row==328 && col==557) + || (row==342 && col==1023) + || (row==400 && col==1078) + || (row==413 && col==717) + || (row==453 && col==558) + || (row==454 && col==1134) + || (row==483 && col==1142) + || (row==512 && col==899) + || (row==535 && col==842) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 7 ; name = 3Right ; InputNumber = 7 ; ChipNumber = 6 +////////////////////////////////////////// + + || (chipNb==6 && + (0 + || (row==13 && col==521) + || (row==33 && col==1025) + || (row==33 && col==1124) + || (row==45 && col==1012) + || (row==47 && col==632) + || (row==62 && col==170) + || (row==77 && col==362) + || (row==86 && col==1082) + || (row==98 && col==1027) + || (row==102 && col==1109) + || (row==105 && col==1053) + || (row==121 && col==306) + || (row==124 && col==862) + || (row==133 && col==94) + || (row==137 && col==289) + || (row==141 && col==910) + || (row==148 && col==659) + || (row==155 && col==802) + || (row==161 && col==1035) + || (row==163 && col==942) + || (row==164 && col==960) + || (row==167 && col==1069) + || (row==179 && col==1056) + || (row==191 && col==1119) + || (row==204 && col==469) + || (row==219 && col==1135) + || (row==231 && col==1075) + || (row==236 && col==550) + || (row==237 && col==959) + || (row==243 && col==559) + || (row==247 && col==1115) + || (row==251 && col==14) + || (row==288 && col==94) + || (row==302 && col==497) + || (row==308 && col==1032) + || (row==312 && col==1141) + || (row==321 && col==534) + || (row==337 && col==1082) + || (row==344 && col==480) + || (row==371 && col==976) + || (row==385 && col==1006) + || (row==394 && col==514) + || (row==405 && col==998) + || (row==407 && col==335) + || (row==411 && col==1124) + || (row==417 && col==518) + || (row==418 && col==1090) + || (row==419 && col>=824 && col<=827) + || (row==420 && col>=836 && col<=844) + || (row>=421 && row<=427 && col==835) + || (row==428 && col==330) + || (row==441 && col==898) + || (row==449 && col==476) + || (row==467 && col==649) + || (row==468 && col==936) + || (row==480 && col==571) + || (row==501 && col==1021) + || (row==505 && col==11) + || (row==511 && col==1067) + || (row==516 && col==1010) + || (row==535 && col==485) + || (row==537 && col==1121) + || (row==550 && col==932) + || (row==558 && col==1112) + || (row==561 && col==1050) + || (row==563 && col==691) + )) + +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 4 ; name = 4Left ; InputNumber = 1 ; ChipNumber = 0 +////////////////////////////////////////// + + || (chipNb==0 && + (0 + || (row==84 && col==1005) + || (row==86 && col==1055) + || (row==93 && col==1066) + || (row==135 && col==1016) + || (row==253 && col>=158 && col<=266) + || (row==292 && col==902) + || (row==305 && col==557) + || (row==431 && col==102) + || (row==507 && col==643) + || (row==524 && col==308) + )) +|| (chipNb==0 && row==253 && col>=158 && col<=266) +////////////////////////////////////////// + +////////////////////////////////////////// +// Plane 8 ; name = KO ; InputNumber = 5 ; ChipNumber = 4 +////////////////////////////////////////// + + || (chipNb==4 && + (0 + )) + +////////////////////////////////////////// + + ; +} + + + +// ----------------------------------------------------------------------------- + +bool vetoPixel_Mi26telescope( int chipNb, int row, int col) { + + // 4 Mimosa 26 telescope configuration, + // + // + // Plane: 1 2 5 6 (plane 3 & 4 are DUT) + // Input: 1 2 5 6 = chipNb+1 + + return + (chipNb==4 && row==43 && col==200) + || (chipNb==2 && row==338 && 176837 && col<843) + || (chipNb==0 && row==535 && col==485) + || (chipNb==6 && row==512 && col==119) + || (chipNb==5 && row==253 && 99[kNFrames]; + for(Int_t i=0;i)word<> 16)!=0x0001) fStart++; + else { + //cout<<"Last word of the first frame " << fStart< 0 && (i < (kNFrames-1))) { + for(int j=0; j=kNFrames){ + printf("Frame = %d: error no existing frame\n",fNFrame); + return kFALSE; + } + + Int_t tmpcnt = 0; + for(Short_t row=0; row> tmpbits) & 0x00000001; + fDataFrame[row+1][col-i] = (word >> (tmpbits+8)) & 0x00000001; + } + tmpbits++; + } + tmpcnt++; + } + } + +return kTRUE; +} + + +//__________________________________________________________________________ +Bool_t AliMIMOSA22RawStreamVASingle::HasData() +{ + + // Modified by JB 2015/05/25 transmit frame # as timestamp + + if (fDebugLevel) printf("ALI22::HasData reading event %d\n", fcountEv); + + ListOfPixels.clear(); + + Short_t value; + + if( !ReadCDH() ) { + return false; + } + + if( !ReadData() ) { + return false; + } + + for(Int_t iframe=0; iframe2) printf("Ali22::HasData adding pixel with value %d row %d col %d\n", value, irow, icol); + //ListOfPixels.push_back( BoardReaderPixel( 1, value, irow, icol) ); + ListOfPixels.push_back( BoardReaderPixel( 1, value, irow, icol, iframe) ); + } + } + + } // end loop on frames + + if (fDebugLevel) printf("Ali22::HasData new event %d will be generated with %lu pixels, trigger nb %d\n", fcountEv, ListOfPixels.size(), fEventCounterCDH); + fCurrentEvent = new BoardReaderEvent( fcountEv, fBoardNumber, fRunNumber, &ListOfPixels); + + return true; + +} + + +//__________________________________________________________________________ +void AliMIMOSA22RawStreamVASingle::PrintStatistics(ostream &stream) +{ + + // Print statistics on the events read by this board + // + // JB, 2014/05/14 + + stream << "***********************************************" << endl; + stream << " Board ALI22 " << fBoardNumber << " found:" << endl; + stream << fEventCounterCDH << " triggers." << endl; + stream << fcountEv << " events in total," << endl; + stream << "***********************************************" << endl; + + +} diff --git a/src/BoardReader.cxx b/src/BoardReader.cxx new file mode 100755 index 0000000..e8fccf7 --- /dev/null +++ b/src/BoardReader.cxx @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////// +// Class Description of BoardReader // +// // +// // // +///////////////////////////////////////////////////////////// +// +// created JB, 2014/05/13 + +#include "BoardReader.h" + +ClassImp(BoardReaderEvent) + +// -------------------------------------------------------------------------------------- + +BoardReaderEvent::BoardReaderEvent( int eventNumber, int boardNumber, int runNumber) { + + // JB, 2014/05/13 + + EventNumber = eventNumber; + BoardNumber = boardNumber; + RunNumber = runNumber; + +} + +// -------------------------------------------------------------------------------------- + +BoardReaderEvent::BoardReaderEvent( int eventNumber, int boardNumber, int runNumber, vector *aListOfPixels) { + + // JB, 2014/05/13 + + EventNumber = eventNumber; + BoardNumber = boardNumber; + RunNumber = runNumber; + ListOfPixels = aListOfPixels; + +} + +// -------------------------------------------------------------------------------------- + +BoardReaderEvent::~BoardReaderEvent() { + + // JB, 2014/05/13 + +// delete ListOfPixels; + +} + + diff --git a/src/BoardReaderEUDAQ.cxx b/src/BoardReaderEUDAQ.cxx new file mode 100644 index 0000000..90b2cfa --- /dev/null +++ b/src/BoardReaderEUDAQ.cxx @@ -0,0 +1,740 @@ +///////////////////////////////////////////////////////////// +// Class Description of BoardReaderEUDAQ +// +// Dedicated to decode output files from the EUDAQ system +// +// +// Based on ... +// +///////////////////////////////////////////////////////////// +// +// created JB, 2016/08/17 + +#include "BoardReaderEUDAQ.h" + +ClassImp(BoardReaderEUDAQ); + +//------------------------------------------+----------------------------------- +BoardReaderEUDAQ::BoardReaderEUDAQ(int boardNumber, int runNumber, int sensorType, int numberOfSensors, int triggerMode, int eventBuildingMode) { + + fDebugLevel = 0; + + fBoardNumber = boardNumber; + fRunNumber = runNumber; + fSensorType = sensorType; + fNumberOfSensors = numberOfSensors; + + cout << "*****************************************" << endl; + cout << " < BoardReaderEUDAQ constructor > " << endl; + cout << "*****************************************" << endl; + cout << "Creating a BoardReaderEUDAQ" << endl; + cout << " * for board : " << fBoardNumber << endl; + cout << " * for runNumber : " << fRunNumber << endl; + cout << " * for sensor type : " << fSensorType << endl; + cout << " * nb of sensors : " << fNumberOfSensors << endl; + + fListOfInputFileNames.clear(); +// fNumberOfFiles = 0; + fCurrentFileNumber = -1; + + fBufferRead = 0; + fEventNumber = 0; + fCurrentEvent = NULL; + +} + +//------------------------------------------+----------------------------------- +BoardReaderEUDAQ::~BoardReaderEUDAQ() +{ + delete fCurrentEvent; + delete fData; + delete fInputFileName; + +} + +// -------------------------------------------------------------------------------------- + +bool BoardReaderEUDAQ::AddFile(char *fileName) { + +// fCurrentFileNumber = 0; + char inputFileName[500] = fileName; + sprintf(inputFileName,"%s", fTool.LocalizeDirName( inputFileName)); + fRawFileStream.open( inputFileName); + if( fRawFileStream.fail() ) { + cout << endl << "ERROR BoardReaderEUDAQ " << fBoardNumber << " file " << inputFileName << " does not exist!" << endl; + return false; + } + fListOfInputFileNames.push_back( inputFileName); + cout << " --> BoardReaderEUDAQ " << fBoardNumber << " New file " << fListOfInputFileNames.back() << ", total of " << fListOfInputFileNames.size() << " files." << endl; + + fCurrentInputFileName = fListOfInputFileNames.begin(); + + return true; +} + +// -------------------------------------------------------------------------------------- +bool BoardReaderEUDAQ::AddFileList(const char *prefixFileName, int startIndex, int endIndex, const char *suffixFileName) { + + // Build the list of rawdata files from start index to endindex + + char inputFileName[500]; + + if(fDebugLevel>0) cout << "Indices: start = " << startIndex << ", end = " << endIndex << endl; + cout << "BoardReaderEUDAQ " << BoardNumber << " adding " << fNumberOfFiles << " files like " << prefixFileName << "*" << suffixFileName << endl; + for(int fileNumber=0; fileNumber<=endIndex-startIndex; fileNumber++){ + sprintf( inputFileName, "%s%d%s", prefixFileName, fileNumber+startIndex, suffixFileName); + sprintf( inputFileName,"%s", fTool.LocalizeDirName( inputFileName)); + if(DebugLevel>0) cout << " checking file " << inputFileName << endl; + fRawFileStream.open( inputFileName); + if( fRawFileStream.fail() ) { + cout << endl << "ERROR BoardReaderEUDAQ " << fBoardNumber << " file " << inputFileName << " does not exist!!" << endl; + fRawFileStream.close(); + return false; + } + else{ + fListOfInputFileNames.push_back( inputFileName); + cout << " --> BoardReaderEUDAQ " << fBoardNumber << " New file " << fListOfInputFileNames.back() << ", total of " << fListOfInputFileNames.size() << " files." << endl; + fRawFileStream.close(); + } + } + //OpenRawFile(ListOfInputFileNames[0]); //reopens the very first file + // RawFileStream.clear(); + + fCurrentInputFileName = fListOfInputFileNames.begin(); + + return true; +} + +// -------------------------------------------------------------------------------------- +bool BoardReaderEUDAQ::LookUpRawFile() { + + // Close the current rawdata file if any + // and try to open the next rawdata file. + + if( !(fListOfInputFileNames.empty()) ) { + + if( fCurrentInputFileName != fListOfInputFileNames.end() ) { + + if( fRawFileStream.is_open() ) { // file already open, close and update iterator + CloseRawFile(); + fCurrentInputFileName++; + } + + if(DebugLevel) cout << " --> BoardReaderEUDAQ " << fBoardNumber << " Next file to read " << fCurrentInputFileName-fListOfInputFileNames.size() << " over " << fListOfInputFileNames.size() << " closing and opening." << endl; + return OpenRawFile( *fCurrentInputFileName ); + + } + + else { // no more file, end the reading + cout << " --> BoardReaderEUDAQ " << fBoardNumber << ": all " << fListOfInputFileNames.size() << " files read, closing!" << endl; +// fNoMoreFile = true; + return false; + } + + } + + else { // no file at all + cout << "ERROR: BoardReaderEUDAQ NO RAW DATA FILE WAS ASSOCIATED WITH BOARD " << fBoardNumber << ", STOPPING!" << endl << endl; + return false; + } + +} + +// -------------------------------------------------------------------------------------- +bool BoardReaderEUDAQ::OpenRawFile( const char *fileName) { + + // Open a rawdata file + + fRawFileStream.open( fileName); + bool b = fRawFileStream.fail(); + if (b == 0) { + BuffersRead = 0; + cout << " -+-+- INFO BoardReaderEUDAQ " << fBoardNumber << ": File " << fileName << " opened." << endl; + } + else { + cout << " -/-/- INFO BoardReaderEUDAQ " << fBoardNumber << ": File " << fileName << " not opened, rc = " << b << "." << endl; + } + return !b; + +} + +// -------------------------------------------------------------------------------------- +bool BoardReaderEUDAQ::CloseRawFile() { + + // Closes a rawdata file + + fRawFileStream.close(); + bool b = fRawFileStream.fail(); + if (b == 0) + cout << " -+-+- INFO BoardReaderEUDAQ " << fBoardNumber << ": File " << *fCurrentInputFileName << " closed " << endl; + else + cout << " -/-/- INFO BoardReaderEUDAQ " << fBoardNumber << ": File " << *fCurrentInputFileName << " not closed, rc = " << b << "(eof="<< fRawFileStream.eof() << ", bad="<< fRawFileStream.bad() <<"." << endl; + return b; + +} + +// -------------------------------------------------------------------------------------- + +bool BoardReaderEUDAQ::FetchEvent( ) { + + // Try to get the next word index from the Data buffer + // either by reading in the current Data buffer + // either by getting a new Data buffer from file and reading first word + // + // Change the bit order according to the endianess. + // + // SizeOfEvent corresponds typically to one event + // + // + // return "false" if nothing to read, "true" otherwise + // + // JB, 2012/06/ + // Modified: JB, 2012/08/18 test the nb of events read + + bool readSuccess = false; + + fEventSize = 1024; // random value for now, might be replaced by method to evaluate event size + + // If we have read the full current Data buffer alreay, + // try to get a new Data buffer + // either from the current file or a new one + if ( !( RawFileStream.eof() ) || LookUpRawFile() ) { + + // Now we can get the next data buffer + RawFileStream.read(reinterpret_cast ( &Data[0] ), sizeof(char) * fEventSize); + if(DebugLevel>2) cout << " BoardReaderEUDAQ " << BoardNumber << ": Got new data buffer " << BuffersRead << " with gcount=" << RawFileStream.gcount() << " bytes, SizeOfEvent=" << fEventSize << endl; + readSuccess = ( (size_t)RawFileStream.gcount() == fEventSize ); + BuffersRead++; + } + return readSuccess; + +} + +// -------------------------------------------------------------------------------------- + +bool BoardReaderEUDAQ::SetBufferPointers( ) { + + // Set the pointers to the differrent elements inside the event buffer + // event header, each input and event trailer + // + // JB, 201 + + if( Data==NULL) { + cout << "WARNING in BoardReaderEUDAQ board " << BoardNumber << ", event pointer is null!" << endl; + return false; + } + + EventHeader = (TEventHeader*)Data; + TriggerLine = EventHeader->VFasCnt[0]; + for( int iInput=0; iInput1 ) cout << " shift for input " << iInput << " is " << InputDataAdress[iInput] << " bytes." << endl; + } + EventTrailer = BuildValue( fEventSize - fEventTrailerSize, 4); + if( SizeOfTrailer>4 ) { + EventTrailer = BuildValue( fEventSize - fEventTrailerSize + 4, 4); + } + + FramesRead++; + + if( DebugLevel>1 ) cout << " SetBufferPointers for IMGBoard " << BoardNumber << " done, trailer is " << hex << EventTrailer << dec << endl; + + EventTrailer=0x89abcdef; + return (EventTrailer==(int)0x89abcdef); +} + +// -------------------------------------------------------------------------------------- + +bool BoardReaderEUDAQ::HasData( ) { + + // Try to find the data for the next event in the file + // loop over the raw data file and decode each word in it + // + // If something goes wrong with an unexpected word, + // a flag (eventOK) is used to return "false" + // Otherwise returns "true" + // + // JB, 2012/07/16 + // Modified: JB 2012/08/18 to store trigger info + + // -+-+- Initialization + + bool eventDone = false; // we start with event incomplete + bool eventOK = true; // we start with a good event by default + CurrentEvent = 0; // Allow to know wether data are correct + ListOfTriggers.clear(); // and clear the vectors + ListOfTimestamps.clear(); + ListOfFrames.clear(); + ListOfPixels.clear(); + + if(DebugLevel>0) { + cout << endl ; + cout << "BoardReaderEUDAQ::HasData() BoardNumber " << BoardNumber << " IMGBoardReader::HasData() - readingEvent " << ReadingEvent << " currentEvent " << CurrentEventNumber << " currentTrigger " << CurrentTriggerNumber << " currentFrame " << CurrentFrameNumber << endl; + } + + if( GetNextEvent() ) { + + eventOK = SetBufferPointers(); + if( DebugLevel>1 ) PrintEventHeader(); + + if( eventOK) { + GetTriggerData(); // JB 2012/08/18, called prior GetInputData since 2013/06/20 + GetInputData(); + + CurrentEvent = new IMGEvent( EventHeader->EvNo, BoardNumber, &ListOfTriggers, &ListOfTimestamps, &ListOfFrames, &ListOfPixels); + if( DebugLevel>1 ) cout << " BoardNumber " << BoardNumber << " create new event " << EventHeader->EvNo << " with " << ListOfPixels.size() << " pixels." << endl; + EventsCount++; + eventDone = true; + } + else{ + cout<<"BoardReaderEUDAQ::HasData() - Event is not ok!"<SetListOfTriggers( &ListOfTriggers); + fCurrentEvent->SetListOfFrames( &ListOfFrames); + }; + return true; + } + + else { + if (fDebugLevel) printf("BoardReaderEUDAQ::HasData wrong event building...stopping!\n"); + return false; + } + +} + +//------------------------------------------+----------------------------------- +bool BoardReaderEUDAQ::FetchEvent() +{ + // Read the necessary frames for all sensors from the raw data files. + // The data are stored in fData array for further decoding. + // It means, a first frame is read (or restored if already read) + // and then subsequent frames are read and associated if related + // to the same trigger. + + + // ----- First loop on sensor to build the current frame + + fIndex = 0; // index of current built event + fBackupIndex = 0; //index of backup data for current event + fEventSize = 0; + //cout << "BoardReaderEUDAQ::FetchEvent declaring temporary backup of size " << fNumberOfSensors*sizeof(MI26_FrameRaw) << endl; + unsigned int *tempDataBackup = new unsigned int[fNumberOfSensors*sizeof(MI26_FrameRaw)]; + int tempBackupIndex = 0; // index of data to backup for next event + + for (int iSensor = 0; iSensor < fNumberOfSensors; ++iSensor) { // Loop on all sensors + + if (fDebugLevel) printf("BoardReaderEUDAQ::FetchEvent fetching frames for event %d sensor %d\n", fEventNumber, iSensor); + + // Get the first frame + MI26_FrameRaw* data = new MI26_FrameRaw; + if ( fBackupSize[iSensor]!=0 ) { // if already read, restore + GetBackupData( iSensor, data); + } + else { // read a new one + if (!GetStart(iSensor)) return false; + GetFrame(iSensor, data); + } + unsigned int trigger = data->TriggerCnt; + if (fDebugLevel>2) printf("BoardReaderEUDAQ::FetchEvent found trigger %d in first frame for sensor %d\n", trigger, iSensor); + ListOfFrames.push_back( data->FrameCnt); + + // Get subsequent frames + GetNextFrames(iSensor, trigger, tempDataBackup, tempBackupIndex); + + delete data; + if (fDebugLevel>2) printf("BoardReaderEUDAQ::FetchEvent end data for trigger %d and sensor %d\n", trigger, iSensor); + + } // end loop on all sensors + + if(fDebugLevel>4) + for (int i = 0; i < fEventSize; ++i) + printf("Data %x\n", fData[i]); + + if (fDebugLevel>2) printf("BoardReaderEUDAQ::FetchEvent end event %d with size %d words\n", fEventNumber, fEventSize); + fEventNumber++; + + + // ----- Second loop on sensors to build the current frame + + if (fDebugLevel) printf("BoardReaderEUDAQ::FetchEvent transfering %d backup words for next event\n", tempBackupIndex); + + for (int iword = 0; iword < tempBackupIndex; iword++) { + fDataBackup[iword] = tempDataBackup[iword]; + } + + + return true; +} + +// private method +// -------------------------------------------------------------------------------------- +bool BoardReaderEUDAQ::GetStart(int iSensor) +{ + // Test if first word of the frame matches sensor id, + // return false if not. + + unsigned int key = GetKeyHeader(iSensor); + + do { +// fread(tmp, sizeof(unsigned int), 1, fRawFileFAdc[iSensor]); + fscanf( fRawFileFAdc[iSensor], "%x", &(fData[fIndex])); + if (fDebugLevel>3) printf("BoardReaderEUDAQ::GetStart first header word %x at index %d (expedted key=%x) for sensor %d\n", fData[fIndex], fIndex, key, iSensor); + if (fData[fIndex] == key) { + if (fDebugLevel>1) printf("BoardReaderEUDAQ::GetStart found starting key %x for sensor %d\n", key, iSensor); + fIndex++; + return true; + } + } while (!feof(fRawFileFAdc[iSensor])); + + return false; +} + +// -------------------------------------------------------------------------------------- +void BoardReaderEUDAQ::GetNextFrames(int iSensor, unsigned int trigger, unsigned int *dataBackup, int &backupIndex) +{ + + // Read additional frames with respect to a first one define by the given trigger. + // When the newly read frame does not match the given trigger, + // backup the data of this frame for the next event. + + if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetNextFrames Getting a potential next frame for sensor %d, current index %d\n", iSensor, fIndex); + + MI26_FrameRaw* data = new MI26_FrameRaw; + bool sameTrigger = true; + int index = 0; + do { + index = fIndex; + if( GetStart(iSensor) ) { + GetFrame(iSensor, data); + if (fDebugLevel>3) printf(" testing trigger %d from new frame / current trigger %d for sensor %d\n", data->TriggerCnt, trigger, iSensor); + if (data->TriggerCnt != trigger) { + sameTrigger = false; + if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetNextFrames the new frame does not match current trigger %d and is not used for sensor %d\n File pointer reader is rewinded by 1 frame.\n", trigger, iSensor); + break; + } + ListOfFrames.push_back( data->FrameCnt); + if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetNextFrames new frame added to current trigger %d for sensor %d\n", trigger, iSensor); + } + else break; + } while(sameTrigger); + + // At this step, two options: + // 1) the last frame does not match the current event (sameTrigger == false) + // -> The already read data shall be backup to avoid reading it again ! + // 2) there is no more frame to read + // -> Indicate there are no backup data + + if ( !sameTrigger) { + //fseek(fRawFileFAdc[iSensor], -2*sizeof(MI26_FrameRaw), SEEK_CUR); + fBackupSize[iSensor] = fIndex - index; + for (int iword=0; iword2) printf( "BoardReaderEUDAQ::GetNextFrames ===> Data were back-up over %d words with header %x, trigger %x, frame %x, for sensor %d\n", fBackupSize[iSensor], fData[index], fData[index+1], fData[index+3], iSensor); + } + + else { + fBackupSize[iSensor] = 0; + if (fDebugLevel) printf( "BoardReaderEUDAQ::GetNextFrames There is no more frame to read for sensor %d!\n", iSensor); + } + + fIndex = index; + fEventSize = fIndex; + if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetNextFrames event size is now %d for sensor %d\n", fEventSize, iSensor); + + delete data; + +} + +// -------------------------------------------------------------------------------------- +void BoardReaderEUDAQ::GetFrame(int iSensor, MI26_FrameRaw* data) +{ + + if (fDebugLevel>2) printf("Getting a new frame for sensor %d, current index %d\n", iSensor, fIndex); + + // 4 more words of frame header + fscanf( fRawFileFAdc[iSensor], "%x", &(fData[fIndex++])); + if (fDebugLevel>3) printf("new header word %x at index %d for sensor %d\n", fData[fIndex-1], fIndex-1, iSensor); + fscanf( fRawFileFAdc[iSensor], "%x", &(fData[fIndex++])); + if (fDebugLevel>3) printf("new header word %x at index %d for sensor %d\n", fData[fIndex-1], fIndex-1, iSensor); + fscanf( fRawFileFAdc[iSensor], "%x", &(fData[fIndex++])); + if (fDebugLevel>3) printf("new header word %x at index %d for sensor %d\n", fData[fIndex-1], fIndex-1, iSensor); + fscanf( fRawFileFAdc[iSensor], "%x", &(fData[fIndex++])); + if (fDebugLevel>3) printf("new header word %x at index %d for sensor %d\n", fData[fIndex-1], fIndex-1, iSensor); + + memcpy(data, &fData[fIndex-GetHeaderSize()], GetHeaderSize()*sizeof(unsigned int)); + + unsigned int dataLength = ((data->DataLength & 0xFFFF0000)>>16); + if (fDebugLevel>2) printf("datalength is %d words from %x for sensor %d\n", dataLength, data->DataLength, iSensor); + + + //fread(&fData[fIndex], sizeof(int), dataLength, fRawFileFAdc[iSensor]); + for (int idata=0; idata3) printf("new data word %x at index %d for sensor %d\n", fData[fIndex-1], fIndex-1, iSensor); + } + + fscanf( fRawFileFAdc[iSensor], "%x", &(fData[fIndex++])); + if (fDebugLevel>3) printf("new trailer word %x at index %d for sensor %d\n", fData[fIndex-1], fIndex-1, iSensor); + + if( fData[fIndex-1] != GetTailHeader() ) { + printf("BoardReaderEUDAQ::GetFrame frame probably incomplete, wrong trailer %x instead of %x!!!\n", fData[fIndex-1], GetTailHeader()); + } + else if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetFrame got a new frame for sensor %d: new index = %d, trailer =%x\n", iSensor, fIndex, fData[fIndex-1]); + + fFramesReadFromFile++; + +} + +// -------------------------------------------------------------------------------------- +void BoardReaderEUDAQ::GetBackupData(int iSensor, MI26_FrameRaw* data) +{ + + if (fDebugLevel>2) printf("Getting backup data (%d words) from frame already read for sensor %d, current index %d\n", fBackupSize[iSensor], iSensor, fIndex); + + // copy the backup words into the data buffer + for (int iword=0; iword3) printf("backup word[%d]=%x copied to index %d for sensor %d\n", fBackupIndex-1, fData[fIndex-1], fIndex-1, iSensor); + } + + if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetBackupData first frame for sensor %d: header %x, trigger %x frame %x dataLength %x\n", iSensor, data->Header, data->TriggerCnt, data->FrameCnt, data->DataLength); + +} + +// -------------------------------------------------------------------------------------- +void BoardReaderEUDAQ::AddPixel( int iSensor, int value, int aLine, int aColumn) +{ + // Add a pixel to the vector of pixels + // require the following info + // - input = number of the sensors (start at 1 !!!!!) + // - value = analog value of this pixel + // - line & column = position of the pixel in the matrix + + if (fDebugLevel>2) printf("BoardReaderEUDAQ::Addpixel adding pixel for sensor %d with value %d line %d row %d\n", iSensor, value, aLine, aColumn); + + ListOfPixels.push_back( BoardReaderPixel( iSensor+1, value, aLine, aColumn, 0) ); + +#ifdef withROOT + if (ValidHistogram()) { + fpHisPixelMap[iSensor]->Fill(aLine, aColumn); + fpHisRateMap[iSensor]->Fill(aColumn); + for (int i = 0; i < 4; ++i) { + if (aColumn >= 258*i && aColumn < (i+1)*258) + fpHisRateMapQ[iSensor]->Fill(i+1); + } + } +#endif + +} + +// -------------------------------------------------------------------------------------- +int BoardReaderEUDAQ::GetSensor(unsigned int key) +{ +// key = (key >> 16) & 0xFFFF; + if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetSensor searching for sensor with key %x\n", key); + + for (int i = 0; i < fNumberOfSensors; i++) { + if (GetKeyHeader(i) == key) { + if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetSensor found sensor %d\n", i); + return i; + } + } + + if (fDebugLevel>2) printf("BoardReaderEUDAQ::GetSensor NOT FOUND!\n"); + return -1; + +} + +// -------------------------------------------------------------------------------------- +bool BoardReaderEUDAQ::CheckTriggerCnt(unsigned int trig) +{ + if (fCurrentTriggerCnt == 0) { + fCurrentTriggerCnt = trig; + ListOfTriggers.push_back( trig); + return true; + } + + if (fCurrentTriggerCnt != trig) + return false; + + return true; +} + +// -------------------------------------------------------------------------------------- +bool BoardReaderEUDAQ::DecodeFrame() +{ + // Read the information of a frame for a given sensor + // We use extensively the structure definined by Gille Clauss + + if (fDebugLevel) printf("BoardReaderEUDAQ::DecodeFrame decoding event %d with size %d\n", fEventNumber, fEventSize); + + fIndex = 0; + while (fIndex < fEventSize) { // Loop on the full event data + + MI26_FrameRaw *frame = (MI26_FrameRaw*)(&fData[fIndex]); + int iSensor = GetSensor(frame->Header); + int localNbOfPixels = 0; + if (!CheckTriggerCnt(frame->TriggerCnt)) { + printf("BoardReaderEUDAQ::DecodeFrame() wrong trigger number %d instead of %d for sensor %d\n",frame->TriggerCnt, fCurrentTriggerCnt, iSensor); + return false; + } + if (fDebugLevel) printf("BoardReaderEUDAQ::DecodeFrame frame matches current trigger %d for sensor %d\n", frame->TriggerCnt, iSensor); + + int dataLength = ((frame->DataLength & 0xFFFF0000)>>16); + unsigned short *frameData = (unsigned short*)(&fData[fIndex+fgkHeaderSize]); + fIndex += fgkHeaderSize + dataLength + 1; + dataLength *= 2; // go to short + +// if (ValidHistogram()) { +// fpHisEvtLength[iSensor]->Fill(frame->TriggerCnt % 1000, dataLength/2); +// if (frame->TriggerCnt % 1000 == 0) fpHisEvtLength[iSensor]->Reset(); +// } + + if (iSensor == -1) { + printf("BoardReaderEUDAQ::DecodeFrame() wrong header key %x\n",frame->Header); + return false; + } + + // -+-+- Pointers AND LOOP to usefull data, i.e. line and states + MI26__TStatesLine* lineStatus; + MI26__TState* state; + + int index = 0; + while( index < dataLength) { // Loop over usefull data + // first 16 bits word is the Status/Line + lineStatus = (MI26__TStatesLine*)frameData; + + if (fDebugLevel > 3) + printf("frame %x %x #state %d Line add %d ovf %d\n", frameData[0], frameData[1], lineStatus->F.StateNb, lineStatus->F.LineAddr, lineStatus->F.Ovf); + + frameData += 1; // goto next word + index += 2; + + if( lineStatus->F.Ovf > 0 ) { // Stop when overflow + if(fEventsOverflow%1000==0) + printf("WARNING : overflow while reading frame %d and sensor %d, total overflow number is %d\n", + frame->FrameCnt, iSensor, fEventsOverflow); + fOverflow = true; + } + + if(fDebugLevel>3) + printf(" line %d, #states %d, overflow %d\n", + lineStatus->F.LineAddr, lineStatus->F.StateNb, lineStatus->F.Ovf); + + fNStatesInLine = 0; + // Next words are the states if any + for( int iState = 0; iState < lineStatus->F.StateNb; iState++ ) { // loop over states found on sensor + state = (MI26__TState*)frameData; + frameData += 1; // goto next word + //index++; + if(lineStatus->F.StateNb!=1) index++; // proposed by Ilaria, 2014/08/27 + if(fDebugLevel > 3) + printf(" number of states %d, number of hits %d,\n", lineStatus->F.StateNb, state->F.HitNb+1); + + fNStatesInLine++; + + // A state contains HitNb+1 pixels + // the first pixel being on the left at the column ColAddr + for( int iPixel=0; iPixel < state->F.HitNb+1; iPixel++) { // loop on pixels in the state + + if(fDebugLevel > 3) + printf(" line %d, col %d,\n", lineStatus->F.LineAddr, state->F.ColAddr+iPixel); + + // create a new pixel only if we are reading an event + // and if the line is in the proper limit + if ( !lineStatus->F.Ovf || !fVetoOverflow ) { + AddPixel( iSensor, 1, lineStatus->F.LineAddr, state->F.ColAddr+iPixel); // sensor starts at zero here + localNbOfPixels++; +// if (pDatRaw->GetPixelsN(iSensor) > pConfig->GetAnalysisPar().HitsInPlaneMaximum) return false; + + } + } + + if(fDebugLevel>2) + printf(" state %d, #pixels %d, column %d at mem.pos %ld\n", + iState, state->F.HitNb+1, state->F.ColAddr, (long int)state); + } // end loop over states + + } // end loop over usefull data + + if( fDebugLevel>2 ) printf(" --> Current frame %d for sensor %d has %d pixels.\n", frame->FrameCnt, iSensor, localNbOfPixels); + + } // end loop on the full event data + + // Count event with overflow + if (fOverflow) { + fEventsOverflow++; + } + + return true; +} + +// -------------------------------------------------------------------------------------- + +void BoardReaderEUDAQ::PrintStatistics(ostream &stream) { + + // Print statistics on the events read by this board + // + // JB, 2014/05/13 + + stream << "***********************************************" << endl; + stream << " Board VME " << fBoardNumber << " found:" << endl; + stream << fCurrentTriggerCnt << " triggers." << endl; + stream << fEventNumber << " events in total," << endl; + stream << fEventsOverflow << " events with an overflow (veto overflow " << fVetoOverflow << ")." << endl; + stream << fFramesReadFromFile<< " frames read overall." << endl; + stream << "***********************************************" << endl; + +} + + diff --git a/src/BoardReaderIHEP.cxx b/src/BoardReaderIHEP.cxx new file mode 100644 index 0000000..c78f333 --- /dev/null +++ b/src/BoardReaderIHEP.cxx @@ -0,0 +1,1095 @@ +///////////////////////////////////////////////////////////// +// Class Description of BoardReaderIHEP +// +// Dedicated to decode output files from the IHEP acquisition system +// dedicated to MIMOSA-28 sensors +// +// This class wraps up the original code of Mingyi DONG, IHEP, 2018/02/11 +// +///////////////////////////////////////////////////////////// +// +// created JB, 2018/06/03 + +#include "BoardReaderIHEP.h" + +ClassImp(BoardReaderIHEP); + +//------------------------------------------+----------------------------------- +BoardReaderIHEP::BoardReaderIHEP(int boardNumber, int triggerMode, int eventBuildingMode) { + + vi_Verbose = 100; + + N_COLUMN = 960; + N_ROW = 928; + N_BANK = 4; + N_BANKCOLUMN = N_COLUMN / N_BANK; + + BYTE = 1; // 1Byte = 8bits + WORD = 2; // 1Word = 2Byte = 16bits (Mi28 default) + DWORD = 4; // 1DWord = 2Word = 32bits + + M_LADDER_HEADER = 0xCCCCCC ; // Ladder Header Marker 32 bits : 0xCCCCCCXX, Check the Big 24 bits + M_LADDER_CHIP = 0x3333333 ; // Ladder Trailer Marker 32 bits : 0x3333333X, Check the Big 28 bits + M_LADDER_TRAILER = 0x99999999 ; // Ladder Trailer Marker 32 bits : 0xCCCCCCCC, Check all the 32 bits + M_LADDER_TriggerHeader = 0xDDDDDDDD ; // Ladder Trigger Header Marker 32 bits : 0x55555555, Check all the 32 bits + M_LADDER_TriggerTRAILER = 0x66666666 ; // Ladder Trigger Trailer Marker 32 bits : 0x66666666, Check all the 32 bits + + vi_Trigger_Header = 0; + vi_Trigger_ID = 0; + vi_Pack_Length = 0; + vi_Pack_State = 0; + vi_Trigger_Trailer = 0; + vi_Ladder_Header = 0; + vi_Ladder_Header_1 = 0; + vi_Ladder_DataLength = 0; + vi_Ladder_Trigger = 0; + vi_Ladder_FrameCounter = 0; + vi_Ladder_Chip = 0; + vi_Ladder_Chip_1 = 0; + vi_Ladder_Trailer = 0; + vi_ID_Ladder = 0; + vi_ID_Ladder_Chip = 0; + vi_N_Ladder_Chip = 0; + + M_CHIP_HEADER = 0x12345678; // hex=1234 5678 + M_CHIP_TRAILER = 0xaaaaaaaa; // hex=aaaa aaaa + + /* Signification of the bits in the Status/Line word */ + M_CHIP_N_STATE = 15 ; // Status/Line, 0-3, number of States + M_CHIP_ADDRESS_LINE = 16368 ; // Status/Line, 4-13, address of the line + M_CHIP_FLAG_RESIDUAL_1 = 16384 ; // Status/Line, 14, 1 bit zero + M_CHIP_FLAG_OVERFLOW = 32768 ; // Status/Line, 15, overflow + + /* Signification of the bits in the State word */ + M_CHIP_N_PIXEL = 3 ; // State, 0-1, number of Pixels + M_CHIP_ADDRESS_COLUMN = 4092 ; // State, 2-11, address of the column + M_CHIP_FLAG_RESIDUAL_2 = 61440 ; // State, 12-15, 4 bits zero + + /* Values for a frame */ + vi_DataRaw = 0; + vi_Chip_Header = 0; + vi_Chip_FrameCounter = 0; + vi_Chip_DataLength = 0; + vi_Chip_DataLength_1 = 0; + vi_Chip_DataLength_2 = 0; + vi_Chip_Status = 0; + vi_Chip_N_State = 0; + vi_Chip_Address_Line = 0; + vi_Chip_Flag_Residual_1 = 0; + vi_Chip_Flag_OverFlow = 0; + vi_Chip_State = 0; + vi_Chip_N_Pixel = 0; + vi_Chip_Address_Column = 0; + vi_Chip_Flag_Residual_2 = 0; + vi_Chip_Trailer = 0; + vi_Column_Temp = 0; + + /* Pointers */ + vi_Pointer_Data = 0; + vi_Pointer_Pack_DataLength = 0; + vi_Pointer_Ladder_DataLength = 0; + vi_Pointer_Chip_DataLength = 0; + + vi_N_Frame_Good = 0; + vi_N_Frame_Bad = 0; + + vd_N_PixelTotal = 0; + vd_N_PixelBankA = 0; + vd_N_PixelBankB = 0; + vd_N_PixelBankC = 0; + vd_N_PixelBankD = 0; + + fBoardNumber = boardNumber; + fEventBuildingMode = eventBuildingMode; + + cout << "*****************************************" << endl; + cout << " < BoardReaderIHEP constructor > " << endl; + cout << "*****************************************" << endl; + cout << "Creating a BoardReaderIHEP" << endl; + cout << " * for board : " << fBoardNumber << endl; + cout << " * for sensor type : MIMOSA-28" << endl; + cout << " * with eventBuildingMode : " << fEventBuildingMode << endl; + + cout << " INFO BoardReaderIHEP the Data format is : " + << std::setw(15) << "hex" + << std::setw(15) << "dec" + << std::setw(15) << "Pointer" << endl; + + fEventNumber = 0; + fCurrentEvent = NULL; + i_Trigger=0; + for (int it=0; it<6; it++) { Trigger[it] = 0; } + memset(Trigger_Framcount, 0, sizeof(Trigger_Framcount)); + + iFile = 0; + + cout << " < BoardReaderIHEP constructor DONE > " << endl; +} + +//------------------------------------------+----------------------------------- +BoardReaderIHEP::~BoardReaderIHEP() +{ + +// delete fCurrentEvent; +// delete fInputFileName; + +} + +// -------------------------------------------------------------------------------------- + +bool BoardReaderIHEP::AddFile(const char *fileName) { + // Adapted from method sent on 2018/08/14 + + /* Open the input Raw Data file, Data getting from FPGA, default txt in 18 32bit-words */ + ifs_DataRaw.close(); + ifs_DataRaw.clear(); + ifs_DataRaw.open( fileName, ios::in|ios::binary); + if (!ifs_DataRaw.good()) + { + cout << "ERROR : Mi28DecodeLadderDataToRoot(), Failed to open input file: " << fileName << endl; + return false; + } + else + { + cout << "INFO : BoardReaderIHEP::AddFile, Successfully open input file: " << fileName << endl; + } + /* Get the size of the binary file */ + ifs_DataRaw.seekg(0, ios::beg); + vi_Pointer_FileBegin = ifs_DataRaw.tellg(); + ifs_DataRaw.seekg(0, ios::end); + vi_Pointer_FileEnd = ifs_DataRaw.tellg(); + vi_N_FileSize = vi_Pointer_FileEnd - vi_Pointer_FileBegin; + ifs_DataRaw.seekg(0, ios::beg); + cout << "INFO : Mi28DecodeLadderDataToRoot(), The input file size is : " << vi_N_FileSize << endl; + cout << "------------------------------------------------------" << endl; + + return true; +} + +// -------------------------------------------------------------------------------------- + +bool BoardReaderIHEP::HasData( ) { + + // Try to find the data for the next event in the file + // loop over the raw data file and decode each word in it + // + // If something goes wrong with an unexpected word, + // a flag (eventOK) is used to return "false" + // Otherwise returns "true" + // + // JB, 2018/07/16 + // Modified, JB, 2018/10/08 + + // -+-+- Initialization + + bool eventOK = true; // we start with a good event by default + fCurrentEvent = 0; // Allow to know wether data are correct + ListOfTriggers.clear(); // and clear the vectors + ListOfTimestamps.clear(); + ListOfFrames.clear(); + ListOfPixels.clear(); + + if(vi_Verbose<10) { + cout << endl ; + cout << "BoardReaderIHEP::HasData() BoardNumber " << fBoardNumber << " IMGBoardReader::HasData() - currentEvent " << fEventNumber << " currentTrigger " << i_Trigger << endl; + } + + if( DecodeNextEvent() ) { + + if( vi_Verbose<10 ) PrintEventHeader(); + + fCurrentEvent = new BoardReaderEvent( fEventNumber, fBoardNumber, 0, &ListOfPixels); // run number set to 0 for now + fCurrentEvent->SetListOfTriggers( &ListOfTriggers); + fCurrentEvent->SetListOfFrames( &ListOfFrames); + if( vi_Verbose<10 ) cout << " BoardNumber " << fBoardNumber << " create new event " << fEventNumber << " with " << ListOfPixels.size() << " pixels" << " from " << ListOfTriggers.size() << " and " << ListOfFrames.size() << " frames." << endl; + fEventNumber++; + + } // getting next buffer was OK + else{ + eventOK = false; + cout<<"BoardReaderIHEP::HasData() - Can't get next frame !"< vi_Pointer_FileEnd) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), file is incomplete at !! Ladder_Header !!, STOP DECODING!" << endl; + break; + } + + /* ------------------------------------------------------ */ + /* Trigger_Header*/ + ifs_DataRaw.read((char *)&vi_Trigger_Header, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Trigger_Header = SwitchDWordWords(vi_Trigger_Header); + if (vi_Trigger_Header != M_LADDER_TriggerHeader) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), find a bad Checking Trigger_Header : " + << std::setw(15) << std::setbase(16) << vi_Trigger_Header << " VS " + << std::setw(11) << std::setbase(16) << M_LADDER_TriggerHeader << "\t@\t" + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + ifs_DataRaw.seekg(BYTE -DWORD, ios::cur); /* Return the Pointer */ + continue; /* Continue to Check Trigger_Header */ + } + else + { + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Checking Trigger_Header is : " + << std::setw(15) << std::setbase(16) << vi_Trigger_Header + << std::setw(15) << std::setbase(10) << vi_Trigger_Header + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + } + /*-------------------------------------------------------*/ + /* Trigger ID */ + ifs_DataRaw.read((char *)&vi_Trigger_ID, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Trigger_ID = SwitchDWordWords(vi_Trigger_ID); + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Trigger_ID is : " + << std::setw(15) << std::setbase(16) << vi_Trigger_ID + << std::setw(15) << std::setbase(10) << vi_Trigger_ID + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + /*--------------------------------------------------------*/ + /*PackLength*/ + ifs_DataRaw.read((char *)&vi_Pack_Length, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Pack_Length = SwitchDWordWords(vi_Pack_Length); + vi_Pointer_Pack_DataLength = vi_Pointer_Data; + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Pack_Length is : " + << std::setw(15) << std::setbase(16) << vi_Pack_Length + << std::setw(15) << std::setbase(10) << vi_Pack_Length + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + + /* Check the the file size */ + if ((vi_Pointer_Data + vi_Pack_Length*BYTE + DWORD) > vi_Pointer_FileEnd) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), file is incomplete at !! Trigger Trailer !!, STOP DECODING!" << endl; + vi_N_Frame_Bad++; + break; + } + /*-----------------------------------------------------------*/ + /* Pack State*/ + ifs_DataRaw.seekg(WORD, ios::cur); + /*------------------------------------------------------------*/ + /* ------------------------------------------------------ */ + /*-------------------------------------------------------*/ + /* Trigger Trailer*/ + ifs_DataRaw.seekg(vi_Pack_Length*BYTE, ios::cur); + ifs_DataRaw.read((char *)&vi_Trigger_Trailer, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + ifs_DataRaw.seekg(-vi_Pack_Length*BYTE - DWORD, ios::cur); /* Return the Pointer */ + vi_Trigger_Trailer = SwitchDWordWords(vi_Trigger_Trailer); + if (vi_Trigger_Trailer != M_LADDER_TriggerTRAILER) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), find a bad Checking Trigger_Trailer : " + << std::setw(15) << std::setbase(16) << vi_Trigger_Trailer << " VS " + << std::setw(11) << std::setbase(16) << M_LADDER_TriggerTRAILER << "\t@\t" + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* Return to Pointer Ladder_DataLength, Continue a new Ladder_Frame */ + ifs_DataRaw.seekg(BYTE - 3*DWORD, ios::cur); /* Return the Pointer */ + continue; /* Continue to Check Trigger_Header */ + } + else + { + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Checking Trigger_Trailer is : " + << std::setw(15) << std::setbase(16) << vi_Trigger_Trailer + << std::setw(15) << std::setbase(10) << vi_Trigger_Trailer + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + } + /*-----------------------------------------------------------*/ + /* Recycling decode the data for less than 5 Ladder */ + /*-----------------------------------------------------------*/ + int vi_N_Ladder = 0; + int vi_N_Ladder_Chip = 0; + while (ifs_DataRaw.tellg() < (vi_Pointer_Pack_DataLength + vi_Pack_Length*BYTE)) + { + /*-----------------------------------------------------------*/ + /* Pack State*/ + + /*------------------------------------------------------------*/ + /* ------------------------------------------------------ */ + /* Ladder_Header */ + ifs_DataRaw.read((char *)&vi_Ladder_Header, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Ladder_Header_1 = SwitchDWordWords(vi_Ladder_Header); + vi_ID_Ladder = vi_Ladder_Header_1 & 0xFF; + vi_Ladder_Header = vi_Ladder_Header_1 >> 8; + if (vi_Ladder_Header != M_LADDER_HEADER) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), find a bad Ladder_Header : " + << std::setw(15) << std::setbase(16) << vi_Ladder_Header << " VS " + << std::setw(11) << std::setbase(16) << M_LADDER_HEADER << "\t@\t" + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* Pass the first BYTE, and Continue to Check Ladder_Header */ + ifs_DataRaw.seekg(BYTE - DWORD, ios::cur); /* Return the Pointer */ + continue; /* Continue to Check Ladder_Header */ + } + else + { + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Ladder_Header is : " + << std::setw(15) << std::setbase(16) << vi_Ladder_Header_1 + << std::setw(15) << std::setbase(10) << vi_Ladder_Header_1 + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + } + /* ------------------------------------------------------ */ + /* Ladder_Trigger */ + ifs_DataRaw.read((char *)&vi_Ladder_Trigger, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Ladder_Trigger = SwitchDWordWords(vi_Ladder_Trigger); + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Ladder_Trigger is : " + << std::setw(15) << std::setbase(16) << vi_Ladder_Trigger + << std::setw(15) << std::setbase(10) << vi_Ladder_Trigger + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* ------------------------------------------------------ */ + + /* ------------------------------------------------------ */ + /* Ladder_FrameCounter */ + ifs_DataRaw.read((char *)&vi_Ladder_FrameCounter, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Ladder_FrameCounter = SwitchDWordWords(vi_Ladder_FrameCounter); + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Ladder_FrameCounter is : " + << std::setw(15) << std::setbase(16) << vi_Ladder_FrameCounter + << std::setw(15) << std::setbase(10) << vi_Ladder_FrameCounter + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + // if the timestamp has not be set yet, + // => start with 1 + // => new trigger + if( timestamp==0 ) { + ListOfTriggers.push_back( vi_Ladder_FrameCounter); + timestamp = 1; + frameID2setTime = vi_Ladder_FrameCounter; + ladderID2setTime = vi_ID_Ladder; + } + // if the ladder ID is different, + // => this is the 1st timestamp of a new ladder + else if( ladderID2setTime!=vi_ID_Ladder ) { + timestamp = 1; + frameID2setTime = vi_Ladder_FrameCounter; + ladderID2setTime = vi_ID_Ladder; + } + // if the timestamp is already 1 for the same ladder. + // => this is the second frame + else if( timestamp==1 && ladderID2setTime==vi_ID_Ladder ){ + timestamp = 2; + } + ListOfFrames.push_back(vi_Ladder_FrameCounter); + + + /* ------------------------------------------------------ */ + /* Ladder_DataLength */ + ifs_DataRaw.read((char *)&vi_Ladder_DataLength, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Ladder_DataLength = SwitchDWordWords(vi_Ladder_DataLength); + vi_Pointer_Ladder_DataLength = vi_Pointer_Data; + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Ladder_DataLength is : " + << std::setw(15) << std::setbase(16) << vi_Ladder_DataLength + << std::setw(15) << std::setbase(10) << vi_Ladder_DataLength + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* Check the the file size */ + if ((vi_Pointer_Data + vi_Ladder_DataLength*WORD + DWORD) > vi_Pointer_FileEnd) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), file is incomplete at !! Ladder_Trailer !!, STOP DECODING!" << endl; + vi_N_Frame_Bad++; + break; + } + + /* ------------------------------------------------------ */ + /* Ladder_Trailer */ + ifs_DataRaw.seekg(vi_Ladder_DataLength*WORD, ios::cur); + ifs_DataRaw.read((char *)&vi_Ladder_Trailer, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + ifs_DataRaw.seekg(-vi_Ladder_DataLength*WORD - DWORD, ios::cur); /* Return the Pointer */ + vi_Ladder_Trailer = SwitchDWordWords(vi_Ladder_Trailer); + if (vi_Ladder_Trailer != M_LADDER_TRAILER) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), find a bad Checking Ladder_Trailer : " + << std::setw(15) << std::setbase(16) << vi_Ladder_Trailer << " VS " + << std::setw(11) << std::setbase(16) << M_LADDER_TRAILER << "\t@\t" + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* Return to Pointer Ladder_DataLength, Continue a new Ladder_Frame */ + ifs_DataRaw.seekg(BYTE - 4*DWORD, ios::cur); /* Return the Pointer */ + continue; /* Continue to Check Ladder_Header */ + } + else + { + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Checking Ladder_Trailer is : " + << std::setw(15) << std::setbase(16) << vi_Ladder_Trailer + << std::setw(15) << std::setbase(10) << vi_Ladder_Trailer + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + } + + /* ------------------------------------------------------ */ + /* Recycling decode the data for less than 10 chips */ + /* ------------------------------------------------------ */ + + while (ifs_DataRaw.tellg() < (vi_Pointer_Ladder_DataLength + vi_Ladder_DataLength*WORD)) + { + /* ------------------------------------------------------ */ + /* Ladder_Chip */ + ifs_DataRaw.read((char *)&vi_Ladder_Chip, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Ladder_Chip_1 = SwitchDWordWords(vi_Ladder_Chip); + vi_ID_Ladder_Chip = vi_Ladder_Chip_1 & 0xF; + vi_Ladder_Chip = vi_Ladder_Chip_1 >> 4; + if (vi_Ladder_Chip != M_LADDER_CHIP) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), find a bad Ladder_Chip : " + << std::setw(15) << std::setbase(16) << vi_Ladder_Chip << " VS " + << std::setw(11) << std::setbase(16) << M_LADDER_CHIP << "\t@\t" + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* Return to Pointer Ladder_Chip, Continue a new Ladder_Chip */ + ifs_DataRaw.seekg(BYTE - DWORD, ios::cur); /* Return the Pointer */ + continue; /* Continue to Check Ladder_Chip */ + } + else + { + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Ladder_Chip is : " + << std::setw(15) << std::setbase(16) << vi_Ladder_Chip_1 + << std::setw(15) << std::setbase(10) << vi_Ladder_Chip_1 + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + } + + /* ------------------------------------------------------ */ + /* Chip_Header */ + ifs_DataRaw.read((char *)&vi_Chip_Header, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Chip_Header = SwitchDWordWords(vi_Chip_Header); + if (vi_Chip_Header != M_CHIP_HEADER) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), find a bad Chip_Header : " + << std::setw(15) << std::setbase(16) << vi_Chip_Header << " VS " + << std::setw(11) << std::setbase(16) << M_CHIP_HEADER << "\t@\t" + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* Return to Pointer Ladder_Chip, Continue a new Ladder_Chip */ + ifs_DataRaw.seekg(BYTE - 2*DWORD, ios::cur); /* Return the Pointer */ + continue; /* Continue to Check Ladder_Chip */ + } + else + { + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Chip_Header is : " + << std::setw(15) << std::setbase(16) << vi_Chip_Header + << std::setw(15) << std::setbase(10) << vi_Chip_Header + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + } + + /* ------------------------------------------------------ */ + /* Chip_FrameCounter */ + ifs_DataRaw.read((char *)&vi_Chip_FrameCounter, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Chip_FrameCounter = SwitchDWordWords(vi_Chip_FrameCounter); + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Chip_FrameCounter is : " + << std::setw(15) << std::setbase(16) << vi_Chip_FrameCounter + << std::setw(15) << std::setbase(10) << vi_Chip_FrameCounter + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* ------------------------------------------------------ */ + /* Chip_DataLength */ + ifs_DataRaw.read((char *)&vi_Chip_DataLength_1, WORD); + ifs_DataRaw.read((char *)&vi_Chip_DataLength_2, WORD); + vi_Chip_DataLength_1 = SwitchWordBytes(vi_Chip_DataLength_1); + vi_Chip_DataLength_2 = SwitchWordBytes(vi_Chip_DataLength_2); + vi_Chip_DataLength = vi_Chip_DataLength_1 + vi_Chip_DataLength_2; + vi_Pointer_Data = ifs_DataRaw.tellg(); + vi_Pointer_Chip_DataLength = vi_Pointer_Data; + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Chip_DataLength is : " + << std::setw(15) << std::setbase(16) << vi_Chip_DataLength + << std::setw(15) << std::setbase(10) << vi_Chip_DataLength + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* Check the the file size */ + if ((vi_Chip_DataLength*WORD + DWORD) > vi_Ladder_DataLength*WORD) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), file frame is incomplete at !! Chip_Trailer !!, STOP DECODING!" << endl; + vi_N_Frame_Bad++; + break; + } + + /* ------------------------------------------------------ */ + /* Chip_Trailer */ + ifs_DataRaw.seekg(vi_Chip_DataLength*WORD, ios::cur); + ifs_DataRaw.read((char *)&vi_Chip_Trailer, DWORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + ifs_DataRaw.seekg(-vi_Chip_DataLength*WORD - DWORD, ios::cur); /* Return the Pointer */ + vi_Chip_Trailer = SwitchDWordWords(vi_Chip_Trailer); + if (vi_Chip_Trailer != M_CHIP_TRAILER) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), find a bad Checking Chip_Trailer : " + << std::setw(15) << std::setbase(16) << vi_Chip_Trailer << " VS " + << std::setw(11) << std::setbase(16) << M_CHIP_TRAILER << "\t@\t" + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + + /* Return to Pointer Ladder_Chip, Continue a new Ladder_Chip */ + ifs_DataRaw.seekg(BYTE - 4*DWORD, ios::cur); /* Return the Pointer */ + continue; /* Continue to Check Ladder_Chip */ + } + else + { + if (vi_Verbose < 6) + { + cout << " INFO : Mi28DecodeLadderDataToRoot(), the Checking Chip_Trailer is : " + << std::setw(15) << std::setbase(16) << vi_Chip_Trailer + << std::setw(15) << std::setbase(10) << vi_Chip_Trailer + << std::setw(15) << std::setbase(10) << vi_Pointer_Data << endl; + } + } + + /* ------------------------------------------------------ */ + /* Deal with useful data */ + /* ------------------------------------------------------ */ + while (ifs_DataRaw.tellg() < (vi_Pointer_Chip_DataLength + vi_Chip_DataLength*WORD)) + { + /* Chip_Status */ + ifs_DataRaw.read((char *)&vi_DataRaw, WORD); + vi_Pointer_Data = ifs_DataRaw.tellg(); + + vi_Chip_Status = SwitchWordBytes(vi_DataRaw); + vi_Chip_N_State = vi_Chip_Status & M_CHIP_N_STATE; + vi_Chip_Address_Line = (vi_Chip_Status & M_CHIP_ADDRESS_LINE) >> 4; + vi_Chip_Flag_Residual_1 = (vi_Chip_Status & M_CHIP_FLAG_RESIDUAL_1) >> 14; + vi_Chip_Flag_OverFlow = (vi_Chip_Status & M_CHIP_FLAG_OVERFLOW) >> 15; + + if (vi_Verbose < 3) + { + vi_Pointer_Data = ifs_DataRaw.tellp(); + cout << " SSSSS" << endl; + cout << " INFO : Status / Pointer_Status / N_State / Address_Line is : " + << std::setw(12) << std::setbase(16) << vi_Chip_Status + << std::setw(12) << std::setbase(10) << vi_Pointer_Data + << std::setw(12) << std::setbase(10) << vi_Chip_N_State + << std::setw(12) << std::setbase(10) << vi_Chip_Address_Line << endl; + } + + /* Check the status word */ + if ((vi_Chip_Address_Line>N_ROW) || (vi_Chip_Address_Line<0)) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), Line counter is wrong, which is " + << std::setbase(10) << vi_Chip_Address_Line << " VS " + << std::setbase(10) << N_ROW << endl; + } + vi_N_Frame_Bad++; + break; + } + if (vi_Chip_Flag_Residual_1 != 0) + { + if (vi_Verbose < 4) + { + cout << " Warning : Mi28DecodeLadderDataToRoot(), Status is wrong! The status residual bit should be 0, not should be " + << std::setbase(10) << vi_Chip_Flag_Residual_1 << endl; + } + } + if (vi_Chip_Flag_OverFlow == 1) + { + if (vi_Verbose < 4) + { + cout << " Warning : Mi28DecodeLadderDataToRoot(), The status is overflow, the bit is " + << std::setbase(10) << vi_Chip_Flag_OverFlow << " @ line " + << std::setbase(10) << vi_Chip_Address_Line << endl; + } + } + + /* Skip the last data word, if not, will lead to read more one word for this frame */ + if ((vi_Pointer_Data + vi_Chip_N_State*WORD) > (vi_Pointer_Chip_DataLength + vi_Chip_DataLength*WORD)) + { + unsigned long int Checking_Stata=0; + unsigned long int M_AAAA=0xAAAA; + for(int i_word=0;i_word<100;i_word++) + { + ifs_DataRaw.read((char *)&Checking_Stata, WORD); + Checking_Stata=SwitchWordBytes(Checking_Stata); + if(Checking_Stata == M_AAAA) + { + // cout << " Warning : Mi28DecodeLadderDataToRoot(), The useful word exceeds the data length, skip this Stata which is @ " + // << std::setbase(10) << vi_Pointer_Data << " + " + // << std::setbase(10) << vi_Chip_N_State << " + "<< std::setbase(10) <> 2; + vi_Chip_Flag_Residual_2 = (vi_Chip_State & M_CHIP_FLAG_RESIDUAL_2) >> 12; + + if (vi_Verbose < 3) + { + cout << " INFO : State / Pointer_State / N_Pixel / Address_Column is : " + << std::setw(12) << std::setbase(16) << vi_Chip_State + << std::setw(12) << std::setbase(10) << vi_Pointer_Data + << std::setw(12) << std::setbase(10) << vi_Chip_N_Pixel + << std::setw(12) << std::setbase(10) << vi_Chip_Address_Column << endl; + } + + /* Check the state word */ + if ((vi_Chip_Address_Column>N_COLUMN) || (vi_Chip_Address_Column<0)) + { + if (vi_Verbose < 11) + { + cout << " ERROR : Mi28DecodeLadderDataToRoot(), Column counter is wrong, which is " + << std::setbase(10) << vi_Chip_Address_Column << " VS " + << std::setbase(10) << N_COLUMN << endl; + } + vi_N_Frame_Bad++; + break; + } + if (vi_Chip_Flag_Residual_2 != 0) + { + if (vi_Verbose < 4) + { + cout << " Warning : Mi28DecodeLadderDataToRoot(), state is wrong! The state residual bits should be 0, not should be " + << std::setbase(10) << vi_Chip_Flag_Residual_2 << endl; + } + } + + /* +1 means that vi_Chip_N_Pixel is the number of pixels after the first column */ + for (unsigned long int iPixel=0; iPixel input %d, line %d column %d, timestamp %d\n", vi_ID_Ladder, vi_ID_Ladder_Chip, vi_ID_Ladder_Chip+(vi_ID_Ladder-1)*2, vi_Chip_Address_Line, vi_Column_Temp, timestamp); + // } + + int input; + switch ( fEventBuildingMode ) { + case 1: + input = vi_ID_Ladder_Chip+(vi_ID_Ladder-1)*10; + break; + + case 2: + input = vi_ID_Ladder; + break; + + default: + input = vi_ID_Ladder_Chip+(vi_ID_Ladder-1)*2; + } + AddPixel( input, 1, vi_Chip_Address_Line, vi_Column_Temp, timestamp); + if (vi_Verbose < 7) { + printf( " Adding pixel from ladder %lu, Chip %lu -> input %d, line %lu column %lu, timestamp %d\n", vi_ID_Ladder, vi_ID_Ladder_Chip, input, vi_Chip_Address_Line, vi_Column_Temp, timestamp); + } + + if ((vi_Column_Temp >= N_BANKCOLUMN*0) && (vi_Column_Temp < N_BANKCOLUMN*1)) + { + vd_N_PixelBankA++; + } + if ((vi_Column_Temp >= N_BANKCOLUMN*1) && (vi_Column_Temp < N_BANKCOLUMN*2)) + { + vd_N_PixelBankB++; + } + if ((vi_Column_Temp >= N_BANKCOLUMN*2) && (vi_Column_Temp < N_BANKCOLUMN*3)) + { + vd_N_PixelBankC++; + } + if ((vi_Column_Temp >= N_BANKCOLUMN*3) && (vi_Column_Temp < N_BANKCOLUMN*4)) + { + vd_N_PixelBankD++; + } + } // End of 'for (unsigned long int iPixel=0; iPixel 1234 +unsigned long int BoardReaderIHEP::SwitchWordBytes(unsigned long int fi_Word) +{ + + // original method sent on 2018/08/14 + + const unsigned long int BYTE_H = 65280; // 1111 1111 0000 0000 + const unsigned long int BYTE_L = 255; // 0000 0000 1111 1111 + + unsigned long int vi_Word_0 = (fi_Word & BYTE_L); + unsigned long int vi_Word_1 = (fi_Word & BYTE_H) >> 8; + //unsigned long int vi_Word_2 = (vi_Word_0 << 8) + vi_Word_1; +unsigned long int vi_Word_2 = (vi_Word_1 << 8) + vi_Word_0; + return vi_Word_2; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// 7856 3412 -> 1234 5678 +unsigned long int BoardReaderIHEP::SwitchDWordBytes(unsigned long int fi_DWord) +{ + + // original method sent on 2018/08/14 + + const unsigned long int WORD_H = 4294901760; // 1111 1111 1111 1111 0000 0000 0000 0000 + const unsigned long int WORD_L = 65535; // 0000 0000 0000 0000 1111 1111 1111 1111 + + unsigned long int vi_DWord_0 = (fi_DWord & WORD_L); + unsigned long int vi_DWord_1 = (fi_DWord & WORD_H) >> 16; + + vi_DWord_0 = SwitchWordBytes(vi_DWord_0); + vi_DWord_1 = SwitchWordBytes(vi_DWord_1); + + unsigned long int vi_DWord_2 = (vi_DWord_0 << 16) + vi_DWord_1; + + return vi_DWord_2; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// 7856 3412 -> 5678 1234 +unsigned long int BoardReaderIHEP::SwitchDWordBytes2(unsigned long int fi_DWord) +{ + + // original method sent on 2018/08/14 + + const unsigned long int WORD_H = 4294901760; // 1111 1111 1111 1111 0000 0000 0000 0000 + const unsigned long int WORD_L = 65535; // 0000 0000 0000 0000 1111 1111 1111 1111 + + unsigned long int vi_DWord_0 = (fi_DWord & WORD_L); + unsigned long int vi_DWord_1 = (fi_DWord & WORD_H) >> 16; + + vi_DWord_0 = SwitchWordBytes(vi_DWord_0); + vi_DWord_1 = SwitchWordBytes(vi_DWord_1); + + unsigned long int vi_DWord_2 = (vi_DWord_1 << 16) + vi_DWord_0; + + return vi_DWord_2; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo...... +// 5678 1234 -> 1234 5678 +unsigned long int BoardReaderIHEP::SwitchDWordWords(unsigned long int fi_DWord) +{ + +// original method sent on 2018/08/14 + + const unsigned long int WORD_H = 4294901760; // 1111 1111 1111 1111 0000 0000 0000 0000 + const unsigned long int WORD_L = 65535; // 0000 0000 0000 0000 1111 1111 1111 1111 + + unsigned long int vi_DWord_0 = (fi_DWord & WORD_L); + unsigned long int vi_DWord_1 = (fi_DWord & WORD_H) >> 16; + + unsigned long int vi_DWord_2 = (vi_DWord_1 << 16) + vi_DWord_0; + + return vi_DWord_2; +} + +//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......ll_120-4.5-A208 diff --git a/src/BoardReaderMIMOSIS.cxx b/src/BoardReaderMIMOSIS.cxx new file mode 100644 index 0000000..cbc1b8b --- /dev/null +++ b/src/BoardReaderMIMOSIS.cxx @@ -0,0 +1,1490 @@ + ///////////////////////////////////////////////////////////// +// Class Description of BoardReaderMIMOSIS +// +// Dedicated to decode output files from the PXI acquisition system +// dedicated to MIMOSIS sensors +// +// Use Gilles Claus library to decode rawdata file, see code/inculde/mimo_daq_lib +// +///////////////////////////////////////////////////////////// +// +// created JB, 2021/04/21 +// Last Modified: Ziad, 2021/06/04 + +#define AP 0 +#include "TCanvas.h" +#include "TApplication.h" + +#include "BoardReaderMIMOSIS.h" +#include "mimo_daq_lib/mimo_daq_lib.h" +#include "mimo_daq_lib/mimo_daq_lib.c" + +ClassImp(BoardReaderMIMOSIS) + + /* ========================================= */ + /* Conditional compilation for DAQ sources */ + /* ========================================= */ + + #define ROOT_ROOT // Disable code parts which can't compile under ROOT + #define CC_UNIX // Specify operating system + //--------------------------------------------------------------------------------- + // Conditionnal compilation switches + // --------------------------------------------------------------------------------- + + + #undef CC_APP_GUI_CPP // Disables C++ Builder GUI application => Memo for error and general messagess logging + + #define CC_MSIS1_BDF_LIGHT // Reduces functions, class integrated from library X:/lib/com/maps/msis1/Data + // in oder to minimize the risk of compilation warnings / errors + + #define CC_NOT_CPP_BUILDER // Removes items (cst, functions, etc ... ) only available under C++ Builder + + + + #undef CC_INTERFACE_FILE // To get variables created in this module + + + // #define APP_ERR_MSG_MACROS_NOT_SUPPORTED // To be defined in case of compilation errors on errors and general messages libs + // ..\..\com\errors_light.c, errors_light.h + // ..\..\com\msg_light.c, msg_light.h + + + #undef CC_APP_ERR_LOG_VIA_PRINTF // If enabled => Error log message are automatically printed in console via printf () function + // Rq : The sames messages are written in MIS1__TBtRunRead_DEF_ERR_LOG_FILE + + #define CC_APP_MSG_LOG_VIA_PRINTF // If enabled => General message log are automatically printed in console via printf () function + // Rq : The sames messages are written in MIS1__TBtRunRead_DEF_MSG_LOG_FILE + + +//------------------------------------------+----------------------------------- +MIS1__TBtRunRead* APP_VGPtRunRead; + +MIS1__TBtAcqRawRec* APP_VGPtAcqSrc; // 26/05/2021 V1.1 + // Pointer on current acq of run = source Acq to be decoded +MIS1__TBtAcqW16A* APP_VGPtAcqW16A; // 26/05/2021 V1.1 + // AcqW16A record = Flex RIO data reoorganized + // Contains Acq data reordered in order to have one array of W16 for each MSis1 + // data provied by Flex RIO are splitted in two different memory blocks : one for each outputs + // having data in one array / MSis 1 will ease data decoding, at the cost a of memory copy + + + +MIS1__TBtAcqDec* APP_VGPtAcqDec; // 26/05/2021 V1.1 + // AcqDec record = Decoded acquisition + // Contains decoded pixels + info on Acq, Frames : reggions nb, fired pixels nb, etc ... + + + +// --------------------------------------------------------------------------------- +// Main : Mimosis 1 beam test run file access example, via class MIS1__TBtRunRead +// --------------------------------------------------------------------------------- + +int BoardReaderMIMOSIS::test() { + + // ---------------------------------------------------------------- + // Variables + // ---------------------------------------------------------------- + + SInt32 VRet; // Error code returned by functions ( 0 => ok, < 0 => error ) + + + // Run parameters + + char VParRunRootDir[GLB_FILE_PATH_SZ]; // Run root directory + UInt32 VParRunNo; // No of run + + // Acqusition (Acq) header printing options + + SInt32 VParHdPrintTriggers = 5; // Nb of triggers to print -1 => All, 0 => None, N > 0 => N first triggers + SInt32 VParHdPrintFrCnt = 3; // Print frame counter of 6 x MSis 1 over N frames, -1 => All frames, 0 => None, N > 0 => N first frames + SInt32 VParHdPrintFiredPixels = 1; // Print fired pixels (per MSis1, per submatrices), 0 => No, 1 => Print, NOT CALCULATD NOW on 19/05/2021 + + // Acqusition (Acq) raw data printing options + + UInt32 VParWSz = 32; // Size of the word to print, cab be 8, 16, 32, 64 bits + UInt32 VParFirstW = 0; // Position of the first word to print, unit is W8, W16, W32, W64 function of VParWSz value + UInt32 VParNbW = 10; // Nb of words to print, in this case with VParWSz = 32 => 10 words of 32 bits will be printed + + // Acquisition "results" + + UInt8 VResReachEndOfRun = 0; // Flag set to 1 when last Acq of run has been reached + + // Acq header and Acq pointers + + MIS1__TBtRunCnfRec* VPtRunConf = NULL; // Pointer to run conf record + MIS1__TBtAcqRawRec* VPtAcq = NULL; // Pointer to current Acq + + + // Size of records allocated for pixels decoding + + UInt32 VAcqW16ASz; // 26/05/2021 V1.1 + // Size of AcqW16A record = Flex RIO data reoorganized + // Contains Acq data reordered in order to have one array of W16 for each MSis1 + // data provied by Flex RIO are splitted in two different memory blocks : one for each outputs + // having data in one array / MSis 1 will ease data decoding, at the cost a of memory copy + + + UInt32 VAcqDecSz; // 26/05/2021 V1.1 + // Size of AcqDec record = Decoded acquisition + // Contains decoded pixels + info on Acq, Frames : reggions nb, fired pixels nb, etc ... + + SInt32 ViFr; // 26/05/2021 V1.1 + // Frame index for pixels list printing + + UInt32 VPrintMaxPix; // 26/05/2021 V1.1 + // Maximum number of pixels to print per frame, to avoid "endless loop" if lot of pixels in frame + + + printf ( "\n" ); + printf ( "**********************************************************\n" ); + printf ( "Beginning of Mimosis 1 data run files access library demo \n" ); + printf ( "**********************************************************\n" ); + printf ( "\n" ); + + + // ---------------------------------------------------------------- + // Check record size Windows / Linux + // ---------------------------------------------------------------- + + + // If can be used for enabling / disabling this part of the demo + + if (1) { + + UInt32 __VRunConfRecSzWin = 1340; + UInt32 __VIndexRecSzWin = 4867212; + UInt32 __VAcqHeadRecSzWin = 40560; + UInt32 __VAcqTotRecSzWin = 3240560; + UInt32 __VAcqDataOffsetW8Win = 40560; + + + UInt32 __VRunConfRecSz; + UInt32 __VIndexRecSz; + UInt32 __VAcqHeadRecSz; + UInt32 __VAcqTotRecSz; + UInt32 __VAcqDataOffsetW8; + MIS1__TBtAcqRawRec* __VPtAcq; + + + printf ( "\n" ); + printf ( "Records size printing for checking if size Linux / Windows are equal \n" ); + printf ( "\n" ); + + + // alloc one acq + + __VPtAcq = (MIS1__TBtAcqRawRec*) malloc ( sizeof ( MIS1__TBtAcqRawRec ) ); + + + if ( __VPtAcq == NULL ) { + printf ( "\n" ); + printf ( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n" ); + printf ( "Abort : Allocation of one Acq record has failed ! \n" ); + printf ( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n" ); + return (-1); + } + + // Run conf record + + __VRunConfRecSz = sizeof ( MIS1__TBtRunCnfRec ); + + printf ( "Run conf record MIS1__TBtRunCnfRec size = %d, Windows size = %d \n\n", __VRunConfRecSz, __VRunConfRecSzWin ); + + // Index file + + __VIndexRecSz = sizeof ( MIS1__TBtRunRawIndexRec ); + + printf ( "Index file record MIS1__TBtRunRawIndexRec size = %d, Windows size = %d \n\n", __VIndexRecSz, __VIndexRecSzWin ); + + // Acq header + + __VAcqHeadRecSz = sizeof ( MIS1__TBtAcqRawHead ); + + printf ( "Acq header record MIS1__TBtAcqRawHead size = %d, Windows size = %d \n\n", __VAcqHeadRecSz, __VAcqHeadRecSzWin ); + + // Acq total record + + __VAcqTotRecSz = sizeof ( MIS1__TBtAcqRawRec ); + + printf ( "Acq total record MIS1__TBtAcqRawRec size = %d, Windows size = %d \n\n", __VAcqTotRecSz, __VAcqTotRecSzWin ); + + // Acq data part offset / beginning + + __VAcqDataOffsetW8 = (UInt32) ((UInt8*) &__VPtAcq->MSisData.Au64[0] - (UInt8*) __VPtAcq); + + printf ( "Acq data part offset = %d W8, Windows offset = %d \n\n", __VAcqDataOffsetW8, __VAcqDataOffsetW8Win ); + + + if ( (__VRunConfRecSz != __VRunConfRecSzWin) || (__VIndexRecSz != __VIndexRecSzWin) || (__VAcqHeadRecSz != __VAcqHeadRecSzWin) || (__VAcqTotRecSz != __VAcqTotRecSzWin) || (__VAcqDataOffsetW8 != __VAcqDataOffsetW8Win) ) { + printf ( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n" ); + printf ( "Record(s) size is/are different Linux / Windows \n" ); + printf ( "\n" ); + printf ( "Please check compiler option, add padding word, etc ... \n" ); + printf ( "\n" ); + printf ( "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \n" ); + printf ( "\n" ); + return (-1); + } + + + printf ( "\n" ); + printf ( "Records have the same size under Linux / Windows => It SHOULD be ok :-) \n" ); + printf ( "\n" ); + + + free ( __VPtAcq ); + } + + + // return (0); // You can enable it in order to stop sw after record size priting + + + // ---------------------------------------------------------------- + // Class creation + // ---------------------------------------------------------------- + + APP_VGPtRunRead = new ( MIS1__TBtRunRead ); + + + if ( APP_VGPtRunRead == NULL ) { + printf ( "\n" ); + printf ( "ERROR : Creation of MIS1__TBtRunRead failed ! \n" ); + return (-1); + } + + printf ( "\n" ); + printf ( "MIS1__TBtRunRead class creation done :-) \n" ); + printf ( "\n" ); + + + + // ---------------------------------------------------------------- + // Error messages logging configuration + // ---------------------------------------------------------------- + // + // Error messages generated by lib can be + // + // - written in a log file, its name is defined by MIS1__TBtRunRead_DEF_ERR_LOG_FILE + // - printed in the console if CC_APP_ERR_LOG_VIA_PRINTF is enabled + // + // - additionnal actions on each error logging can be implemented, if needed, in function + // SInt32 MIS1__TBtRunRead_FErrLogUsrPrint ( char Type, char* ErrLocation, char* ErrUserMsg, char* FullMsg ) + // which is located in msis1_data.c + // + // Errors logging configuration is done in the following lines + // + + + // Sets errors logging, it can be + // + // ERR_LOG_LVL_NONE + // ERR_LOG_LVL_ALL + // ERR_LOG_LVL_WARNINGS_ERRORS + // ERR_LOG_LVL_ERRORS + + + APP_VGPtRunRead->FErrLogSetLevel ( ERR_LOG_LVL_WARNINGS_ERRORS ); + + + // ---------------------------------------------------------------- + // General messages logging configuration + // ---------------------------------------------------------------- + // + // General messages generated by lib can be + // + // - written in a log file, its name is defined by MIS1__TBtRunRead_DEF_MSG_LOG_FILE + // - printed in the console if CC_APP_MSG_LOG_VIA_PRINTF is enabled + // + // - additionnal actions on each error logging can be implemented, if needed, in function + // SInt32 MIS1__TBtRunRead_FMsgLogUsrPrint ( char* Msg ) + // which is located in msis1_data.c + // + // General messages logging configuration is done in the following lines + // + + + // Sets messages logging, 127 is the only value handled now + + APP_VGPtRunRead->FMsgLogSetLevel ( 127 ); + + + // ---------------------------------------------------------------- + // Print read run log files names location + // ---------------------------------------------------------------- + + printf ( "\n" ); + printf ( "============================================================= \n" ); + printf ( "Errors log file => %s \n", APP_VGPtRunRead->FErrLogSetFilename () ); + printf ( "Messages log file => %s \n", APP_VGPtRunRead->FMsgLogSetFilename () ); + printf ( "============================================================= \n" ); + printf ( "\n" ); + + + // ---------------------------------------------------------------- + // Allocate record to convert one Acq + // 26/05/2021 V1.1 + // ---------------------------------------------------------------- + + // AcqW16A record + + APP_VGPtAcqW16A = MIS1__BT_FBtAcqW16AAlloc ( 1 /* Alloc */, &VAcqW16ASz ); + + // Error + + if ( APP_VGPtAcqW16A == NULL ) { + printf ( "\n" ); + printf ( "Allocation of AcqW16A of %.1f MB failed ! \n", VAcqW16ASz / 1024. / 1024. ); + printf ( "You can try to reduce max frames nb / Acq via constant MIS1__BT_VRS_MAX_FR_NB_PER_ACQ = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); + return (-1); + } + + // OK + + printf ( "\n" ); + printf ( "Allocation of AcqW16A of %.1f MB ... \n", VAcqW16ASz / 1024. / 1024. ); + printf ( "Max frames nb / Acq = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); + printf ( "Done :-) \n" ); + printf ( "\n" ); + + + // AcqDec + + APP_VGPtAcqDec = MIS1__BT_FBtAcqDecAlloc ( 1 /* Alloc */, &VAcqDecSz ); + + // Error + + if ( APP_VGPtAcqDec == NULL ) { + printf ( "\n" ); + printf ( "Allocation of AcqDec of %.1f MB failed ! \n", VAcqDecSz / 1024. / 1024. ); + printf ( "You can try to reduce max frames nb / Acq via constant MIS1__BT_VRS_MAX_FR_NB_PER_ACQ = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); + printf ( "You can try to reduce max pixels nb / Frame via constant MIS1__BT_FR_DEC_MAX_PIX_NB = %d \n", MIS1__BT_FR_DEC_MAX_PIX_NB ); + return (-1); + } + + + // OK + + printf ( "\n" ); + printf ( "Allocation of AcqDec of %.1f MB ... \n", VAcqDecSz / 1024. / 1024. ); + printf ( "Max frames nb / Acq = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); + printf ( "Max pixels nb / Frame = %d \n", MIS1__BT_FR_DEC_MAX_PIX_NB ); + printf ( "Done :-) \n" ); + printf ( "\n" ); + + + + // ---------------------------------------------------------------- + // Config run to read <=> Open run + // ---------------------------------------------------------------- + + // Sets run directory + + // sprintf ( VParRunRootDir, "%s", "C:/Data/msis1" ); + + sprintf ( VParRunRootDir, "%s", "../../data" ); + + + // Sets run no + + VParRunNo = 2; + + // Tries to configure run + + VRet = APP_VGPtRunRead->FRunConf ( VParRunRootDir, VParRunNo, 0 /* PrintRunHeader */, MIS1__BT_RUN_RD_FILE_FORMAT ); + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Configuration of run no %d from root directory = %s \n", VParRunNo, VParRunRootDir ); + printf ( "Failed : %s \n", APP_VGPtRunRead->FErrGetLastMsg () ); + return (-1); + } + + printf ( "\n" ); + printf ( "Configuration of run no %d from root directory = %s \n", VParRunNo, VParRunRootDir ); + printf ( "Done :-) \n" ); + printf ( "\n" ); + + + // ---------------------------------------------------------------- + // Print run header + // ---------------------------------------------------------------- + + // If can be used for enabling / disabling this part of the demo + + if (1) { + + // Prints run conf + get a pointer on run conf + + VPtRunConf = APP_VGPtRunRead->FRunHeaderGet ( 1 /* Print */ ); + + // Remark : To get only a pointer on run conf withotu prionting => Set Print param to 0 + + + if ( VPtRunConf == NULL ) { + printf ( "\n" ); + printf ( "Run configuration record printing failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + printf ( "\n" ); + printf ( "Run configuration record printing done :-) \n" ); + printf ( "\n" ); + printf ( "Results have been written in file %s \n", APP_VGPtRunRead->FMsgLogSetFilename () ); + printf ( "Results have been printed in console if macro CC_APP_MSG_LOG_VIA_PRINTF is enabled \n" ); + printf ( "\n" ); + + + } + + + // ---------------------------------------------------------------- + // Goto first Acq of run + // ---------------------------------------------------------------- + + // If can be used for enabling / disabling this part of the demo + + if (1) { + + // Configure Acq header printing options + // + // If you don't want to print header + // - Sets param PrintAcqHead of FAcqFirst (...) to 0 + // - You don't need to call FAcqHeadPrintOptSet (...) + + + VParHdPrintTriggers = 5; // Nb of triggers to print -1 => All, 0 => None, N > 0 => N first triggers + VParHdPrintFrCnt = 3; // Print frame counter of 6 x MSis 1 over N frames, -1 => All frames, 0 => None, N > 0 => N first frames + VParHdPrintFiredPixels = 1; // Print fired pixels (per MSis1, per submatrices), 0 => No, 1 => Print, NOT CALCULATD NOW on 19/05/2021 + + + VRet = APP_VGPtRunRead->FAcqHeadPrintOptSet ( VParHdPrintTriggers, VParHdPrintFrCnt, VParHdPrintFiredPixels ); + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Configure Acq header printing option has failed \n" ); + printf ( "\n" ); + return (-1); + } + + + // Parameter ChkAcqHead 0/1 is used to enable header checking => Not implemented now + // Acq header record can be printed if param PrintAcqHead iss et to 1 + + VPtAcq = APP_VGPtRunRead->FAcqFirst ( 0 /* ChkAcqHead */, 1 /* PrintAcqHead */ ); + + if ( VPtAcq == NULL ) { + printf ( "\n" ); + printf ( "Goto first Acq of run has failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + printf ( "\n" ); + printf ( "Goto first Acq of run done :-) \n" ); + printf ( "\n" ); + printf ( "Acquisition header has been printed :-) \n" ); + printf ( "\n" ); + printf ( "Results have been written in file %s \n", APP_VGPtRunRead->FMsgLogSetFilename () ); + printf ( "Results have been printed in console if macro CC_APP_MSG_LOG_VIA_PRINTF is enabled \n" ); + printf ( "\n" ); + + } + + + // ---------------------------------------------------------------- + // Print current Acq of run (Acq header fields + data as hex words) + // ---------------------------------------------------------------- + + // If can be used for enabling / disabling this part of the demo + + // Remark 1 : To get a ptr on the current Acq => APP_VGPtRunRead->FAcqGetPt () + // + // Remark 2 : To get a access to the raw data VPtAcq = APP_VGPtRunRead->FAcqGetPt () + // + // VPtAcq->MSisData.Au8 => raw data as an array of W8 + // VPtAcq->MSisData.Au16 => raw data as an array of W16 + // VPtAcq->MSisData.Au32 => raw data as an array of W32 + // VPtAcq->MSisData.Au64 => raw data as an array of W64 + + + + if (1) { + + // Header printing options + + VParHdPrintTriggers = 5; // Nb of triggers to print -1 => All, 0 => None, N > 0 => N first triggers + VParHdPrintFrCnt = 3; // Print frame counter of 6 x MSis 1 over N frames, -1 => All frames, 0 => None, N > 0 => N first frames + VParHdPrintFiredPixels = 1; // Print fired pixels (per MSis1, per submatrices), 0 => No, 1 => Print, NOT CALCULATD NOW on 19/05/2021 + + // Raw data printing options + + VParWSz = 32; // Size of the word to print, cab be 8, 16, 32, 64 bits + VParFirstW = 0; // Position of the first word to print, unit is W8, W16, W32, W64 function of VParWSz value + VParNbW = 10; // Nb of words to print, in this case with VParWSz = 32 => 10 words of 32 bits will be printed + + + VRet = APP_VGPtRunRead->FAcqPrint ( APP_VGPtRunRead->FAcqGetPt (), VParHdPrintTriggers, VParHdPrintFrCnt, VParHdPrintFiredPixels, VParWSz, VParFirstW, VParNbW, 0 /* VRS */ ); + + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Printing first Acq of run has failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + printf ( "\n" ); + printf ( "Printing first Acq of run done :-) \n" ); + printf ( "\n" ); + printf ( "Acquisiiton has been printed :-) \n" ); + printf ( "\n" ); + printf ( "Results have been written in file %s \n", APP_VGPtRunRead->FMsgLogSetFilename () ); + printf ( "Results have been printed in console if macro CC_APP_MSG_LOG_VIA_PRINTF is enabled \n" ); + printf ( "\n" ); + + + } + + + + + + // ---------------------------------------------------------------- + // Decode first Acq of run + // Only for foirst MSis, a loop must done to convert all MSis + // 26/05/2021 V1.1 + // ---------------------------------------------------------------- + + // If can be used for enabling / disabling this part of the demo + + + if (1) { + + // Get a pointer on current Acq + + APP_VGPtAcqSrc = APP_VGPtRunRead->FAcqGetPt (); + + if ( APP_VGPtAcqSrc == NULL ) { + printf ( "\n" ); + printf ( "Get a pointer on first Acq of run has failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + // Reset decoding memory, Rq : can be disable to reduce execution time, useful for debugging + + if ( 1 ) { + memset ( APP_VGPtAcqW16A, 0, sizeof (MIS1__TBtAcqW16A) ); + memset ( APP_VGPtAcqDec , 0, sizeof (MIS1__TBtAcqDec) ); + } + + // Convert FleRIO memory image to list of W16 for each MSis + + VRet = MIS1__BT_FBtAcqW16AFill ( APP_VGPtAcqSrc , APP_VGPtAcqW16A, -1 /* FrNb, -1 => All */, 0 /* MeasExecTime */, 0 /* PrintLvl */, 80 /* FuncVers */ ); // A partir de là on peut lire des pixels. + + // Error + + if ( VRet < 0 ) { + printf ( "Filling AcqW16A failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + // Decode MSis + // + // Done for first MSis = No 0 + // A loop with apram MSIsId = 0 to 5 must be done to convert the data of the full telescope + // The conversion function MIS1__BT_FBtDecodeFrLight (...) will fail if the converted MSis does not exist in the run data + + VRet = MIS1__BT_FBtDecodeFr ( APP_VGPtAcqW16A, APP_VGPtAcqDec, 0 /* MSIsId 0 to 5 */, -1 /* FrNb */, 0 /* MeasExecTime */, 0 /* PrintLvl */ ); + + if ( VRet < 0 ) { + printf ( "Decoding MSis data failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + + printf ( "\n" ); + printf ( "Decoding first Acq of run done :-) \n" ); + printf ( "\n" ); + + + } + + + // ---------------------------------------------------------------- + // Print general info on first Acq of run, regions, pixels nb etc ... + // Only for first MSis, a loop must done to print all MSis + // 26/05/2021 V1.1 + // ---------------------------------------------------------------- + + // If can be used for enabling / disabling this part of the demo + + if (1) { + + // Param PrintMode - 0 => Print all info, 1 => Print only region, fired pixels cnt + + VRet = MIS1__BT_FAcqDecPrintGen ( APP_VGPtAcqDec, 0 /* MSIsId 0 to 5 */, 0 /* PrintMode */ ); + + if ( VRet < 0 ) { + printf ( "Decoding MSis data failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + + + printf ( "\n" ); + printf ( "Printing info of first decoded Acq of run done :-) \n" ); + printf ( "\n" ); + printf ( "Results have been written in file %s \n", APP_VGPtRunRead->FMsgLogSetFilename () ); + printf ( "Results have been printed in console if macro CC_APP_MSG_LOG_VIA_PRINTF is enabled \n" ); + printf ( "\n" ); + + } + + + // ---------------------------------------------------------------- + // Print pixels of first Acq of run + // Only for first MSis, a loop must done to print all MSis + // Only frames with pixels are printed + // + // Where to find info to access pixels (which variable etc ) ? + // - Read following sourcer code + // - Read source code of MIS1__BT_FAcqDecPrintPix (...) in msis1_data.c + // - Read type defintion of MIS1__TBtAcqDec in msis1_data.typ + // + // 26/05/2021 V1.1 + // ---------------------------------------------------------------- + + // If can be used for enabling / disabling this part of the demo + + if (1) { + + VPrintMaxPix = 100; // Maximum number of pixels to print per frame, to avoid "endless loop" if lot of pixels in frame + + // Loop to scan the frame of Acq, WARNING : Frame nb to scan is hard coded here to 100, is a run has less than 100 fr/acq it will generate an error + + for ( ViFr = 0; ViFr < 100; ViFr++ ) { + + // Only frames with pixels are printed + + if ( APP_VGPtAcqDec->ResAAFrHead[ 0 /* MSisId */][ViFr].FiredPixNb > 0 ) { + + VRet = MIS1__BT_FAcqDecPrintPix ( APP_VGPtAcqDec, 0 /* MSIsId 0 to 5 */, ViFr, VPrintMaxPix, 0 /* PrintMode */ ); + + if ( VRet < 0 ) { + printf ( "Printing pixels of frame No %d of MSis No 0 failed ! \n", ViFr ); + printf ( "\n" ); + return (-1); + } + + } + + } // End for ( ViFr ) + + // Param PrintMode - 0 => Not used now + + + printf ( "\n" ); + printf ( "$$$ Printing pixels of MSis No 0 of first decoded Acq of run done :-) \n" ); + printf ( "\n" ); + printf ( "Results have been written in file %s \n", APP_VGPtRunRead->FMsgLogSetFilename () ); + printf ( "Results have been printed in console if macro CC_APP_MSG_LOG_VIA_PRINTF is enabled \n" ); + printf ( "\n" ); + + } + + + + // ---------------------------------------------------------------- + // Goto next Acq of run + // ---------------------------------------------------------------- + + // If can be used for enabling / disabling this part of the demo + + if (1) { + + // Configure Acq header printing options + // + // If you don't want to print header + // - Sets param PrintAcqHead of FAcqFirst (...) to 0 + // - You don't need to call FAcqHeadPrintOptSet (...) + + + VParHdPrintTriggers = 5; // Nb of triggers to print -1 => All, 0 => None, N > 0 => N first triggers + VParHdPrintFrCnt = 3; // Print frame counter of 6 x MSis 1 over N frames, -1 => All frames, 0 => None, N > 0 => N first frames + VParHdPrintFiredPixels = 1; // Print fired pixels (per MSis1, per submatrices), 0 => No, 1 => Print, NOT CALCULATD NOW on 19/05/2021 + + + VRet = APP_VGPtRunRead->FAcqHeadPrintOptSet ( VParHdPrintTriggers, VParHdPrintFrCnt, VParHdPrintFiredPixels ); + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Configure Acq header printing option has failed \n" ); + printf ( "\n" ); + return (-1); + } + + + // Parameter ChkAcqHead 0/1 is used to enable header checking => Not implemented now + // Acq header record can be printed if param PrintAcqHead iss et to 1 + + VPtAcq = APP_VGPtRunRead->FAcqNext ( 0 /* ChkAcqHead */, 1 /* PrintAcqHead */, &VResReachEndOfRun ); + + if ( VPtAcq == NULL ) { + printf ( "\n" ); + printf ( "Goto next Acq of run has failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + printf ( "\n" ); + printf ( "Goto next Acq of run done :-) \n" ); + printf ( "\n" ); + printf ( "Acquisition header has been printed :-) \n" ); + printf ( "\n" ); + printf ( "Results have been written in file %s \n", APP_VGPtRunRead->FMsgLogSetFilename () ); + printf ( "Results have been printed in console if macro CC_APP_MSG_LOG_VIA_PRINTF is enabled \n" ); + printf ( "\n" ); + + if ( VResReachEndOfRun ) { + + printf ( "\n" ); + printf ( "End of run has been reached \n" ); + printf ( "\n" ); + + // Advise + // + // You easily modiy the code to scan the run here and priting the header of each Acq by + // - Replacing the if (1) at the head of this block by a while (1) + // - Enabling the hereafter break command, but warning => it can run for a while if many Acq in run ... + // + // break; + + } + + } + + + // ---------------------------------------------------------------- + // Print current Acq of run (Acq header fields + data as hex words) + // ---------------------------------------------------------------- + + // If can be used for enabling / disabling this part of the demo + + // Remark 1 : To get a ptr on the current Acq => APP_VGPtRunRead->FAcqGetPt () + // + // Remark 2 : To get a access to the raw data VPtAcq = APP_VGPtRunRead->FAcqGetPt () + // + // VPtAcq->MSisData.Au8 => raw data as an array of W8 + // VPtAcq->MSisData.Au16 => raw data as an array of W16 + // VPtAcq->MSisData.Au32 => raw data as an array of W32 + // VPtAcq->MSisData.Au64 => raw data as an array of W64 + + + + if (1) { + + // Header printing options + + VParHdPrintTriggers = 5; // Nb of triggers to print -1 => All, 0 => None, N > 0 => N first triggers + VParHdPrintFrCnt = 3; // Print frame counter of 6 x MSis 1 over N frames, -1 => All frames, 0 => None, N > 0 => N first frames + VParHdPrintFiredPixels = 1; // Print fired pixels (per MSis1, per submatrices), 0 => No, 1 => Print, NOT CALCULATD NOW on 19/05/2021 + + // Raw data printing options + + VParWSz = 32; // Size of the word to print, cab be 8, 16, 32, 64 bits + VParFirstW = 0; // Position of the first word to print, unit is W8, W16, W32, W64 function of VParWSz value + VParNbW = 10; // Nb of words to print, in this case with VParWSz = 32 => 10 words of 32 bits will be printed + + + VRet = APP_VGPtRunRead->FAcqPrint ( APP_VGPtRunRead->FAcqGetPt (), VParHdPrintTriggers, VParHdPrintFrCnt, VParHdPrintFiredPixels, VParWSz, VParFirstW, VParNbW, 0 /* VRS */ ); + + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Printing next Acq of run has failed ! \n" ); + printf ( "\n" ); + return (-1); + } + + printf ( "\n" ); + printf ( "Printing next Acq of run done :-) \n" ); + printf ( "\n" ); + printf ( "Acquisiiton has been printed :-) \n" ); + printf ( "\n" ); + printf ( "Results have been written in file %s \n", APP_VGPtRunRead->FMsgLogSetFilename () ); + printf ( "Results have been printed in console if macro CC_APP_MSG_LOG_VIA_PRINTF is enabled \n" ); + printf ( "\n" ); + + + } + + + + // ---------------------------------------------------------------- + // Close run + // ---------------------------------------------------------------- + + VRet = APP_VGPtRunRead->FRunClose (); + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Close of run no %d from root directory = %s \n", VParRunNo, VParRunRootDir ); + printf ( "Failed : %s \n", APP_VGPtRunRead->FErrGetLastMsg () ); + return (-1); + } + + + printf ( "\n" ); + printf ( "Close of run no %d from root directory = %s \n", VParRunNo, VParRunRootDir ); + printf ( "Done :-) \n" ); + printf ( "\n" ); + + + // ---------------------------------------------------------------- + // Free record to convert one Acq + // 26/05/2021 V1.1 + // ---------------------------------------------------------------- + + // AcqW16A record + + VRet = MIS1__BT_FBtAcqW16AFree ( APP_VGPtAcqW16A ); + + APP_VGPtAcqW16A = NULL; + + // Error + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Free of AcqW16A failed ! \n" ); + return (-1); + } + + // OK + + printf ( "\n" ); + printf ( "Free of AcqW16A done :-) \n" ); + + + // AcqDec + + VRet = MIS1__BT_FBtAcqDecFree ( APP_VGPtAcqDec ); + + APP_VGPtAcqDec = NULL; + + + // Error + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Free of AcqDec failed ! \n" ); + return (-1); + } + + // OK + + printf ( "\n" ); + printf ( "Free of AcqDec done :-) \n" ); + + + + // ---------------------------------------------------------------- + // Class destruction + // ---------------------------------------------------------------- + + // Class destruction + + delete ( APP_VGPtRunRead ); + + printf ( "\n" ); + printf ( "**********************************************************\n" ); + printf ( "End of Mimosis 1 data run files access library demo \n" ); + printf ( "**********************************************************\n" ); + printf ( "\n" ); + + +} +//------------------------------------------+----------------------------------- +BoardReaderMIMOSIS::BoardReaderMIMOSIS(int boardNumber, char* dataPath, int runNumber, int nSensors, int triggerMode, int eventBuildingMode, int endianness) { + // Board creator + // Load the rawdata file + // + // Ziad, 2021 + + + int VParHdPrintTriggers = 5; // Nb of triggers to print -1 => All, 0 => None, N > 0 => N first triggers + int VParHdPrintFrCnt = 3; // Print frame counter of 6 x MSis 1 over N frames, -1 => All frames, 0 => None, N > 0 => N first frames + int VParHdPrintFiredPixels = 1; // Print fired pixels (per MSis1, per submatrices), 0 => No, 1 => Print, NOT CALCULATD NOW on 19/05/2021 + + fDebugLevel = 0; // Used for printing info later + fBoardNumber = boardNumber; + fRunNumber = runNumber; + fNSensors = nSensors; + fTriggerMode = triggerMode; + fEventBuildingMode = eventBuildingMode; + fEndianness = endianness; + fVetoOverflow = false; // set later by SetVetoPixel + fisfirstAcq = true; + + fBadDecFrameCounter = 0; + + fReachEndOfRun = 0; + + SInt32 VRet; // Error code returned by functions ( 0 => ok, < 0 => error ) + + UInt32 VAcqW16ASz; // 26/05/2021 V1.1 + // Size of AcqW16A record = Flex RIO data reoorganized + // Contains Acq data reordered in order to have one array of W16 for each MSis1 + // data provied by Flex RIO are splitted in two different memory blocks : one for each outputs + // having data in one array / MSis 1 will ease data decoding, at the cost a of memory copy + + + UInt32 VAcqDecSz; // 26/05/2021 V1.1 + // Size of AcqDec record = Decoded acquisition + // Contains decoded pixels + info on Acq, Frames : reggions nb, fired pixels nb, etc ... + + cout << "*****************************************" << endl; + cout << " < BoardReaderMIMOSIS constructor > " << endl; + cout << "*****************************************" << endl; + cout << "Creating a BoardReaderMIMOSIS" << endl; + cout << " * board nb: " << fBoardNumber << endl; + cout << " * runNumber : " << runNumber << endl; + cout << " * nb of sensors: " << fNSensors << endl; + cout << " * trigger mode: " << fTriggerMode << endl; + cout << " * event building mode: " << fEventBuildingMode << endl; + cout << " * Endiannes: " << fEndianness << " => " << (fEndianness==0?"NO SWAP":"SWAP") << endl; + cout << " * usage of veto for event with overflow: " << fVetoOverflow << " => " << (fVetoOverflow?"YES":"NO") << endl; + cout << " * dataPath : " << dataPath << endl; + + // Initialization + fCurrentFileNumber = 0; // See also AddFileList + fNoMoreFile = false; + fCurrentEventNumber = 0; + fCurrentTriggerNumber = 0; + fTriggerCount = 0; + fFrameCount = 0; + fNEventsWithOverflow = 0; + + fCurrentAcqNumber = -1; + fCurrentFrameNumber = 0; + + // Initialization of Current Acquisition Number and Current Frame Number + + // ---------------------------------------------------------------- + // Reading Class creation + // ---------------------------------------------------------------- + MIS1__TBtRunCnfRec* VPtRunConf = NULL; // Pointer to run conf record + MIS1__TBtAcqRawRec* VPtAcq = NULL; // Pointer to current Acq + + APP_VGPtRunRead = new MIS1__TBtRunRead(); + + if ( APP_VGPtRunRead == NULL ) { + printf ( "\n" ); + printf ( "ERROR : Creation of MIS1__TBtRunRead failed ! \n" ); + } + + printf ( "\n" ); + printf ( "MIS1__TBtRunRead class creation done :-) \n" ); + printf ( "\n" ); + + // Initialisation required by DAQ library + //APP__TContext* VPtCont = &APP__VGContext; //ZE 2021/06/09 not used in BoardReaderMIMOSIS + + char msgFile[100], errFile[100]; // JB 2011/06/28 + // int runNumber ; + sprintf( msgFile, "Results/%d/msg_run%d.txt", runNumber, runNumber); + sprintf(msgFile,"%s", fTool.LocalizeDirName( msgFile)); // JB 2011/07/07 + sprintf( errFile, "Results/%d/err_run%d.txt", runNumber, runNumber); + sprintf(errFile,"%s", fTool.LocalizeDirName( errFile)); // JB 2011/07/07 + + cout << " * msgFile : " << msgFile << " errFile = " << errFile << endl; + + // ZE 2021/06/01 access configuration file + + VRet = APP_VGPtRunRead->FRunConf ( dataPath, runNumber, 0 /* PrintRunHeader */, MIS1__BT_RUN_RD_FILE_FORMAT ); + if( VRet<0 ) { + cout << endl << "ERROR: cannot configure run -> return of RunConf = " << VRet << endl; + cout << " Consult " << errFile << " to investigate." << endl << endl; + return; + } + + ERR_FBegin ( ( APP_VGErrFileLogLvl != 0 ) /* Enable */, errFile ); + ERR_FSetFileLogLevel ( APP_VGErrFileLogLvl ); + ERR_FSetUserLogLevel ( APP_VGErrUserLogLvl ); + MSG_FBegin ( (APP_VGMsgFileLogLvl != 0) /* Enable */, msgFile ); + MSG_FSetFileLogLevel ( APP_VGMsgFileLogLvl ); + MSG_FSetUserLogLevel ( APP_VGMsgUserLogLvl ); + + // ZE 2021/06/03 two following steps to get the number of frames per acquisition + + VPtRunConf = APP_VGPtRunRead->FRunHeaderGet ( 1 /* Print */ ); + + fnbFrPerAcq = VPtRunConf->FrNbPerAcq ; + cout << " * Number of Frames per Acq : " << fnbFrPerAcq << endl; + + // In case of more info required in log_msg and log_err use the syntax below + /* + err_trace (( ERR_OUT, "This is a trace message - VMyVar=%d", VMyVar )); + err_warning (( ERR_OUT, "This is a warning message - VMyVar=%d", VMyVar )); + err_error (( ERR_OUT, "This is an error message - VMyVar=%d", VMyVar )); + + + msg (( MSG_OUT, "This is the log file of run : %d \n", runNumber)); + msg (( MSG_OUT, "Data Path : %s \n", dataPath)); + msg (( MSG_OUT, "Number of Frames per Acquisition : %d \n", VPtRunConf->FrNbPerAcq)); + */ + + VRet = APP_VGPtRunRead->FAcqHeadPrintOptSet ( VParHdPrintTriggers, VParHdPrintFrCnt, VParHdPrintFiredPixels ); + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "ERROR: Configure Acq header printing option has failed \n" ); + printf ( "\n" ); + return; + } + + // AcqW16A record + + APP_VGPtAcqW16A = MIS1__BT_FBtAcqW16AAlloc ( 1 /* Alloc */, &VAcqW16ASz ); + + if ( APP_VGPtAcqW16A == NULL ) { + printf ( "\n" ); + printf ( "Allocation of AcqW16A of %.1f MB failed ! \n", VAcqW16ASz / 1024. / 1024. ); + printf ( "You can try to reduce max frames nb / Acq via constant MIS1__BT_VRS_MAX_FR_NB_PER_ACQ = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); + } + + // OK + + if(fDebugLevel>1) { + printf ( "\n" ); + printf ( "Allocation of AcqW16A of %.1f MB ... \n", VAcqW16ASz / 1024. / 1024. ); + printf ( "Max frames nb / Acq = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); + printf ( "Done :-) \n" ); + printf ( "\n" ); + } + + // AcqDec + + APP_VGPtAcqDec = MIS1__BT_FBtAcqDecAlloc ( 1 /* Alloc */, &VAcqDecSz ); + + // Error + + if ( APP_VGPtAcqDec == NULL ) { + printf ( "\n" ); + printf ( "Allocation of AcqDec of %.1f MB failed ! \n", VAcqDecSz / 1024. / 1024. ); + printf ( "You can try to reduce max frames nb / Acq via constant MIS1__BT_VRS_MAX_FR_NB_PER_ACQ = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); + printf ( "You can try to reduce max pixels nb / Frame via constant MIS1__BT_FR_DEC_MAX_PIX_NB = %d \n", MIS1__BT_FR_DEC_MAX_PIX_NB ); + // return (-1); + } + + + // OK + //if(fDebugLevel>1) { + printf ( "\n" ); + printf ( "Allocation of AcqDec of %.1f MB ... \n", VAcqDecSz / 1024. / 1024. ); + printf ( "Max frames nb / Acq = %d \n", MIS1__BT_VRS_MAX_FR_NB_PER_ACQ ); + printf ( "Max pixels nb / Frame = %d \n", MIS1__BT_FR_DEC_MAX_PIX_NB ); + //printf ( "Done :-) \n" ); + //printf ( "\n" ); + //} + + + cout << "*****************************************" << endl; + cout << " < BoardReaderMIMOSIS constructor DONE > " << endl; + cout << "*****************************************" << endl; +} + +//------------------------------------------+----------------------------------- +BoardReaderMIMOSIS::~BoardReaderMIMOSIS() +{ + + // ---------------------------------------------------------------- + // Free record to convert one Acq + // 26/05/2021 V1.1 + // ---------------------------------------------------------------- + + // AcqW16A record + SInt32 VRet; // Error code returned by functions ( 0 => ok, < 0 => error ) + + VRet = MIS1__BT_FBtAcqW16AFree ( APP_VGPtAcqW16A ); + + APP_VGPtAcqW16A = NULL; + + // Error + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Free of AcqW16A failed ! \n" ); + // return (-1); + } + + // OK + if (fDebugLevel > 0) { + printf ( "\n" ); + printf ( "Free of AcqW16A done :-) \n" ); + } + // Free Memory AcqDec + + VRet = MIS1__BT_FBtAcqDecFree ( APP_VGPtAcqDec ); + + APP_VGPtAcqDec = NULL; + + // Error + + if ( VRet < 0 ) { + printf ( "\n" ); + printf ( "Free of AcqDec failed ! \n" ); + // return (-1); + } + + // OK + if (fDebugLevel > 0) { + printf ( "\n" ); + printf ( "Free of AcqDec done :-) \n" ); + } + + +// delete fCurrentEvent; +// delete fInputFileName; + +} + +// -------------------------------------------------------------------------------------- + +bool BoardReaderMIMOSIS::HasData( ) { + // Try to find the pixel data for the next event in the raw data file + // + // ==> THIS MIGHT BE TOO SIMPLISTIC depending on the data format <== + // + // + // If something goes wrong with the decoding or no more events, + // a flag (eventOK) is used to return "false" + // Otherwise returns "true" + // + + // -+-+- Initialization + + bool eventOK = true; // we start with a good event by default +// fCurrentEvent = NULL; // Allow to know wether data are correct + fListOfTriggers.clear(); // and clear the vectors + fListOfTimestamps.clear(); + fListOfFrames.clear(); + fListOfPixels.clear(); + + if(fDebugLevel) { + cout << endl ; + cout << "BoardReaderMIMOSIS::HasData() fBoardNumber " << fBoardNumber << " BoardReaderMIMOSIS::HasData() - currentEvent " << fCurrentEventNumber << " currentTrigger " << fCurrentTriggerNumber << endl; + } + + if( DecodeNextEvent() ) { + + if(fDebugLevel>1) PrintEventHeader(); + + fCurrentEvent = new BoardReaderEvent( fCurrentEventNumber, fBoardNumber, 0, &fListOfPixels); // run number set to 0 for now + fCurrentEvent->SetListOfTriggers( &fListOfTriggers); + fCurrentEvent->SetListOfFrames( &fListOfFrames); + if(fDebugLevel) cout << " fBoardNumber " << fBoardNumber << " created new event " << fCurrentEventNumber << " with " << fListOfPixels.size() << " pixels from " << fListOfTriggers.size() << " triggers and " << fListOfFrames.size() << " frames." << endl; + + fListOfTriggers.push_back( fCurrentEventNumber); + fListOfTimestamps.push_back( 0); + fListOfFrames.push_back( fCurrentEventNumber); + + fCurrentEventNumber++; + + } // getting next buffer was not OK + else{ + eventOK = false; + cout<<" -/-/- ERROR BoardReaderMIMOSIS::HasData() - Can't get next event !"< ready = false + + SInt32 VRet; // Error code returned by functions ( 0 => ok, < 0 => error ) + + + MIS1__TBtAcqRawRec* VPtAcq ; // Pointer to current Acq + MIS1__TBtAcqRawHead* VPtAcqHead; // Pointer to current Acq Header + MIS1__TBtTrigRec* VPtTrig; // Pointer to triggers of current Acquisition + + + // UInt32 VAcqW16ASz; // 26/05/2021 V1.1 + // Size of AcqW16A record = Flex RIO data reoorganized + // Contains Acq data reordered in order to have one array of W16 for each MSis1 + // data provied by Flex RIO are splitted in two different memory blocks : one for each outputs + // having data in one array / MSis 1 will ease data decoding, at the cost a of memory copy + + + // UInt32 VAcqDecSz; // 26/05/2021 V1.1 + // Size of AcqDec record = Decoded acquisition + // Contains decoded pixels + info on Acq, Frames : reggions nb, fired pixels nb, etc ... + + UInt8 VResReachEndOfRun = (UInt8) fReachEndOfRun; + SInt32 nbTrg; + + // Decoding status + + bool ready = false; + + if(fDebugLevel>1) printf( " BoardReaderMIMOSIS board %d::DecodeNextEvent() trying with event %d (current Acq=%d, frame=%d)\n", fBoardNumber, fCurrentEventNumber, fCurrentAcqNumber, fCurrentFrameNumber); + + // Check if first Acquisition or if CurrentFrameNumber less than fnbFrPerAcq; fnbFrPerAcq is not mandatory equal to MIS1__BT_VRS_MAX_FR_NB_PER_ACQ + + if ((fCurrentFrameNumber % fnbFrPerAcq == 0) || (fCurrentFrameNumber % MIS1__BT_VRS_MAX_FR_NB_PER_ACQ == 0)) { + + if (fisfirstAcq == true) { + if(fDebugLevel>1) cout << "BoardReaderMIMOSIS Getting the pointer for the first acquisition " << endl; + VPtAcq = APP_VGPtRunRead->FAcqFirst ( 0 /* ChkAcqHead */, 0 /* PrintAcqHead */ ); + fCurrentAcqNumber ++; + fisfirstAcq = false; + fCurrentFrameNumber = 0; // ZE 2021/06/04 + } + else { + if(fDebugLevel>1) printf (" BoardReaderMIMOSIS Changing to NextAcq % d since fCurrentFrameNumber = % d \n", fCurrentAcqNumber + 1, fCurrentFrameNumber); + VPtAcq = APP_VGPtRunRead->FAcqNext ( 0 /* ChkAcqHead */, 0 /* PrintAcqHead */, &VResReachEndOfRun ); + fCurrentAcqNumber ++; + fCurrentFrameNumber = 0; // ZE 2021/06/04 + } + + + // ZE 2021/06/09. Access Triggers + + // Get A point for the hear of acquisition + VPtAcqHead = &(APP_VGPtAcqW16A->AcqRawHead); + + if (VPtAcqHead == NULL){ + printf ( "\n" ); + printf ( " ERROR in getting pointer to the acquisition header ! \n" ); + printf ( "\n" ); + } + + // Getting the information on the triggers in the current acquisition + VPtTrig = &(VPtAcqHead->Trigs); + nbTrg = VPtAcqHead->Trigs.TrigNb; + + // Printing the Triggers information + printf("Printing triggers information in Acquistion % d \n", fCurrentAcqNumber); + VRet = MIS1__BT_FTrigRecPrint ( nbTrg, VPtTrig); // Function described in line file msis1_data.c, line 15312 + + if ( VRet < 0 ) { + + printf ( "WARNING: Failed in printing Trigger information for Acquisition : %d ! \n", VPtAcqHead->Ids.AcqIdInRun); + printf ( "\n" ); + return (-1); + + } + + } + + fReachEndOfRun = (int) VResReachEndOfRun; + + if(fDebugLevel>1) { + printf("fReachEndOfRun = %d ", fReachEndOfRun); + printf("\n"); + } + + // Get a pointer for the first Acquisition + APP_VGPtAcqSrc = (MIS1__TBtAcqRawRec*) APP_VGPtRunRead->FAcqGetPt (); + + + if ( APP_VGPtAcqSrc == NULL ) { + printf ( "\n" ); + printf ( "WARNING: BoardReaderMIMOSIS Get a pointer on first Acq of run has failed ! \n" ); + printf ( "\n" ); + return (-1); + } + else { + ready = true; + + if(fDebugLevel>1) { + printf ( "\n" ); + printf ( " BoardReaderMIMOSIS Get a pointer on first Acq of run done ! \n" ); + printf ( "\n" ); + } + + } + /* + if ( 1 ) { + memset ( APP_VGPtAcqW16A, 0, sizeof (MIS1__TBtAcqW16A) ); + memset ( APP_VGPtAcqDec , 0, sizeof (MIS1__TBtAcqDec) ); + } + */ + // Convert FleRIO memory image to list of W16 for each MSis + VRet = MIS1__BT_FBtAcqW16AFill ( APP_VGPtAcqSrc , APP_VGPtAcqW16A, -1 /* FrNb, -1 => All */, 0 /* MeasExecTime */, 0 /* PrintLvl */, 80 /* FuncVers */ ); + + // Error + + if ( VRet < 0 ) { + + printf ( "WARNING: BoardReaderMIMOSIS Filling AcqW16A failed ! \n" ); + printf ( "\n" ); + return (-1); + + } + else if(fDebugLevel>1) { + + printf ( "\n" ); + printf ( " BoardReaderMIMOSIS Filling AcqW16A done ! \n" ); + printf ( "\n" ); + + } + + + // ZE 2021/06/02, just for test. Has to write a method specific to TAF + //VRet = MIS1__BT_FAcqDecPrintGen ( APP_VGPtAcqDec, 0 /* MSIsId 0 to 5 */, 0 /* PrintMode */ ); + + // Gilles's method rewritten for TAF in DecodeFrame() method + //VRet = MIS1__BT_FAcqDecPrintPix ( APP_VGPtAcqDec, 0 /* MSIsId 0 to 5 */, ViFr, VPrintMaxPix, 0 /* PrintMode */ ); + DecodeFrame(); + + if (fReachEndOfRun > 0){ + ready = false; + printf(" End Of Run Reached --> fReachEndOfRun = % d \n", fReachEndOfRun); + printf(" Number of processed events/acquisitions : %d \n ", fCurrentAcqNumber ); + } + + + return ready; + +} + +//------------------------------------------+----------------------------------- + +bool BoardReaderMIMOSIS::DecodeFrame() { + + SInt32 VRet; + + MIS1__TPixXY VPix; + SInt32 VPrintMaxPix = 100; + + // ZE 2021/06/02. This is Gilles's standalone methode. Had to write a method specific to TAF. + //VRet = MIS1__BT_FAcqDecPrintPix ( APP_VGPtAcqDec, 0 /* MSIsId 0 to 5 */, frameID, VPrintMaxPix, 0 /* PrintMode */ ); + + /* + fListOfTriggers.push_back( fCurrentEventNumber); + fListOfTimestamps.push_back( 0); + fListOfFrames.push_back( fCurrentEventNumber); + */ + // ZE 2021/06/03. Loop over sensors to decode pixels of current frame. + for ( int MSisId = 0; MSisId < fNSensors; MSisId++ ) { + + + VRet = MIS1__BT_FBtDecodeFr ( APP_VGPtAcqW16A, APP_VGPtAcqDec, MSisId, fCurrentFrameNumber, 0 /* MeasExecTime */, 0 /* PrintLvl */ ); + + if ( VRet < 0 ) { + printf ( "WARNING: Decoding MSis data failed for Sensor : %d and FrameNb : %d \n", MSisId, fCurrentFrameNumber ); + printf ( "\n" ); + fBadDecFrameCounter ++; + return (-1); + } + + //VRet = MIS1__BT_FAcqDecPrintGen ( APP_VGPtAcqDec, MSisId, 0 /* PrintMode */ ); + + // if ( VRet < 0 ) + // printf ( "Printing info of decoded Acq failed for sensor : % d :-( \n\n", MSisId ); + + + // Decode pixels only for frames with FiredPixNb > 0 + if ( APP_VGPtAcqDec->ResAAFrHead[MSisId][fCurrentFrameNumber].FiredPixNb > 0 ) { + + if (fDebugLevel > 3) { + if (fCurrentFrameNumber >= APP_VGPtAcqDec->ResAFrNb[MSisId]) //ZE 2021/06/04 Check if frameID > nbFramesPerAcq + + printf("fCurrentFrameNumber %d Exceeded the number of frames %d for sensor %d \n ", fCurrentFrameNumber, APP_VGPtAcqDec->ResAFrNb[MSisId], MSisId); + printf(" nbFiredPix : %.4d in AcqID : %.4d - frID : %.4d - SensorID : %.4d \n ", APP_VGPtAcqDec->ResAAFrHead[MSisId][fCurrentFrameNumber].FiredPixNb, fCurrentAcqNumber, fCurrentFrameNumber, MSisId ); + } + + for ( int ViPix = 0; ViPix < APP_VGPtAcqDec->ResAAFrHead[MSisId][fCurrentFrameNumber].FiredPixNb; ViPix++ ) { + + VPix = APP_VGPtAcqDec->ResAAAFrPix[MSisId][fCurrentFrameNumber][ViPix]; + + if (fDebugLevel > 3) { + printf(" Pixel [%.4d] : Y = %.4d - X = %.4d - frameID = %d \n ", ViPix, VPix.C.y, VPix.C.x, fCurrentFrameNumber ); + } + AddPixel( MSisId, 1, VPix.C.y ,VPix.C.x ); + + }// End of Loop over pixels in a sensor for the current frame + + } // End of if condition : FiredPixNb > 0 + + }// End of Loop over sensors + + fCurrentFrameNumber ++ ; + +} + + +// -------------------------------------------------------------------------------------- +void BoardReaderMIMOSIS::AddPixel( int iSensor, int value, int aLine, int aColumn, int aTime) { + // Add a pixel to the vector of pixels + // require the following info + // - input = number of the sensors + // - value = output value of this pixel + // - line & column = position of the pixel in the matrix + // - time = something related to the frame or the trigger + + //if (fDebugLevel>3) + // printf("BoardReaderMIMOSIS::Addpixel adding pixel for sensor %d with value %d line %d row %d\n", iSensor, value, aLine, aColumn, aTime); + + fListOfPixels.push_back( BoardReaderPixel( iSensor + 1, value, aLine, aColumn, 0 /*TimeStamp has to be given for the constructor*/) ); + +} + +// -------------------------------------------------------------------------------------- + +void BoardReaderMIMOSIS::SetVetoPixel( int noiseRun) { + // Select the required function to veto the pixel depending on the run number. + // + + if( fDebugLevel) printf( " BoardReaderMIMOSIS board %d::SetVetoPixel with noise run number %d\n", fBoardNumber, noiseRun); + if (noiseRun>0 ) fTool.SetVetoPixel( noiseRun); + +} + +// -------------------------------------------------------------------------------------- +void BoardReaderMIMOSIS::PrintEventHeader() { + // Print Event Header + +} + +// -------------------------------------------------------------------------------------- +void BoardReaderMIMOSIS::SkipNextEvent() { + // This method might be useful to ignore the next event + // + + if(fDebugLevel) printf(" BoardReaderMIMOSIS: %d skipping current event %d\n", fBoardNumber, fCurrentEventNumber); + +} + +// -------------------------------------------------------------------------------------- +void BoardReaderMIMOSIS::PrintStatistics(ostream &stream) { + // Print statistics on all the events read by this board + + stream << "***********************************************" << endl; + stream << " Board MIMOSIS " << fBoardNumber << " found:" << endl; + stream << fTriggerCount << " triggers read overall," << endl; + stream << fCurrentEventNumber << " events in total," << endl; + stream << fNEventsWithOverflow << " events with an overflow (veto overflow " << fVetoOverflow << ")," << endl; + stream << fFrameCount << " frames read overall " << endl; + stream << fBadDecFrameCounter << " frames with decoding errors. " << endl; + stream << "***********************************************" << endl; + +} + +// -------------------------------------------------------------------------------------- + diff --git a/src/DAcq.cxx b/src/DAcq.cxx new file mode 100644 index 0000000..f024490 --- /dev/null +++ b/src/DAcq.cxx @@ -0,0 +1,2456 @@ +// @(#)maf/dtools:$Name: $:$Id: DAcq.cxx,v.2 2005/10/02 18:03:46 sha Exp $ +// Author: Dirk Meier 97/12/06 +// Completly rewritten: JB 2008/10/13 +// Last modified: JB 2009/05/06 +// Last modified: JB 2009/05/22 +// Last modified: JB 2009/05/25 +// Last modified: JB 2009/08/20 +// Last modified: RDM 2009/08/25 +// Last modified: JB 2009/09/09 +// Last modified: JB 2009/09/28 new TNT specs +// Last modified: JB 2010/06/16 and 07/07 get list of frames and triggers from BoardReaders +// Last modified: JB 2010/08/23 Allow multiple module types in the same acquisition +// Last modified: JB 2011/03/14 Declaration of PXIBoardReader to cope with DAQlib +// Last modified: JB 2011/06/19 Introduction of PXI & PXIe readers for backward compatibility +// Last modified: SS 2011/11/14 EventBuildingMode passed to PXIe +// Last modified: SS 2011/12/14 PrintStatistics +// Last modified: MG 2012/03/14 NextEvent +// Last modified: JB 2012/05/04 NextEvent +// Last modified: JB 2012/07/10 NextEvent +// Last modified: JB 2012/07/22 Introduction of IMGBoardEvent +// Last modified: SS 2012/08/10 Introduction of output bits for NextEvent +// Last modified: JB 2012/08/17 Counting missed events +// Last modified: JB 2013/08/14 DAcq, GetMatchingPlaneAndShift, NextEvent +// Last modified: LC 2013/08/20 GetSynchroInfo +// Last Modified: BH 2013/08/20 warning corrections from clang +// Last Modified: JB 2014/03/13 DAcq +// Last Modified: VR 2014/03/20 configuration of PXI DAQ LIB VERSION centralized in file pxi_daq_lib_config.h +// Last Modified: JB 2014/05/13-15 new BoardReader added VME, ALIM22, DecoderM18 +// Last Modified: JB 2014/08/26 replace DecoderM18_fb with DecoderM18 and add param for ALIM22 +// Last Modified: LC 2014/12/08 Adding MonteCarlo Parameters. +// Last Modified: LC 2014/12/15 Class DMonteCarlo Removed. Now MC info in DPixel Class. DPixel contain a vector of MC Info. +// Last Modified: LC 2014/12/15 Memory reduction if no MC + New infos easily added. +// Last Modified: LC 2014/12/15 New parameter in the config file : HitMonteCarlo If GIGBordReader HitMonteCarlo:1=enable :0=disable +// Last Modified: JB 2014/12/16 DAcq, NextEvent, PrintStatistics +// Last Modified: JB 2015/03/27 NextEvent and ___Synchro, for DecoderM18 synchro +// Last Modified: JB 2015/05/25 NextEvent +// Last Modified: AP 2016/04/15 Including MCBoardReader to read MC n-tuple +// Last Modified: AP 2016/04/21 Added an Object DEventMC which will serve as a MCInfoHolder, with the list of particles, hits and pixels (both physical and from noise) +// Last Modified: AP,JB 2016/09/20 DAcq for new param in IMGBoardReader +// Last Modified: JB 2017/11/20 DAcq +// Last Modified: JB 2018/02/11 InitTimeRefInfo -> updated 2018/03/21 +// Last Modified: JB 2020/02/17 Introduction of vetoPixdl for VMEBoardreader +// Last Modofies: JB 2021/05/01 Adding BoardReaderMIMOSIS + +//*-- Modified : IG +//*-- Copyright: RD42 +//*-- Author : Dirk Meier 97/12/06 +//*KEEP,CopyRight. +/************************************************************************ +* Copyright(c) 1997, Diamond.Detector@cern.ch, DiamondTracking. +***********************************************************************/ +//*KEND. + +#include "DAcq.h" + +#define MIMO_DAQ_LIB_VERSION_1_1 // (MIMOSIS1) +/* +#Include "pxi_daq_lib_config.h" // PXI DAQ Library version configuration is made in this file +#ifdef PXI_DAQ_LIB_VERSION_1_1 + #include "pxi_daq_lib_v.1.1/sync_index_rec.typ" + #include "pxi_daq_lib_v.1.1/sync_index_rec.c" +#endif +#ifdef PXI_DAQ_LIB_VERSION_1_2 + #include "pxi_daq_lib_v.1.2/sync_index_rec.typ" + #include "pxi_daq_lib_v.1.2/sync_index_rec.c" +#endif +#ifdef PXI_DAQ_LIB_VERSION_2_1 + #include "pxi_daq_lib_v.2.1/sync_index_rec.typ" + #include "pxi_daq_lib_v.2.1/sync_index_rec.c" +#endif +#ifdef PXI_DAQ_LIB_VERSION_3_1 + #include "pxi_daq_lib_v.3.1/sync_index_rec.typ" + #include "pxi_daq_lib_v.3.1/sync_index_rec.c" +#endif + */ +#ifdef MIMO_DAQ_LIB_VERSION_1_1 + #include "mimo_daq_lib/sync_index_rec.typ" + #include "mimo_daq_lib/sync_index_rec.c" +#endif + ///////////////////////////////////////////////////////////////////////////// + // Class Description of DAcq (DataAcquisition) // + // // + // + construct the DataAcquisition with its devices, inputs and channels // + // + prepare buffers for data // + // + translation of binary data to variables // + // // + ///////////////////////////////////////////////////////////////////////////// + + + ClassImp(DAcq) // Description of Single Detector DAcq + +//______________________________________________________________________________ +// + DAcq::DAcq() +{ + // Default DAcq ctor. + cout << "Default DAcq Constructor " << endl; +} + +//______________________________________________________________________________ +// +DAcq::DAcq(DSetup& c) +{ + // Constructs the Data Acquisition with value + // read from configuration file + // + // JB, 2008/10/14 + // modified JB 2009/05/06 + // modified JB 2009/08/20 to add PXI boards + // modified JB 2010/07/07 to init NULL pointers for list of triggers + // modified JB 2010/08/23 to allow new triggerMode flag and use of moduleType/10 + // modified JB 2011/06/19 Introduction of PXI & PXIe readers for backward compatibility + // modified JB 2011/06/28 passage of #rows to PXIe + // modified SS 2011/11/14 passage of eventBuildingMode for PXIe + // modified MG 2012/03/14 init ListOfLineOverflow + // modified JB 2012/04/25 to add GIG boards (GEANT4-DIGMaps) + // Modified JB 2012/07/22 to add IMG boards (analog Imager) + // Modified JB 2012/08/10 to count missed events + // Modified JB 2012/08/18 to pass eventsPerFile to IMGBoardReader + // Modified JB 2012/08/19 to pass FileHeaderLine to IMGBoardReader + // Modified JB 2013/06/22 passage of eventBuildingBoardMode + // Modified JB 2013/08/14,15 manage input offset to allow severall planes on same input + // Modified JB 2014/03/13 forward DUT status to Reader + // Modified JB 2014/05/13 to add VME boards (Eleuterio's format) + // Modified JB 2014/12/16 counter for NotOK events added + // Modified LC 2014/12/15 Class DMonteCarlo removed --> included in DPixel + // Modified JB 2015/05/26 Usage of timestamp added (fUseTimestamp) + // Modified JB 2016/09/20 Transmission of Nframes and NColumns (done by AP) to IMGBoardReader + // Modified JB 2017/11/20 allow Zero Suppression to IMGBoardReader + // Modified JB 2018/02/11 Test if init of TimeRefInfo is neeeded + + cout << endl << " -*-*- DAcq Constructor -*-*- " << endl; + + fc = &c; + fDebugAcq = fc->GetDebug(); + fRunNumber = fc->GetRunPar().Number; + fEventNumber = 0; + fRealEventNumber= 0; + fEventsMissed = 0; // JB 2012/08/17 + fEventsDataNotOK = 0; // JB 2014/12/16 + fEventsModuleNotOK = 0;// JB 2014/12/16 + Int_t mdt, mdl; + fModuleTypes = fc->GetAcqPar().ModuleTypes; + + fMaxSegments = 50; // JB 2013/08/14 + + // Timing information, 0 is the default which could be updated from data + // JB 2018/02/12 + fEventReferenceTime = 0; + fEventTime = 0; + + ListOfTriggers = NULL; // JB 2010/07/07 + ListOfFrames = NULL; + ListOfTimestamps = NULL; + ListOfLineOverflow = NULL; // MG 2012/02/15 + + fIsMCBoardReader = false; + + Bool_t initOK = kTRUE; // we start with proper init... + + cout << " Dacq building events" << ( (fc->GetAcqPar().TriggerMode==0)?" without":" with" ) << " trigger." << endl; + if (fDebugAcq) cout <<" DAcq: ModuleTypes " << fModuleTypes << endl; + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Count the total number of modules + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // JB 2010/08/23 + Int_t totalNmodules = 0; + for (mdt = 1; mdt <= fModuleTypes; mdt++){ // loop on module types + totalNmodules += fc->GetModulePar(mdt).Devices; + } + if(fDebugAcq) cout <<" DAcq: total modules " << totalNmodules << endl; + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Create the array structures to store the data + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + + // ========================== + //fRawData = new Int_t**[fModuleTypes]; // Pointer to raw data for each module type, only for readout=2 + fMatchingPlane = new Int_t***[totalNmodules]; + fIndexShift = new Int_t***[totalNmodules]; + fInputSegments = new vector**[totalNmodules]; + fListOfPixels = new vector[fc->GetTrackerPar().Planes]; + //fListOfMonteCarlo = new vector[fc->GetTrackerPar().Planes]; // LC 2014/12/15 :: DMonteCarlo included in DPixel + fLineOverflowN = new Int_t[10]; //MG 2012/02/15 : be carefull if the number of plane is bigger than 10 ! + fUseTimestamp = new Bool_t*[totalNmodules]; // JB 2015/05/26 + // ========================== + + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Create the pointers to each module types + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // JB 2010/08/23 + // JB 2012/04/25, GIGBoard added + // JB 2014/05/13, VMEBoard added + + // Create as many pointer as modules for each type even if some of them will not be used + fTNT = new TNTBoardReader*[totalNmodules]; + fPXI = new PXIBoardReader*[totalNmodules]; + // Ziad EL BITAR 2021/05/25 disregard PXIeModule when using MimosisBoardReader + //fPXIe = new PXIeBoardReader*[totalNmodules]; + fGIG = new GIGBoardReader*[totalNmodules]; + fIMG = new IMGBoardReader*[totalNmodules]; + fVME = new VMEBoardReader*[totalNmodules]; + fMC = new MCBoardReader*[totalNmodules]; + fALI22 = new AliMIMOSA22RawStreamVASingle*[totalNmodules]; + fM18 = new DecoderM18*[totalNmodules]; + fGeant = new DecoderGeant*[totalNmodules]; + fIHEP = new BoardReaderIHEP*[totalNmodules]; + fMSIS = new BoardReaderMIMOSIS*[totalNmodules]; + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Loop on each acquisition module type to set its properties + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // this include completing the array structure for the data + + Char_t aFileName[500], aBaseName[100]; + Int_t iModule=0; // module index, from 0 to totalNmodules + + //==================== + // Check for synchronization, JB 2012/07/22 + Bool_t synchroNeeded = false; + if( fModuleTypes>1 ) synchroNeeded = true; + + for (mdt = 1; mdt <= fModuleTypes; mdt++){ // loop on module types + + if(fDebugAcq) cout <<" DAcq: Starting building modules for type nb " << mdt << endl; + + // ========================== + //fRawData[mdt-1] = new Int_t*[fc->GetModulePar(mdt).Devices]; // Pointer to raw data for this module type, used for not zero-suppressed data + fMatchingPlane[mdt-1] = new Int_t**[fc->GetModulePar(mdt).Devices]; + fIndexShift[mdt-1] = new Int_t**[fc->GetModulePar(mdt).Devices]; + fInputSegments[mdt-1] = new vector*[fc->GetModulePar(mdt).Devices]; + fUseTimestamp[mdt-1] = new Bool_t[fc->GetModulePar(mdt).Devices]; // JB 2015/05/26 + // ========================== + + for (mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + if (fDebugAcq) cout << " DAcq: building module " << mdl << " of type " << fc->GetModulePar(mdt).Type << endl; + + fMatchingPlane[mdt-1][mdl-1] = new Int_t*[fc->GetModulePar(mdt).Inputs]; + fIndexShift[mdt-1][mdl-1] = new Int_t*[fc->GetModulePar(mdt).Inputs]; + fInputSegments[mdt-1][mdl-1] = new vector[fc->GetModulePar(mdt).Inputs]; + for ( Int_t iInp=0; iInpGetModulePar(mdt).Inputs; iInp++) { + fMatchingPlane[mdt-1][mdl-1][iInp] = new Int_t[fMaxSegments]; + fIndexShift[mdt-1][mdl-1][iInp] = new Int_t[fMaxSegments]; + } + + + // The real module type is defined by Type/10 + // JB 2010/08/23 + + switch ( (fc->GetModulePar(mdt).Type)/10 ) { + + // -+-+- IMG modules + case 1: + + fUseTimestamp[mdt-1][mdl-1] = kFALSE; // JB 2015/05/26 + //fIMG[iModule] = new IMGBoardReader( iModule, fc->GetModulePar(mdt).Inputs, fc->GetModulePar(mdt).Channels, fc->GetAcqPar().EventBufferSize, fc->GetRunPar().EventsInFile, fc->GetAcqPar().FileHeaderLine, fc->GetModulePar(mdt).Bits, fc->GetModulePar(mdt).SigBits, fc->GetAcqPar().BinaryCoding, fc->GetAcqPar().TriggerMode, fc->GetModulePar(mdt).EventBuildingBoardMode /*(fc->GetModulePar(mdt).Type)%10*/); + fIMG[iModule] = new IMGBoardReader( iModule, + fc->GetModulePar(mdt).Inputs, + fc->GetModulePar(mdt).Channels, + fc->GetAcqPar().EventBufferSize, + fc->GetRunPar().EventsInFile, + fc->GetAcqPar().FileHeaderLine, + fc->GetAcqPar().EventTrailerSize, // trailer indicated, JB 2018/03/19 + fc->GetModulePar(mdt).Bits, + fc->GetModulePar(mdt).SigBits, + fc->GetAcqPar().BinaryCoding, + fc->GetAcqPar().TriggerMode, + fc->GetModulePar(mdt).EventBuildingBoardMode /*(fc->GetModulePar(mdt).Type)%10*/, + fc->GetModulePar(mdt).NColumns, + fc->GetModulePar(mdt).NMultiFrames); + if( fc->GetModulePar(mdt).IfZeroSuppress > 0) { // JB 2017/11/20 + fIMG[iModule]->SetZeroSuppression( fc->GetModulePar(mdt).ThresholdZero); + } + fIMG[iModule]->SetDebugLevel( fDebugAcq); + //cout << "Setting number of columns to " << fc->GetPlanePar(1).Strips(0) << endl; + if( fc->GetModulePar(mdt).DeviceDataFile[mdl-1]!=NULL ) { + if( strcmp(fc->GetModulePar(mdt).DeviceDataFile[mdl-1], "") ) { + sprintf( aBaseName, "%s", fc->GetModulePar(mdt).DeviceDataFile[mdl-1]); + } else { + sprintf( aBaseName, "RUN_%d_", fRunNumber); + } + } else { + sprintf( aBaseName, "RUN_%d_", fRunNumber); + } + sprintf( aFileName, "%s/%s", fc->GetRunPar().DataPath, aBaseName); + if( !( fIMG[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ) ) ) { + sprintf( aFileName, "%s/%d/%s", fc->GetRunPar().DataPath, fRunNumber, aBaseName); + if( !( fIMG[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ) ) ) { + sprintf( aBaseName, "%d", fRunNumber); + sprintf( aFileName, "%s/%s", fc->GetRunPar().DataPath, aBaseName); + if( !( fIMG[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ) ) ) { + sprintf( aFileName, "%s/%d/%s", fc->GetRunPar().DataPath, fRunNumber, aBaseName); + initOK &= fIMG[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ); + } else { + initOK &= kTRUE; + } + } else { + initOK &= kTRUE; + } + } else { + initOK &= kTRUE; + } + break; + + + // -+-+- TNT modules + case 3: + + fUseTimestamp[mdt-1][mdl-1] = kTRUE; // JB 2015/05/26 + sprintf( aFileName, "%s/%s", fc->GetRunPar().DataPath, fc->GetModulePar(mdt).DeviceDataFile[mdl-1]); //RDM 140509, JB 2009/05/25 + fTNT[iModule] = new TNTBoardReader( iModule, fc->GetAcqPar().EventBufferSize, fc->GetAcqPar().BinaryCoding, fc->GetTrackerPar().TimeLimit, fc->GetAcqPar().TriggerMode, fc->GetModulePar(mdt).Bits[0], fc->GetModulePar(mdt).SigBits[0]); + fTNT[iModule]->SetDebugLevel( fDebugAcq); + initOK &= fTNT[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ); + break; + + + // -+-+- PXI modules + // JB 2009/08/20 + case 4: + + fUseTimestamp[mdt-1][mdl-1] = kTRUE; // JB 2015/05/26 + if(fc->GetTrackerPar().TimeLimit<0) fc->GetTrackerPar().TimeLimit = 2; + sprintf( aFileName, "%s/%scnf.bin", fc->GetRunPar().DataPath, fc->GetModulePar(mdt).DeviceDataFile[mdl-1]); + fPXI[iModule] = new PXIBoardReader( iModule, aFileName, fc->GetAcqPar().TriggerMode, fc->GetAcqPar().BinaryCoding); + fPXI[iModule]->SetDebugLevel( fDebugAcq); + sprintf( aFileName, "%s/%s", fc->GetRunPar().DataPath, fc->GetModulePar(mdt).DeviceDataFile[mdl-1]); //RDM 140509, JB 2009/05/25 + fPXI[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ); + break; + + + // -+-+- PXIe modules + // JB 2011/03/14 + // Ziad EL BITAR 2021/05/25 disregard PXIeModule when using MimosisBoardReader + /* + case 5: + + fUseTimestamp[mdt-1][mdl-1] = kTRUE; // JB 2015/05/26 + if(fc->GetTrackerPar().TimeLimit<0) fc->GetTrackerPar().TimeLimit = 2; + sprintf( aFileName, "%s/", fc->GetRunPar().DataPath); + fPXIe[iModule] = new PXIeBoardReader(iModule, + aFileName, + fRunNumber, + fc->GetAcqPar().TriggerMode, + fc->GetModulePar(mdt).EventBuildingBoardMode /*fc->GetAcqPar().EventBuildingMode*/ + /* ,0, + fc->GetAcqPar().BinaryCoding, + fc->GetPlanePar(1).Strips(1), + fc->GetPlanePar(1).MimosaType); //SS 2011.11.14 - EventBuildingMode can be loaded externally + cout << "Ziad : fileName : " << aFileName << endl; + cout << "Ziad : fRunNumber " << fRunNumber << endl; + cout << "Ziad : fc->GetPlanePar(1).Strips(1) " << fc->GetPlanePar(1).Strips(1) << endl; + cout << "Ziad : fc->GetAcqPar().BinaryCoding " << fc->GetAcqPar().BinaryCoding << endl; + + fPXIe[iModule]->SetDebugLevel( fDebugAcq); + fPXIe[iModule]->SetVetoPixel( fc->GetRunPar().NoiseRun); + fPXIe[iModule]->SetFlag(((fc->GetModulePar(mdt).Type)%10)); + fPXIe[iModule]->SetNumberOfColumns(fc->GetPlanePar(1).Strips(0)); + + break; + +*/ + // -+-+- GIG modules (GEANT4 - DIGMaps) + // JB 2011/03/14 + case 6: + + fUseTimestamp[mdt-1][mdl-1] = kFALSE; // JB 2015/05/26 + fGIG[iModule] = new GIGBoardReader( iModule, fc->GetTrackerPar().Planes); + sprintf( aFileName, "%s", fc->GetRunPar().DataPath); + fGIG[iModule]->AddFile( aFileName ); + fGIG[iModule]->SetDebugLevel( fDebugAcq); + fIfMonteCarlo = fc->GetTrackerPar().HitMonteCarlo; + break; + + + // -+-+- VME modules + // JB 2014/05/13 + case 7: + + fUseTimestamp[mdt-1][mdl-1] = kFALSE; // JB 2015/05/26 + sprintf( aFileName, "%s/", fc->GetRunPar().DataPath); + fVME[iModule] = new VMEBoardReader( iModule, fc->GetRunPar().DataPath, fc->GetModulePar(mdt).DeviceDataFile[mdl-1], fc->GetRunPar().Extension, fRunNumber, fc->GetModulePar(mdt).Inputs, fc->GetPlanePar(1).Strips(1)); + fVME[iModule]->SetDebugLevel( fDebugAcq); + fVME[iModule]->SetVetoPixel( fc->GetRunPar().NoiseRun); + break; + + + // -+-+- ALI modules for M-22 + // JB 2014/05/14 + case 8: + + fUseTimestamp[mdt-1][mdl-1] = kTRUE; // JB 2015/05/26 + if(fc->GetTrackerPar().TimeLimit<0) fc->GetTrackerPar().TimeLimit = 1; + sprintf( aFileName, "%s/FIFOdata_M22.dat", fc->GetRunPar().DataPath); + fALI22[iModule] = new AliMIMOSA22RawStreamVASingle(); + fALI22[iModule]->SetInputFile(aFileName); + fALI22[iModule]->SetNFrames(fc->GetModulePar(mdt).NbOfFramesPerChannel[mdl-1]); // JB 2014/08/26 + fALI22[iModule]->SetDebugLevel( fDebugAcq); + break; + + + // -+-+- Decoder MIMOSA-18 modules + // JB 2014/05/15 + // JB+CB+PRL, 2015/03/24 for additional param of decoder + case 9: + + fUseTimestamp[mdt-1][mdl-1] = kTRUE; // JB 2015/05/26 + sprintf( aFileName, "%s/", fc->GetRunPar().DataPath); + fM18[iModule] = new DecoderM18(iModule, fRunNumber, mdl-1); + // JB,CB,PLR 2015/03/24 + // PixelShift set to module-specific value, JB 2015/05/12 + // fM18[iModule]->SetShift( fc->GetModulePar(mdt).PixelShift ); + if (fDebugAcq)printf( " DAqcq:: setting kShift=%d for iModule=%d and mdl-1=%d\n", fc->GetModulePar(mdt).PixelShiftMod[mdl-1], iModule, mdl-1); + fM18[iModule]->SetShift( fc->GetModulePar(mdt).PixelShiftMod[mdl-1] ); + fM18[iModule]->SetOffset( fc->GetModulePar(mdt).AmpOffset ); + fM18[iModule]->SetMulFactor( fc->GetModulePar(mdt).AmpFactor ); + fM18[iModule]->SetTrailer( fc->GetModulePar(mdt).Trailer ); + fM18[iModule]->SetInputFile(Form("%s/%s%d%s",fc->GetRunPar().DataPath, fc->GetModulePar(mdt).DeviceDataFile[mdl-1], mdl-1, fc->GetRunPar().Extension)); + fM18[iModule]->SetDebugLevel( fDebugAcq); + break; + + + // -+-+- GEANT modules + + case 10: + fUseTimestamp[mdt-1][mdl-1] = kFALSE; // JB 2015/05/26 + sprintf( aFileName, "%s/", fc->GetRunPar().DataPath); + fGeant[iModule] = new DecoderGeant(iModule, fRunNumber); + fGeant[iModule]->SetInputFile(Form("%s/%s%d%s",fc->GetRunPar().DataPath, fc->GetModulePar(mdt).DeviceDataFile[mdl-1], mdl-1, fc->GetRunPar().Extension)); + fGeant[iModule]->SetDebugLevel( fDebugAcq); + break; + + // -+-+- MC modules + // AP 2016/04/15 + case 11: + + fUseTimestamp[mdt-1][mdl-1] = kFALSE; // AP 2016/04/15 + sprintf( aFileName, "%s/", fc->GetRunPar().DataPath); + fMC[iModule] = new MCBoardReader( iModule, + fRunNumber, + TString(fc->GetRunPar().DataPath), + TString(fc->GetModulePar(mdt).DeviceDataFile[mdl-1]), + TString(fc->GetModulePar(mdt).MCTreeName.Data()), + fc); + fMC[iModule]->SetDebugLevel( fDebugAcq); + + //Holder for the MC truth information + //Only initialized when reading MC data + MCInfoHolder = new DEventMC(); + + //Passing the pointer of the MCInfoHolder to be filled up + //Inside MCBoardReader for each event + fMC[iModule]->SetMCInforHolder(MCInfoHolder); + + fIsMCBoardReader = true; + + break; + + // -+-+- IHEP modules + case 12: + + fUseTimestamp[mdt-1][mdl-1] = kFALSE; + fIHEP[iModule] = new BoardReaderIHEP( iModule, fc->GetAcqPar().TriggerMode, fc->GetModulePar(mdt).EventBuildingBoardMode); + if( fc->GetModulePar(mdt).DeviceDataFile[mdl-1]!=NULL ) { + if( strcmp(fc->GetModulePar(mdt).DeviceDataFile[mdl-1], "") ) { + sprintf( aFileName, "%s/%s.%s", fc->GetRunPar().DataPath, fc->GetModulePar(mdt).DeviceDataFile[mdl-1], fc->GetRunPar().Extension); + } else { + sprintf( aFileName, "%s/1.%s", fc->GetRunPar().DataPath, fc->GetRunPar().Extension); + } + } else { + sprintf( aFileName, "%s/1.%s", fc->GetRunPar().DataPath, fc->GetRunPar().Extension); + } + initOK &= fIHEP[iModule]->AddFile( aFileName ); + break; + + + // -+-+- MIMOSIS modules + case 13: + fUseTimestamp[mdt-1][mdl-1] = kFALSE; + fMSIS[iModule] = new BoardReaderMIMOSIS( iModule, + fc->GetRunPar().DataPath, // ZE 2021/06/01 + fRunNumber, //ZE 2021/05/28 + fc->GetModulePar(mdt).Inputs, + fc->GetAcqPar().TriggerMode, + fc->GetModulePar(mdt).EventBuildingBoardMode, + fc->GetAcqPar().BinaryCoding); + + fMSIS[iModule]->SetDebugLevel( fDebugAcq); + /* + fMSIS[iModule]->SetVetoPixel( fc->GetRunPar().NoiseRun); + if( fc->GetModulePar(mdt).DeviceDataFile[mdl-1]!=NULL ) { + if( strcmp(fc->GetModulePar(mdt).DeviceDataFile[mdl-1], "") ) { + sprintf( aBaseName, "%s%d", fc->GetModulePar(mdt).DeviceDataFile[mdl-1], fRunNumber); + } else { + sprintf( aBaseName, "RUN_%d", fRunNumber); + } + } else { + sprintf( aBaseName, "RUN_%d", fRunNumber); + } + sprintf( aFileName, "%s/%s", fc->GetRunPar().DataPath, aBaseName); + if( !( fMSIS[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ) ) ) { + sprintf( aFileName, "%s/%d/%s", fc->GetRunPar().DataPath, fRunNumber, aBaseName); + if( !( fMSIS[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ) ) ) { + sprintf( aBaseName, "%d", fRunNumber); + sprintf( aFileName, "%s/%s", fc->GetRunPar().DataPath, aBaseName); + if( !( fMSIS[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ) ) ) { + sprintf( aFileName, "%s/%d/%s", fc->GetRunPar().DataPath, fRunNumber, aBaseName); + initOK &= fMSIS[iModule]->AddFileList( aFileName, fc->GetRunPar().StartIndex, fc->GetRunPar().EndIndex, fc->GetRunPar().Extension ); + } else { + initOK &= kTRUE; + } + } else { + initOK &= kTRUE; + } + } else { + initOK &= kTRUE; + } + */ + break; + + + // -+-+- Other modules + default: + cout << "WARNING: DAcq, unknown module type " << fc->GetModulePar(mdt).Type << "!" << endl; + }; // end switch on module types + + cout << " DAcq: << " << fc->GetModulePar(mdt).Name << " module " << mdl << " build with " << fc->GetModulePar(mdt).Inputs << " inputs of " << fc->GetModulePar(mdt).Channels[0] << " channels" << endl << endl; + + iModule++; + + } // end loop on each modules of this type + + } // end loop on module types + + + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Loop on each plane to match its input + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // We associate a module to a plane + // and store a potential shift between the channel index of the input and the real pixel index + // Also, if plane is a DUT, the module might need to know it + + Int_t aModuleType, aModuleNumber, aInput, aChannel, aOffset, aSegment; + //Int_t aChannelNumber; + cout << "Number of Planes: " << fc->GetTrackerPar().Planes << endl; + for ( Int_t iPlane = 1; iPlane <= fc->GetTrackerPar().Planes; iPlane++){ // loop on planes + for ( Int_t iInp = 0; iInp < fc->GetPlanePar(iPlane).Inputs; iInp++) { // loop on inputs for this plane + if (fc->GetPlanePar(iPlane).ModuleType[iInp] == 0) { + continue; + } + if (fDebugAcq) { + cout << " DAcq: Associating input " << iInp << " of plane " << iPlane << endl; + cout << "Input " << iInp << " of type " << fc->GetPlanePar(iPlane).ModuleType[iInp] << " number " << fc->GetPlanePar(iPlane).ModuleNumber[iInp] << " input " << fc->GetPlanePar(iPlane).InputNumber[iInp] << " shift " << fc->GetPlanePar(iPlane).ChannelNumber[iInp] << " offset " << fc->GetPlanePar(iPlane).ChannelOffset[iInp] << " #channels " << fc->GetPlanePar(iPlane).Channels[iInp] << endl; + } + aModuleType = fc->GetPlanePar(iPlane).ModuleType[iInp]; + aModuleNumber = fc->GetPlanePar(iPlane).ModuleNumber[iInp]; + aInput = fc->GetPlanePar(iPlane).InputNumber[iInp]; + aChannel = fc->GetPlanePar(iPlane).ChannelNumber[iInp]; + aOffset = fc->GetPlanePar(iPlane).ChannelOffset[iInp]; // JB 2013/08/15 + //aChannelNumber = fc->GetPlanePar(iPlane).Channels[iInp]; + aSegment = fInputSegments[aModuleType-1][aModuleNumber-1][aInput-1].size(); + + if (aSegment==fMaxSegments) { + cout << " WARNING in DACQ constructor: input " << aInput << " of module type " << aModuleType << " nb " << aModuleNumber << " reach the maximum nb of segments allowed (" << fMaxSegments << "), new segment added to previous one!" << endl; + aSegment = fMaxSegments-1; + } + fMatchingPlane[aModuleType-1][aModuleNumber-1][aInput-1][aSegment] = iPlane; + fIndexShift[aModuleType-1][aModuleNumber-1][aInput-1][aSegment] = aChannel; + fInputSegments[aModuleType-1][aModuleNumber-1][aInput-1].push_back(aOffset); + cout << " segment " << aSegment << " with offset " << aOffset << " of input " << aInput << " of module type " << aModuleType << " nb " << aModuleNumber << " associated to plane " << iPlane << " with index shift " << aChannel << endl; + + } // end loop on inputs + } // end loop on planes + + + // Now, check that each input has some correct plane number associated + // JB, 2009/05/25; modified JB 2013/08/14 + iModule = 0; + Int_t aPlaneNumber; + for (mdt = 1; mdt <= fModuleTypes; mdt++){ // loop on module types + if( fc->GetAcqPar().IfExternalTimeRef ) { + InitTimeRefInfo( ); // JB 2018/02/11 + } + +for (mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each module + + for ( Int_t iInp = 1; iInp <= fc->GetModulePar(mdt).Inputs; iInp++) { // loop on inputs + for ( Int_t iSeg=1; iSeg<=(Int_t)fInputSegments[mdt-1][mdl-1][iInp-1].size(); iSeg++) { //loop on segments + + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][iInp-1][iSeg-1]; + if( aPlaneNumber<1 && aPlaneNumber>fc->GetTrackerPar().Planes ) { + printf( "ERROR: module type %d, module # %d, input %d segment %d is not associated properly to a plane! Getting %d instead of 1-%d.\n", mdt, mdl, iInp, iSeg, fMatchingPlane[mdt-1][mdl-1][iInp-1][iSeg-1], fc->GetTrackerPar().Planes); + } + + // For DUT plane, indicate it to the module + // Note the inputNumber-1 because PXIeBoardReader input index starts at 0 + // JB 2014/03/13 + else if( fc->GetPlanePar(aPlaneNumber).Status == 3 ) { + if (fDebugAcq) cout << "Declaring plane " << aPlaneNumber << " as DUT to module " << mdl << " of type " << fc->GetModulePar(mdt).Type << " linked to input(from 0) " << fc->GetPlanePar(aPlaneNumber).InputNumber[0]-1 << endl; + switch ( (fc->GetModulePar(mdt).Type)/10 ) { + // -+-+- PXIe modules + // Comment added by Ziad EL BITAR on May 25, 2021, disregard PXIeModule when using MimosisBoardReader + // case 5: + // fPXIe[iModule]->AddDUTSensor( fc->GetPlanePar(aPlaneNumber).InputNumber[0]-1 ); + + // ZE on May 31, 2021 + // case 13: + // fMSIS[iModule]->AddDUTSensor( fc->GetPlanePar(aPlaneNumber).InputNumber[0]-1 ); + }; + } + + } // end loop on segments + } // end loop on each inputs + + iModule++; + } // end loop on each modules of this type + } // end loop on module types + + if( synchroNeeded ) { + InitSynchroInfo( ); // JB 2012/07/19 + } + + if( fc->GetAcqPar().IfExternalTimeRef ) { + InitTimeRefInfo( ); // JB 2018/02/11 + } + + + // STOP when something was wrong in the init, JB 2009/05/25 + // only if rawdata reading required, JB 2013/08/21 + if( !initOK ) { + Char_t choice; + Warning( "DAcq", "Cannot construct Acquisition !!\n -> Choose your option: type [q] to quit or anything else to proceed (if you know you don't need acq)."); + cin >> choice; + if (choice=='q') { + Fatal("DAcq", "--> STOPPING because no acquisition <--"); + } + } + cout << endl << " -*-*- DAcq Constructor DONE -*-*- " << endl; +} + +//______________________________________________________________________________ +// +DAcq::~DAcq() +{ + // Default DAcq destructor. +} + +//______________________________________________________________________________ +// +void DAcq::SetDebug(Int_t aDebug) +{ + // Set the debug level + // JB 2009/05/22 + // Modified JB 2009/08/20, PXIBoard added + // Modified JB 2009/09/09, debug set if level=0 + // Modified JB 2010/08/23 to use modulteType/10 + // Modified JB 2011/06/19 Introduction of PXI & PXIe readers for backward compatibility + // Modified MG 2012/03/14 added lineOverflow for PXIeBoardReader + // Modified JB 2012/04/25 to add GIG boards (GEANT4-DIGMaps) + // Modified SS 2012/08/01 to add IMG boards + // Modified JB 2014/05/13 to add VME boards + // Modified JB 2018/10/09 to add IHEP boards + + Int_t iModule=0; // module index, from 0 to totalNmodules + + cout << "DAcq: debug set: " << aDebug << endl; + + if( aDebug<=0 ) { // if negative level, set acquisition module level + + for ( Int_t mdt = 1; mdt <= fModuleTypes; mdt++){ // loop on module types + + switch ( (fc->GetModulePar(mdt).Type)/10 ) { + + // -+-+- IMG modules + case 1: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fIMG[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- TNT modules + case 3: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fTNT[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- PXI modules + case 4: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fPXI[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- PXIe modules + // Ziad EL BITAR, 2021/05/25 comment PXIe module when using Mimosis1 + /* + case 5: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fPXIe[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; +*/ + // -+-+- GIG modules + case 6: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fGIG[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- VME modules + case 7: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fVME[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- ALI22 modules + case 8: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fALI22[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- DecoderM18 modules + case 9: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fM18[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- DecoderGeant modules + case 10: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fGeant[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- MC modules + case 11: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fMC[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- IHEP modules + case 12: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fIHEP[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + // -+-+- MIMOSIS modules + case 13: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fMSIS[iModule]->SetDebugLevel( abs(aDebug) ); + iModule++; + } // end loop on each module of this type + break; + + }; // end switch on module types + + + } // end loop on module types + + } // end if negative level + + fDebugAcq = abs(aDebug); + cout << "DAcq debug updated to " << abs(aDebug) << endl; + +} + +//______________________________________________________________________________ +// +Int_t* DAcq::GetRawData( Int_t mdt, Int_t mdl, Int_t input) +{ + // Return the pointer to the address of the first data of + // the given mdt module type, mdl module number and input + // all these index are expected to start at 1 + // + // JB, 2008/10/17 + // Modified: JB 2013/08/16 manage different channel numbers per input + + return fRawData[mdt-1][mdl-1]+(input-1)*fc->GetModulePar(mdt).Channels[input-1]; + +} + +//______________________________________________________________________________ +// +void DAcq::GetMatchingPlaneAndShift( Int_t mdt, Int_t mdl, Int_t input, Int_t channel, Int_t &aPlane, Int_t &aShift) +{ + // Set the plane and the shift matching the given + // module type, number, input and channel. + // All indexes expected to start at 1. + // + // The vector fInputSegments provides the lower limits of a segment + // for a given module type and number and input number. + // Its minimum size is 1. + // This means that if an input has only one segment: fInputSegments[0] = 1, + // and with segments like 1-256 / 257-512: + // fInputSegments[0] = 1 and fInputSegments[1] = 257 + // + // JB 2013/08/14 + + if(fDebugAcq>3) { + printf("DAcq::GetMatchingPlaneAndShift looking for plane associated with module type %d, nb %d, input %d, channel %d", mdt, mdl, input, channel); + printf(" within %d segments",(int)fInputSegments[mdt-1][mdl-1][input-1].size()); // removing warning: cast 'size_type' (aka 'unsigned long') to 'int' BH 2013/08/20 + for (Int_t iSeg=0; iSeg<(Int_t)fInputSegments[mdt-1][mdl-1][input-1].size(); iSeg++) { // removing warning: cast 'size_type' (aka 'unsigned long') to 'Int_t' (aka 'int') BH 2013/08/20 + printf(": %d", fInputSegments[mdt-1][mdl-1][input-1].at(iSeg)); + } + printf("\n"); + } + + Int_t aSegment = (Int_t)fInputSegments[mdt-1][mdl-1][input-1].size()-1; + + while (03) printf("DAcq::GetMatchingPlaneAndShift found plane %d and shift %d from segment %d\n", aPlane, aShift, aSegment); + +} + +//______________________________________________________________________________ +// +Bool_t DAcq::InitSynchroInfo( ) +{ + // Decide the synchronization strategy depending on the types of BoardReader. + // + // * In general: do nothing + // + // * When PXIeBoardReader and IMGBoardReader: + // Read the file containing the synchronization information + // and store them in a buffer. + // + // Return true upon success. + // + // JB, 2012/07/19 + // Modified: JB 205/03/27 to allow for different strategy + + Int_t nIMGBoard = 0; + Int_t nPXIeBoard = 0; + Int_t nM18Decoder = 0; + + for (int mdt = 1; mdt <= fModuleTypes; mdt++){ // loop on module types + switch ( (fc->GetModulePar(mdt).Type)/10 ) { + case 1: + nIMGBoard++; + break; + case 5: + nPXIeBoard++; + break; + case 9: + if ( nM18Decoder==0 ) { + fSynchroFirstM18Decoder = mdt; + } + nM18Decoder++; + break; + }; + } // loop on module types + + //=================== + + // Ziad EL BITAR 2021/05/25 disregard PXIeModule when using MimosisBoardReader + /* + if (nIMGBoard>0 && nPXIeBoard>0 ) { // if synchro IMG, PXIe + + // Set the file name + fSynchroFileName = new Char_t[550]; + sprintf( fSynchroFileName, "%s/RUN_%d_sync.bin", fc->GetRunPar().DataPath, fRunNumber); + if (fDebugAcq) cout << " DAcq::InitSynchro(), opening synchronization file " << fSynchroFileName << endl; + + // Get the file size which is the size of the buffer needed + Int_t bufferSize= GetFileSize( fSynchroFileName); + if (fDebugAcq) cout << " DAcq::InitSynchro(), synchronization file contains " << bufferSize << " Bytes, from structure of " << sizeof( APP__TSyncIndexRec) << " Bytes." << endl; + + // Then, load the file in the buffer + fNbSynchroInfo = 0; // will stay at 0 if something fails + if( bufferSize>0 && bufferSize%sizeof( APP__TSyncIndexRec)==0 ) { + fSynchroInfo = new unsigned char[bufferSize]; + fNbSynchroInfo = GetSyncPointer( fSynchroFileName, fSynchroInfo, bufferSize); + if (fDebugAcq) cout << " DAcq::InitSynchro(), " << fNbSynchroInfo << " words have been loaded." << endl; + } + else { + fSynchroInfo = NULL; + cout << "ERROR, problem with the synchronization file which is either empty (size = " << bufferSize << " Bytes) or corrupted (file_size%structure_size = " << bufferSize%sizeof( APP__TSyncIndexRec) << ")." << endl; + } + + // If success, the buffer size is not 0 + return bufferSize>0 && fNbSynchroInfo>0; + + } // end if synchro IMG, PXIe + +*/ + //=================== + if ( nM18Decoder>=2 ) { + cout << endl << "Synchronization of M18Decoders requires passing OMKDTransition information from one file to the other." << endl; + cout << " -> first M18Decoder used to read OMKDTransition is of type " << fSynchroFirstM18Decoder << endl; + } + + + //=================== + // if no known case of synchro found, simply don't complain + cout << endl << "Though several BoardTypes are declared, no specicif synchronization mechanism is needed." << endl; + + return kTRUE; +} + +//______________________________________________________________________________ +// +Bool_t DAcq::GetSynchroInfo( int anEventId, int &anAcqId, int &aFrameId) +{ + + // Get the synchornization information between two files (two boards). + // anEventId is the event number of the first file. + // anAcqId and aFrameId are the returned position in the second file of + // the corresponding event. + // + // Return true upon success, if failure IDs are set to -1. + // + // JB, 2012/07/19 + // Modified: SS, 2012/08/01 bug fix for iEvent init + // Modified: SS, 2013/06/25 bug fix for iEvent exceeding fNbSynchroInfo + // Modified: LC, 2013/08/20 bug fix for iEvent < 0 + + Bool_t eventFound = false; + anAcqId = -1; + aFrameId = -1; + int absoluteFrameNb = -1; + + if (fDebugAcq>1) cout << " DAcq::GetSynchroInfo(), searching for event " << anEventId << " among " << fNbSynchroInfo << " entries." << endl; + + if( fSynchroInfo != NULL ) { + + APP__TSyncIndexRec* pointer2Event = (APP__TSyncIndexRec*)fSynchroInfo; + + unsigned int iEvent=anEventId; //SS 2012.08.06 Reset iEvent counter always starts at 0 to account for missed events, Changed to expected event, JB 2012 + if (iEvent>=(unsigned int)fNbSynchroInfo) iEvent=fNbSynchroInfo-1; //SS 2013.06.25 protection against that iEvent exceeds the limit of fNbSynchroInfo + //printf( " anEventID=%d, iEvent=%d", anEventId, iEvent); + //printf( ", DutEvId=%d\n", (int)pointer2Event[iEvent].DutEvId); + + // Added protection against iEvent<0 in the loop below, LC 2013/08/20 + while( 0 iEvent) { + iEvent -= pointer2Event[iEvent].DutEvId - anEventId; + } + else { + iEvent = 0; + } + //printf(" --> new iEvent=%d\n", iEvent); + } + while( iEvent<(unsigned int)fNbSynchroInfo && anEventId>=(int)pointer2Event[iEvent].DutEvId && !eventFound) { + if (fDebugAcq>1) cout << " DAcq::GetSynchroInfo(), testing entry " << iEvent << " with eventId = " << pointer2Event[iEvent].DutEvId << endl; + if( anEventId == (int)pointer2Event[iEvent].DutEvId ) { + anAcqId = pointer2Event[iEvent].TelTrigAcqId; + aFrameId = pointer2Event[iEvent].TelTrigFrIdInAcq; // add a -1 for TEMPORARY FIX runs 32703 to 32705 DESY June 2013 beam test, JB 2013/06/22 + absoluteFrameNb = pointer2Event[iEvent].TelTrigEvTag; + eventFound = true; + } + iEvent++; + } + if (fDebugAcq>1) cout << " DAcq::GetSynchroInfo(), event " << anEventId << " has " << (eventFound?"":"NOT") << " been found and corresponds to AckID = " << anAcqId << ", FrameID = " << aFrameId << " absolute nb = " << absoluteFrameNb << endl; + + } + else { + cout << "WARNING DAcq::GetSynchroInfo(), synchronization information has not been initialized properly." << endl; + } + + return eventFound; +} + +//______________________________________________________________________________ +// +Bool_t DAcq::InitTimeRefInfo( ) +{ + // Open the external file with time reference information + // + // Return true upon success. + // + // JB, 2018/02/11 + // Modified JB 2018/03/21 Check both case of time ref file location w and wo runNumber in path + + FILE *timeRefFile; + + // Set the file name + // Get the file size which is the size of the buffer needed + fTimeRefFileName = new Char_t[550]; + sprintf( fTimeRefFileName, "%s/time_stamp_log.bin", fc->GetRunPar().DataPath); + if (fDebugAcq) cout << " DAcq::InitTimeRef(), opening time reference file " << fTimeRefFileName << endl; + Int_t bufferSize = GetFileSize( fTimeRefFileName); + if( !(bufferSize>0) ) { + sprintf( fTimeRefFileName, "%s/%d/time_stamp_log.bin", fc->GetRunPar().DataPath, fRunNumber); + if (fDebugAcq) cout << " DAcq::InitTimeRef(), opening time reference file " << fTimeRefFileName << endl; + bufferSize = GetFileSize( fTimeRefFileName); + } + if (fDebugAcq) { + cout << " DAcq::InitTimeRef(), synchronization file contains " << bufferSize << " Bytes, from structure of " << sizeof( SEXP_TTsRec) << " Bytes, which should be " << fTimeRefRecordSize << " Bytes." << endl; + cout << " nb of records expected = " << bufferSize/sizeof( SEXP_TTsRec) << " -> is that an integer? " << !(bufferSize%sizeof( SEXP_TTsRec)) << endl; + } + + // Then, load the file in the buffer + fNbTimeRefInfo = 0; // will stay at 0 if something fails + fTimeRefInfo = NULL; + if( bufferSize>0 && bufferSize%sizeof( SEXP_TTsRec)==0 && sizeof( SEXP_TTsRec)==fTimeRefRecordSize ) { + timeRefFile = fopen ( fTimeRefFileName, "rb" ); + if( timeRefFile != NULL ) { + + int expectedInfoNb = bufferSize / sizeof( SEXP_TTsRec); + fTimeRefInfo = new SEXP_TTsRec[expectedInfoNb]; + fNbTimeRefInfo = fread ( fTimeRefInfo, sizeof( SEXP_TTsRec), expectedInfoNb, timeRefFile ); + if( fNbTimeRefInfo != expectedInfoNb ) { + fNbTimeRefInfo = 0; + fTimeRefInfo = NULL; + cout << "ERROR, cannot read info in time reference file " << fTimeRefFileName << "." << endl; + } + else { + if (fDebugAcq) cout << " DAcq::InitTimeRef(), " << fNbTimeRefInfo << " records have been loaded." << endl; + } + + if( fclose( timeRefFile ) ) { + cout << "WARNING, cannot close time reference file " << fTimeRefFileName << "." << endl; + } + + } // timeRefFile != NULL + + else { // File cannot be opened + cout << "ERROR, cannot open time reference file " << fTimeRefFileName << "." << endl; + } + + } + else { // in case the file cannot be read properly, switch off + cout << "ERROR, problem with the synchronization file which is either empty (size = " << bufferSize << " Bytes) or corrupted (file_size%structure_size = " << bufferSize%sizeof( APP__TSyncIndexRec) << ")." << endl; + } + + if ( fTimeRefInfo == NULL ) { + cout << "ERROR, CANNOT use external time reference, reverting to not using it!" << endl; + fc->GetAcqPar().IfExternalTimeRef = 0; + fCurrentTimeRefInfo = 0; + return kFALSE; + } + + fCurrentTimeRefInfo = 0; + return kTRUE; +} + + +//______________________________________________________________________________ +// +Bool_t DAcq::GetTimeRef( int index, int &recordID, int &cycleID, int &rtcTime, int &ntpTime) +{ + // Get the time reference information at the given index + // The returned format of rtcTime and ntpTime is the number of seconds since + // + // Return true upon success. + // + // JB, 2018/02/11 + + if( fTimeRefInfo == NULL || index>=fNbTimeRefInfo ) return kFALSE; + + // Possibly test that ResCnt = ReStartCnt + recordID = fTimeRefInfo[index].RecCnt; + cycleID = fTimeRefInfo[index].InfoCyclicTS; + // Still need to decide how to format ime + struct std::tm atime; + atime.tm_year = fTimeRefInfo[index].RtcDateTime.Date.Year+100; // Gille's info is year since 2000 while years since 1900 is expected + atime.tm_mon = fTimeRefInfo[index].RtcDateTime.Date.Month; + atime.tm_mday = fTimeRefInfo[index].RtcDateTime.Date.Day; + atime.tm_hour = fTimeRefInfo[index].RtcDateTime.Time.Hour; + atime.tm_min = fTimeRefInfo[index].RtcDateTime.Time.Min; + atime.tm_sec = fTimeRefInfo[index].RtcDateTime.Time.Sec; + atime.tm_isdst = 0; // no daylight saving time is not used in Japan + rtcTime = mktime( &atime); + // rtcTime = fTimeRefInfo[index].RtcDateTime.Time.Sec; + + struct std::tm btime; + btime.tm_year = fTimeRefInfo[index].NtpDateTime.Date.Year+100; // Gille's info is year since 2000 while years since 1900 is expected + btime.tm_mon = fTimeRefInfo[index].NtpDateTime.Date.Month; + btime.tm_mday = fTimeRefInfo[index].NtpDateTime.Date.Day; + btime.tm_hour = fTimeRefInfo[index].NtpDateTime.Time.Hour; + btime.tm_min = fTimeRefInfo[index].NtpDateTime.Time.Min; + btime.tm_sec = fTimeRefInfo[index].NtpDateTime.Time.Sec; + btime.tm_isdst = 0; // no daylight saving time is not used in Japan + rtcTime = mktime( &btime); + // ntpTime = fTimeRefInfo[index].NtpDateTime.Time.Sec; + + if ( fDebugAcq>2 ) { + cout << " DAcq::GetTimeRef for index " << index << ", record " << recordID; + cout << ", cycle " << cycleID << ", rtc time " << rtcTime << ", ntp time " << ntpTime << " seconds since Epoch."<< endl; + cout << " Detail RTC info: year/month/day = " << 1900+atime.tm_year << "/" << atime.tm_mon << "/" << atime.tm_mday << ", hour/min/sec/ms = " << atime.tm_hour << "/" << atime.tm_min << "/" << atime.tm_sec << "/" << fTimeRefInfo[index].RtcDateTime.Time.Ms << endl; + cout << " Detail NTP info: year/month/day = " << 1900+btime.tm_year << "/" << btime.tm_mon << "/" << btime.tm_mday << ", hour/min/sec/ms = " << btime.tm_hour << "/" << btime.tm_min << "/" << btime.tm_sec << "/" << fTimeRefInfo[index].NtpDateTime.Time.Ms << endl; + } + + return kTRUE; +} + + +//______________________________________________________________________________ +// +void DAcq::Reset() +{ + // Reset event reading at 0 + // So that next event is the very first one + // + // NOT FULLY FUNCTIONAL YET + // + // JB 2015/03/02 + + if( fModuleTypes>1 ) { + cout << "CANNOT RESET DAQ when more than one module type -> nop." << endl << endl; + } + + //==================== + if (fDebugAcq) cout << " DAcq: resetting to first event" << endl; + Int_t iModule=0; // module index, from 0 to totalNmodules + for ( Int_t mdt = 1; mdt <= fModuleTypes; mdt++){ // loop on module types + + switch ( (fc->GetModulePar(mdt).Type)/10 ) { + + // -+-+- PXIe modules +/* + case 5: + fPXIe[iModule]->ResetReading(); + iModule++; + break; +*/ + // No other case implemented + default: + cout << " RESET DAQ not yet implemented for this module type -> nop." << endl << endl; + iModule++; + + } + + } // end loop on module types + +} + +//______________________________________________________________________________ +// +TBits* DAcq::NextEvent( Int_t eventNumber, Int_t aTrigger) +{ + // Read next event from file(s), + // the event number is defined by DSession. + // If aTrigger != -1 (default is -1) then the event with this specific trigger + // number is searched for (valid only for PXIeBoardReader yet). + // The return code is a pointer to 3 bits : + // bit 0: 1 if readout is OK (meaning there are still some events to read), + // bit 1: 1 if synchronization between modules was required and succesfull, + // bit 2: 1 if event data is OK (meaning analysis can be performed). + // + // JB, 208/10/13 + // Last modified JB 2009/05/12 + // Last modified JB 2009/08/20 to add PXI boards + // Last modified JB 2010/06/16 to store full trigger and frame info from BoardReaders + // Last modified JB 2010/08/23 to use modulteType/10 + // Last modified JB 2011/06/19 Introduction of PXI & PXIe readers for backward compatibility + // Last modified MG 2012/03/14 Line overflow vector for PXIe + // Last modified JB 2012/04/25 to add GIG boards (GEANT4-DIGMaps) + // Last modified JB 2012/07/10 to allow selection of event by trigger + // Last modified JB 2012/07/22 to add IMG boards (analog Imager) + // Last modified JB 2012/07/22 to synchronized IMG and PXIe boards + // Last modified SS 2012/08/01 bug fixes for synchronization + // Last modified SS 2012/08/10 introducing TBits output and missed events + // Last modified JB 2013/06/22 concatenation of lists from different modules + // Last modified JB 2013/08/14 usage of GetMatchingPlaneAndShift + // Last modified JB 2014/05/13 to add VME boards + // Last modified JB 2015/03/27 to synchronize two DecoderM18 + // Last modified JB 2015/05/25 TimeStamp added for Ali22 + // Last modified JB 2018/02/21 reads external time reference if required + + Bool_t eventOK = kTRUE; // init at true, end-up false if one module fails + Bool_t moduleOK = true; // init at true, end-up false if HasData() fails + Bool_t eventMissed = kFALSE; // to check correct synchronization, SS 2012/08/10 + Bool_t dataOK = kTRUE; // to check the event data can be processed, JB 2012/08/18 + + TBits* DAcqResult=new TBits(3); + Int_t aPlaneNumber, aShift; + + BoardReaderEvent *readerEvent; + BoardReaderPixel *readerPixel; + + fEventNumber = eventNumber; // JB 2009/05/26 + if (fDebugAcq) cout << " DAcq::NextEvent(), getting event " << fEventNumber << endl; + + // Init added because each module types update those lists + // JB 2013/06/22 + fTriggersN = 0; + fFramesN = 0; + fTimestampsN = 0; + if (ListOfTriggers!=NULL) ListOfTriggers->clear(); + if (ListOfFrames!=NULL) ListOfFrames->clear(); + if (ListOfTimestamps!=NULL) ListOfTimestamps->clear(); + + //==================== + // erasing pixel and pixel list for all planes + if (fDebugAcq) cout << " DAcq::NextEvent(), erasing Pixel list for all planes." << endl; + for( Int_t iPlane = 0; iPlaneGetTrackerPar().Planes; iPlane++) { + for( Int_t iPix=0; iPix<(Int_t)fListOfPixels[iPlane].size(); iPix++) { + delete fListOfPixels[iPlane].at(iPix); + } + /* + for( Int_t iMonteCarlo=0; iMonteCarlo<(Int_t)fListOfMonteCarlo[iPlane].size(); iMonteCarlo++) { + delete fListOfMonteCarlo[iPlane].at(iMonteCarlo); + } + */ + fListOfPixels[iPlane].clear(); + //fListOfMonteCarlo[iPlane].clear(); + } + + //==================== + // Check for synchronization, JB 2012/07/22 + Bool_t synchroNeeded = false; + if( fModuleTypes>1 ) synchroNeeded = true; + + //==================== + // Check for external time reference, JB 2018/02/12 + // ==> JUST READ THE FIRST ONE for now, JB 2018/03/21 + int recordID, cycleID; + int rtcTime, ntpTime; + if( fc->GetAcqPar().IfExternalTimeRef ) { + if( fCurrentTimeRefInfo==0 ) { // first reading the timeRef info ? + if( GetTimeRef( fCurrentTimeRefInfo, recordID, cycleID, rtcTime, ntpTime) ) { + fEventReferenceTime = rtcTime; + fCurrentTimeRefInfo++; + if ( fDebugAcq ) cout << " -> Got new external time reference " << fEventReferenceTime << ", from index " << fCurrentTimeRefInfo << endl; + } + else { // timeRef info already read + cout << "WARNING: DAcq, Cannot read time reference !!." << endl; + } + } + + else { // timeRef info already read + if ( fDebugAcq ) cout << " -> Keep external time reference " << fEventReferenceTime << ", from index " << fCurrentTimeRefInfo << endl; + } + } + + else { // IfExternalTimeRef is false + if ( fDebugAcq ) cout << " -> No more external time reference, sticking to " << fEventReferenceTime << endl; + } + + + //==================== + if (fDebugAcq) cout << " DAcq: getting raw data:" << endl; + Int_t iModule=0; // module index, from 0 to totalNmodules + + for ( Int_t mdt = 1; mdt <= fModuleTypes; mdt++){ // loop on module types + + switch ( (fc->GetModulePar(mdt).Type)/10 ) { + + // -+-+- IMG modules (added JB 2012/07/22) + case 1: + IMGEvent *imgEvent; + IMGPixel *imgPixel; + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + // if (fDebugAcq) cout << " DAcq: erasing fRawData for module " << mdl << " of type " << fc->GetModulePar(mdt).Type << " # indexes " << fc->GetModulePar(mdt).Channels[0]*fc->GetModulePar(mdt).Inputs << endl; + // for( Int_t iPix=0; iPixGetModulePar(mdt).Channels[0]*fc->GetModulePar(mdt).Inputs; iPix++) { + // fRawData[mdt-1][mdl-1][iPix] = 0; + // } + + + moduleOK = fIMG[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + imgEvent = fIMG[iModule]->GetEvent(); // get the event + if( imgEvent ) { // If event pointer correct + fRealEventNumber = imgEvent->GetEventNumber(); + fTriggersN += imgEvent->GetNumberOfTriggers(); + fFramesN += imgEvent->GetNumberOfFrames(); + fTimestampsN += imgEvent->GetNumberOfTimestamps(); + if (ListOfTriggers==NULL) { + ListOfTriggers = imgEvent->GetTriggers(); + } + else { + ListOfTriggers->insert( ListOfTriggers->end(), (imgEvent->GetTriggers())->begin(), (imgEvent->GetTriggers())->end()); + ; + } + if (ListOfFrames==NULL) { + ListOfFrames = imgEvent->GetFrames(); + } + else { + ListOfFrames->insert( ListOfFrames->begin(), (imgEvent->GetFrames())->begin(), (imgEvent->GetFrames())->end()); + ; + } + if (ListOfTimestamps==NULL) { + ListOfTimestamps = imgEvent->GetTimestamps(); + } + else { + ListOfTimestamps->insert( ListOfTimestamps->begin(), (imgEvent->GetTimestamps())->begin(), (imgEvent->GetTimestamps())->end()); + ; + } + if (fDebugAcq) { + cout << " module " << mdl << " found " << imgEvent->GetNumberOfPixels() << " hit pixels with " << fTriggersN << " triggers: "; + for( Int_t iTrig=0; iTrigat( iTrig) << ", "; + } + cout << " and " << fFramesN << " frames: "; + for( Int_t iFr=0; iFrat( iFr) << ", "; + } + cout << " and " << fTimestampsN << " timestamps: "; + for( Int_t iTs=0; iTsat( iTs) << ", "; + } + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + imgPixel = imgEvent->GetPixelAt( iPix); + GetMatchingPlaneAndShift( mdt, mdl, imgPixel->GetInput()+1, imgPixel->GetIndex()+1, aPlaneNumber, aShift); + //aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][imgPixel->GetInput()]; + //aShift = fIndexShift[mdt-1][mdl-1][imgPixel->GetInput()]; + if(fDebugAcq>2) cout << " pixel " << iPix << " index " << imgPixel->GetIndex() << " from input " << imgPixel->GetInput() << " with value " << imgPixel->GetValue() << ", associated to plane " << aPlaneNumber << " with an index shift of " << aShift << " Timestamp " << imgPixel->GetTimeStamp() << endl; + //if (imgPixel->GetValue()<0) {cout << " we also have negative pulseheights " << imgPixel->GetValue() << endl; } //YV check 22/07/09 + + DPixel* APixel = new DPixel( aPlaneNumber, imgPixel->GetIndex()+aShift, (Double_t)imgPixel->GetValue(), imgPixel->GetTimeStamp()); + //fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, imgPixel->GetIndex()+aShift, (Double_t)imgPixel->GetValue(), imgPixel->GetTimeStamp())); + fListOfPixels[aPlaneNumber-1].push_back(APixel); + + } // end loop on Pixels + + } // End if event pointer correct + else { + if (fEventsDataNotOK%1000==0) { + cout << "WARNING: DAcq, Pointer to imgevent incorrect, " << fEventsDataNotOK << " such events so far!" << endl; + } + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + break; + + + // -+-+- TNT modules + case 3: + TNTEvent *tntEvent; + TNTPixel *tntPixel; + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + // if (fDebugAcq) cout << " DAcq: erasing fRawData for module " << mdl << " of type " << fc->GetModulePar(mdt).Type << " # indexes " << fc->GetModulePar(mdt).Channels[0]*fc->GetModulePar(mdt).Inputs << endl; + // for( Int_t iPix=0; iPixGetModulePar(mdt).Channels[0]*fc->GetModulePar(mdt).Inputs; iPix++) { + // fRawData[mdt-1][mdl-1][iPix] = 0; + // } + + + moduleOK = fTNT[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + tntEvent = fTNT[iModule]->GetEvent(); // get the event + if( tntEvent ) { // If event pointer correct, JB 2009/05/26 + fRealEventNumber = tntEvent->GetEventNumber(); + fTriggersN += tntEvent->GetNumberOfTriggers(); + fFramesN += tntEvent->GetNumberOfFrames(); + fTimestampsN += tntEvent->GetNumberOfTimestamps(); + if (ListOfTriggers==NULL) { + ListOfTriggers = tntEvent->GetTriggers(); + } + else { + ListOfTriggers->insert( ListOfTriggers->end(), (tntEvent->GetTriggers())->begin(), (tntEvent->GetTriggers())->end()); + ; + } + if (ListOfFrames==NULL) { + ListOfFrames = tntEvent->GetFrames(); + } + else { + ListOfFrames->insert( ListOfFrames->begin(), (tntEvent->GetFrames())->begin(), (tntEvent->GetFrames())->end()); + ; + } + if (ListOfTimestamps==NULL) { + ListOfTimestamps = tntEvent->GetTimestamps(); + } + else { + ListOfTimestamps->insert( ListOfTimestamps->begin(), (tntEvent->GetTimestamps())->begin(), (tntEvent->GetTimestamps())->end()); + ; + } + if (fDebugAcq) { + cout << " module " << mdl << " found " << tntEvent->GetNumberOfPixels() << " hit pixels with " << fTriggersN << " triggers: "; + for( Int_t iTrig=0; iTrigat( iTrig) << ", "; + } + cout << " and " << fFramesN << " frames: "; + for( Int_t iFr=0; iFrat( iFr) << ", "; + } + cout << " and " << fTimestampsN << " timestamps: "; + for( Int_t iTs=0; iTsat( iTs) << ", "; + } + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + + tntPixel = tntEvent->GetPixelAt( iPix); + GetMatchingPlaneAndShift( mdt, mdl, tntPixel->GetInput()+1, tntPixel->GetIndex()+1, aPlaneNumber, aShift); + //aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][tntPixel->GetInput()]; // JB 2009/05/06 + //aShift = fIndexShift[mdt-1][mdl-1][tntPixel->GetInput()]; // JB 2009/05/06 + if(fDebugAcq>2) cout << " pixel " << iPix << " index " << tntPixel->GetIndex() << " from input " << tntPixel->GetInput() << " with value " << tntPixel->GetValue() << ", associated to plane " << aPlaneNumber << " with an index shift of " << aShift << endl; + //if (tntPixel->GetValue()<0) {cout << " we also have negative pulseheights " << tntPixel->GetValue() << endl; } //YV check 22/07/09 + if( tntPixel->GetValue()>-4000.) { + + DPixel* APixel = new DPixel( aPlaneNumber, tntPixel->GetIndex()+aShift, tntPixel->GetValue()); + //fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, tntPixel->GetIndex()+aShift, tntPixel->GetValue())); //YV move the cut of the raw value of the pixel from 0 to -4000 22/07/09 + fListOfPixels[aPlaneNumber-1].push_back(APixel); //YV move the cut of the raw value of the pixel from 0 to -4000 22/07/09 + } + //fRawData[mdt-1][mdl-1][tntPixel->GetIndex()+(fc->GetModulePar(mdt).Channels[0])*(tntPixel->GetInput())] = tntPixel->GetValue(); + + } // end loop on Pixels + + } // End if event pointer correct, JB 2009/05/26 + else { + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + break; + + + + // -+-+- PXI modules + // JB 2009/08/20 + case 4: + PXIEvent *pxiEvent; + PXIPixel *pxiPixel; + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + // if (fDebugAcq) cout << " DAcq: erasing fRawData for module " << mdl << " of type " << fc->GetModulePar(mdt).Type << " # indexes " << fc->GetModulePar(mdt).Channels[0]*fc->GetModulePar(mdt).Inputs << endl; + // for( Int_t iPix=0; iPixGetModulePar(mdt).Channels[0]*fc->GetModulePar(mdt).Inputs; iPix++) { + // fRawData[mdt-1][mdl-1][iPix] = 0; + // } + + + moduleOK = fPXI[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + pxiEvent = fPXI[iModule]->GetEvent(); // get the event + if( pxiEvent ) { // If event pointer correct + fRealEventNumber = pxiEvent->GetEventNumber(); + fTriggersN += pxiEvent->GetNumberOfTriggers(); + fFramesN += pxiEvent->GetNumberOfFrames(); + if (ListOfTriggers==NULL) { + ListOfTriggers = pxiEvent->GetTriggers(); + } + else { + ListOfTriggers->insert( ListOfTriggers->end(), (pxiEvent->GetTriggers())->begin(), (pxiEvent->GetTriggers())->end()); + ; + } + if (ListOfFrames==NULL) { + ListOfFrames = pxiEvent->GetFrames(); + } + else { + ListOfFrames->insert( ListOfFrames->begin(), (pxiEvent->GetFrames())->begin(), (pxiEvent->GetFrames())->end()); + ; + } + if (fDebugAcq) { + cout << " module " << mdl << " found " << pxiEvent->GetNumberOfPixels() << " hit pixels with " << fTriggersN << " triggers: "; + for( Int_t iTrig=0; iTrigat( iTrig); + } + cout << " and " << fFramesN << " frames: "; + for( Int_t iFr=0; iFrat( iFr); + } + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + + pxiPixel = pxiEvent->GetPixelAt( iPix); + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][pxiPixel->GetInput()-1][0]; + if(fDebugAcq>2) cout << " pixel " << iPix << " line " << pxiPixel->GetLineNumber() << " column " << pxiPixel->GetColumnNumber() << " from input " << pxiPixel->GetInput() << " with value " << pxiPixel->GetValue() << ", associated to plane " << aPlaneNumber << endl; + + DPixel* APixel = new DPixel( aPlaneNumber, pxiPixel->GetLineNumber(), pxiPixel->GetColumnNumber(), (Double_t)pxiPixel->GetValue()); + //fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, pxiPixel->GetLineNumber(), pxiPixel->GetColumnNumber(), (Double_t)pxiPixel->GetValue())); + fListOfPixels[aPlaneNumber-1].push_back(APixel); + + } // end loop on Pixels + + } // End if event pointer correct, JB 2009/05/26 + else { + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + break; + + + // -+-+- PXIe modules + // JB 2011/06/19 + /* + // ZE 2021/05/25 + case 5: + cout << "Ziad --> Reading Data in PXIe module" << endl; + // This is the place for the snchronization + int acqId, frId; + acqId=-1; + frId=-1; //SS 2012.08.01 - acqId and frId were not initialized + if( synchroNeeded ) { + eventMissed |= !GetSynchroInfo( fRealEventNumber, acqId, frId); + if( eventMissed ) { + cout << "WARNING: Acquisition missed the synchronization of event " << fRealEventNumber + << ", corresponding to acquisition " << acqId + << " and frame " << frId + << " in PXIexpress." + << endl; + fEventsMissed++; + } + } + + if(!eventMissed){ // check event is not missed (always true if synchro not needed), SS 2012/08/10 + PXIeEvent *pxieEvent; + PXIePixel *pxiePixel; + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + // if (fDebugAcq) cout << " DAcq: erasing fRawData for module " << mdl << " of type " << fc->GetModulePar(mdt).Type << " # indexes " << fc->GetModulePar(mdt).Channels[0]*fc->GetModulePar(mdt).Inputs << endl; + // for( Int_t iPix=0; iPixGetModulePar(mdt).Channels[0]*fc->GetModulePar(mdt).Inputs; iPix++) { + // fRawData[mdt-1][mdl-1][iPix] = 0; + // } + + if( aTrigger!=-1 ) { + moduleOK = fPXIe[iModule]->HasData( aTrigger); // ask for the event matching trigger, JB 2012/07/10 + } + else if( acqId!=-1 && frId!=-1 ) { + moduleOK = fPXIe[iModule]->HasData( acqId, frId); // ask for the event matching the frame, JB 2012/07/22 + } + else { + moduleOK = fPXIe[iModule]->HasData(); // ask for the next event + } + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + pxieEvent = fPXIe[iModule]->GetEvent(); // get the event + if( pxieEvent!=NULL ) { // If event pointer correct + fRealEventNumber = pxieEvent->GetEventNumber(); + fTriggersN += pxieEvent->GetNumberOfTriggers(); + fFramesN += pxieEvent->GetNumberOfFrames(); + fTimestampsN += pxieEvent->GetNumberOfTimestamps(); + if (ListOfTriggers==NULL) { + ListOfTriggers = pxieEvent->GetTriggers(); + } + else { + ListOfTriggers->insert( ListOfTriggers->begin(), (pxieEvent->GetTriggers())->begin(), (pxieEvent->GetTriggers())->end()); + } + if (ListOfFrames==NULL) { + ListOfFrames = pxieEvent->GetFrames(); + } + else { + if(fPXIe[iModule]->GetFlag() == 0) { + ListOfFrames->insert( ListOfFrames->begin(), (pxieEvent->GetFrames())->begin(), (pxieEvent->GetFrames())->end()); + } + } + if (ListOfTimestamps==NULL) { + ListOfTimestamps = pxieEvent->GetTimestamps(); + } + else { + ListOfTimestamps->insert( ListOfTimestamps->begin(), (pxieEvent->GetTimestamps())->begin(), (pxieEvent->GetTimestamps())->end()); + } + + fEventTime = fEventReferenceTime + ListOfTimestamps->at(0)*115.e-6; // seconds since Epoch JB 2018/02/12 + ListOfLineOverflow = pxieEvent->GetLineOverflow(); //MG 2012/02/15 + if (fDebugAcq) cout << " event time " << fEventTime << " sec" << endl; + + for(int i=0;iGetTrackerPar().Planes;i++) fLineOverflowN[i]=ListOfLineOverflow[i].size() ;//MG 2012/02/15 + + if (fDebugAcq) { + cout << " module " << mdl << " found " << pxieEvent->GetNumberOfPixels() << " hit pixels with " << fTriggersN << " triggers: "; + for( Int_t iTrig=0; iTrigat( iTrig); + } + cout << " and " << fTimestampsN << " timestamps: "; + for( Int_t iTs=0; iTsat( iTs) << ", "; + } + cout << " and " << fFramesN << " frames: "; + for( Int_t iFr=0; iFrat( iFr); + } + + cout << " and lines in overflow: "; + for(int i=0;iGetTrackerPar().Planes;i++){ + cout << ", " << fLineOverflowN[i] << " for pl "<< i; //MG 2012/02/15 + } + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + + pxiePixel = pxieEvent->GetPixelAt( iPix); + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][pxiePixel->GetInput()-1][0]; + if(fDebugAcq>2) cout << " pixel " << iPix << " line " << pxiePixel->GetLineNumber() << " column " << pxiePixel->GetColumnNumber() << " from input " << pxiePixel->GetInput() << " with value " << pxiePixel->GetValue() << ", associated to plane " << aPlaneNumber << endl; + + DPixel* APixel = new DPixel( aPlaneNumber, pxiePixel->GetLineNumber(), pxiePixel->GetColumnNumber(), (Double_t)pxiePixel->GetValue(), ListOfTimestamps->at(0)); // relative timestamp added JB 2018/02/12 + //fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, pxiePixel->GetLineNumber(), pxiePixel->GetColumnNumber(), (Double_t)pxiePixel->GetValue())); + fListOfPixels[aPlaneNumber-1].push_back(APixel); + + } // end loop on Pixels + + } // End if event pointer correct, JB 2009/05/26 + else { + if (fEventsDataNotOK%1000==0) { + cout << "WARNING: DAcq, Pointer to pxievent incorrect, " << fEventsDataNotOK << " such events so far!" << endl; + } + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + } // end check event is not missed + break; + +*/ + // -+-+- GIG modules + // JB 2012/04/25 + case 6: + GIGEvent *gigEvent; + GIGPixel *gigPixel; + GIGMonteCarlo *gigMonteCarlo; + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + moduleOK = fGIG[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + gigEvent = fGIG[iModule]->GetEvent(); // get the event + if( gigEvent ) { // If event pointer correct + fRealEventNumber = gigEvent->GetEventNumber(); + if (fDebugAcq) { + cout << " module " << mdl << " found " << gigEvent->GetNumberOfPixels() << " hit pixels"; + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + + gigPixel = gigEvent->GetPixelAt( iPix); + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][gigPixel->GetInput()-1][0]; + + if(fDebugAcq>2) cout << " pixel " << iPix << " line " << gigPixel->GetLineNumber() << " column " << gigPixel->GetColumnNumber() << " from input " << gigPixel->GetInput() << " with value " << gigPixel->GetValue() << ", associated to plane " << aPlaneNumber << endl; + + DPixel* APixel = new DPixel( aPlaneNumber, gigPixel->GetLineNumber(), gigPixel->GetColumnNumber(), (Double_t)gigPixel->GetValue()); + + if( fIfMonteCarlo == 1) { + gigMonteCarlo = gigEvent->GetMonteCarloAt(iPix); + APixel->SetMonteCarlo(gigMonteCarlo->GetMonteCarloX(), gigMonteCarlo->GetMonteCarloY(), gigMonteCarlo->GetMonteCarloZ(), gigMonteCarlo->GetLine(), gigMonteCarlo->GetColumn() ); + } + + fListOfPixels[aPlaneNumber-1].push_back(APixel); + } // end loop on Pixels + /* + for( Int_t iMonteCarlo=0; iMonteCarloGetNumberOfMonteCarlo(); iMonteCarlo++) { // loop on Pixels + + gigMonteCarlo = gigEvent->GetMonteCarloAt( iMonteCarlo); + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][gigMonteCarlo->GetInput()-1][0]; + fListOfMonteCarlo[aPlaneNumber-1].push_back( new DMonteCarlo( aPlaneNumber, gigMonteCarlo->GetMonteCarloX(), gigMonteCarlo->GetMonteCarloY(), gigMonteCarlo->GetMonteCarloZ(), gigMonteCarlo->GetValue(), gigMonteCarlo->GetLine(), gigMonteCarlo->GetColumn(), 0 ) ); // 0 = timestamp = non def. + //std::cout<<" DAcq Monte Carlo X = "<GetMonteCarloX()<GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + moduleOK = fVME[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + readerEvent = (BoardReaderEvent*)fVME[iModule]->GetEvent(); // get the event + if( readerEvent ) { // If event pointer correct + fRealEventNumber = readerEvent->GetEventNumber(); + fTriggersN += readerEvent->GetNumberOfTriggers(); + // fFramesN += readerEvent->GetNumberOfFrames(); + if (ListOfTriggers==NULL) { + ListOfTriggers = readerEvent->GetTriggers(); + } + else { + ListOfTriggers->insert( ListOfTriggers->end(), (readerEvent->GetTriggers())->begin(), (readerEvent->GetTriggers())->end()); + ; + } + if (ListOfFrames==NULL) { + ListOfFrames = readerEvent->GetFrames(); + } + else { + ListOfFrames->insert( ListOfFrames->begin(), (readerEvent->GetFrames())->begin(), (readerEvent->GetFrames())->end()); + ; + } + if (fDebugAcq) { + cout << " module " << mdl << " found " << readerEvent->GetNumberOfPixels() << " hit pixels with " << fTriggersN << " triggers: "; + for( Int_t iTrig=0; iTrigat( iTrig); + } + cout << " and " << fFramesN << " frames: "; + for( Int_t iFr=0; iFrat( iFr); + } + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + + readerPixel = (BoardReaderPixel*)readerEvent->GetPixelAt( iPix); + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][readerPixel->GetInput()-1][0]; + if(fDebugAcq>2) cout << " pixel " << iPix << " line " << readerPixel->GetLineNumber() << " column " << readerPixel->GetColumnNumber() << " from input " << readerPixel->GetInput() << " with value " << readerPixel->GetValue() << ", associated to plane " << aPlaneNumber << endl; + + DPixel* APixel = new DPixel( aPlaneNumber, readerPixel->GetLineNumber(), readerPixel->GetColumnNumber(), (Double_t)readerPixel->GetValue()); + //fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, readerPixel->GetLineNumber(), readerPixel->GetColumnNumber(), (Double_t)readerPixel->GetValue())); + fListOfPixels[aPlaneNumber-1].push_back(APixel); + + } // end loop on Pixels + + } // End if event pointer correct, JB 2009/05/26 + else { + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + break; + + + // -+-+- ALI22 modules + // JB 2014/05/13, 2015/05/25 + case 8: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + moduleOK = fALI22[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + readerEvent = (BoardReaderEvent*)fALI22[iModule]->GetEvent(); // get the event + if( readerEvent ) { // If event pointer correct + fRealEventNumber = fALI22[iModule]->GetCDHEventCounter(); + // fTriggersN += readerEvent->GetNumberOfTriggers(); + // fFramesN += readerEvent->GetNumberOfFrames(); + if (fDebugAcq) { + cout << " module " << mdl << " found " << readerEvent->GetNumberOfPixels() << " hit pixels"; + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + // Pass only pixels with a value>0 + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + + readerPixel = (BoardReaderPixel*)readerEvent->GetPixelAt( iPix); + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][readerPixel->GetInput()-1][0]; + if(fDebugAcq>2) cout << " pixel " << iPix << " line " << readerPixel->GetLineNumber() << " column " << readerPixel->GetColumnNumber() << " frame " << readerPixel->GetTimeStamp() << " from input " << readerPixel->GetInput() << " with value " << readerPixel->GetValue() << ", associated to plane " << aPlaneNumber << endl; + if(readerPixel->GetValue()>0) fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, readerPixel->GetLineNumber(), readerPixel->GetColumnNumber(), (Double_t)readerPixel->GetValue(), (Int_t)readerPixel->GetTimeStamp())); + + } // end loop on Pixels + + } // End if event pointer correct, JB 2009/05/26 + else { + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + break; + + + // -+-+- DecoderM18 modules + // JB 2014/05/15 + // modified by INFN, 2014/08/26 to use new DecoderM18 class + case 9: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + // Set OMKDTransition info if this is not the "master" or first Decoder + // JB 2015/03/27 + if( synchroNeeded && !eventMissed && mdt!=fSynchroFirstM18Decoder ) { + fM18[iModule]->SetOMKDTransition( fSynchroOMKDTransition ); + fM18[iModule]->SetStopPointerTransition( fSynchroStopPointerTransition ); + } + + moduleOK = fM18[iModule]->ReadData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + if( moduleOK ) { // If event pointer correct + fRealEventNumber = fM18[iModule]->Get_EvNumber(); + if (fDebugAcq) { + cout << " module " << mdl << " found " << fM18[iModule]->Get_NHitPixel() << " hit pixels"; + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + // Pass only pixels with a value>0 + for( Int_t iPix=0; iPixGet_NHitPixel(); iPix++) { // loop on Pixels + + GetMatchingPlaneAndShift( mdt, mdl, 1, 1, aPlaneNumber, aShift); + //aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][0][0]; + if(fDebugAcq>2) cout << " pixel " << iPix << " index " << fM18[iModule]->GetIndex( iPix) << " line " << fM18[iModule]->GetRow( iPix) << " column " << fM18[iModule]->GetCol( iPix) << " from input " << 0 << " with value " << fM18[iModule]->GetAmp( iPix) << ", associated to plane " << aPlaneNumber << " with an index shift of " << aShift << endl; + + if( (Double_t)fM18[iModule]->GetAmp( iPix)>0 ) { // cut tails //!!!!scommentare + + //fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, fM18[iModule]->GetIndex(iPix)+aShift+1, (Double_t)fM18[iModule]->GetAmp( iPix)) );//added +1 in shift 17/6 + DPixel* APixel = new DPixel( aPlaneNumber, fM18[iModule]->GetIndex(iPix)+aShift+1, /*(Double_t)fM18[iModule]->GetAmp( iPix)*/TMath::Abs((Double_t)fM18[iModule]->GetAmp( iPix)) ); //added +1 in shift 17/6 + fListOfPixels[aPlaneNumber-1].push_back(APixel); + } // end cut tails + + } // end loop on Pixels + + // if synchro is required, read OMKDTransition info + // BUT store it only from the first module + // JB 2015/03/27 + if( synchroNeeded && mdt==fSynchroFirstM18Decoder ) { + Int_t OMKDinfo = fM18[iModule]->GetOMKDTransition(); + Int_t StopPointerinfo = fM18[iModule]->GetStopPointerTransition(); + if( fDebugAcq>1 ) { + cout << " ==> Synchronization info found for module " << iModule; + cout << " OMKDTransition = " << OMKDinfo << endl; + cout << " StopPointerTransition = " << StopPointerinfo << endl; + } + if ( iModule==0 ){ + fSynchroOMKDTransition = OMKDinfo; + fSynchroStopPointerTransition = StopPointerinfo; + + } + } + } // End if event pointer correct, JB 2009/05/26 + + else { + // set eventMissed flag if synchro was required + // JB 2015/03/27 + if( synchroNeeded ) { + eventMissed |= kTRUE; + cout << "WARNING: Acquisition missed the synchronization of event " << fRealEventNumber << " in DecoderM18." << endl; + fEventsMissed++; + } + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + break; + + + // -+-+- DecoderGeant modules + // + case 10: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + moduleOK = fGeant[iModule]->ReadData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + if( moduleOK ) { // If event pointer correct + fRealEventNumber = fGeant[iModule]->Get_EvNumber(); + if (fDebugAcq) { + cout << " module " << mdl << " found " << fGeant[iModule]->Get_NHitPixel() << " hit pixels"; + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + // Pass only pixels with a value>0 + for( Int_t iPix=0; iPixGet_NHitPixel(); iPix++) { // loop on Pixels + + GetMatchingPlaneAndShift( mdt, mdl, 1, 1, aPlaneNumber, aShift); + //aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][0][0]; + if(fDebugAcq>2) cout << " pixel " << iPix << " index " << fGeant[iModule]->GetIndex( iPix) << " line " << fGeant[iModule]->GetRow( iPix) << " column " << fGeant[iModule]->GetCol( iPix) << " from input " << 0 << " with value " << fGeant[iModule]->GetAmp( iPix) << ", associated to plane " << aPlaneNumber << endl; + if((Double_t)fGeant[iModule]->GetAmp( iPix)>0) { // cut tails + // fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, fGeant[iModule]->GetIndex(iPix), (Double_t)fGeant[iModule]->GetAmp( iPix)) ); + // fListOfPixels[aPlaneNumber-1].push_back( new DPixel( aPlaneNumber, fGeant[iModule]->GetRow( iPix), fGeant[iModule]->GetCol(iPix), (Double_t)fGeant[iModule]->GetAmp( iPix)) ); + DPixel* APixel = new DPixel( aPlaneNumber, fGeant[iModule]->GetRow( iPix), fGeant[iModule]->GetCol(iPix), (Double_t)fGeant[iModule]->GetAmp( iPix)); + fListOfPixels[aPlaneNumber-1].push_back(APixel); + } // end cut tails + + } // end loop on Pixels + + } // End if event pointer correct, JB 2009/05/26 + else { + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + break; + + // -+-+- MC modules + // AP 2016/04/15 + case 11: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + moduleOK = fMC[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + readerEvent = (BoardReaderEvent*)fMC[iModule]->GetEvent(); // get the event + if( readerEvent ) { // If event pointer correct + fRealEventNumber = readerEvent->GetEventNumber(); + fTriggersN += readerEvent->GetNumberOfTriggers(); + //fFramesN += readerEvent->GetNumberOfFrames(); + + if(ListOfTriggers == NULL) ListOfTriggers = readerEvent->GetTriggers(); + else ListOfTriggers->insert( ListOfTriggers->end(), (readerEvent->GetTriggers())->begin(), (readerEvent->GetTriggers())->end()); + + if(ListOfFrames == NULL) ListOfFrames = readerEvent->GetFrames(); + else ListOfFrames->insert( ListOfFrames->begin(), (readerEvent->GetFrames())->begin(), (readerEvent->GetFrames())->end()); + + if(fDebugAcq) { + cout << " module " << mdl << " found " << readerEvent->GetNumberOfPixels() << " hit pixels with " << fTriggersN << " triggers: "; + for( Int_t iTrig=0; iTrigat( iTrig); + cout << " and " << fFramesN << " frames: "; + for( Int_t iFr=0; iFrat( iFr); + cout << " from daq event " << fRealEventNumber << endl << endl; + } + + if(fDebugAcq) { + cout << endl; + cout << "Got it this event " << MCInfoHolder->GetNSimParticles() << " sim-particles" << endl; + for(int ipart=0;ipartGetNSimParticles();ipart++) { + cout << " This particle of frame " << MCInfoHolder->GetASimParticle(ipart).FrameNumber << " has " << MCInfoHolder->GetASimParticle(ipart).NHits << " hits" << endl; + for(int ihit=0;ihitGetASimParticle(ipart).NHits;ihit++) { + int HitIdx = MCInfoHolder->GetASimParticle(ipart).FirstHitIdx + ihit; + cout << " This hit has " << MCInfoHolder->GetASimHit(HitIdx).Npixels << " pixels" << endl; + } + } + cout << "Total sim-hits = " << MCInfoHolder->GetNSimHits() << endl; + cout << "Total sim-pixels = " << MCInfoHolder->GetNSimPixels() << endl; + int NNoisePixels = 0; + for(int ipix=0;ipixGetNSimPixels();ipix++) { + if(MCInfoHolder->GetASimPixel(ipix).HitIdx == -1) NNoisePixels++; + } + cout << "Noise sim-pixels = " << NNoisePixels << endl; + cout << endl; + } + + // Set values for hit pixels + //New method to includ the index of the hit turning on this pixel from the MC info + //Index is -1 if pixel is turned on by noise + for( Int_t iPix=0; iPix < MCInfoHolder->GetNSimPixels(); iPix++) { // loop on Pixels + aPlaneNumber = MCInfoHolder->GetASimPixel(iPix).sensorID+1; + Double_t Value = 1.0; + if(fc->GetPlanePar(aPlaneNumber).AnalysisMode == 2) Value = MCInfoHolder->GetASimPixel(iPix).ChargeAnalog; + if(fDebugAcq>2) cout << " pixel " << iPix + << " line " << MCInfoHolder->GetASimPixel(iPix).row + << " column " << MCInfoHolder->GetASimPixel(iPix).col + << " from input " << MCInfoHolder->GetASimPixel(iPix).sensorID + << " with value " << Value + << ", associated to plane " << aPlaneNumber + << endl; + DPixel* APixel = new DPixel(aPlaneNumber, + MCInfoHolder->GetASimPixel(iPix).row, + MCInfoHolder->GetASimPixel(iPix).col, + Value); //The value. Suppose digital readout + APixel->SetPixelMCHitIdx(MCInfoHolder->GetASimPixel(iPix).HitIdx); //Set the MC hit index for this pixel + fListOfPixels[aPlaneNumber-1].push_back(APixel); + + } // end loop on Pixels + + /* + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + readerPixel = (BoardReaderPixel*)readerEvent->GetPixelAt(iPix); + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][readerPixel->GetInput()-1][0]; + if(fDebugAcq>2) cout << " pixel " << iPix + << " line " << readerPixel->GetLineNumber() + << " column " << readerPixel->GetColumnNumber() + << " from input " << readerPixel->GetInput() + << " with value " << readerPixel->GetValue() + << ", associated to plane " << aPlaneNumber + << endl; + + DPixel* APixel = new DPixel( aPlaneNumber, readerPixel->GetLineNumber(), readerPixel->GetColumnNumber(), (Double_t)readerPixel->GetValue()); + fListOfPixels[aPlaneNumber-1].push_back(APixel); + } // end loop on Pixels + */ + + } // End if event pointer correct, JB 2009/05/26 + else { + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of this type + break; + + + // -+-+- IHEP modules + // JB 2018/10/09 + case 12: + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + + moduleOK = fIHEP[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + readerEvent = (BoardReaderEvent*)fIHEP[iModule]->GetEvent(); // get the event + if( readerEvent ) { // If event pointer correct + fRealEventNumber = readerEvent->GetEventNumber(); + fTriggersN += readerEvent->GetNumberOfTriggers(); + fFramesN += readerEvent->GetNumberOfFrames(); + if (ListOfTriggers==NULL) { + ListOfTriggers = readerEvent->GetTriggers(); + } + else { + ListOfTriggers->insert( ListOfTriggers->end(), (readerEvent->GetTriggers())->begin(), (readerEvent->GetTriggers())->end()); + ; + } + if (ListOfFrames==NULL) { + ListOfFrames = readerEvent->GetFrames(); + } + else { + ListOfFrames->insert( ListOfFrames->begin(), (readerEvent->GetFrames())->begin(), (readerEvent->GetFrames())->end()); + ; + } + if (fDebugAcq) { + cout << " module " << mdl << " found " << readerEvent->GetNumberOfPixels() << " hit pixels with " << fTriggersN << " triggers: "; + for( Int_t iTrig=0; iTrigat( iTrig); + } + cout << " and " << fFramesN << " frames: "; + for( Int_t iFr=0; iFrat( iFr); + } + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + + readerPixel = (BoardReaderPixel*)readerEvent->GetPixelAt( iPix); + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][readerPixel->GetInput()-1][0]; + if(fDebugAcq>2) cout << " pixel " << iPix << " line " << readerPixel->GetLineNumber() << " column " << readerPixel->GetColumnNumber() << " at timestamp " << readerPixel->GetTimeStamp() << " from input " << readerPixel->GetInput() << " with value " << readerPixel->GetValue() << ", associated to plane " << aPlaneNumber << endl; + + DPixel* APixel = new DPixel( aPlaneNumber, readerPixel->GetLineNumber(), readerPixel->GetColumnNumber(), (Double_t)readerPixel->GetValue(), readerPixel->GetTimeStamp()); + // if(readerPixel->GetInput()!=5 && readerPixel->GetInput()!=6 && readerPixel->GetTimeStamp()==1) + fListOfPixels[aPlaneNumber-1].push_back(APixel); + + } // end loop on Pixels + + } // End if event pointer correct + else { + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of IHEP type + break; + + + // -+-+- MIMOSIS modules + // JB 2021/05/01 + case 13: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + moduleOK = fMSIS[iModule]->HasData(); // ask for an event + eventOK &= moduleOK; + if (fDebugAcq) cout << " DAcq: getting raw data for module " << iModule << " or " << mdl << " of type " << fc->GetModulePar(mdt).Type << ", OK? " << moduleOK << endl; + + readerEvent = (BoardReaderEvent*)fMSIS[iModule]->GetEvent(); // get the event + if( readerEvent ) { // If event pointer correct + fRealEventNumber = readerEvent->GetEventNumber(); + fTriggersN += readerEvent->GetNumberOfTriggers(); + fFramesN += readerEvent->GetNumberOfFrames(); + if (ListOfTriggers==NULL) { + ListOfTriggers = readerEvent->GetTriggers(); + } + else { + ListOfTriggers->insert( ListOfTriggers->end(), (readerEvent->GetTriggers())->begin(), (readerEvent->GetTriggers())->end()); + ; + } + if (ListOfFrames==NULL) { + ListOfFrames = readerEvent->GetFrames(); + } + else { + ListOfFrames->insert( ListOfFrames->begin(), (readerEvent->GetFrames())->begin(), (readerEvent->GetFrames())->end()); + ; + } + if (fDebugAcq) { + cout << " module " << mdl << " found " << readerEvent->GetNumberOfPixels() << " hit pixels with " << fTriggersN << " triggers: "; + for( Int_t iTrig=0; iTrigat( iTrig); + } + cout << " and " << fFramesN << " frames: "; + for( Int_t iFr=0; iFrat( iFr); + } + cout << " from daq event " << fRealEventNumber << endl << endl; + } + // Set values for hit pixels + for( Int_t iPix=0; iPixGetNumberOfPixels(); iPix++) { // loop on Pixels + readerPixel = (BoardReaderPixel*)readerEvent->GetPixelAt( iPix); + // cout << " Got pixel " << iPix << " for input " << readerPixel->GetInput() << endl; + aPlaneNumber = fMatchingPlane[mdt-1][mdl-1][readerPixel->GetInput()-1][0]; + + if(fDebugAcq>2) cout << " pixel " << iPix << " line " << readerPixel->GetLineNumber() << " column " << readerPixel->GetColumnNumber() << " at timestamp " << readerPixel->GetTimeStamp() << " from input " << readerPixel->GetInput() << " with value " << readerPixel->GetValue() << ", associated to plane " << aPlaneNumber << endl; + DPixel* APixel = new DPixel( aPlaneNumber, readerPixel->GetLineNumber(), readerPixel->GetColumnNumber(), (Double_t)readerPixel->GetValue(), readerPixel->GetTimeStamp()); + // if(readerPixel->GetInput()!=5 && readerPixel->GetInput()!=6 && readerPixel->GetTimeStamp()==1) + fListOfPixels[aPlaneNumber-1].push_back(APixel); + } // end loop on Pixels + + } // End if event pointer correct + else { + dataOK &= kFALSE; + } + + iModule++; + } // end loop on each module of MIMSOSIS type + break; + + + }; // end switch on module types + + // Interrupt the loop on modules if one event data is not OK + // JB 2012/08/18 -> undesired behavior JB 2015/03/25 + //if( !dataOK ) { + // break; + //} + + } // end loop on module types + + + //Subtracting hot pixels from hit pixels list + for(int iPlane=0;iPlaneGetTrackerPar().Planes;iPlane++) { // Loop on planes + + if( fc->GetPlanePar(iPlane+1).HotPixelList_lin.size() == 0 + && fc->GetPlanePar(iPlane+1).HotPixelList_index.size() == 0) { + if (fDebugAcq>2) cout << "DAcq: no hot pixel to subtract." << endl; + continue; + } + + if (fDebugAcq>1) cout << "DAcq: Subtracting hot pixels, from a list of " << int(fc->GetPlanePar(iPlane+1).HotPixelList_lin.size()) << " ordered in 2D, or from a list of " << int(fc->GetPlanePar(iPlane+1).HotPixelList_index.size()) << " ordered in 1D, from plane " << iPlane+1 << " with " << int(fListOfPixels[iPlane].size()) << " fired pixels." << endl; + + //temporal list with hit pixels excluding hot-pixels + std::vector Temp_list; + Temp_list.clear(); + for(int iPix=0;iPixGetPlanePar(iPlane+1).HotPixelList_lin.size());i_hot++) { // loop on 2D ordered hot pixel list + if (fDebugAcq>2) printf("DAcq: 2D-testing pixel[%d] (%d,%d) against known hot pixel[%d] (%d,%d)\n", iPix, fListOfPixels[iPlane][iPix]->GetPixelLine(), fListOfPixels[iPlane][iPix]->GetPixelColumn(), i_hot, fc->GetPlanePar(iPlane+1).HotPixelList_lin[i_hot], fc->GetPlanePar(iPlane+1).HotPixelList_col[i_hot] ); + if((fListOfPixels[iPlane][iPix]->GetPixelLine() == fc->GetPlanePar(iPlane+1).HotPixelList_lin[i_hot]) + && + (fListOfPixels[iPlane][iPix]->GetPixelColumn() == fc->GetPlanePar(iPlane+1).HotPixelList_col[i_hot])) { + IsAHotPixel = true; + if (fDebugAcq>2) printf( " hot pixel found at row %d, col %d\n", fListOfPixels[iPlane][iPix]->GetPixelLine(), fListOfPixels[iPlane][iPix]->GetPixelColumn() ); + break; + } + } // end loop on 2D ordered hot pixel list + + for(int i_hot = 0; i_hotGetPlanePar(iPlane+1).HotPixelList_index.size());i_hot++) { // loop on 1D ordered hot pixel list + if (fDebugAcq>2) printf("DAcq: 1D-testing pixel[%d] (%d) against known hot pixel[%d] (%d)\n", iPix, fListOfPixels[iPlane][iPix]->GetDAQIndex(), i_hot, fc->GetPlanePar(iPlane+1).HotPixelList_index[i_hot] ); + if( fListOfPixels[iPlane][iPix]->GetDAQIndex() == fc->GetPlanePar(iPlane+1).HotPixelList_index[i_hot] ) { + IsAHotPixel = true; + if (fDebugAcq>2) printf( " hot pixel found at index %d\n", fListOfPixels[iPlane][iPix]->GetDAQIndex() ); + break; + } + } // end loop on 1D ordered hot pixel list + + if(!IsAHotPixel) Temp_list.push_back(fListOfPixels[iPlane][iPix]); + } // end loop on read pixels + + fListOfPixels[iPlane].clear(); + for(int iPix=0;iPixGetModulePar(mdt).Type) { + + case 3:// -+-+- TNT modules + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fTNT[iModule]->SkipNextEvent(); + } // end loop on each module of this type + break; + + }; // end switch on module types + + } // end loop on module types + + } //end if something went wrong + */ + + // Update some counters + // JB 2014/12/16 + if( !moduleOK ) fEventsModuleNotOK++; + if( !dataOK ) fEventsDataNotOK++; + + if (fDebugAcq) { + cout << "Over all modules, DAQ found: " << fTriggersN << " triggers, " << fTimestampsN << " timestamps, " << fFramesN << " frames from daq event " << fRealEventNumber << endl << endl; + + cout << " DAcq: getting event done, OK? " << eventOK << " and missed event? " << eventMissed << " and data OK? " << dataOK << endl; + + cout << " so far: " << fEventNumber << " events read, wrong ones with: module pb = " << fEventsModuleNotOK << ", data pb = " << fEventsDataNotOK << " and missed synchro = " << fEventsMissed << endl; + } + + // multi-bit return code, SS 2012/08/10 + DAcqResult->SetBitNumber(0,eventOK); + DAcqResult->SetBitNumber(1,eventMissed); + DAcqResult->SetBitNumber(2,dataOK); + return DAcqResult; + +} + +//______________________________________________________________________________ +// +Bool_t DAcq::DumpHexToTerm() +{ + // print Event Buffer sedezimal (hexadecimal) + + // Int_t i = 0; + + cout << setbase(16) << endl; + +// cout << " DAcq: BufferLength: " << fRawEventBufferLength << endl; +// while(i <= GetRawEventBufferLength()){ +// if ((i == 0) || +// (i % 0x10) == 0) +// cout << endl << i << ": "; +// cout << theValue(fRawEventStart + i,1) << " "; +// i++; +// } + + cout << "******************" << endl; + cout << setbase(10) << endl; + cout << "******************" << endl; + return kTRUE; +} + +//______________________________________________________________________________ +// +void DAcq::PrintStatistics(ostream &stream) +{ + // print Statistics for each acquisition module + // + // JB 2009/09/09 + // Last modified JB 2010/08/23 to use modulteType/10 + // Modified SS 2011/12/14 output stream can be set from outside + // Modified JB 2012/08/17 printout nb of events (total and missed) + // Modified JB 2014/12/16 printout nb of events with module or data pb + + Int_t iModule=0; // module index, from 0 to totalNmodules + for (Int_t mdt = 1; mdt <= fModuleTypes; mdt++){ // loop on module types + + switch ( (fc->GetModulePar(mdt).Type)/10 ) { + + // -+-+- IMG modules + case 1: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fIMG[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + + // -+-+- TNT modules + case 3: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fTNT[iModule]->PrintStatistics(stream); // JB 2010/08/26 + iModule++; + } // end loop on each modules of this type + break; + + + + // -+-+- PXI modules + case 4: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fPXI[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + + // -+-+- PXIe modules + // JB 2011/06/21 + // ZE 2021/05/25 + /* + case 5: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fPXIe[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + +*/ + + // -+-+- GIG modules + case 6: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fGIG[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + // -+-+- VME modules + case 7: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fVME[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + // -+-+- ALI22 modules + case 8: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fALI22[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + // -+-+- DecoderM18 modules + case 9: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fM18[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + // -+-+- DecoderGeant + case 10: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fGeant[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + // -+-+- MC modules + case 11: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fMC[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + // -+-+- IHEP modules + case 12: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fIHEP[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + // -+-+- MIMOSIS modules + case 13: + + for (Int_t mdl = 1; mdl <= fc->GetModulePar(mdt).Devices; mdl++){ // loop on each modules of this type + fMSIS[iModule]->PrintStatistics(stream); + iModule++; + } // end loop on each modules of this type + break; + + + // -+-+- Other modules + default: + stream << "WARNING: DAcq, unknown module type " << fc->GetModulePar(mdt).Type << "!" << endl; + + }; + + + } // end loop on module types + + stream << "DAcq: Number of events read: " << fEventNumber << "." << endl; + stream << "DAcq: Number of events with synchro missed: " << fEventsMissed << "." << endl; + stream << "DAcq: Number of events with data pb: " << fEventsDataNotOK << "." << endl; // JB 2014/12/16 + stream << "DAcq: Number of events with module pb: " << fEventsModuleNotOK << "." << endl;// JB 2014/12/16 + +} + +//______________________________________________________________________________ +// +void DAcq::DumpSynchroInfo( Int_t nEvents) +{ + // Print the information on synchronisation in a file + // for the required nb of events + // + // JB 2013/08/20 + + if( nEvents<0 ) nEvents = fNbSynchroInfo; + + if( fSynchroInfo != NULL ) { + + Char_t fileName[300]; + sprintf( fileName, "Results/%d/synchroInfo_dump.txt", fRunNumber); + sprintf( fileName,"%s", fTool.LocalizeDirName( fileName)); + FILE *outFile; + outFile = fopen( fileName, "w"); + + APP__TSyncIndexRec* pointer2Event = (APP__TSyncIndexRec*)fSynchroInfo; + + if(fDebugAcq) printf( " line EventId AcqId FrameId EventTag\n"); + fprintf( outFile, " line EventId AcqId FrameId EventTag\n"); + for ( Int_t iEvt=0; iEvt + +#include "DAlign.h" +#include "DHit.h" +#include "DTrack.h" +#include "DR3.h" +#include "DGlobalTools.h" + +ClassImp(DAlign) // Description of DAlign + +//______________________________________________________________________________ +// +DAlign::DAlign() +{ + SetDebug( 0 ); + fPlaneNumber = 0; +} + +//______________________________________________________________________________ +// +DAlign::DAlign( Int_t aPlaneNumber, Int_t aDebugLevel) +{ + + // Default DAcqModule ctor. + + SetDebug( aDebugLevel ); + //if( aPlaneNumber==3) fDebugAlign=1; + if(fDebugAlign) cout << endl << " -*-*- DAlign User Constructor -*-*- " << endl; + + fPlaneNumber = aPlaneNumber; + fEnoughU = kFALSE; + fEnoughV = kFALSE; + fEnough2D = kFALSE; + fAlignResolutionU = 0.0; + fAlignMeanU = 0.0; + fAlignResolutionV = 0.0; + fAlignMeanV = 0.0; + fAlignSum_du = 0.0; + fAlignSum_dudu = 0.0; + fAlignSum_duvt = 0.0; + fAlignSum_vt = 0.0; + fAlignSum_vtvt = 0.0; + fAlignCountu = 0; + fAlignSum_dv = 0.0; + fAlignSum_dvdv = 0.0; + fAlignSum_dvut = 0.0; + fAlignSum_ut = 0.0; + fAlignSum_utut = 0.0; + fAlignCountv = 0; + fAlignSum_uvt2 = 0.; + fAlignSum_dvuduv = 0.0; + fAlignCount2D = 0; + fAlignTiltW = 0.0; + fAlignOffsetU = 0.0; + fAlignOffsetV = 0.0; // JB + fAlignTiltWError = 0.0; + fAlignOffsetUError= 0.0; + fAlignOffsetVError= 0.0; // JB + fAlignCorrelation = 0.0; + fNumberOfEvents = 300; // preliminary number (100->400 YG), JB 2008/10/20 + fBound = 5000.; // preliminary max distance track-hit + fBoundU = 5000.; // preliminary max distance track-hit, JB 2013/06/10 + fBoundV = 5000.; // preliminary max distance track-hit, JB 2013/06/10 + + fAlignCanvas = NULL; + fpfxAlignCanvas = NULL; + fAlign3DCanvas = NULL; + fhAlignDU = NULL; + fhAlignDV = NULL; + fhAlignDVDU = NULL; + fhAlignPosUV = NULL; + fhAlignPosVU = NULL; + fhAlignPosUU = NULL; + fhAlignPosVV = NULL; + fhAlignUU = NULL; + fhAlignVV = NULL; + fhAlignPosUUV = NULL; + fhAlignPosVUV = NULL; + fpfxAlignPosUV = NULL; + fpfxAlignPosVU = NULL; + fpfxAlignPosUU = NULL; + fpfxAlignPosVV = NULL; + + if(fDebugAlign) { + cout << " Plane " << fPlaneNumber; + cout << " Miminal number of events to accumulate " << fNumberOfEvents << endl; + cout << " Maxinal distance between track and hit " << fBound << ", in U " << fBoundU << ", in V " << fBoundV << endl; + } + + if(fDebugAlign) cout << endl << " -*-*- DAlign User Constructor DONE -*-*- " << endl; + +} + +//______________________________________________________________________________ +// +DAlign::~DAlign() +{ + // Default DAlign destructor. + + if (fAlignCanvas) {delete fAlignCanvas; fAlignCanvas=0;} + if (fpfxAlignCanvas) {delete fpfxAlignCanvas; fpfxAlignCanvas=0;} // BB 060314 + if (fhAlignPosUV) {delete fhAlignPosUV; fhAlignPosUV=0;} + if (fpfxAlignPosUV) {delete fpfxAlignPosUV; fpfxAlignPosUV=0;} // BB 060314 + if (fpfxAlignPosVU) {delete fpfxAlignPosVU; fpfxAlignPosVU=0;} // BB 060314 + if (fpfxAlignPosUU) {delete fpfxAlignPosUU; fpfxAlignPosUU=0;} // BB 060314 + if (fpfxAlignPosVV) {delete fpfxAlignPosVV; fpfxAlignPosVV=0;} // BB 060314 + if (fhAlignPosUUV) {delete fhAlignPosUUV; fhAlignPosUUV=0;} // BB 070414 + if (fhAlignPosVUV) {delete fhAlignPosVUV; fhAlignPosVUV=0;} // BB 070414 + if (fhAlignPosVU) {delete fhAlignPosVU; fhAlignPosVU=0;} + if (fhAlignPosUU) {delete fhAlignPosUU; fhAlignPosUU=0;} + if (fhAlignPosVV) {delete fhAlignPosVV; fhAlignPosVV=0;} + if (fhAlignDU) {delete fhAlignDU; fhAlignDU=0;} + if (fhAlignDV) {delete fhAlignDV; fhAlignDV=0;} + if (fhAlignDVDU) {delete fhAlignDVDU; fhAlignDVDU=0;} + if (fhAlignUU) {delete fhAlignUU; fhAlignUU=0;} // JB 2014/08/26 + if (fhAlignVV) {delete fhAlignVV; fhAlignVV=0;} +} + +//______________________________________________________________________________ +// +void DAlign::SetBounding(Double_t aBound) +{ + + // Change boundings in U and V to accept a track to hit distance + // to the same value + // and update histograms axis + // + // JB, 2008/10/14 + // Updated, JB 2009/05/14 + // Updated, JB 2013/06/10 to use SetBoundings + + SetBoundings( aBound, aBound); + +} + +//______________________________________________________________________________ +// +void DAlign::SetBoundings(Double_t aBoundU, Double_t aBoundV) +{ + + // Change boundings in U and V to accept a track to hit distance + // and update histograms axis + // + // JB, 2013/06/10 from a copy of the old SetBounding method. + // Modified JB 2013/08/31 update of fBound as well + + fBoundU = aBoundU; + fBoundV = aBoundV; + fBound = sqrt( fBoundU*fBoundU+fBoundV*fBoundV); // JB 2013/08/31 + cout <<"Bound set to "<SetAxisRange( -fBoundU, fBoundU, "Y"); } + if (fpfxAlignPosUV) { fpfxAlignPosUV->SetAxisRange( -fBoundU, fBoundU, "Y"); } // BB 06/03/14 + if (fpfxAlignPosVU) { fpfxAlignPosVU->SetAxisRange( -fBoundV, fBoundV, "Y"); } // BB 06/03/14 + if (fpfxAlignPosUU) { fpfxAlignPosUU->SetAxisRange( -fBoundU, fBoundU, "Y"); } // BB 06/03/14 + if (fpfxAlignPosVV) { fpfxAlignPosVV->SetAxisRange( -fBoundV, fBoundV, "Y"); } // BB 06/03/14 + if (fhAlignPosUUV) { fhAlignPosUUV->SetAxisRange( -fBoundU, fBoundU, "Z"); } // BB 08/04/14 + if (fhAlignPosVUV) { fhAlignPosVUV->SetAxisRange( -fBoundV, fBoundV, "Z"); } // BB 08/04/14 + if (fhAlignPosVU) { fhAlignPosVU->SetAxisRange( -fBoundV, fBoundV, "Y"); } + if (fhAlignPosUU) { fhAlignPosUU->SetAxisRange( -fBoundU, fBoundU, "Y"); } + if (fhAlignPosVV) { fhAlignPosVV->SetAxisRange( -fBoundV, fBoundV, "Y"); } + if (fhAlignDU) { fhAlignDU->SetAxisRange( -fBoundU, fBoundU, "X"); } + if (fhAlignDV) { fhAlignDV->SetAxisRange( -fBoundV, fBoundV, "X"); } + if (fhAlignDVDU) { + fhAlignDVDU->SetAxisRange( -fBoundU, fBoundU, "X"); + fhAlignDVDU->SetAxisRange( -fBoundV, fBoundV, "Y"); + } +} + +//______________________________________________________________________________ +// +void DAlign::SetGeoLimits(Double_t umin, Double_t umax, Double_t vmin, Double_t vmax) +{ + // Define geometrical limits of hits to be considered for alignment. + // Those limits are given in the plane frame. + // + // JB 2013/06/10 + + fLimitsU[0] = umin; + fLimitsU[1] = umax; + fLimitsV[0] = vmin; + fLimitsV[1] = vmax; + +} + +//______________________________________________________________________________ +// +void DAlign::CreateDisplay( Double_t Umin, Double_t Umax, Double_t Vmin, Double_t Vmax) +{ + // Create the canvas and histos to monitor alignement + // JB, 2008/10/24 + // Modified: RDM 010809 + // Modified BB 050314 to study tilt + // Modified JB 2014/08/26 to add simple correlation plots + + Char_t name[50], title[100]; + sprintf( name, "cAlignP%d", fPlaneNumber); + sprintf( title, "Align monitor plane %d", fPlaneNumber); + fAlignCanvas = new TCanvas( name, title, fPlaneNumber*50, fPlaneNumber*50, 750, 600); + fAlignCanvas->Divide(2,4); + + sprintf( name, "hAlignPosUV%d", fPlaneNumber); + sprintf( title, "align monitor - #Delta U vs V - Plane %d", fPlaneNumber); + fhAlignPosUV = new TH2F( name, title, 100, Vmin, Vmax, 100,-fBoundU, fBoundU); //RDM010809 + fhAlignPosUV->SetXTitle("V (#mum)"); + fhAlignPosUV->SetYTitle("#Delta U (#mum)"); + + sprintf( name, "hAlignDU%d", fPlaneNumber); + sprintf( title, "align monitor - #Delta U - Plane %d", fPlaneNumber); + fhAlignDU = new TH1F( name, title, 100, -fBoundU, fBoundU); + fhAlignDU->SetXTitle("#Delta U (#mum)"); + + sprintf( name, "hAlignPosVU%d", fPlaneNumber); + sprintf( title, "align monitor - #Delta V vs U - Plane %d", fPlaneNumber); + fhAlignPosVU = new TH2F( name, title, 100, Umin, Umax, 100,-fBoundV, fBoundV); //RDM010809 + fhAlignPosVU->SetXTitle("U (#mum)"); + fhAlignPosVU->SetYTitle("#Delta V (#mum)"); + + sprintf( name, "hAlignDV%d", fPlaneNumber); + sprintf( title, "align monitor - #Delta V - Plane %d", fPlaneNumber); + fhAlignDV = new TH1F( name, title, 100, -fBoundV, fBoundV); + fhAlignDV->SetXTitle("#Delta V (#mum)"); + + sprintf( name, "hAlignDVDU%d", fPlaneNumber); + sprintf( title, "align monitor - #Delta V vs #Delta U - Plane %d", fPlaneNumber); + fhAlignDVDU = new TH2F( name, title, 100, -fBoundU, fBoundU, 100, -fBoundV, fBoundV); + fhAlignDVDU->SetXTitle("#Delta U (#mum)"); + fhAlignDVDU->SetYTitle("#Delta V (#mum)"); + + sprintf( name, "hAlignPosUU%d", fPlaneNumber); + sprintf( title, "align monitor - #Delta U vs U - Plane %d", fPlaneNumber); + fhAlignPosUU = new TH2F( name, title, 100, Umin, Umax, 100,-fBoundU, fBoundU); //RDM010809 + fhAlignPosUU->SetXTitle("U (#mum)"); + fhAlignPosUU->SetYTitle("#Delta U (#mum)"); + + sprintf( name, "hAlignPosVV%d", fPlaneNumber); + sprintf( title, "align monitor - #Delta V vs V - Plane %d", fPlaneNumber); + fhAlignPosVV = new TH2F( name, title, 100, Vmin, Vmax, 100,-fBoundV, fBoundV); //RDM010809 + fhAlignPosVV->SetXTitle("V (#mum)"); + fhAlignPosVV->SetYTitle("#Delta V (#mum)"); + + sprintf( name, "hAlignUU%d", fPlaneNumber); + sprintf( title, "align monitor - Uhit vs Utrack - Plane %d", fPlaneNumber); + fhAlignUU = new TH2F( name, title, 100, Umin, Umax, 100, Umin, Umax); //JB 2014/08/26 + fhAlignUU->SetXTitle("U track (#mum)"); + fhAlignUU->SetYTitle("U hit (#mum)"); + + sprintf( name, "hAlignVV%d", fPlaneNumber); + sprintf( title, "align monitor - Vhit vs Vtrack - Plane %d", fPlaneNumber); + fhAlignVV = new TH2F( name, title, 100, Vmin, Vmax, 100, Vmin, Vmax); //JB 2014/08/26 + fhAlignVV->SetXTitle("V track (#mum)"); + fhAlignVV->SetYTitle("V hit (#mum)"); +} + +//______________________________________________________________________________ +// +void DAlign::CreateDisplayDeformation( Double_t Umin, Double_t Umax, Double_t Vmin, Double_t Vmax){ + + Char_t name[50], title[100]; + + sprintf( name, "cPfxAlignP%d", fPlaneNumber); // BB 060314 + sprintf( title, "Profile of align monit plane %d", fPlaneNumber); + fpfxAlignCanvas = new TCanvas( name, title, fPlaneNumber*50, fPlaneNumber*50, 750, 450); + fpfxAlignCanvas->Divide(2,2); + + sprintf( name, "cAlign3DP%d", fPlaneNumber); // BB 070414 + sprintf( title, "3D Align plane %d", fPlaneNumber); + fAlign3DCanvas = new TCanvas( name, title, fPlaneNumber*50, fPlaneNumber*50, 750, 450); + fAlign3DCanvas->Divide (1,2); + + sprintf( name, "pfxAlignPosUV%d", fPlaneNumber); // BB 060314 + sprintf( title, "profile of align monitor - U dim vs V - Plane %d", fPlaneNumber); // BB 060314 + fpfxAlignPosUV = new TProfile( name, title, 100, Vmin, Vmax); // BB 060314 + fpfxAlignPosUV->SetXTitle("V (#mum)"); // BB 060314 + fpfxAlignPosUV->SetYTitle("#Delta U (#mum)"); // BB 060314 + + sprintf( name, "pfxAlignPosVU%d", fPlaneNumber); // BB 060314 + sprintf( title, "profile of align monitor - V dim vs U - Plane %d", fPlaneNumber); // BB 060314 + fpfxAlignPosVU = new TProfile( name, title, 100, Umin, Umax); // BB 060314 + fpfxAlignPosVU->SetXTitle("U (#mum)"); // BB 060314 + fpfxAlignPosVU->SetYTitle("#Delta V (#mum)"); // BB 060314 + + sprintf( name, "pfxAlignPosUU%d", fPlaneNumber); // BB 060314 + sprintf( title, "profile of align monitor - U dim vs U - Plane %d", fPlaneNumber); // BB 060314 + fpfxAlignPosUU = new TProfile( name, title, 100, Umin, Umax); // BB 060314 + fpfxAlignPosUU->SetXTitle("U (#mum)"); // BB 060314 + fpfxAlignPosUU->SetYTitle("#Delta U (#mum)"); // BB 060314 + + sprintf( name, "pfxAlignPosVV%d", fPlaneNumber); // BB 060314 + sprintf( title, "profile of align monitor - V dim vs V - Plane %d", fPlaneNumber); // BB 060314 + fpfxAlignPosVV = new TProfile( name, title, 100, Vmin, Vmax); // BB 060314 + fpfxAlignPosVV->SetXTitle("V (#mum)"); // BB 060314 + fpfxAlignPosVV->SetYTitle("#Delta V (#mum)"); // BB 060314 + + sprintf( name, "hAlignPosUUV%d",fPlaneNumber); // BB 070414 + sprintf( title, "align monitor - U dim vs U and V - Plane %d", fPlaneNumber); // BB 070414 + fhAlignPosUUV = new TH2F( name, title, 10, Umin, Umax, 10, Vmin, Vmax); // BB 070414 + fhAlignPosUUV->SetXTitle("U (#mum)"); // BB 070414 + fhAlignPosUUV->SetYTitle("V (#mum)"); // BB 070414 + fhAlignPosUUV->SetZTitle("#Delta U (#mum)"); // BB 080414 + + sprintf( name, "hAlignPosVUV%d",fPlaneNumber); // BB 070414 + sprintf( title, "align monitor - V dim vs U and V - Plane %d", fPlaneNumber); // BB 070414 + fhAlignPosVUV = new TH2F( name, title, 10, Umin, Umax, 10, Vmin, Vmax); // BB 070414 + fhAlignPosVUV->SetXTitle("U (#mum)"); // BB 070414 + fhAlignPosVUV->SetYTitle("V (#mum)"); // BB 070414 + fhAlignPosVUV->SetZTitle("#Delta V (#mum)"); // BB 080414 + +} + +//______________________________________________________________________________ +// +void DAlign::StoreU(DR3& aTrackPos, Double_t aDistanceU){ + + // Simply store distances track-hit without trying to minimize + // only for later Display() + // + // JB, 2009/09/08 + + if( fDebugAlign>1) printf(" DAlign: plane %d Store in U with distance %f %.1f\n", fPlaneNumber, aDistanceU, fBoundU); + + // Accumulation of hits + if ( fabs(aDistanceU)<=fBoundU && fhAlignPosUV && fhAlignPosUU && fhAlignUU && fhAlignDU) { + fAlignCountu++; + fhAlignPosUV->Fill( aTrackPos(1), aDistanceU); + fhAlignPosUU->Fill( aTrackPos(0), aDistanceU); + fhAlignUU->Fill( aTrackPos(0), aDistanceU+aTrackPos(0)); // JB 2014/08/26 + fhAlignDU->Fill( aDistanceU); +// if( fAlignCountu%50==0 ) { +// fAlignCanvas->cd(1); +// fhAlignPosU->Draw(); +// fAlignCanvas->Update(); +// } + } + + // Accumulation of hits for profile of residual as a function of the position of the hit on the plane + if ( fabs(aDistanceU)<=fBoundU && fpfxAlignPosUV && fpfxAlignPosUU && fhAlignPosUUV){ // BB 2014/05/20 + + fAlignCountu++; + fpfxAlignPosUV->Fill( aTrackPos(1), aDistanceU); // BB 060314 + fpfxAlignPosUU->Fill( aTrackPos(0), aDistanceU); // BB 060314 + fhAlignPosUUV->Fill(aTrackPos(0),aTrackPos(1), aDistanceU); //BB 070414 + } + +} + +//______________________________________________________________________________ +// +void DAlign::StoreV(DR3& aTrackPos, Double_t aDistanceV){ + + // Simply store distances track-hit without trying to minimize + // only for later Display() + // + // JB, 2009/09/08 + + if( fDebugAlign>1) printf(" DAlign: plane %d Store in V with distance %f %.1f\n", fPlaneNumber, aDistanceV, fBoundV); + + // Accumulation of hits + if ( fabs(aDistanceV)<=fBoundV && fhAlignPosVU && fhAlignPosVV && fhAlignVV && fhAlignDV) { + fAlignCountv++; + fhAlignPosVU->Fill( aTrackPos(0), aDistanceV); + fhAlignPosVV->Fill( aTrackPos(1), aDistanceV); + fhAlignVV->Fill( aTrackPos(1), aDistanceV+aTrackPos(1)); // JB 2014/08/26 + fhAlignDV->Fill( aDistanceV); +// if( fAlignCountv%50==0 ) { +// fAlignCanvas->cd(2); +// fhAlignPosV->Draw(); +// fAlignCanvas->Update(); +// } + } + + // Accumulation of hits for profile of residual as a function of the position of the hit on the plane + if ( fabs(aDistanceV)<=fBoundV && fpfxAlignPosVU && fpfxAlignPosVV && fhAlignPosVUV){ // BB 2014/05/20 + + fAlignCountv++; + fpfxAlignPosVU->Fill( aTrackPos(0), aDistanceV); // BB 060314 + fpfxAlignPosVV->Fill( aTrackPos(1), aDistanceV); // BB 060314 + fhAlignPosVUV->Fill(aTrackPos(0),aTrackPos(1), aDistanceV); //BB 070414 + } + +} + +//______________________________________________________________________________ +// +void DAlign::Store2D(DR3& aTrackPos, Double_t aDistanceU, Double_t aDistanceV){ + + // Simply store distances track-hit without trying to minimize + // only for later Display() + // + // JB, 2009/05/13 + // Modified: JB 2009/09/08 to count stored events + // Modified: BB 2014/03/06 for new histos + + if( fDebugAlign>1) printf(" DAlign: plane %d Store in U and V with distance (%f, %f) (%.1f, %.1f)\n", fPlaneNumber, aDistanceU, aDistanceV, fBoundU, fBoundV); + + // Accumulation of hits + if ( fabs(aDistanceU)<=fBoundU && fhAlignPosUV + && fabs(aDistanceV)<=fBoundV && fhAlignPosVU && fhAlignPosUU && fhAlignPosVV && fhAlignDVDU && fhAlignDU && fhAlignDV) { // BB 2015/07/28 + fAlignCount2D++; // JB 2009/08/09 + fhAlignPosUV->Fill( aTrackPos(1), aDistanceU); + fhAlignDU->Fill( aDistanceU); + fhAlignPosVU->Fill( aTrackPos(0), aDistanceV); + fhAlignDV->Fill( aDistanceV); + fhAlignPosUU->Fill( aTrackPos(0), aDistanceU); + fhAlignUU->Fill( aTrackPos(0), aDistanceV+aTrackPos(0)); // JB 2014/08/26 + fhAlignPosVV->Fill( aTrackPos(1), aDistanceV); + fhAlignVV->Fill( aTrackPos(1), aDistanceV+aTrackPos(1)); // JB 2014/08/26 + fhAlignDVDU->Fill( aDistanceU, aDistanceV); + +// if( fAlignCount2D%50==0 ) { +// fAlignCanvas->cd(1); +// fhAlignPosU->Draw(); +// fAlignCanvas->cd(2); +// fhAlignPosV->Draw(); +// fAlignCanvas->Update(); +// } + } + + // Accumulation of hits for profile of residual as a function of hit position on the plane + + if ( fabs(aDistanceU)<=fBoundU && fpfxAlignPosUV && fabs(aDistanceV)<=fBoundV && fpfxAlignPosVU && fpfxAlignPosUU && fpfxAlignPosVV && fhAlignPosUUV && fhAlignPosVUV){ // BB 2014/05/20 + + fAlignCount2D++; + fpfxAlignPosUV->Fill( aTrackPos(1), aDistanceU); // BB 06/03/14 + fpfxAlignPosVU->Fill( aTrackPos(0), aDistanceV); // BB 06/03/14 + fpfxAlignPosUU->Fill( aTrackPos(0), aDistanceU); // BB 06/03/14 + fpfxAlignPosVV->Fill( aTrackPos(1), aDistanceV); // BB 06/03/14 + fhAlignPosUUV->Fill(aTrackPos(0),aTrackPos(1), aDistanceU); // BB 07/04/14 + fhAlignPosVUV->Fill(aTrackPos(0),aTrackPos(1), aDistanceV); // BB 07/04/14 + } + +} + +//______________________________________________________________________________ +// +void DAlign::Display(){ + + // Display stored distances track-hit + // + // JB, 2009/05/13 + // Modified, JB 2012/08/23 condition on non nul-entries added + // Modified, JB 2012/08/22 fit added if Integral large enough + + //cout<GetPlaneNumber()<GetEntries()>0) { + fAlignCanvas->cd(1); + fhAlignPosUV->Draw(); + } + if ( fhAlignDU && fhAlignDU->Integral()>0) { + fAlignCanvas->cd(5); + fhAlignDU->Draw(); + fhAlignDU->Fit("gaus"); + //gPad->SaveAs(fileNameResDU); + } + if ( fhAlignPosVU && fhAlignPosVU->GetEntries()>0) { + fAlignCanvas->cd(2); + fhAlignPosVU->Draw(); + } + if ( fhAlignDVDU && fhAlignDVDU->GetEntries()>0) { + fAlignCanvas->cd(2); + fhAlignDVDU->Draw(); + } + if ( fhAlignDV && fhAlignDV->Integral()>0) { + fAlignCanvas->cd(6); + fhAlignDV->Draw(); + fhAlignDV->Fit("gaus"); + //gPad->SaveAs(fileNameResDV); + } + if ( fhAlignPosUU && fhAlignPosUU->GetEntries()>0) { + fAlignCanvas->cd(3); + fhAlignPosUU->Draw(); + } + if ( fhAlignPosVV && fhAlignPosVV->GetEntries()>0) { + fAlignCanvas->cd(4); + fhAlignPosVV->Draw(); + } + if ( fhAlignUU && fhAlignUU->GetEntries()>0) { // JB 2014/08/26 + fAlignCanvas->cd(7); + fhAlignUU->Draw(); + } + if ( fhAlignVV && fhAlignVV->GetEntries()>0) { // JB 2014/08/26 + fAlignCanvas->cd(8); + fhAlignVV->Draw(); + } + fAlignCanvas->Update(); +} + +//______________________________________________________________________________ +// +void DAlign::DisplayDeformation(){ + + // Display profile of stored distance track-hit + // BB 2014/05/20 + + if ( fpfxAlignPosUV && fpfxAlignPosUV->GetEntries()>0){ + fpfxAlignCanvas->cd(1); + fpfxAlignPosUV->Draw(); + } + fpfxAlignCanvas->Update(); + if ( fpfxAlignPosVU && fpfxAlignPosVU->GetEntries()>0){ + fpfxAlignCanvas->cd(2); + fpfxAlignPosVU->Draw(); + } + if ( fpfxAlignPosUU && fpfxAlignPosUU->GetEntries()>0){ + fpfxAlignCanvas->cd(3); + fpfxAlignPosUU->Draw(); + } + if ( fpfxAlignPosVV && fpfxAlignPosVV->GetEntries()>0){ + fpfxAlignCanvas->cd(4); + fpfxAlignPosVV->Draw(); + } + fpfxAlignCanvas->Update(); + + if ( fhAlignPosUUV && fhAlignPosUUV->GetEntries()>0){ // BB 070414 + fAlign3DCanvas->cd(1); + fhAlignPosUUV->Draw("surf1"); + } + if ( fhAlignPosVUV && fhAlignPosVUV->GetEntries()>0){ // BB 080414 + fAlign3DCanvas->cd(2); + fhAlignPosVUV->Draw("surf1"); + } + fAlign3DCanvas->Update(); + +} + +//______________________________________________________________________________ +// +void DAlign::DisplayDeformationFitted(){ + // Display profile of stored distance track-hit with a Legendre polynomials fit + // BB 2014/05/20 + // Modified JB 2015/10/31 to update Legendre polynome coefficients + + TF1 *fit = NULL; + +// Double_t *coeffU = new Double_t[8]; +// Double_t *coeffV = new Double_t[8]; +// if( f1legendre7U != NULL) coeffU = (Double_t*)f1legendre7U->GetParameters(); +// if( f1legendre7V != NULL) coeffV = (Double_t*)f1legendre7V->GetParameters(); + Double_t coeffU[8], coeffV[8]; + printf( "\n Current coeff for DeltaU vs U:"); + for (Int_t ipar=0; ipar<8; ipar++) { + if( f1legendre7U != NULL) coeffU[ipar] = f1legendre7U->GetParameter( ipar); + else coeffU[ipar] = 0.0; + printf(" %.1f", coeffU[ipar]); + } + printf("\n"); + printf( " Current coeff for DeltaU vs V:"); + for (Int_t ipar=0; ipar<8; ipar++) { + if( f1legendre7V != NULL) coeffV[ipar] = f1legendre7V->GetParameter( ipar); + else coeffV[ipar] = 0.0; + printf(" %.1f", coeffV[ipar]); + } + printf("\n"); + + + + if ( fpfxAlignPosUV && fpfxAlignPosUV->GetEntries()>0){ + fpfxAlignCanvas->cd(1); + fpfxAlignPosUV->Fit("f1legendre7V"); + fpfxAlignPosUV->Draw(); + fit = fpfxAlignPosUV->GetFunction("f1legendre7V"); + if( fit != NULL){ + printf( "\n -> NEW fitted coeff for DeltaU vs V:\n coeffLegendreV"); + for (Int_t ipar=1; ipar<8; ipar++) { + printf(": %.1f", coeffV[ipar]+fit->GetParameter( ipar)); + } + printf("\n\n"); + } + } + fpfxAlignCanvas->Update(); + fit=NULL; + if ( fpfxAlignPosVU && fpfxAlignPosVU->GetEntries()>0){ + fpfxAlignCanvas->cd(2); + fpfxAlignPosVU->Fit("f1legendre7U"); + fpfxAlignPosVU->Draw(); +// fit = fpfxAlignPosVU->GetFunction("f1legendre7U"); +// if( fit != NULL){ +// printf( "\n -> NEW fitted coeff for DeltaV vs U:"); +// for (Int_t ipar=0; ipar<8; ipar++) { +// printf(" %.1f", fit->GetParameter( ipar)); +// } +// printf("\n\n"); +// } + } + fit=NULL; + if ( fpfxAlignPosUU && fpfxAlignPosUU->GetEntries()>0){ + fpfxAlignCanvas->cd(3); + fpfxAlignPosUU->Fit("f1legendre7U"); + fpfxAlignPosUU->Draw(); + fit = fpfxAlignPosUU->GetFunction("f1legendre7U"); + if( fit != NULL){ + printf( "\n -> NEW fitted coeff for DeltaU vs U:\n coeffLegendreU"); + for (Int_t ipar=1; ipar<8; ipar++) { + printf(": %.1f", coeffU[ipar]+fit->GetParameter( ipar)); + } + printf("\n\n"); + } + } + fit=NULL; + if ( fpfxAlignPosVV && fpfxAlignPosVV->GetEntries()>0){ + fpfxAlignCanvas->cd(4); + fpfxAlignPosVV->Fit("f1legendre7V"); + fpfxAlignPosVV->Draw(); +// fit = fpfxAlignPosVV->GetFunction("f1legendre7V"); +// if( fit != NULL){ +// printf( "\n -> NEW fitted coeff for DeltaV vs V:"); +// for (Int_t ipar=0; ipar<8; ipar++) { +// printf(" %.1f", fit->GetParameter( ipar)); +// } +// printf("\n\n"); +// } + } + fpfxAlignCanvas->Update(); + +} + +//______________________________________________________________________________ +// +void DAlign::Display(Int_t fRunNumber){ + + // Display stored distances track-hit + // + // JB, 2009/05/13 + // Modified, JB 2012/08/23 condition on non nul-entries added + //cout<GetPlaneNumber()<GetEntries()>0) { + fAlignCanvas->cd(1); + fhAlignPosUV->Draw(); + } + if ( fhAlignDU && fhAlignDU->GetEntries()>0) { + fAlignCanvas->cd(5); + fhAlignDU->Draw(); + fhAlignDU->Fit("gaus"); + fhAlignDU->SaveAs(fileNameResDU); + } + if ( fhAlignPosVU && fhAlignPosVU->GetEntries()>0) { + fAlignCanvas->cd(2); + fhAlignPosVU->Draw(); + } + if ( fhAlignDVDU && fhAlignDVDU->GetEntries()>0) { + fAlignCanvas->cd(2); + fhAlignDVDU->Draw(); + } + if ( fhAlignDV && fhAlignDV->GetEntries()>0) { + fAlignCanvas->cd(6); + fhAlignDV->Draw(); + fhAlignDV->Fit("gaus"); + fhAlignDV->SaveAs(fileNameResDV); + } + if ( fhAlignPosUU && fhAlignPosUU->GetEntries()>0) { + fAlignCanvas->cd(3); + fhAlignPosUU->Draw(); + } + if ( fhAlignPosVV && fhAlignPosVV->GetEntries()>0) { + fAlignCanvas->cd(4); + fhAlignPosVV->Draw(); + } + if ( fhAlignUU && fhAlignUU->GetEntries()>0) { // JB 2014/08/26 + fAlignCanvas->cd(7); + fhAlignUU->Draw(); + } + if ( fhAlignVV && fhAlignVV->GetEntries()>0) { // JB 2014/08/26 + fAlignCanvas->cd(8); + fhAlignVV->Draw(); + } + fAlignCanvas->Update(); +} + +//______________________________________________________________________________ +// +void DAlign::DisplayDeformation(Int_t fRunNumber){ + + // Display profile of stored distances track-hit + // BB 2014/05/20 + // + // JB, 2009/05/13 + // Modified, JB 2012/08/23 condition on non nul-entries added + //cout<GetPlaneNumber()<GetEntries()>0) { // BB 060314 + fpfxAlignCanvas->cd(1); + fpfxAlignPosUV->Draw(); + } + if (fpfxAlignPosVU && fpfxAlignPosVU->GetEntries()>0) { // BB 060314 + fpfxAlignCanvas->cd(2); + fpfxAlignPosVU->Draw(); + } + + if (fpfxAlignPosUU && fpfxAlignPosUU->GetEntries()>0) { // BB 060314 + fpfxAlignCanvas->cd(3); + fpfxAlignPosUU->Draw(); + } + if (fpfxAlignPosVV && fpfxAlignPosVV->GetEntries()>0) { // BB 060314 + fpfxAlignCanvas->cd(4); + fpfxAlignPosVV->Draw(); + } + fpfxAlignCanvas->Update(); + + if ( fhAlignPosUUV && fhAlignPosUUV->GetEntries()>0){ // BB 070414 + fAlign3DCanvas->cd(1); + fhAlignPosUUV->Draw("surf1"); + } + if ( fhAlignPosVUV && fhAlignPosVUV->GetEntries()>0){ // BB 070414 + fAlign3DCanvas->cd(2); + fhAlignPosUUV->Draw("surf1"); + } + fAlign3DCanvas->Update(); + +} + +//______________________________________________________________________________ +// +void DAlign::DisplayDeformationFitted(Int_t fRunNumber){ + // Display profile of stored distance track-hit with a Legendre polynomials fit + // BB 2014/05/20 + // Modified JB 2015/10/31 to update Legendre polynome coefficients + + TF1 *fit = NULL; + + Double_t *coeffU, *coeffV; + coeffU = (Double_t*)f1legendre7U->GetParameters(); + coeffV = (Double_t*)f1legendre7V->GetParameters(); + printf( "\n Current coeff for DeltaU vs U:"); + for (Int_t ipar=0; ipar<8; ipar++) { + printf(" %.1f", coeffU[ipar]); + } + printf("\n"); + printf( " Current coeff for DeltaU vs V:"); + for (Int_t ipar=0; ipar<8; ipar++) { + printf(" %.1f", coeffV[ipar]); + } + printf("\n"); + + + + if ( fpfxAlignPosUV && fpfxAlignPosUV->GetEntries()>0){ + fpfxAlignCanvas->cd(1); + fpfxAlignPosUV->Fit("f1legendre7V"); + fpfxAlignPosUV->Draw(); + fit = fpfxAlignPosUV->GetFunction("f1legendre7V"); + if( fit != NULL){ + printf( "\n -> NEW fitted coeff for DeltaU vs V:\n coeffLegendreV"); + for (Int_t ipar=1; ipar<8; ipar++) { + printf(": %.1f", coeffV[ipar]+fit->GetParameter( ipar)); + } + printf("\n\n"); + } + } + fpfxAlignCanvas->Update(); + if ( fpfxAlignPosVU && fpfxAlignPosVU->GetEntries()>0){ + fpfxAlignCanvas->cd(2); + fpfxAlignPosVU->Fit("f1legendre7U"); + fpfxAlignPosVU->Draw(); + } + fit=NULL; + if ( fpfxAlignPosUU && fpfxAlignPosUU->GetEntries()>0){ + fpfxAlignCanvas->cd(3); + fpfxAlignPosUU->Fit("f1legendre7U"); + fpfxAlignPosUU->Draw(); + fit = fpfxAlignPosUU->GetFunction("f1legendre7U"); + if( fit != NULL){ + printf( "\n -> NEW fitted coeff for DeltaU vs U:\n coeffLegendreU"); + for (Int_t ipar=1; ipar<8; ipar++) { + printf(": %.1f", coeffU[ipar]+fit->GetParameter( ipar)); + } + printf("\n\n"); + } + } + if ( fpfxAlignPosVV && fpfxAlignPosVV->GetEntries()>0){ + fpfxAlignCanvas->cd(4); + fpfxAlignPosVV->Fit("f1legendre7V"); + fpfxAlignPosVV->Draw(); + } + fpfxAlignCanvas->Update(); + + +} +//______________________________________________________________________________ +// +void DAlign::SaveDisplay( const Char_t *fileName){ + + // Save all canvas and histos in a file + // + // JB 2014/04/06 + + TFile *outputFile=new TFile(fileName,"UPDATE"); + + // Canvas + fAlignCanvas->Write(); + //fAlign3DCanvas->Write(); // COMMENT BB 2015/07/28 + + + // histos + fhAlignDU->Write(); + fhAlignDV->Write(); + fhAlignDVDU->Write(); + fhAlignPosUV->Write(); + fhAlignPosVU->Write(); + fhAlignPosUU->Write(); + fhAlignPosVV->Write(); + fhAlignUU->Write(); // JB 2014/08/26 + fhAlignVV->Write(); + //fhAlignPosUUV->Write(); + //fhAlignPosVUV->Write(); + + outputFile->Close(); + +} + +//______________________________________________________________________________ +// +void DAlign::SaveDisplayDeformation( const Char_t *fileName){ + // Save all canvas and histos in a file + // + // JB 2014/04/06, modified BB 2014/05/20 + + TFile *outputFileDeformation=new TFile(fileName,"UPDATE"); + + // Canvas + fpfxAlignCanvas->Write(); + //fAlign3DCanvas->Write(); + + // histos + fpfxAlignPosUV->Write(); + fpfxAlignPosVU->Write(); + fpfxAlignPosUU->Write(); + fpfxAlignPosVV->Write(); + + outputFileDeformation->Close(); + +} + +//______________________________________________________________________________ +// +void DAlign::AccumulateU(DR3& aTrackPos, Double_t aDistanceU){ + + // First updates event by event measured and predicted positions to compute a chi square. + // Once the number of events is enough (hard coded to 200, see below), + // does a line fit to the measurements of (u_hit - u_track) versus (v_track), + // u_track and v_track are the intersections of the track with this plane, + // u_hit=aDistanceU is the measured position of the hit in this plane. + // + // Only for U direction (see equivalent function for V dim), JB, 2007 June + // + // Last Modified: JB 2010/12/14, taking into account potential rotation in Y is now unecessary due to the proper management of the plane rotations + + Double_t tDenominator; + + if(fDebugAlign>1) printf(" DAlign: plane %d Accumulating in U with distance %.1f %.1f\n", fPlaneNumber, aDistanceU, fBoundU); + if(fDebugAlign && fAlignCountu%50==0 && fAlignCountu) cout << " plane " << fPlaneNumber << " has accumulated " << fAlignCountu << " distances in the U direction." << endl; + + // Accumaltion of hits + if (fabs(aDistanceU) <= fBoundU) { + if (fhAlignPosUV) { + fhAlignPosUV->Fill( aTrackPos(1), aDistanceU); + if( fAlignCountu%50==0 ) { + fAlignCanvas->cd(1); + fhAlignPosUV->Draw(); + fAlignCanvas->Update(); + } + } + if (fpfxAlignPosUV) { // BB 060314 + fpfxAlignPosUV->Fill( aTrackPos(1), aDistanceU); + if( fAlignCountu%50==0 ) { + fpfxAlignCanvas->cd(1); + fpfxAlignPosUV->Draw(); + fpfxAlignCanvas->Update(); + } + } + + if (fhAlignPosUUV) { + fhAlignPosUUV->Fill( aTrackPos(0), aTrackPos(1), aDistanceU); // BB 080414 + if ( fAlignCountu%50==0) { + fAlign3DCanvas->cd(1); + fhAlignPosUUV->Draw("colz"); + fAlign3DCanvas->Update(); + } + } + fAlignSum_du += aDistanceU; // summation of u_hit - u_track + fAlignSum_dudu += (aDistanceU * aDistanceU); // summation for Resolution estimate + fAlignSum_duvt += (aDistanceU * aTrackPos(1)); // summation of (u_hit - u_track) * v_track + fAlignSum_vt += aTrackPos(1); + fAlignSum_vtvt += (aTrackPos(1) * aTrackPos(1)); + fAlignCountu++; + if (fDebugAlign) printf(" DAlign::AccumulateU plane %d, dist=%.1f / %.1f, du=%.1f, dudu=%.1f, vt=%.1f, countU=%d/%d\n", fPlaneNumber, fabs(aDistanceU), fBoundU, fAlignSum_du, fAlignSum_dudu, fAlignSum_vt, fAlignCountu, fNumberOfEvents); + } + + // Compute parameters according to the linear chisquare fit + if (fAlignCountu > fNumberOfEvents) { + + tDenominator = fAlignCountu * fAlignSum_vtvt - fAlignSum_vt * fAlignSum_vt; + + fAlignOffsetU= (fAlignSum_du * fAlignSum_vtvt - fAlignSum_duvt * fAlignSum_vt) / tDenominator; + fAlignTiltW = (fAlignCountu * fAlignSum_duvt - fAlignSum_du * fAlignSum_vt) / tDenominator; + + fAlignOffsetUError = sqrt( fAlignSum_vtvt / tDenominator ); + fAlignTiltWError = sqrt( fAlignCountu / tDenominator ); + fAlignCorrelation = fAlignSum_vt / ( tDenominator * fAlignOffsetUError * fAlignTiltWError ); + + fAlignOffset(0) = fAlignOffsetU; + + fAlignMeanU = fAlignSum_du/fAlignCountu; + fAlignResolutionU = sqrt(fAlignSum_dudu/fAlignCountu - fAlignMeanU * fAlignMeanU); + + fEnoughU = kTRUE; + if (fDebugAlign) printf("DAlign::AccumulateU Pl %d Uoffset=%.1f +/- %.1f, Uresidu=%.1f +/- %.1f\n", fPlaneNumber, fAlignOffsetU, fAlignOffsetUError, fAlignMeanU, fAlignResolutionU); + if (fDebugAlign && fhAlignPosUV) printf(" histoU mean=%.1f rms=%.1f\n", fhAlignPosUV->GetMean(2), fhAlignPosUV->GetRMS(2)); + } + else + fEnoughU = kFALSE; +} + +//______________________________________________________________________________ +// +void DAlign::AccumulateV(DR3& aTrackPos, Double_t aDistanceV){ + + // First updates event by event measured and predicted positions to compute a chi square. + // Once the number of events is enough (hard coded to 200, see below), + // does a line fit to the measurements of (v_hit - v_track) versus (u_track), + // u_track and v_track are the intersections of the track with this plane, + // v_hit=aDistanceV is the measured position of the hit in this plane + // + // Only for V direction (See equivalent function for U dim, JB, 2007 June + // + // Inversion of tilt angle when plane is X-ratated by 180deg + // Last Modified: JB 2010/12/14, taking into account potential rotation in X is now unecessary due to the proper management of the plane rotations + + Double_t tDenominator; + + if( fDebugAlign>1) printf(" DAlign: plane %d Accumulating in V with distance %.1f %.1f\n", fPlaneNumber, aDistanceV, fBoundV); + if(fDebugAlign && fAlignCountv && fAlignCountv%50==0 ) cout << " plane " << fPlaneNumber << " has accumulated " << fAlignCountv << " distances in the V direction." << endl; + + // Accumaltion of hits + if (fabs(aDistanceV) <= fBoundV) { + if (fhAlignPosVU) { + fhAlignPosVU->Fill( aTrackPos(0), aDistanceV); + if( fAlignCountv%50==0 ) { + fAlignCanvas->cd(2); + fhAlignPosVU->Draw(); + fAlignCanvas->Update(); + } + } + if (fpfxAlignPosVU) { // BB 060314 + fpfxAlignPosVU->Fill( aTrackPos(0), aDistanceV); + if( fAlignCountv%50==0 ) { + fpfxAlignCanvas->cd(2); + fpfxAlignPosVU->Draw(); + fpfxAlignCanvas->Update(); + } + } + + if (fhAlignPosVUV) { + fhAlignPosVUV->Fill( aTrackPos(0), aTrackPos(1), aDistanceV); // BB 080414 + if ( fAlignCountv%50==0) { + fAlign3DCanvas->cd(1); + fhAlignPosVUV->Draw("colz"); + fAlign3DCanvas->Update(); + } + } + fAlignSum_dv += aDistanceV; // summation of v_hit - v_track + fAlignSum_dvdv += aDistanceV * aDistanceV; // summation for Resolution estimate + fAlignSum_dvut += aDistanceV * aTrackPos(0); // summation of (v_hit - v_track) * u_track + fAlignSum_ut += aTrackPos(0); + fAlignSum_utut += aTrackPos(0) * aTrackPos(0); + fAlignCountv++; + if (fDebugAlign) printf(" DAlign::AccumulateV plane %d, dist=%.1f / %.1f, dv=%.1f, dvdv=%.1f, ut=%.1f, countV=%d/%d\n", fPlaneNumber, fabs(aDistanceV), fBoundV, fAlignSum_dv, fAlignSum_dvdv, fAlignSum_ut, fAlignCountv, fNumberOfEvents); + } + + // Compute parameters according to the linear chisquare fit + if (fAlignCountv > fNumberOfEvents) { + + tDenominator = fAlignCountv * fAlignSum_utut - fAlignSum_ut * fAlignSum_ut; + + fAlignOffsetV= (fAlignSum_dv * fAlignSum_utut - fAlignSum_dvut * fAlignSum_ut) / tDenominator; + + fAlignOffsetVError = sqrt( fAlignSum_utut / tDenominator ); + + fAlignOffset(1) = fAlignOffsetV; + + fAlignMeanV = fAlignSum_dv/fAlignCountv; + fAlignResolutionV = sqrt(fAlignSum_dvdv/fAlignCountv - fAlignMeanV * fAlignMeanV); + + fEnoughV = kTRUE; + if (fDebugAlign) printf(" DAlign::AccumulateV plane %d Voffset=%.1f +/- %.1f, Vresidu=%.1f +/- %.1f\n", fPlaneNumber, fAlignOffsetV, fAlignOffsetVError, fAlignMeanV, fAlignResolutionV); + if (fDebugAlign && fhAlignPosVU) printf(" histoV mean=%.1f rms=%.1f\n", fhAlignPosVU->GetMean(2), fhAlignPosVU->GetRMS(2)); + } + else + fEnoughV = kFALSE; +} + +//______________________________________________________________________________ +// +void DAlign::Accumulate2D(DR3& aTrackPos, Double_t aDistanceU, Double_t aDistanceV){ + + // method to correlate alignment in U and V + // + // First updates event by event measured and predicted positions to compute a chi square: + // chi2 = M-matrix x Align-vector - Shift-vector, + // where Shift-vector = {sum(uhit-utrack), sum(vhit-vtrack), sum[vtrack(uhit-utrack)-utrack(vhit-vtrack)]} + // and Align-vector = { Uoffser, Voffset, TiltW}. + // Once the number of events is enough (fNumberOfEvents), + // does a line fit or simulatenous chi2 minimization to determine inverse-M. + // So, Align-vector = inverse-M x Shift-vector. + // + // JB, 2008/10/27 + // Last Modified: JB 2010/12/14, taking into account potential rotation in X or Y is now unecessary due to the proper management of the plane rotations + + + if( fDebugAlign>1) printf(" DAlign: plane %d Accumulating in U and V with distance (%f, %f) (%.1f, %.1f)\n", fPlaneNumber, aDistanceU, aDistanceV, fBoundU, fBoundV); + + // Accumaltion of hits +// Double_t aDistanceU = aHitPos(0)-aTrackPos(0); +// Double_t aDistanceV = aHitPos(1)-aTrackPos(1); + if ( fabs(aDistanceU)<=fBoundU && fabs(aDistanceV)<=fBoundV ) { + +// if (fhAlignPosU) { +// fhAlignPosU->Fill( aTrackPos(1), aDistanceU); +// if( fAlignCountu%50==0 ) { +// fAlignCanvas->cd(1); +// fhAlignPosU->Draw(); +// fAlignCanvas->Update(); +// } +// } +// if (fhAlignPosV) { +// fhAlignPosV->Fill( aTrackPos(0), aDistanceV); +// if( fAlignCountv%50==0 ) { +// fAlignCanvas->cd(2); +// fhAlignPosV->Draw(); +// fAlignCanvas->Update(); +// } +// } + + fAlignSum_du += aDistanceU; // summation of u_hit - u_track + fAlignSum_dv += aDistanceV; // summation of v_hit - v_track + fAlignSum_ut += aTrackPos(0); + fAlignSum_vt += aTrackPos(1); + fAlignSum_utut += aTrackPos(0) * aTrackPos(0); + fAlignSum_vtvt += (aTrackPos(1) * aTrackPos(1)); + fAlignSum_uvt2 += aTrackPos(0) * aTrackPos(0) + aTrackPos(1) * aTrackPos(1); + fAlignSum_dvuduv += aDistanceU * aTrackPos(1) - aDistanceV * aTrackPos(0); + fAlignSum_dudu += aDistanceU * aDistanceU; // summation for Resolution estimate + fAlignSum_dvdv += aDistanceV * aDistanceV; // summation for Resolution estimate + fAlignSum_duvt += (aDistanceU * aTrackPos(1)); // summation of (u_hit - u_track) * v_track + fAlignSum_dvut += aDistanceV * aTrackPos(0); // summation of (v_hit - v_track) * u_track + fAlignCount2D++; + + if (fDebugAlign) printf(" DAlign::Accumulate2D plane %d, dist=(%.1f, %.1f) (%.1f, %.1f), track=(%.1f, %.1f), Sum=(%.1f, %.1f), count2D=%d/%d\n", fPlaneNumber, aDistanceU, aDistanceV, fBoundU, fBoundV, aTrackPos(0), aTrackPos(1), fAlignSum_ut, fAlignSum_vt, fAlignCount2D, fNumberOfEvents); + } + + // Compute parameters according to the linear chisquare fit + if (fAlignCount2D > fNumberOfEvents) { + + /* + Double_t tDenominator = fAlignCount2D * fAlignSum_uvt2 - fAlignSum_ut * fAlignSum_ut - fAlignSum_vt * fAlignSum_vt; + + Double_t invM[3][3]; + invM[0][0] = fAlignSum_uvt2-fAlignSum_ut*fAlignSum_ut/fAlignCount2D; + invM[0][1] = -fAlignSum_vt*fAlignSum_ut/fAlignCount2D; + invM[0][2] = fAlignSum_vt; + invM[1][0] = -fAlignSum_vt*fAlignSum_ut/fAlignCount2D; + invM[1][1] = fAlignSum_uvt2-fAlignSum_vt*fAlignSum_vt/fAlignCount2D; + invM[1][2] = -fAlignSum_ut; + invM[2][0] = -fAlignSum_vt; + invM[2][1] = fAlignSum_ut; + invM[2][2] = -fAlignCount2D; + + Double_t vec[3] = { fAlignSum_du, fAlignSum_dv, fAlignSum_dvuduv}; + Double_t sol[3] = {0., 0., 0.}; + // sol = invM * vec; + for( Int_t i=0; i<3; i++) { + for( Int_t j=0; j<3; j++) { + sol[i] += invM[i][j]*vec[j]; + } + sol[i] /= tDenominator; + } + + fAlignOffsetU = sol[0]; + fAlignOffsetV = sol[1]; + fAlignTiltW = sol[2]; + + fAlignOffsetUError = 0.; // don't know yet how to compute + fAlignOffsetVError = 0.; + fAlignTiltWError = 0.; + */ + + Double_t tDenominator = fAlignCount2D * fAlignSum_vtvt - fAlignSum_vt * fAlignSum_vt; + fAlignOffsetU= (fAlignSum_du * fAlignSum_vtvt - fAlignSum_duvt * fAlignSum_vt) / tDenominator; + fAlignTiltW = (fAlignCount2D * fAlignSum_duvt - fAlignSum_du * fAlignSum_vt) / tDenominator; + fAlignOffsetUError = sqrt( fAlignSum_vtvt / tDenominator ); + fAlignTiltWError = sqrt( fAlignCount2D / tDenominator ); + fAlignCorrelation = fAlignSum_vt / ( tDenominator * fAlignOffsetUError * fAlignTiltWError ); + tDenominator = fAlignCount2D * fAlignSum_utut - fAlignSum_ut * fAlignSum_ut; + fAlignOffsetV= (fAlignSum_dv * fAlignSum_utut - fAlignSum_dvut * fAlignSum_ut) / tDenominator; + fAlignOffsetVError = sqrt( fAlignSum_utut / tDenominator ); + + fAlignOffset(0) = fAlignOffsetU; + fAlignOffset(1) = fAlignOffsetV; + + fAlignMeanU = fAlignSum_du/fAlignCount2D; + fAlignResolutionU = sqrt(fAlignSum_dudu/fAlignCount2D - fAlignMeanU * fAlignMeanU); + fAlignMeanV = fAlignSum_dv/fAlignCount2D; + fAlignResolutionV = sqrt(fAlignSum_dvdv/fAlignCount2D - fAlignMeanV * fAlignMeanV); + + fEnough2D = kTRUE; + if (fDebugAlign) printf(" DAlign::Accumulate2D plane %d uoffset=%.1f +/- %.1f Voffset=%.1f +/- %.1f, Uresidu=%.1f +/- %.1f, Vresidu=%.1f +/- %.1f\n", fPlaneNumber, fAlignOffsetU, fAlignOffsetUError, fAlignOffsetV, fAlignOffsetVError, fAlignMeanU, fAlignResolutionU, fAlignMeanV, fAlignResolutionV); +// if (fDebugAlign && fhAlignPosU) printf(" histoU mean=%.1f rms=%.1f\n", fhAlignPosU->GetMean(2), fhAlignPosU->GetRMS(2)); +// if (fDebugAlign && fhAlignPosV) printf(" histoV mean=%.1f rms=%.1f\n", fhAlignPosV->GetMean(2), fhAlignPosV->GetRMS(2)); + } + else + fEnough2D = kFALSE; +} + +//______________________________________________________________________________ +// +void DAlign::Modified() +{ + // reset the summation variables + // and update the max distance track-hit + // + // Modified: JB 2011/04/05 re-init of Enough flags added + + printf(" Alignement Accumulation restarts .... \n\n"); + + fAlignSum_du = 0.0; + fAlignSum_dudu = 0.0; + fAlignSum_duvt = 0.0; + fAlignSum_vt = 0.0; + fAlignSum_vtvt = 0.0; + fAlignCountu = 0; + fEnoughU = kFALSE; // JB 2011/04/05 + fAlignSum_dv = 0.0; // JB + fAlignSum_dvdv = 0.0; + fAlignSum_dvut = 0.0; + fAlignSum_ut = 0.0; + fAlignSum_utut = 0.0; + fAlignCountv = 0; + fEnoughV = kFALSE; // JB 2011/04/05 + fAlignSum_dvuduv = 0; // JB 2009/05/18 + fAlignSum_uvt2 = 0; // JB 2009/05/18 + fAlignCount2D = 0; // JB 2009/05/13 + fEnough2D = kFALSE; // JB 2011/04/05 + Double_t tBoundU, tBoundV; + // Introduction of bounds in both direction, JB 2013/06/10 + // tBound /= 2.; // replaced by the following 2 lines, JB, 2007 August + // minimal value, changed from 150 to 50 by JB, 2009/07/19 + Double_t minimalBound = 50.; + tBoundU = TMath::Max( minimalBound, 1.5*fabs(fAlignResolutionU)); + tBoundV = TMath::Max( minimalBound, 1.5*fabs(fAlignResolutionV)); + if( tBoundU < fBoundU ) { + SetBoundings(tBoundU, fBoundV); + } + if( tBoundV < fBoundV ) { + SetBoundings(fBoundU, tBoundV); + } +// if(fhAlignPosU) fhAlignPosU->Reset(); +// if(fhAlignPosV) fhAlignPosV->Reset(); +} + +//______________________________________________________________________________ +// + +void DAlign::ShowCorrection() +{ + printf(" Found Deviation in U Position [um] : %f\n",fAlignOffsetU); + printf(" Found Deviation in V Position [um] : %f\n",fAlignOffsetV); + printf(" Found Deviation in W-Tilt [deg]: %f\n",fAlignTiltW*180/M_PI); + printf(" -> Estimated Resolution U %f um at Residual Mean %f um\n",fAlignResolutionU,fAlignMeanU); + printf(" -> Estimated Resolution V %f um at Residual Mean %f um\n",fAlignResolutionV,fAlignMeanV); + printf(" Estimated Offest-U Error [um] : %f\n",fAlignOffsetUError); + printf(" Estimated Offest-V Error [um] : %f\n",fAlignOffsetVError); + printf(" Estimated Tilt-W Error [deg]: %f\n",fAlignTiltWError*180/M_PI); + printf(" Correlation between du and vt : %f\n",fAlignCorrelation); +} + +//______________________________________________________________________________ +// + +void DAlign::ShowStoredResolution() +{ + // JB 2010/12/14 + printf(" -> Estimated Resolution U %f um at Residual Mean %f um\n",fhAlignDU->GetRMS(),fhAlignDU->GetMean()); + printf(" -> Estimated Resolution V %f um at Residual Mean %f um\n",fhAlignDV->GetRMS(),fhAlignDV->GetMean()); +} + +//______________________________________________________________________________ +// +void DAlign::FitDeformation(Double_t (*CoeffLegendreU), Double_t (*CoeffLegendreV), Float_t minU, Float_t maxU, Float_t minV, Float_t maxV){ + + // Define a Legendre polynomial of the order of 7th + // + // BB 2014/05/20 + // Modified JB 2015/10/31 range for fit function implemented + + cout << " Coefficients for U | Coefficients for V coordinates written in config file : " << endl; + cout << " - CoeffU(0) : " << CoeffLegendreU[0] << " | CoeffV(0) : " << CoeffLegendreV[0] << endl; + cout << " - CoeffU(1) : " << CoeffLegendreU[1] << " | CoeffV(1) : " << CoeffLegendreV[1] << endl; + cout << " - CoeffU(2) : " << CoeffLegendreU[2] << " | CoeffV(2) : " << CoeffLegendreV[2] << endl; + cout << " - CoeffU(3) : " << CoeffLegendreU[3] << " | CoeffV(3) : " << CoeffLegendreV[3] << endl; + cout << " - CoeffU(4) : " << CoeffLegendreU[4] << " | CoeffV(4) : " << CoeffLegendreV[4] << endl; + cout << " - CoeffU(5) : " << CoeffLegendreU[5] << " | CoeffV(5) : " << CoeffLegendreV[5] << endl; + cout << " - CoeffU(6) : " << CoeffLegendreU[6] << " | CoeffV(6) : " << CoeffLegendreV[6] << endl; + cout << " - CoeffU(7) : " << CoeffLegendreU[7] << " | CoeffV(7) : " << CoeffLegendreV[7] << endl; + + // If no specified range, use sensor size (coeff[0]) + if( fabs(minU-maxU)<1. ) { + minU = -CoeffLegendreU[0]; + maxU = CoeffLegendreU[0]; + } + if( fabs(minV-maxV)<1. ) { + minV = -CoeffLegendreV[0]; + maxV = CoeffLegendreV[0]; + } + + f1legendre7U = new TF1("f1legendre7U","[1] + [2]*x/[0] + [3]*(3*x*x/[0]/[0]-1)/8 + [4]*x/[0]*(5*x*x/[0]/[0]-3)/2 + [5]*(35*x*x*x*x/[0]/[0]/[0]/[0]-30*x*x/[0]/[0]+3)/8 + [6]*x/[0]*(63*x*x*x*x/[0]/[0]/[0]/[0]-70*x*x*x/[0]/[0]/[0]+15)/8 + [7]*(231*x*x*x*x*x*x/[0]/[0]/[0]/[0]/[0]/[0]-315*x*x*x*x/[0]/[0]/[0]/[0]+105*x*x/[0]/[0]-5)/16", minU, maxU); + f1legendre7U->SetParameters( CoeffLegendreU[0], CoeffLegendreU[1], CoeffLegendreU[2], CoeffLegendreU[3], CoeffLegendreU[4], CoeffLegendreU[5], CoeffLegendreU[6], CoeffLegendreU[7]); + f1legendre7U->FixParameter( 0, CoeffLegendreU[0]); + + f1legendre7V = new TF1("f1legendre7V","[1] + [2]*x/[0] + [3]*(3*x*x/[0]/[0]-1)/8 + [4]*x/[0]*(5*x*x/[0]/[0]-3)/2 + [5]*(35*x*x*x*x/[0]/[0]/[0]/[0]-30*x*x/[0]/[0]+3)/8 + [6]*x/[0]*(63*x*x*x*x/[0]/[0]/[0]/[0]-70*x*x*x/[0]/[0]/[0]+15)/8 + [7]*(231*x*x*x*x*x*x/[0]/[0]/[0]/[0]/[0]/[0]-315*x*x*x*x/[0]/[0]/[0]/[0]+105*x*x/[0]/[0]-5)/16", minV, maxV); + f1legendre7V->SetParameters( CoeffLegendreV[0], CoeffLegendreV[1], CoeffLegendreV[2], CoeffLegendreV[3], CoeffLegendreV[4], CoeffLegendreV[5], CoeffLegendreV[6], CoeffLegendreV[7]); + f1legendre7V->FixParameter( 0, CoeffLegendreV[0]); +} diff --git a/src/DBeaster.cxx b/src/DBeaster.cxx new file mode 100644 index 0000000..2e14363 --- /dev/null +++ b/src/DBeaster.cxx @@ -0,0 +1,1573 @@ +//**********************************************************************************// +//Autor: Daniel Cuesta +//Purpose of Class : +// Holds all the modules needed to perform pattern recognition with PLUME ladders +// - Fill_Modules_HitList : Built the list of hits on each module +// - Particle_Reconstruction : Call sub methods for pattern recognition depending of the number of hits in modules +// It will return a list of reconstructed particles +// -- SpatialClustering : For each hit it will find the closest hit in the module( under a predifined limit) +// and put them together as coming from the same particle +// -- Superposition : Same idea but with hits from different modules of the same ladder +// -- Allignement : Test the Allignement of hits (helps to reconstruct loopers) +// - RecoCategorieClassification : Classified particles in the differents hits pattern (take the output list of reconstructed particles from "Particle reconstruction") +// +//**********************************************************************************// +#include "DBeaster.h" +ClassImp(DBeaster) +DBeaster::DBeaster(DTracker *Tracker) +{ + // DBeaster default constructor + tTracker=Tracker; + fHelixFitter = new DHelixFitter(Tracker); +} +DBeaster::~DBeaster(){ + return; +} +//=========================================================================================================== +DR3 DBeaster::GetHitPositionOnLabRefFrame(int PlaneId,int HitId) { + //Pour l'instant dans DBeaster mais devras être mis ailleurs + //Take a Hit position in the Sensor reference frame + //Define it in the Ladder reference frame + + aPlane=tTracker->GetPlane(PlaneId); + Dprec=aPlane->GetPrecAlignment(); + LadderNumber=aPlane->GetLadderNumber(); + aHit = aPlane->GetHit(HitId); + hitPositionPlane=aHit->GetPosition(); + return hitPositionLab=Dprec->TransformHitToTracker(*hitPositionPlane); +} +//=========================================================================================================== +DR3 DBeaster::GetHitPositionOnLadderRefFrame(int PlaneId,int HitId) { + //Pour l'instant dans DBeaster mais devras être mis ailleurs + //Take a Hit position in the Sensor reference frame + //Define it in the Ladder reference frame + + aPlane=tTracker->GetPlane(PlaneId); + Dprec=aPlane->GetPrecAlignment(); + LadderNumber=aPlane->GetLadderNumber(); + aHit = aPlane->GetHit(HitId); + hitPositionPlane=aHit->GetPosition(); + hitPositionLab=Dprec->TransformHitToTracker(*hitPositionPlane); + aLadder=tTracker->GetLadder(LadderNumber); + if (LadderNumber==1) PlaneIdx=PlaneId; + else PlaneIdx=PlaneId-12; + return aLadder->PlaneToLadder(*hitPositionPlane,PlaneIdx); +} +//=========================================================================================================== +void DBeaster::Clear_List() { + ListOfBeastHitsOnM1.clear(); + ListOfBeastHitsOnM2.clear(); + ListOfRecoPartsM1_SC.clear(); + ListOfRecoPartsM2_SC.clear(); + ListOfRecoPartsM1_AL.clear(); + ListOfRecoPartsM2_AL.clear(); + ListOfRecoParts_SP.clear(); + ListOfTslCandidat.clear(); + ListOfSimuPartClass.clear(); + ListOfSimuPartIdL1.clear(); + ListOfSimuPartIdL2.clear(); + return; + } +//=========================================================================================================== +void DBeaster::Fill_Modules_HitList(int LadderId){ + int iHitGlobalIdx=0; + if (LadderId==1) { + SensorMin=1; + SensorMax=12; + }else{ + SensorMin=13; + SensorMax=24; + } + // std::cout << "FILL MODULES HITLIST" << '\n'; + for( int iPlane=SensorMin; iPlane<=SensorMax; iPlane++ ) { + // loop on planes + aPlane=tTracker->GetPlane(iPlane); + if(aPlane->GetHitsN()==0) continue; + for( Int_t iHit=1; iHit <= aPlane->GetHitsN(); iHit++ ) { // loop on plane hits + aHit = aPlane->GetHit(iHit); + // if(aHit->GetStripsInCluster()<=0) continue; + if(aHit->GetMCHitID()<0) continue; + if(aPlane->GetLadderNumber()==0) continue; + ABeastHit BeastHit; + BeastHit.LadderId = aPlane->GetLadderNumber(); + BeastHit.SensorId = iPlane; + BeastHit.HitId = iHit; + BeastHit.hitPositionLadderUVW = GetHitPositionOnLadderRefFrame(iPlane,iHit); + BeastHit.hitPositionLadderUVW(0)= BeastHit.hitPositionLadderUVW(0)/1000.; + BeastHit.hitPositionLadderUVW(1)= BeastHit.hitPositionLadderUVW(1)/1000.; + BeastHit.hitPositionLadderUVW(2)= BeastHit.hitPositionLadderUVW(2)/1000.; + BeastHit.hitPositionLabXYZ = GetHitPositionOnLabRefFrame(iPlane,iHit); + BeastHit.McHitId = aHit->GetMCHitID(); + //Spatial Clustering(SC) + BeastHit.RecoId_SC = -1; + BeastHit.IsRec_SC = false; + //Superposition(SP) + BeastHit.RecoId_SP = -1; + BeastHit.IsRec_SP = false; + BeastHit.RpairedSP = 20000; + BeastHit.IsFill_SC = false; + //Allignement + BeastHit.RecoId_AL = -1; + BeastHit.IsRec_AL = false; + BeastHit.VpairedAL = 20000; + if (iPlane<=12) { + if(iPlane<=6) { + BeastHit.ModuleId=1; + ListOfBeastHitsOnM1.push_back(BeastHit); //Module 1 + }else{ + BeastHit.ModuleId=2; + ListOfBeastHitsOnM2.push_back(BeastHit); //Module 2 + } + }else{ + if(iPlane<=18) { + BeastHit.ModuleId=1; + ListOfBeastHitsOnM1.push_back(BeastHit); //Module 1 + }else{ + BeastHit.ModuleId=2; + ListOfBeastHitsOnM2.push_back(BeastHit); //Module 2 + } + } + }//End loop on Hits + }//End loop on Planes + // std::cout << "Hits on M1" <GetTracker(); + MCInfoHolder = tTracker->GetMCInfoHolder(); + + NbPart=MCInfoHolder->GetNSimParticles(); + // std::cout << "Npart = "<GetASimParticle(ipart).NHits; + // std::cout << "Nb Hits = "<< NbHitsTest << '\n'; + if(NbHitsTest!=0){ + for(int ihit=0;ihitGetASimParticle(ipart).FirstHitIdx; + HitIndex = FirstHitIdx + ihit; + iHitNPixels=MCInfoHolder->GetASimHit(FirstHitIdx + ihit).Npixels; + // std::cout << "iHitNPixels = " << iHitNPixels<< '\n'; + // if(iHitNPixels>0){ + if (MCInfoHolder->GetASimHit(FirstHitIdx + ihit).sensorID<=12) { + Ladder1=true; + if (MCInfoHolder->GetASimHit(FirstHitIdx + ihit).sensorID<=6) { + Module1=true; + }else{ //end IF Ladder 1 Module 1 + Module2=true; + }//end IF Ladder 1 Module 2 + }else{ //End if Ladder 1 + Ladder2=true; + if (MCInfoHolder->GetASimHit(FirstHitIdx + ihit).sensorID<=18) { + Module1=true; + }else{ //end IF Ladder 2 Module 1 + Module2=true; + } //end IF Ladder 2 Module 2 + }//End if Ladder 2 + // }//End if Npixels !=0 + }//end loop on Hits of real parts + + if(Ladder1==true && Ladder2==false){ + LadderIdTest=1; + ListOfSimuPartIdL1.push_back(ipart); + } + if(Ladder1==false && Ladder2==true){ + LadderIdTest=2; + ListOfSimuPartIdL2.push_back(ipart); + } + if(Module1==true && Module2==true){ + if(NbHitsTest>2){ //TWO SIDES LOOPER ELECTRON + ListOfSimuPartClass.push_back(4); + if(Ladder1){NbTslL1++;} + if(Ladder2){NbTslL2++;} + //h_cathitLadder1_Real->Fill(4); + } + if(NbHitsTest==2){ //TWO SIDES ELECTRON + ListOfSimuPartClass.push_back(2); + // std::cout << "push_back TS" << '\n'; + //h_cathitLadder1_Real->Fill(2); + } + }else if((Module1==true && Module2==false)||(Module1==false && Module2==true)){ + if(NbHitsTest>1){ //ONE SIDE LOOPER ELECTRON + //if(MoreThanTwoHits==true) //ONE SIDE LOOPER ELECTRON + ListOfSimuPartClass.push_back(3); + //h_cathitLadder1_Real->Fill(3); + }else if(NbHitsTest==1){ //ONE SIDE ELECTRON + ListOfSimuPartClass.push_back(1); + //h_cathitLadder1_Real->Fill(1); + } + } + + }//end If !=0 + }//End Loop On parts + // h_NbTslL1->Fill(NbTslL1); + // h_NbTslL2->Fill(NbTslL2); + return; +} +//=========================================================================================================== + +void DBeaster::SimuCategorieClassificationNew(){ + // std::cout << "inside SimuCategorieClassification" << '\n'; + int NbTslL1=0; + int NbTslL2=0; + int iHitNPixels; + // tTracker = fSession->GetTracker(); + MCInfoHolder = tTracker->GetMCInfoHolder(); + NbPart=MCInfoHolder->GetNSimParticles(); + // std::cout << "Nbpart = "<GetASimParticle(ipart).NHits; + // std::cout << "Nb Hits = "<< NbHitsTest<< '\n'; + if(NbHitsTest!=0){ + for(int ihit=0;ihitGetASimParticle(ipart).FirstHitIdx; + HitIndex = FirstHitIdx + ihit; + iHitNPixels=MCInfoHolder->GetASimHit(FirstHitIdx + ihit).Npixels; + // std::cout << "iHitNPixels = " << iHitNPixels<< '\n'; + if(iHitNPixels>0){ + // std::cout << "PIXELS OK" << '\n'; + if (MCInfoHolder->GetASimHit(FirstHitIdx + ihit).sensorID<=12) { + Ladder1=true; + if (MCInfoHolder->GetASimHit(FirstHitIdx + ihit).sensorID<=6) { + Module1=true; + }else{ //end IF Ladder 1 Module 1 + Module2=true; + }//end IF Ladder 1 Module 2 + }else{ //End if Ladder 1 + Ladder2=true; + if (MCInfoHolder->GetASimHit(FirstHitIdx + ihit).sensorID<=18) { + Module1=true; + }else{ //end IF Ladder 2 Module 1 + Module2=true; + } //end IF Ladder 2 Module 2 + }//End if Ladder 2 + }//End if Npixels !=0 + }//end loop on Hits of real parts + + if(Ladder1==true && Ladder2==false){ + LadderIdTest=1; + ListOfSimuPartIdL1.push_back(ipart); + } + if(Ladder1==false && Ladder2==true){ + LadderIdTest=2; + ListOfSimuPartIdL2.push_back(ipart); + } + double MC_VrtXpos = MCInfoHolder->GetASimParticle(ipart).ProdVtx.X(); + double MC_VrtYpos = MCInfoHolder->GetASimParticle(ipart).ProdVtx.Y(); + double MC_VrtZpos = MCInfoHolder->GetASimParticle(ipart).ProdVtx.Z(); + // std::cout << "Vrtx Pos X = "<1){ //ONE SIDE LOOPER ELECTRON + ListOfSimuPartClass.push_back(4); + // std::cout << "OSL" << '\n'; + }else if(NbHitsTest==1){ //ONE SIDE ELECTRON + ListOfSimuPartClass.push_back(1); + // std::cout << "OS" << '\n'; + } + // std::cout << "ON OS" << '\n'; + }else{ + ListOfSimuPartClass.push_back(-999); + } + int TestpatternType = -999; + TestpatternType = ListOfSimuPartClass[ipart]; + if(Ladder1==true || Ladder2==true){ + // if(Ladder1) std::cout << "LadderId = 1"<< '\n'; + // if(Ladder2) std::cout << "LadderId = 2"<< '\n'; + // std::cout << "Particle Pattern Type: "<< TestpatternType<< '\n'; + } + } + }//End Loop On parts + // h_NbTslL1->Fill(NbTslL1); + // h_NbTslL2->Fill(NbTslL2); + return; +} +//=========================================================================================================== +void DBeaster::RecoCategorieClassification(int ladderId,int iHitSeuil){ + // std::cout << "RecoCategorieClassification For Ladder" << ladderId<<'\n'; + int NbPart=ListOfRecoParts_SP.size(); + int LadderIdTest; + for(int ipart=0;ipart2){MoreThanTwoHits=true;} + for(int ihit=0;ihit1){ + //if(MoreThanTwoHits==true)//ONE SIDE LOOPER ELECTRON + // std::cout << "******RECO OSL ****** " << '\n'; + ListOfRecoParts_SP[ipart].ClassType=3; + }else if(NbHitsTest==1){ //ONE SIDE ELECTRON + // std::cout << "******RECO OS ****** " << '\n'; + ListOfRecoParts_SP[ipart].ClassType=1; + } + } + } + // int Classtype=ListOfRecoParts_SP[ipart].ClassType; + }//End Loop on parts + + FillListOfBeastRecoPart(ladderId); + + return; +} + +//=========================================================================================================== +void DBeaster::Particle_Reconstruction(int ladderId){ + double ScSeuil=0.; + double SpSeuil=0.; + if(ladderId==1){ + ScSeuil=15.; + SpSeuil=15.; + } + if(ladderId==2){ + ScSeuil=10.; + SpSeuil=10.; + } + if((ListOfBeastHitsOnM1.size()==1&&ListOfBeastHitsOnM2.size()==0)||(ListOfBeastHitsOnM1.size()==0 && ListOfBeastHitsOnM2.size()==1)){ + // cout<<"CAT1"<1){ + if((ListOfBeastHitsOnM1.size()==1) && (ListOfBeastHitsOnM2.size()==1)){ + // cout<<"CAT2"<ListOfBeastHitsOnM1[jhit].RecoId_SC){ + for(int khit=0;khitListOfBeastHitsOnM2[jhit].RecoId_SC){ + for(int khit=0;khit=jhit) continue; + double jhitRecoID_SC= ListOfBeastHitsOnM1[jhit].RecoId_SC; + if(jhitRecoID_SC!=-1){ + V1=ListOfBeastHitsOnM1[ihit].hitPositionLadderUVW(1); + V2=ListOfBeastHitsOnM1[jhit].hitPositionLadderUVW(1); + dV=abs(V1-V2); + if(dV<=VminAL){ + if(!ListOfBeastHitsOnM1[jhit].IsRec_AL){ + //if(!(Frame.ListOfHitsM1[jhit].IsRec_AL)) + VminAL=dV; + jhitmin=jhit; + } + if((ListOfBeastHitsOnM1[jhit].IsRec_AL) && (dV=jhit) continue; + double jhitRecoID_SC= ListOfBeastHitsOnM2[jhit].RecoId_SC; + if(jhitRecoID_SC!=-1){ + V1=ListOfBeastHitsOnM2[ihit].hitPositionLadderUVW(1); + V2=ListOfBeastHitsOnM2[jhit].hitPositionLadderUVW(1); + dV=abs(V1-V2); + if(dV<=VminAL){ + if(!ListOfBeastHitsOnM2[jhit].IsRec_AL){ + //if(!(Frame.ListOfHitsM2[jhit].IsRec_AL)) + VminAL=dV; + jhitmin=jhit; + } + if((ListOfBeastHitsOnM2[jhit].IsRec_AL) && (dV=jhit) continue; + double jhitRecoID= ListOfBeastHitsOnM1[jhit].RecoId_SC; + if(ihitRecoID==jhitRecoID && (!ListOfBeastHitsOnM1[jhit].IsFill_SC)){ + ListOfRecoPartsM1_SC[NbRecoPartsM1-1].HitList.push_back(ListOfBeastHitsOnM1[jhit]); + ListOfRecoPartsM1_SC[NbRecoPartsM1-1].HitScIdList.push_back(ListOfBeastHitsOnM1[jhit].RecoId_SC); + ListOfRecoPartsM1_SC[NbRecoPartsM1-1].HitSpIdList.push_back(ListOfBeastHitsOnM1[jhit].RecoId_SP); + + ListOfBeastHitsOnM1[jhit].IsFill_SC=true; + // IsScFillM1[jhit]=1; + } + } + } + //if(ihitRecoID==0) + if(ihitRecoID==-1){ + ABeastRecoPart particle; + particle.HitList.clear(); + particle.HitScIdList.clear(); + particle.HitSpIdList.clear(); + particle.HitList.push_back(ListOfBeastHitsOnM1[ihit]); + particle.HitScIdList.push_back(ListOfBeastHitsOnM1[ihit].RecoId_SC); + particle.HitSpIdList.push_back(ListOfBeastHitsOnM1[ihit].RecoId_SP); + particle.IsRec_SPreco=false; + particle.IsRec_ALreco=true; + particle.ClassType=0; + ListOfRecoPartsM1_SC.push_back(particle); + // std::cout << "PushBack Sc Part M1" << '\n'; + + ListOfBeastHitsOnM1[ihit].IsFill_SC=true; + // IsScFillM1[ihit]=1; + NbRecoPartsM1++; + double ihitRecoID_AL= ListOfBeastHitsOnM1[ihit].RecoId_AL; + if(ihitRecoID_AL!=-1){ + for(int jhit=0;jhit=jhit) continue; + double jhitRecoID_AL= ListOfBeastHitsOnM1[jhit].RecoId_AL; + if(ihitRecoID_AL==jhitRecoID_AL ){ + ListOfRecoPartsM1_SC[NbRecoPartsM1-1].HitList.push_back(ListOfBeastHitsOnM1[jhit]); + ListOfRecoPartsM1_SC[NbRecoPartsM1-1].HitScIdList.push_back(ListOfBeastHitsOnM1[jhit].RecoId_SC); + ListOfRecoPartsM1_SC[NbRecoPartsM1-1].HitSpIdList.push_back(ListOfBeastHitsOnM1[jhit].RecoId_SP); + ListOfBeastHitsOnM1[jhit].IsFill_SC=true; + // IsScFillM1[jhit]=1; + } + } + } + } + } + + double NbRecoPartsM2=0; + for(int ihit=0; ihit=jhit) continue; + double jhitRecoID= ListOfBeastHitsOnM2[jhit].RecoId_SC; + if(ihitRecoID==jhitRecoID && (!ListOfBeastHitsOnM2[jhit].IsFill_SC)){ + ListOfRecoPartsM2_SC[NbRecoPartsM2-1].HitList.push_back(ListOfBeastHitsOnM2[jhit]); + ListOfRecoPartsM2_SC[NbRecoPartsM2-1].HitScIdList.push_back(ListOfBeastHitsOnM2[jhit].RecoId_SC); + ListOfRecoPartsM2_SC[NbRecoPartsM2-1].HitSpIdList.push_back(ListOfBeastHitsOnM2[jhit].RecoId_SP); + ListOfBeastHitsOnM2[jhit].IsFill_SC=true; + // IsScFillM2[jhit]=1; + } + } + } + //if(ihitRecoID==0) + if(ihitRecoID==-1){ + ABeastRecoPart particle; + particle.HitList.clear(); + particle.HitScIdList.clear(); + particle.HitSpIdList.clear(); + particle.HitList.push_back(ListOfBeastHitsOnM2[ihit]); + particle.HitScIdList.push_back(ListOfBeastHitsOnM2[ihit].RecoId_SC); + particle.HitSpIdList.push_back(ListOfBeastHitsOnM2[ihit].RecoId_SP); + particle.IsRec_SPreco=false; + particle.IsRec_ALreco=true; + particle.ClassType=0; + ListOfRecoPartsM2_SC.push_back(particle); + // std::cout << "PushBack Sc Part M2" << '\n'; + ListOfBeastHitsOnM2[ihit].IsFill_SC=true; + // IsScFillM2[ihit]=1; + NbRecoPartsM2++; + double ihitRecoID_AL= ListOfBeastHitsOnM2[ihit].RecoId_AL; + if(ihitRecoID_AL!=-1){ + for(int jhit=0;jhit=jhit) continue; + double jhitRecoID_AL= ListOfBeastHitsOnM2[jhit].RecoId_AL; + if(ihitRecoID_AL==jhitRecoID_AL ){ + ListOfRecoPartsM2_SC[NbRecoPartsM2-1].HitList.push_back(ListOfBeastHitsOnM2[jhit]); + ListOfRecoPartsM2_SC[NbRecoPartsM2-1].HitScIdList.push_back(ListOfBeastHitsOnM2[jhit].RecoId_SC); + ListOfRecoPartsM2_SC[NbRecoPartsM2-1].HitSpIdList.push_back(ListOfBeastHitsOnM2[jhit].RecoId_SP); + ListOfBeastHitsOnM2[jhit].IsFill_SC=true; + // IsScFillM2[jhit]=1; + } + } + } + } + } + + return; +} +//======================================================================================================= +void DBeaster::FillListOfRecoPartsSP(){ + ListOfRecoParts_SP.clear(); + // std::cout << "Inside fill List size = " << ListOfRecoParts_SP.size() <<'\n'; + double NbPartsM1=ListOfRecoPartsM1_SC.size(); + double NbPartsM2=ListOfRecoPartsM2_SC.size(); + double NbRecoPartsSP=0; + + if(NbPartsM1!=0 && NbPartsM2!=0){ + for(int ipart=0;ipart1){ + ListOfRecoPartsM1_SC[ipart].IsRec_SPreco=true; + ListOfRecoPartsM2_SC[jpart].IsRec_SPreco=true; + ListOfRecoParts_SP.push_back(ListOfRecoPartsM1_SC[ipart]); + // std::cout << "+-+-+--+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-PushBack SP Part TSL" << '\n'; + ListOfRecoParts_SP[NbRecoPartsSP].HitList.insert(ListOfRecoParts_SP[NbRecoPartsSP].HitList.end(),ListOfRecoPartsM2_SC[jpart].HitList.begin(),ListOfRecoPartsM2_SC[jpart].HitList.end()); + NbRecoPartsSP++; + } + if(ipart==(NbPartsM1-1)){ + if( !(ListOfRecoPartsM2_SC[jpart].IsRec_SPreco) ){ + ListOfRecoParts_SP.push_back(ListOfRecoPartsM2_SC[jpart]); + // std::cout << "PushBack SP Part" << '\n'; + NbRecoPartsSP++; + } + } + }//END loop on parts from M2 + if( !(ListOfRecoPartsM1_SC[ipart].IsRec_SPreco)){ + ListOfRecoParts_SP.push_back(ListOfRecoPartsM1_SC[ipart]); + // std::cout << "PushBack SP Part" << '\n'; + NbRecoPartsSP++; + } + }//END loop on parts from M1 + }//END IF NbParts!=0 + if(NbPartsM1==0){ + for(int jpart=0;jpartFill(RecoPartClassType); +// break; +// case 2: +// h_SimuTS->Fill(RecoPartClassType); +// break; +// case 3: +// h_SimuOSL->Fill(RecoPartClassType); +// break; +// case 4: +// h_SimuTSL->Fill(RecoPartClassType); +// break; +// }//End Switch +// }//End loop on Reco Hits +// }//End loop on Reco Parts +// +// return; +// } +// //======================================================================================================= +// void DBeaster::PurityTest_Partner(){ +// +// for(int ipart=0;ipartFill(RecoPartClassType); +// break; +// case 2: +// h_SimuTS_Good->Fill(RecoPartClassType); +// break; +// case 3: +// h_SimuOSL_Good->Fill(RecoPartClassType); +// break; +// case 4: +// h_SimuTSL_Good->Fill(RecoPartClassType); +// break; +// }//End Switch +// }else{ +// switch(SimuPartClassTypeihit){ +// case 1: +// h_SimuOS_Bad->Fill(RecoPartClassType); +// break; +// case 2: +// h_SimuTS_Bad->Fill(RecoPartClassType); +// break; +// case 3: +// h_SimuOSL_Bad->Fill(RecoPartClassType); +// break; +// case 4: +// h_SimuTSL_Bad->Fill(RecoPartClassType); +// break; +// }//End Switch +// }//End if Partner +// }//End loop on Reco Hits (ihit) +// }//End loop on Reco Parts +// +// return; +// } +//======================================================================================================= +// +// void DBeaster::Categorie_Momentum(){ +// +// for(int ipart=0;ipartFill(abs(P)); +// break; +// case 2: +// h_MomentumTS->Fill(abs(P)); +// break; +// case 3: +// h_MomentumOSL->Fill(abs(P)); +// break; +// case 4: +// h_MomentumTSL->Fill(abs(P)); +// break; +// }//End switch +// }//End loop on hits +// }//End loop on parts +// +// return; +// } +// //======================================================================================================= +// void DBeaster::Angular_DistributionSimuTS(){ +// double ep=2.27; +// for(int ipart=0;ipartFill(Angle); +// } +// } +// for(int ipart=0;ipartFill(Angle); +// } +// } +// +// return; +// } +// //======================================================================================================= +// void DBeaster::Angular_DistributionSimuTSL(){ +// double ep=2.27; +// int CurrentIhit; +// int CurrentJhit; +// // cout<<"**********************Ladder 1"<< endl; +// for(int ipart=0;ipart0.05){ +// //cout<<"*Fill TSL L"<< endl; +// h_AngularDistributionTslL1->Fill(Angle); +// } +// CurrentIhit++; +// }//End IF Ihit is on M1 +// }//End For ihit +// }//End if TSL +// }//End loop on L1 parts +// // cout<<"**********************END Ladder 1"<< endl; +// // cout<<"**********************Ladder 2"<< endl; +// for(int ipart=0;ipart0.5){ +// h_AngularDistributionTslL2->Fill(Angle); +// } +// }//End IF Ihit is on M1 +// +// }//End For ihit +// }//End if TSL +// }//End loop on L2 parts +// // cout<<"**********************END Ladder 2"<< endl; +// return; +// } +//======================================================================================================= +void DBeaster::FillListOfRecoPartsSPnew(){ + + double NbPartsM1=ListOfRecoPartsM1_SC.size(); + double NbPartsM2=ListOfRecoPartsM2_SC.size(); + double NbRecoPartsSP=0; + + if(NbPartsM1!=0 && NbPartsM2!=0){ + for(int ipart=0;ipart1){ + ListOfRecoPartsM1_SC[ipart].IsRec_SPreco=true; + ListOfRecoPartsM2_SC[jpart].IsRec_SPreco=true; + ListOfRecoParts_SP.push_back(ListOfRecoPartsM1_SC[ipart]); + ListOfRecoParts_SP[NbRecoPartsSP].HitList.insert(ListOfRecoParts_SP[NbRecoPartsSP].HitList.end(),ListOfRecoPartsM2_SC[jpart].HitList.begin(),ListOfRecoPartsM2_SC[jpart].HitList.end()); + NbRecoPartsSP++; + } + if(ipart==(NbPartsM1-1)){ + if( !(ListOfRecoPartsM2_SC[jpart].IsRec_SPreco) ){ + ListOfRecoParts_SP.push_back(ListOfRecoPartsM2_SC[jpart]); + NbRecoPartsSP++; + } + } + }//END loop on parts from M2 + if( !(ListOfRecoPartsM1_SC[ipart].IsRec_SPreco)){ + ListOfRecoParts_SP.push_back(ListOfRecoPartsM1_SC[ipart]); + NbRecoPartsSP++; + } + }//END loop on parts from M1 + }//END IF NbParts!=0 + if(NbPartsM1==0){ + for(int jpart=0;jpart > v; +} +//======================================================================================================= +void DBeaster::FillTslCandidat(){ + int NbTslCandidat=ListOfTslCandidat.size(); + if(NbTslCandidat>1){ + for(int ipart=0;ipartGetPlane(1); + // DR3 PosXYZ = aPlane->GetPosition(); + // std::cout << "--------oooo00OO00oooo-----oooo00OO00oooo" << '\n'; + // std::cout << "PosXYZ -> X = "<< (PosXYZ)(0) + // << "PosXYZ -> Y = "<< (PosXYZ)(1) + // << "PosXYZ -> Z = "<< (PosXYZ)(2)<< '\n'; + // Dprec = aPlane->GetPrecAlignment(); + // std::cout << "------------------------------------------" << '\n'; + // std::cout << "x1000" << '\n'; + // DR3 PosXYZTest((PosXYZ)(0)*1e-3,(PosXYZ)(1)*1e-3,(PosXYZ)(2)*1e-3); + // DR3 HelixPosUVW = Dprec->TransformHitToPlane(PosXYZTest); + // std::cout << "PosUVW -> U = "<< (HelixPosUVW)(0) + // << " PosUVW -> V = "<< (HelixPosUVW)(1) + // << " PosUVW -> W = "<< (HelixPosUVW)(2)<< '\n'; + // std::cout << "------------------------------------------" << '\n'; + // std::cout << "x1" << '\n'; + // DR3 HelixPosUVWbis = Dprec->TransformHitToPlane(PosXYZ); + // std::cout << "PosUVW -> U = "<< (HelixPosUVWbis)(0) + // << " PosUVW -> V = "<< (HelixPosUVWbis)(1) + // << " PosUVW -> W = "<< (HelixPosUVWbis)(2)<< '\n'; + // std::cout << "--------oooo00OO00oooo-----oooo00OO00oooo" << '\n'; + + BuildMcTrueTsFromIpList(iLadder); + // BuildMcTrueTsList(iLadder); + // BuildFakeRecoTsList(iLadder); + return; +} +//======================================================================================================= +void DBeaster::BuildMcTrueTsFromIpList(int iLadder){ + MCInfoHolder = tTracker->GetMCInfoHolder(); + ListOfTsIpCandidat.clear(); + if(iLadder == 1 ){ + int NParts=ListOfSimuPartIdL1.size(); + for(int ipart=0;ipartGetASimParticle(iPartIdx)); + } + } + } + if(iLadder == 2){ + int NParts=ListOfSimuPartIdL2.size(); + for(int ipart=0;ipartGetASimParticle(iPartIdx)); + } + } + } + TVector3 HelixParameter; + DHelixFitter *aHelixFitter; + aHelixFitter=GetHelixFitter(); + TVector3 r1; + TVector3 r2; + TVector2 r1local; + TVector2 r2local; + std::vector ListOfHitsTsIpCandidat; + int NbParts=ListOfTsIpCandidat.size(); + std::cout << "NPART = " <GetASimHit(FirstHitIdx + 0).sensorID), + int(MCInfoHolder->GetASimHit(FirstHitIdx + 1).sensorID), + 0.); + ListOfHitsTsIpCandidat.push_back(r3); + + HelixParameter = aHelixFitter->GetHelixParameter(ListOfHitsTsIpCandidat); + std::cout << "Sensor ID 1 = "<< MCInfoHolder->GetASimHit(FirstHitIdx + 0).sensorID<<" Sensor ID 2 = "<< MCInfoHolder->GetASimHit(FirstHitIdx + 1).sensorID<< '\n'; + std::cout << "Transverse Momentum = " << pt <<"[MeV]"<< '\n'; + std::cout << "Longitudinal Momentum = " << pz <<"[MeV]"<< '\n'; + double TanL = pz/pt; + std::cout << "TanLambda = "<< TanL << '\n'; + // std::cout << "Momentum Hit 0 = " << MCInfoHolder->GetASimHit(FirstHitIdx + 0).MomentumInXYZMeV.Mag() << '\n'; + + std::cout << "Fitted Tansverse Momentum = " << HelixParameter.X()*1000 <<"[MeV]"<< '\n'; + + // std::cout << "Position 1 X = "<< r1.X() << "[mm]" + // << ", Y = "<< r1.Y() << "[mm]" + // << ", Z = "<< r1.Z() << "[mm]" << '\n'; + // std::cout << "Position 2 X = "<< r2.X() << "[mm]" + // << ", Y = "<< r2.Y() << "[mm]" + // << ", Z = "<< r2.Z() << "[mm]" << '\n'; + // std::cout << "Position 1 U = "<< r1local.X() << "[mm]" + // << ", V = "<< r1local.Y() << "[mm]" + // << '\n'; + // std::cout << "Position 2 U = "<< r2local.X() << "[mm]" + // << ", V = "<< r2local.Y() << "[mm]" + // << '\n'; + // DR3 R1Local; + // DR3 R1LabBis; + // DR3 R1Lab(r1.X()*1e3,r1.Y()*1e3,r1.Z()*1e3); + // DR3 R2Local; + // DR3 R2LabBis; + // DR3 R2Lab(r2.X()*1e3,r2.Y()*1e3,r2.Z()*1e3); + // + // aPlane = tTracker->GetPlane(r3.X()+1); + // Dprec = aPlane->GetPrecAlignment(); + // R1Local = Dprec->TransformHitToPlane(R1Lab); + // R1LabBis = Dprec->TransformHitToTracker(R1Local); + // aPlane = tTracker->GetPlane(r3.Y()+1); + // Dprec = aPlane->GetPrecAlignment(); + // R2Local = Dprec->TransformHitToPlane(R2Lab); + // R2LabBis = Dprec->TransformHitToTracker(R2Local); + // + // std::cout << "Test TransformHitToPlane" << '\n'; + // std::cout << "Position 1 U = "<< (R1Local)(0)/1000<< "[mm]" + // << ", V = "<< (R1Local)(1)/1000 << "[mm]" + // << ", W = " << (R1Local)(2)/1000 << '\n'; + // std::cout << "Position 2 U = "<< (R2Local)(0)/1000 << "[mm]" + // << ", V = "<< (R2Local)(1)/1000 << "[mm]" + // << ", W = " << (R2Local)(2)/1000 << '\n'; + // std::cout << "*------ RLab Bis -------*" << '\n'; + // std::cout << "Position 1 X = "<< (R1LabBis)(0) << "[mm]" + // << ", Y = "<< (R1LabBis)(1) << "[mm]" + // << ", Z = "<< (R1LabBis)(2) << "[mm]" << '\n'; + // std::cout << "Position 2 X = "<< (R2LabBis)(0)/1000 << "[mm]" + // << ", Y = "<< (R2LabBis)(1)/1000 << "[mm]" + // << ", Z = "<< (R2LabBis)(2)/1000 << "[mm]" << '\n'; + // } + + } + return; +} +//======================================================================================================= +void DBeaster::BuildMcTrueTsList(int iLadder){ + MCInfoHolder = tTracker->GetMCInfoHolder(); + ListOfTsCandidat.clear(); + if(iLadder == 1 ){ + int NParts=ListOfSimuPartIdL1.size(); + for(int ipart=0;ipartGetASimParticle(iPartIdx)); + } + } + } + if(iLadder == 2){ + int NParts=ListOfSimuPartIdL2.size(); + for(int ipart=0;ipartGetASimParticle(iPartIdx)); + } + } + } + TVector3 HelixParameter; + DHelixFitter *aHelixFitter; + aHelixFitter=GetHelixFitter(); + TVector3 r1; + TVector3 r2; + + std::vector ListOfHitsTsCandidat; + int NbParts=ListOfTsCandidat.size(); + for(int ipart=0;ipartGetASimHit(FirstHitIdx + 0).PosInXYZmm; + r2 = MCInfoHolder->GetASimHit(FirstHitIdx + 1).PosInXYZmm; + // r1=ListOfTsIpCandidat[ipart].HitList[0].hitPositionLabXYZ; + // r2=ListOfTsIpCandidat[ipart].HitList[1].hitPositionLabXYZ; + ListOfHitsTsCandidat.clear(); + ListOfHitsTsCandidat.push_back(r1); + ListOfHitsTsCandidat.push_back(r2); + HelixParameter = aHelixFitter->GetHelixParameter(ListOfHitsTsCandidat); + } + return; +} + +//======================================================================================================= +void DBeaster::BuildFakeRecoTsList(int iLadder){ + ListOfRecoTS.clear(); + ListOfFakeRecoTs.clear(); + MCInfoHolder = tTracker->GetMCInfoHolder(); + if(iLadder == 1){ + int Npart = ListOfBeastRecoParts_L1.size(); + for(int ipart=0;ipartGetASimHit(McHitId).ParticleIdx; + int McClassType = ListOfSimuPartClass[McPartIdx]; + if(McClassType !=2) IsFake = true; + } + if(IsFake) ListOfFakeRecoTs.push_back(ListOfRecoTS[jpart]); + } + + TVector3 HelixParameter; + DHelixFitter *aHelixFitter; + aHelixFitter=GetHelixFitter(); + TVector3 r1; + TVector3 r2; + TVector3 r3; // Contain Sensor Number for both hits + std::vector ListOfHitsFakeRecoTs; + int NbParts=ListOfFakeRecoTs.size(); + for(int ipart=0;ipartGetASimHit(ListOfFakeRecoTs[ipart].HitList[0].McHitId).PosInXYZmm; + r2 = MCInfoHolder->GetASimHit(ListOfFakeRecoTs[ipart].HitList[1].McHitId).PosInXYZmm; + TVector3 r3(MCInfoHolder->GetASimHit(ListOfFakeRecoTs[ipart].HitList[0].McHitId).sensorID, + MCInfoHolder->GetASimHit(ListOfFakeRecoTs[ipart].HitList[1].McHitId).sensorID, + 0.); + // r1=ListOfTsIpCandidat[ipart].HitList[0].hitPositionLabXYZ; + // r2=ListOfTsIpCandidat[ipart].HitList[1].hitPositionLabXYZ; + ListOfHitsFakeRecoTs.clear(); + ListOfHitsFakeRecoTs.push_back(r1); + ListOfHitsFakeRecoTs.push_back(r2); + ListOfHitsFakeRecoTs.push_back(r3); + + HelixParameter = aHelixFitter->GetHelixParameter(ListOfHitsFakeRecoTs); + } + return; +} diff --git a/src/DCut.cxx b/src/DCut.cxx new file mode 100644 index 0000000..a884e27 --- /dev/null +++ b/src/DCut.cxx @@ -0,0 +1,145 @@ +// @(#)maf/dtools:$Name: $:$Id: DCut.cxx,v.2 2005/10/02 18:03:46 sha Exp $ +// Author: ? +// Last Modified: JB 2009/08/30 + + ///////////////////////////////////////////////////////////// + // // + // Class Description of DCut // + // // + //////////////////////////////////////////////////////////// + +#include "DCut.h" +#include "DSetup.h" +#include "DPlane.h" +#include "DR3.h" + + +ClassImp(DCut) // Description of Cuts + +//______________________________________________________________________________ +// +DCut::DCut() +{ +// Default DCut ctor. + +} + +//______________________________________________________________________________ +// +DCut::DCut(DPlane& aPlane) +{ + + // DCut User constructor + // + // Modified by JB, 2009/05/07 to separate STRIPS and PIXELS plane + // Modified by JB, 2009/08/30 to add limits in # pixels and in area of a cluster + // Modified by JB, 2013/08/29 to add noise limits + // Modified by VR, 2014/07/12 calcul of fStripsInClusterArea more coherent with DHit::Analyse + // if ( !aNeighbour->Found() && fPSeed->Distance( *aNeighbour) < fClusterLimit->Length() ... + // Modified by VR, 2014/07/16 Add field ClusterLimitRadius for DHit::Analyse_2_cog() + + fDebugCut = aPlane.GetDebug(); + if (fDebugCut) cout << " -+-+- Defining Cut ..." << endl ; + + fPlaneNumber = aPlane.GetPlaneNumber(); + if (fDebugCut) printf(" for plane number= %d\n",fPlaneNumber); + fc = &aPlane.GetSetup(); + fSeedPulseHeightToNoise = fc->GetPlanePar(fPlaneNumber).ThreshSeedSN; + fNeighbourPulseHeightToNoise = fc->GetPlanePar(fPlaneNumber).ThreshNeighbourSN; + fMaximalNoise = fc->GetPlanePar(fPlaneNumber).MaximalNoise; + fMinimalNoise = fc->GetPlanePar(fPlaneNumber).MinimalNoise; +// fMaximalNoise = 100.; // temporary fixed value, JB 2013/08/29 + if (fDebugCut) { + cout << " fSeedPulseHeightToNoise=" << fSeedPulseHeightToNoise << endl; + cout << " fNeighbourPulseHeightToNoise=" << fNeighbourPulseHeightToNoise << endl; + cout << " fMaximalNoise=" << fMaximalNoise << endl; + } + + fClusterLimit = &fc->GetPlanePar(fPlaneNumber).ClusterLimit; + + DR3 tPitch = fc->GetPlanePar(fPlaneNumber).Pitch; + + if( aPlane.GetAnalysisMode()==1){ // STRIPS + if (fDebugCut) cout << " fClusterLimit=" << (*fClusterLimit)(0) << endl; + fStripsInClusterArea = (Int_t)( (*fClusterLimit)(0) * 2 / tPitch(0)) +1 ; // changed, JB 2012/08/21, was -2 ??? + } + else // PIXELS + { + if (aPlane.GetHitFinder() != 2) + { + if (fDebugCut) cout << " fClusterLimit=" << (*fClusterLimit)(0) << ", " << (*fClusterLimit)(1) << endl; + // slightly modified JB 2009/09/23 + + fStripsInClusterArea = ceil( ((*fClusterLimit)(0)*2./tPitch(0)+1) * ((*fClusterLimit)(1)*2./tPitch(1)+1) ); +// fStripsInClusterArea = (Int_t)( ((*fClusterLimit)(0)*2./tPitch(0)) * ((*fClusterLimit)(1)*2./tPitch(1)) );//VR 2014/07/12 + + if (fDebugCut) cout << " fStripsInClusterArea= " << fStripsInClusterArea << endl; + + fStripsInClusterMin = fc->GetPlanePar(fPlaneNumber).MinNStrips; // JB 2009/08/30 + fStripsInClusterMax = fc->GetPlanePar(fPlaneNumber).MaxNStrips; // JB 2009/08/30 + if (fDebugCut) cout << " # strips in cluster limits = " << fStripsInClusterMin << " to " << fStripsInClusterMax << endl; + + // Check that the Cluster-Limit and the MaxNStrips-Limit match. + // If not, update the MaxNStrips with the Cluster-Limit. + // JB 2012/05/09 + if( fStripsInClusterMax != fStripsInClusterArea ) { + fStripsInClusterMax = fStripsInClusterArea; + printf( "WARNING, your configuration file has incoherent cluster maximum size (%d) directives for plane %d\n ---> It is now fixed to %d strips\n\n", fc->GetPlanePar(fPlaneNumber).MaxNStrips, aPlane.GetPlaneNumber(), fStripsInClusterArea); + } + // Check that the MinNStrips-Limit is coherent + // If not, update the MinNStrips + // VR 2014/07/16 + if( fStripsInClusterMin < 1 ) { + fStripsInClusterMin = 1; + printf( "WARNING, your configuration file has incoherent cluster minimum size (%d) directives for plane %d\n ---> It is now fixed to %d strips\n\n", fc->GetPlanePar(fPlaneNumber).MinNStrips, aPlane.GetPlaneNumber(), fStripsInClusterMin); + } + } + if (aPlane.GetHitFinder() == 2) // VR 2014/07/16 Add the DHit::Analyse_2_cog() with Min/MaxNStrips and ClusterLimitRadius parameters + { + fClusterLimitRadius = fc->GetPlanePar(fPlaneNumber).ClusterLimitRadius; + if (fc->GetPlanePar(fPlaneNumber).MinNStrips < 1) + { + fStripsInClusterMin = 1; + printf( "WARNING, your configuration file has incoherent cluster minimum size (%d) directives for plane %d\n ---> It is now fixed to %d strips\n\n", fc->GetPlanePar(fPlaneNumber).MinNStrips, aPlane.GetPlaneNumber(), fStripsInClusterMin); + } + else fStripsInClusterMin = fc->GetPlanePar(fPlaneNumber).MinNStrips; + if (fc->GetPlanePar(fPlaneNumber).MaxNStrips < 1) + { + fStripsInClusterMax = 100; // to not be a limit + printf( "WARNING, your configuration file has incoherent cluster maximum size (%d) directives for plane %d\n ---> It is now fixed to %d strips to not limit cluster size\n\n", fc->GetPlanePar(fPlaneNumber).MaxNStrips, aPlane.GetPlaneNumber(), fStripsInClusterMax); + } + else fStripsInClusterMax = fc->GetPlanePar(fPlaneNumber).MaxNStrips; + + + + + if (fDebugCut) cout << " # pixels in cluster min = " << fStripsInClusterMin << " and search radius is " << fClusterLimitRadius << endl; + } + } + + + // the threshold on neighbourstrips should depend on the tilting angle between the + // track and the detector plane. + if (fDebugCut) cout << " ... Defining Cut done -+-+- " << endl ; +} + +//______________________________________________________________________________ +// +DCut::~DCut() +{ + // Default DCut destructor +} + +//______________________________________________________________________________ +// +void DCut::SetSeedPulseHeightToNoise(Float_t aPulseHeightToNoise) +{ + fSeedPulseHeightToNoise = aPulseHeightToNoise; +} + +//______________________________________________________________________________ +// +void DCut::SetNeighbourPulseHeightToNoise(Float_t aPulseHeightToNoise) +{ + fNeighbourPulseHeightToNoise = aPulseHeightToNoise; +} diff --git a/src/DEvent.cxx b/src/DEvent.cxx new file mode 100644 index 0000000..d361150 --- /dev/null +++ b/src/DEvent.cxx @@ -0,0 +1,727 @@ +// @(#)maf/dtools:$Name: $:$Id: DEvent.cxx,v.2 2005/10/02 18:03:46 sha Exp $ +// Author: Dirk Meier 98/02/18 +// Last Modified, JB 2009/05/12 +// Last Modified, JB 2009/06/26 +// Last Modified, JB 2009/09/08 +// Last Modified, JB 2010/07/07 to managed list of triggers,... +// Last Modified, SS 2011/08/10 to limit #frames written in TTree +// Last Modified, JB 2013/11/08 DAuthenticHit +// Last Modified, JB 2014/08/29 DTransparentPlane +// Last Modified, JB 2014/12/23 DTransparentPlane + +//////////////////////////////////////////////////////////////// +// Class Description of DEvent // +// // +// Trigger event contains values from detector planes // +// This event is later written to a data summary ".root" file // +// // +//////////////////////////////////////////////////////////////// + + +//*-- Modified : IG +//*-- Copyright: RD42 +//*-- Author : Dirk Meier 98/02/18 +//*KEEP,CopyRight. +/************************************************************************ + * Copyright(c) 1998, RD42@CERN, DiamondTracking. + ***********************************************************************/ + +#include "DEvent.h" +#include "DSetup.h" +#include "DPlane.h" +#include "DHit.h" +#include "DTracker.h" +#include "DTrack.h" +#include "DR3.h" +#include "DStrip.h" +#include "DLine.h" +#include "DCut.h" +#include "DAcq.h" +#include "DGlobalTools.h" + + + ClassImp(DEvent) + ClassImp(DEventHeader) + ClassImp(DAuthenticPlane) + ClassImp(DAuthenticHit) + ClassImp(DTransparentPlane) + + Int_t fDebugEvent=0; // flag for debugging + +//_____________________________________________________________________________ +// + void DEventHeader::Set(const Int_t aNEvent, + const Int_t aNRun, + const Int_t aDate, + const Int_t aTime, + const Int_t aType, + vector *aListOfTriggers, + vector *aListOfFrames, + vector *aListOfTimestamps) +{ + + // Array sizes are limited, but it has no influence on the hits or tracks srored + // the information on the list of #frames, #triggers used in this event is simply lost + // beyond MaxNumberOf (defined in DEvent.h) + + // Modified JB 2010/07/07 to add list of triggers,... + // Modified SS 2011/08/10 to limit lists to array size + + + Ek = aNEvent; + Erunk = aNRun; + Edate = aDate; // YYMMDD + Etime = aTime; // HHMMSS + + // calculate time in seconds relative to start of Month (fMtime) + Int_t tYears; // YY + Int_t tMonths; // MM + Int_t tDays; // DD + Int_t tHours; // HH + Int_t tMinutes; // MM + Int_t tSeconds; // SS + tYears = int( Edate/10000 ); + tMonths = int( (Edate - 10000 * tYears) / 100 ); + tDays = int( (Edate - 10000 * tYears) - 100 * tMonths ); + tHours = int( Etime/10000 ); + tMinutes = int( (Etime - 10000 * tHours) / 100 ); + tSeconds = int( (Etime - 10000 * tHours) - 100 * tMinutes ); + Erelative = tSeconds + 60 * tMinutes + 3600 * tHours + 86400 * tDays; + Etype = aType; + + ENumberOfTriggers = (aListOfTriggers!=NULL)?aListOfTriggers->size():0; + // Mechanism to limit #frames to 50, SS 2011/08/10 + if (ENumberOfTriggers>MaxNumberOf){ + printf("DEvent:Too many (%d) triggers in the event %d, set back to %d\n",ENumberOfTriggers,aNEvent,MaxNumberOf); + ENumberOfTriggers=MaxNumberOf; + } + for( Int_t index=0; indexat(index); + } + ENumberOfFrames = (aListOfFrames!=NULL)?aListOfFrames->size():0; + // Mechanism to limit #frames to 50, SS 2011/08/10 + if (ENumberOfFrames>MaxNumberOf){ +// printf("DEvent:Too many (%d) frames in the event %d, set back to %d\n",ENumberOfFrames,aNEvent,MaxNumberOf); + ENumberOfFrames=MaxNumberOf; + } + for( Int_t index=0; indexat(index); + } + ENumberOfTimestamps = (aListOfTimestamps!=NULL)?aListOfTimestamps->size():0; + // Mechanism to limit #frames to 50, SS 2011/08/10 + if (ENumberOfTimestamps>MaxNumberOf){ +// printf("DEvent:Too many (%d) timestamps in the event %d, set back to %d\n",ENumberOfTimestamps,aNEvent,MaxNumberOf); + ENumberOfTimestamps=MaxNumberOf; + } + for( Int_t index=0; indexat(index); + } + +} + +//_____________________________________________________________________________ +// +void DEventHeader::Clear(const Option_t *){ + + //if(fDebugEvent) printf(" DEventHeader::Clear clearing\n"); + +} + +//_____________________________________________________________________________ +// +void DEventHeader::SetTimeSinceLastEvent(const Int_t aDeltaTime){ + EtimeSinceLastEvent = aDeltaTime; +} + +//_____________________________________________________________________________ +// +void DEventHeader::Print() +{ + + // Modified JB 2010/07/07 to add list of triggers,... + // Modified JB 2011/06/30 correction of printouts + + printf("-------------------- EventHeader ---------------------------------\n"); + printf(" RunNumber %d, EventNumber %d\n",Erunk, Ek); + printf(" Date %d, Time %d \n",Edate,Etime); + printf("# triggers: %d", ENumberOfTriggers); + for( Int_t iTrig=0; iTrigClear(); + fAPlanes->Clear(); + fT1Planes->Clear(); + fAHitsN = 0; + fAPlanesN = 0; + fT1PlanesN = 0; + fTDC = 0.; + +} + +//______________________________________________________________________________ +// +void DEvent::AddAuthenticPlane(DPlane& aPlane, Int_t aNEvent) +{ + TClonesArray &tData = *fAPlanes; + new(tData[fAPlanesN++]) DAuthenticPlane(aPlane, aNEvent); +} + +//______________________________________________________________________________ +// +void DEvent::AddAuthenticHit(DHit& aHit, Int_t aNEvent, DTrack &aTrack) +{ + TClonesArray &tData = *fAHits; + new(tData[fAHitsN++]) DAuthenticHit(aHit, aNEvent, aTrack); +} + + +//______________________________________________________________________________ +// +void DEvent::AddTransparentPlane(DPlane& aPlane, DTrack& aTrack, DHit& aHit, Bool_t hitAssociated, DTracker &aTracker) +{ + + TClonesArray &tData = *fT1Planes; + + new(tData[fT1PlanesN++]) DTransparentPlane(aPlane, aTrack, aHit, hitAssociated, aTracker); + +} + +//______________________________________________________________________________ +// +void DEvent::SetHeader(const Int_t aNEvent, + const Int_t aNRun, + const Int_t aDate, + const Int_t aTime, + const Int_t aType, + std::vector *aListOfTriggers, + std::vector *aListOfFrames, + std::vector *aListOfTimestamps) { + + // Modified JB 2010/07/07 to add list of triggers,... + + fHeader.Set(aNEvent, aNRun, aDate, aTime, aType, + aListOfTriggers, aListOfFrames, aListOfTimestamps); + fEvt = aNEvent; +} + +//_____________________________________________________________________________ +// +void DEvent::SetTimeInterval(const Int_t aDeltaTime) +{ + fHeader.SetTimeSinceLastEvent(aDeltaTime); +} + +//______________________________________________________________________________ +// +void DEvent::SetFrame(const Int_t aFrameNb, const Int_t aLineNb) +{ + + fFrameNb = aFrameNb; + fLineNb = aLineNb; +} + +//______________________________________________________________________________ +// +DAuthenticHit::DAuthenticHit(DHit& aHit, Int_t aNEvent, DTrack& aTrack) : TObject() +{ + // Note that all positions here are in the Plane coord. system + // Modified to get rid of call to DStrip class + // JB, 2009/05/12 + // JB, 2009/06/26 + // JB, 2009/09/08 + // JB, 2013/11/08 Better management of seed strip/pixel information + + //DStrip *tSeed; // JB, 2009/05/12 + Int_t tNeighboursN; + DPlane *tPlane; + DR3 tTrackPos; + + //cout << "DAuthenticHit adding a hit" << endl; +// if(fDebugEvent) printf(" DAuthenticHit::DAuthenticHit adding hit %d (over %d)\n", aHit.GetNumber(), aHit.GetPlane()->GetHitsN()); + if(fDebugEvent) printf(" DAuthenticHit::DAuthenticHit adding hit %d (over %d) with seed %d\n", aHit.GetNumber(), aHit.GetPlane()->GetHitsN(), aHit.GetIndexSeed()); + + Hevt = aNEvent; + Hpk = aHit.GetPlane()->GetPlaneNumber(); + + //tSeed = aHit.GetSeed(); // JB, 2009/05/12 + Hhk = aHit.GetNumber(); + HhN = aHit.GetPlane()->GetHitsN(); +// cout << "Basic counts" << endl; + + if(aHit.GetStripsInCluster() > 0) { + Hsu = aHit.GetSeedU(); + Hsv = aHit.GetSeedV(); // added by JB, 2007 June + } + else { + Hsu = aHit.GetPositionUhit(); + Hsv = aHit.GetPositionVhit(); + } + Hu = aHit.GetPositionUhit(); + Hv = aHit.GetPositionVhit(); + + Hresu = aHit.GetResolutionUhit(); + Hresv = aHit.GetResolutionVhit(); + + HTS = aHit.GetTimestamp(); + + if(aHit.GetStripsInCluster() > 0) { + HuCG = aHit.GetPositionUhitCG(); + HvCG = aHit.GetPositionVhitCG(); // added by JB, 2007 June + HuEta = aHit.GetPositionUhitEta(); + HvEta = aHit.GetPositionVhitEta(); // added by JB, 2007 November + } + else { + HuCG = Hu; + HvCG = Hv; + HuEta = Hu; + HvEta = Hv; + } +// cout << "Positions" << endl; + + tPlane = aHit.GetPlane(); + + HtN = tPlane->GetTracker()->GetTracksN(); +// cout << "# tracks" << HtN << endl; + + if( /*&aTrack*/ HtN>0 ) { // Check that tracking was actually done, condition changed JB 2017/02/04 + Htk = aTrack.GetNumber(); // JB 2009/06/26 + HtHn = aTrack.GetHitsNumber(); // JB 2009/09/08 + tTrackPos = aTrack.Intersection(tPlane); + Htu = tTrackPos(0); + Htv = tTrackPos(1); + HtChi2 = aTrack.GetChiSquare(); + HtChi2u = aTrack.GetChiSquareU(); + HtChi2v = aTrack.GetChiSquareV(); + } +// cout << "Track" << endl; + + if(aHit.GetStripsInCluster() > 0) { + Hqc = aHit.GetClusterPulseSum(); + HsN = aHit.GetSNseed(); // changed to SNRseed, JB 2013/11/08 + HSNc = aHit.GetClusterSignalToNoise(); + //Hsn = tSeed->GetNoise(); // JB, 2009/05/12 + //Hsn = aHit.GetNoise(0); //YV, 15/10/09 + Hsn = aHit.GetSeedNoise(); //JB, 2013/11/08 + + //HsnPulse = tSeed->GetPulseHeight(); // JB, 2009/05/12 + //HsnPulse = aHit.GetPulseHeight(0); // JB, 2009/05/12 + HsnPulse = aHit.GetSeedPulseHeight(); // JB, 2013/11/08 + //HsnIndex = tSeed->GetStripIndex(); // JB, 2009/05/12 + //HsnIndex = aHit.GetIndex(0); // JB, 2009/05/12 + HsnIndex = aHit.GetIndexSeed(); // JB 2013/11/08 + + Hnc = aHit.GetClusterNoiseAverage(); + if(Hsn!=0.0){ + HSNc1 = Hqc/Hsn; + } + //Hsk = tSeed->GetStripIndex(); // JB, 2009/05/12 + Hsk = aHit.GetIndex(0); // JB, 2009/05/12 + } + else { + Hqc = 0.0; + HsN = 0.0; + HSNc = 0.0; + Hsn = 1.0; + + HsnPulse = 0.0; + + double col,row; + tPlane->ComputeStripPosition_UVToColRow(Hu,Hv,col,row); + int index = int(col) + tPlane->GetStripsNu()*int(row); + + HsnIndex = index; + + Hnc = aHit.GetClusterNoiseAverage(); + if(Hsn!=0.0){ + HSNc1 = Hqc/Hsn; + } + Hsk = index; + } +// cout << "Cluster" << endl; + + //tNeighboursN = tSeed->GetNeighbourCount(); // JB, 2009/05/12 + tNeighboursN = aHit.GetStripsInCluster(); // JB, 2009/05/12 + HNNS = tNeighboursN ; // same as HsN + + + for(Int_t i = 0; i<100; i++) + { // change stop condition with max neighbours possible, JB 2009/05/12 + HqM[i]=0 ; + HkM[i]=0 ; + HnM[i]=0; + } + + for(Int_t i=0; iGetPulseHeight(); // JB, 2009/05/12 + //HkM[i] = aHit.GetMinor(i)->GetStripIndex(); + //HnM[i] = aHit.GetMinor(i)->GetNoise(); + HqM[i] = aHit.GetPulseHeight(i); // JB, 2009/05/12 + HkM[i] = aHit.GetIndex(i); + HnM[i] = aHit.GetNoise(i); //YV 21/10/09 + } + + //Hq0 = aHit.GetMinor(0)->GetPulseHeight(); + //Hk0 = aHit.GetMinor(0)->GetStripIndex(); + //Hn0 = aHit.GetMinor(0)->GetNoise(); + + Hq0 = HqM[0]; + Hk0 = HkM[0]; + Hn0 = HnM[0]; + Hq1 = HqM[1]; + Hk1 = HkM[1]; + Hn1 = HnM[1]; + Hq2 = HqM[2]; + Hk2 = HkM[2]; + Hn2 = HnM[2]; + Hq3 = HqM[3]; + Hk3 = HkM[3]; + Hn3 = HnM[3]; + Hq4 = HqM[4]; + Hk4 = HkM[4]; + Hn4 = HnM[4]; + Hq5 = HqM[5]; + Hk5 = HkM[5]; + Hn5 = HnM[5]; + Hq6 = HqM[6]; + Hk6 = HkM[6]; + Hn6 = HnM[6]; + Hq7 = HqM[7]; + Hk7 = HkM[7]; + Hn7 = HnM[7]; + Hq8 = HqM[8]; + Hk8 = HkM[8]; + Hn8 = HnM[8]; + + HqL = aHit.GetPulseHeightLeft(); + HqR = aHit.GetPulseHeightRight(); + HqLoS = aHit.GetPulseHeightLeftOfSeed(); + HqRoS = aHit.GetPulseHeightRightOfSeed(); + HkL = aHit.GetIndexLeft(); + HuL = aHit.GetPositionULeft(); + + HSNneighbour = aHit.GetSNneighbour(); + + //cout << " Hit created with: Hqc=" << Hqc << ", HsN=" << HsN << ", Hsn=" << Hsn << ", HsnPulse=" << HsnPulse << ", Hq1=" << Hq1 << "." << endl; + +} + +//______________________________________________________________________________ +// + +DAuthenticPlane::DAuthenticPlane(DPlane& aPlane, Int_t aNEvent) : TObject() +{ + + // Modified for readout conditional variables, JB 2011/06/17 + + Pevt = aNEvent; + Ppk = aPlane.GetPlaneNumber(); + + if(fDebugEvent) printf(" DAuthenticPlane::DAuthenticPlane adding plane %d with readout %d\n", Ppk, aPlane.GetReadout()); + + PhN = aPlane.GetHitsN(); + PtN = aPlane.GetTracker()->GetTracksN(); // JB 2009/06/26 + + Pt = aPlane.GetThreshold(); + PotN = aPlane.GetOverThresholdN(); + PotQ = aPlane.GetOverThresholdC(); + + PCDSvar =aPlane.GetCDSvariance(); + + if( aPlane.GetReadout() < 100 ) { // for readouts without 0-supression only, JB 2011/06/17 + Pcom1 = aPlane.GetCommonModeRegion(1); + if(Ppk > 1){ // condition changed, JB 2011/06/17 + Pcom2 = aPlane.GetCommonModeRegion(2); + Pcom3 = aPlane.GetCommonModeRegion(3); + Pcom4 = aPlane.GetCommonModeRegion(4); + Pcom5 = aPlane.GetCommonModeRegion(5); + Pcom6 = aPlane.GetCommonModeRegion(6); + } + Int_t Npixels = aPlane.GetStripsN(); + PFq= 0.0; + PFn= 0.0; + PFp= 0.0; + PFr= 0.0; + PFrfr1= 0.0; + PFrfr2= 0.0; + + for(Int_t aPix=0; aPix < Npixels; aPix++){ + PFq+= aPlane.GetPulseHeight(aPix); //CDS - pedestal - common mode. + PFn+= aPlane.GetNoise(aPix); //Noise + PFp+= aPlane.GetPedestal(aPix); //GetCommonMode(aPix); //GetPedestal(aPix); //pedestal + PFr+= aPlane.GetRawValue(aPix); // CDS ? + PFrfr1+= aPlane.GetRawFrame1Value(aPix); // GetRawFrame1Value(aPix); // raw 1 + PFrfr2+= aPlane.GetRawFrame2Value(aPix); // GetRawFrame2Value(aPix); // raw 2 + } + if(Npixels!=0){ + PFq= PFq/float(Npixels); + PFn= PFn/float(Npixels); + PFp= PFp/float(Npixels); + PFr= PFr/float(Npixels); + PFrfr1=PFrfr1/float(Npixels); + PFrfr2=PFrfr2/float(Npixels); + } + + // get a random strip + Int_t mcStrip = (Int_t)(gRandom->Uniform(1.)*Npixels); + if( mcStrip == Npixels ) mcStrip--; + DStrip *aStrip = (DStrip*)aPlane.GetStrip(mcStrip); + Psk = aStrip->GetStripIndex(); + Psq = aStrip->GetPulseHeight(); + Pnq = aStrip->GetNoise(); + Ppq = aStrip->GetPedestal(); + + } // end for readouts without 0-supression only + +} + +//______________________________________________________________________________ +// +DTransparentPlane::DTransparentPlane(DPlane& aPlane, DTrack& aTrack, DTracker &aTracker) : TObject() +{ + + DTransparentPlane( aPlane, aTrack, *(aPlane.GetPrincipalHit()), kFALSE, aTracker); + +} +//______________________________________________________________________________ +// +DTransparentPlane::DTransparentPlane(DPlane& aPlane, DTrack& aTrack, DHit& aHit, Bool_t hitAssociated, DTracker &aTracker) : TObject() +{ + + // Basic storage of a track associated with a hit. + // With this method, the track is not systematically associated to the so called "Principal" hit. + // + // JB, September 2007 + // Modified to get rid of call to DStrip class, JB 2009/05/12 and 2009/06/26 + // Modified to store # hits in the track, JB 2009/09/08 + // Modified for readout conditional variables, JB 2011/06/17 + // Modified to indicate if hit is associated to track or not, JB 2014/08/29 + // Modified to replace track by subtrack if any, JB 2014/12/15 + + TString tPurpose = aPlane.GetPlanePurpose() ; + + Tpk = aPlane.GetPlaneNumber(); + TtN = aPlane.GetTracker()->GetTracksN(); // JB 2009/06/26 + if(fDebugEvent) printf(" DTransparentPlane::DTransparentPlane adding track %d, with plane %d\n", aTrack.GetNumber(), aPlane.GetPlaneNumber()); + + // track information + Ttk = aTrack.GetNumber(); + TtHn = aTrack.GetHitsNumber(); // JB 2009/09/08 + // Consider the subtrack rather than the full track if it exists + DR3 trackPos; + DTrack *aSubTrack; + if( aTracker.GetNPlanesForSubTrack()>1 ) { + aSubTrack = (DTrack*)(aTracker.GetSubTrack( Ttk)); + trackPos = aSubTrack->Intersection(&aPlane); // subtrack position in device frame (uvw) +// DR3 fullTrackPos = aTrack.Intersection(&aPlane); +// printf(" Subtrack %d pos (%.2f, %.2f) versus full track %d pos (%.2f, %.2f)\n", aSubTrack->GetNumber(), trackPos(0), trackPos(1), aTrack.GetNumber(), fullTrackPos(0), fullTrackPos(1)); + } + else { + trackPos = aTrack.Intersection(&aPlane); // track position in device frame (uvw) + } + Tu = trackPos(0); + Tv = trackPos(1); + TDOX = aTrack.GetDeltaOrigineX() ; + TDOY = aTrack.GetDeltaOrigineY() ; + Tx = aTrack.GetLinearFit().GetOrigin()(0); + Ty = aTrack.GetLinearFit().GetOrigin()(1); + Tz = aTrack.GetLinearFit().GetOrigin()(2); + Tdx = aTrack.GetLinearFit().GetSlopeZ()(0); + Tdy = aTrack.GetLinearFit().GetSlopeZ()(1); + Tchi2 = aTrack.GetChiSquare(); + Tchi2u = aTrack.GetChiSquareU(); + Tchi2v = aTrack.GetChiSquareV(); + TvertexU = aTrack.GetVertexX(); // LC 201212/17 + TvertexV = aTrack.GetVertexY(); + TvertexW = aTrack.GetVertexZ(); + + if(fDebugEvent) printf(" DTransparentPlane::DTransparentPlane pos u,v=(%.1f, %.1f), x,y=(%.1f, %.1f), slope=(%.3f, %.3f), chi2=%f\n", Tu, Tv, Tx, Ty, Tdx, Tdy, Tchi2); + + DR3 tSlopeInPlane; + tSlopeInPlane = aPlane.TrackerToPlane( aTrack.GetLinearFit().GetSlopeZ() ); + Tdu = tSlopeInPlane(0); + Tdv = tSlopeInPlane(1); + + //RDM250909 begin initialization + + Tud = 9999.; + Tvd = 9999.; + ThN = 0; + Thk = 0; + TsN = 0; + Tqc = 0; + Tq0 = 0; + //RDM250909 end initialization + + + // Compare position with nearest hit reconstructed + // Hit number is set <0 if hit was used to fit track + if( &aHit ) { // JB 2009/06/26 + if(fDebugEvent) printf(" DTransparentPlane::DTransparentPlane hit pos u,v=(%.1f, %.1f), number %d from %d, with %d strips, charge = %f, qseed = %f\n", aHit.GetPositionUhit(), aHit.GetPositionVhit(), aHit.GetNumber(), aPlane.GetHitsN(), aHit.GetStripsInCluster(), aHit.GetClusterPulseSum(), aHit.GetPulseHeight(0)); + Tud = aHit.GetPositionUhit() - Tu; + Tvd = aHit.GetPositionVhit() - Tv; + ThN = aPlane.GetHitsN(); + Thk = (hitAssociated?-1:1)*aHit.GetNumber(); + TsN = aHit.GetStripsInCluster(); + //This condition corresponds to some MC generated hits where they are generated with a position but with not pixel/strips associated. + // in this case they have a cluster size of 0 pixels/strips + if(aHit.GetStripsInCluster() == 0) Tqc = 0; + else Tqc = aHit.GetClusterPulseSum(); + //Tq0 = aHit.GetSeed()->GetPulseHeight(); // added, JB 2007 Sept + //Tn0 = aHit.GetSeed()->GetNoise(); // added, JB 2007 Sept + if(aHit.GetStripsInCluster() == 0) Tq0 = 0; + else Tq0 = aHit.GetPulseHeight(0); // modified, JB 2009/05/12 + //Tn0 = aHit.GetNoise(0); // modified, JB 2009/05/12 + } + + + // Investigate signal on pixels neighbouring the track impact + // only available for non sparsified data! + if( aPlane.GetReadout() < 100 ) { // for readouts without 0-supression only + + DStrip *tNearest; + DStrip *tNextNeighbour; + DR3 trackPos; + + //DStrip *nl; + //DStrip *nr; + //DStrip *n1; + //DStrip *n2; + //DStrip *no; + Int_t tNeighboursN; + Int_t tIndex[10]; + Float_t tDist[10]; + Float_t tPos[10]; + Float_t tPulseHeight[10]; + + tNearest = aPlane.NearestStrip(trackPos); // bef980830 (trackPosOff); + tNeighboursN = tNearest->GetNeighbourCount(); + Int_t st; + for (st = 0; st < (tNeighboursN < 10 ? tNeighboursN : 10); st++){ + tNextNeighbour = tNearest->GetNeighbour(st); + tPos[st] = tNextNeighbour->DistanceU(trackPos); + tDist[st] = fabs(tPos[st]); + tPulseHeight[st] = tNextNeighbour->GetPulseHeight(); + tIndex[st] = st; + } + + // now order the index set (st) so that tDist is in ascending order, leaves tDist unchanged + + Int_t tN = (tNeighboursN-1) < 9 ? (tNeighboursN-1) : 9; + + DGlobalTools aTool; // JB 2011/07/18 + aTool.OrderIndexAsc(&tIndex[0], &tDist[0], tN); // find tIndex order so that tDist is ascending + + Tq1 = tPulseHeight[tIndex[0]]; + if (tN > 1) Tq2 = tPulseHeight[tIndex[1]]; else Tq2 = 0.; + if (tN > 2) Tq3 = tPulseHeight[tIndex[2]]; else Tq3 = 0.; + if (tN > 3) Tq4 = tPulseHeight[tIndex[3]]; else Tq4 = 0.; + if (tN > 4) Tq5 = tPulseHeight[tIndex[4]]; else Tq5 = 0.; + if (tN > 5) Tq6 = tPulseHeight[tIndex[5]]; else Tq6 = 0.; + if (tN > 6) Tq7 = tPulseHeight[tIndex[6]]; else Tq7 = 0.; + if (tN > 7) Tq8 = tPulseHeight[tIndex[7]]; else Tq8 = 0.; + if (tN > 8) Tq9 = tPulseHeight[tIndex[8]]; else Tq9 = 0.; + + aTool.OrderIndexAsc(&tIndex[0], &tPos[0], tN); // find tIndex order so that tPos is ascending + + if( tNeighboursN>=3 ) { // test added, JB 2012/08/20 + //n1 = tNearest->GetNeighbour(1); + //n2 = tNearest->GetNeighbour(2); + + //if (fabs(n1->DistanceU(trackPos)) < fabs(n2->DistanceU(trackPos)) ) + // no = n1; + //else + // no = n2; + + //if (no->GetPosition()(0) < tNearest->GetPosition()(0)){ + // nl = no; + // nr = tNearest; + //} + //else { + // nl = tNearest; + // nr = no; + //} + } + + Tu1 = tNearest->GetPosition()(0); + Tk1 = tNearest->GetStripIndex(); + + } // end for readouts without 0-supression only + else { + Tu1 = 0; + Tk1 = 0; + } + +} + diff --git a/src/DEventMC.cxx b/src/DEventMC.cxx new file mode 100644 index 0000000..56156db --- /dev/null +++ b/src/DEventMC.cxx @@ -0,0 +1,280 @@ +// @(#)maf/dtools:$Name: $:$Id: DEventMC.cxx,v.2 2016/04/20 17:02:46 sha Exp $ +// Author: Alejandro Perez 2016/04/20 +// Last Modified, AP 2016/04/20 + +////////////////////////////////////////////////////////////////////// +// Class Description of DEventMC // +// // +// Container of the MC truth information when reading a MC n-tuple // +// This info can be used for hit and track truth matching // +// // +////////////////////////////////////////////////////////////////////// + +#include "DEventMC.h" +#include "DSetup.h" +#include "DPlane.h" +#include "DHit.h" +#include "DTracker.h" +#include "DTrack.h" +#include "DR3.h" +#include "DStrip.h" +#include "DLine.h" +#include "DCut.h" +#include "DAcq.h" +#include "DGlobalTools.h" + + +ClassImp(DEvent) + +Int_t fDebugEventMC=0; // flag for debugging +//_____________________________________________________________________________ +// +DEventMC::DEventMC() +{ + + ResetLists(); + + return; + +} +//______________________________________________________________________________ +// +DEventMC::~DEventMC() +{ + + Clear(); + + return; + +} +//______________________________________________________________________________ +// +void DEventMC::Clear(const Option_t *) +{ + + if(fDebugEventMC) cout << " DEventMC::Clear clearing" << endl; + ResetLists(); + + return; + +} +//_____________________________________________________________________________ +// +void DEventMC::ResetLists(void) +{ + + ListOfSimParticles.clear(); + ListOfSimHits.clear(); + ListOfSimPixels.clear(); + + ListOfNonSensitiveSimParticles.clear(); + ListOfNonSensitiveSimHits.clear(); + + return; + +} +//_____________________________________________________________________________ +// +void DEventMC::DoHitTruthMatching(DHit* aHit, int &MCHitID, int &NpixelsMCHitID) +{ + + // This function performs a Truth-matching between the reconstructed hit (aHit) and the actual hit (MC-hit) + // and returns the Id of the hit generating this reconstructed hit. + // The algorithm + // - Loops over the pixels of the aHit object + // - Checks where those pixels come from, i.e. was this pixel from a MC-hit or noise + // - Then counts how many different MC-hit generated pixels in this reconstructed hit + // - Returns the ID of the MC-hit with the highest number of pixels in this reconstructed hit (MCHitID). + // - Returns as well the number of pixels in the reconstructed hit belogning to the MC-hit with ID = MCHitID + + + int NpixelsInCluster = aHit->GetStripsInCluster(); + + if(NpixelsInCluster == 0) { + MCHitID = aHit->GetMCHitID(); + NpixelsMCHitID = 0; + + return; + } + + std::vector MCHitIdxList; + MCHitIdxList.clear(); + for(int ipixInHit=0;ipixInHit < NpixelsInCluster;ipixInHit++) { + MCHitIdxList.push_back((aHit->GetPlane()->GetPixelFromList(aHit->GetIndexInOriginalList(ipixInHit)))->GetPixelMCHitIdx()); + } + + //List of non-repeated + std::vector ReducedMCHitIdxList; + ReducedMCHitIdxList.clear(); + std::vector ReducedMCHitIdxList_Npixels; + ReducedMCHitIdxList_Npixels.clear(); + //Check how many different hit indexes are in this hit + for(int i=0;i N_jjjp1) { + int idx_aux = ReducedMCHitIdxList[jjj]; + ReducedMCHitIdxList[jjj] = ReducedMCHitIdxList[jjj+1]; + ReducedMCHitIdxList[jjj+1] = idx_aux; + + int N_aux = ReducedMCHitIdxList_Npixels[jjj]; + ReducedMCHitIdxList_Npixels[jjj] = ReducedMCHitIdxList_Npixels[jjj+1]; + ReducedMCHitIdxList_Npixels[jjj+1] = N_aux; + } + } + } + + if(NpixelsInCluster == 2 && ReducedMCHitIdxList.size() > 1) { + // If reconstructed hit has only 2 pixels then take as the truth-matched + // one that which is higher than -1 (i.e. coming from a real particle) + for(int iredu=0;iredu MCPartIdxList; + MCPartIdxList.clear(); + for(int ihitInTrk=0;ihitInTrk < aTrack->GetHitsNumber();ihitInTrk++) { + int MCHitID = aTrack->GetHit(ihitInTrk)->GetMCHitID(); + if(MCHitID < 0) MCPartIdxList.push_back(-1); + MCPartIdxList.push_back(GetASimHit(MCHitID).ParticleIdx); + } + + //List of non-repeated + std::vector ReducedMCPartIdxList; + ReducedMCPartIdxList.clear(); + std::vector ReducedMCPartIdxList_NHits; + ReducedMCPartIdxList_NHits.clear(); + //Check how many different MC-particle indexes are in this track + for(int i=0;i N_jjjp1) { + int idx_aux = ReducedMCPartIdxList[jjj]; + ReducedMCPartIdxList[jjj] = ReducedMCPartIdxList[jjj+1]; + ReducedMCPartIdxList[jjj+1] = idx_aux; + + int N_aux = ReducedMCPartIdxList_NHits[jjj]; + ReducedMCPartIdxList_NHits[jjj] = ReducedMCPartIdxList_NHits[jjj+1]; + ReducedMCPartIdxList_NHits[jjj+1] = N_aux; + } + } + } + + if(aTrack->GetHitsNumber() == 2 && ReducedMCPartIdxList.size() > 1) { + // If reconstructed track has only 2 hits then take as the truth-matched + // one that which is higher than -1 (i.e. coming from a real particle) + for(int iredu=0;iredu +#include + +using namespace std; + +ClassImp(DGlobalTools) + +//______________________________________________________________________________ +// +//DGlobalTools *gTool = new DGlobalTools(); +DGlobalTools *DGlobalTools::fgInstance = 0; // returns pointer to global object + +//______________________________________________________________________________ +// +DGlobalTools::DGlobalTools() +{ + + gPI = M_PI; + gEULER = 2.7; + gSpeedOfLight = 3.0; // for test purpose + VetoPixel = NULL; // JB 2012/03/11 + + // Multiple scattering considerations + + fMass["electron"] = 511e-6;// GeV + fCharge["electron"] = 1; + fMass["pion"] = 0.1396; + fCharge["pion"] = 1; + fMass["kaon"] = 0.4937; + fCharge["kaon"] = 1; + fMass["proton"] = 0.9383; + fCharge["proton"] = 1; + fMass["muon"] = 105.66e-6; + fCharge["muon"] = 1; + + fX0["copper"] = 1.43e+4; + fX0["silicon"] = 9.36e+4;//um + fX0["aluminum"] = 8.8900e+4; + fX0["beryllium"] = 35.28e+4; + fX0["epoxy"] = 30.e+4; + fX0["kapton"] = 28.e+4; + fX0["glass"] = 12.30e+4; + fX0["nai"] = 2.59e+4; + fX0["csi"] = 1.86e+4; + fX0["tungsten"] = 0.35e+4; + fX0["iron"] = 1.76e+4; + fX0["water"] = 36.08e+4; + fX0["DryAir"] = 30.39e+7; + fX0["Vacuum"] = 1.00e+20; + fX0["mylar"] = 28.7e+4; + fX0["CarbonFiber"] = 23.7e+4; + + // the following table is taken from Bronstein/Semendjajew, + // "Taschenbuch der Mathematik", 24 Auflage, Harri Deutsch Verlag + + + fProbabilityTest[0] = 0.00; fProbabilityPhiZ[0] = 0.0000; + fProbabilityTest[1] = 0.01; fProbabilityPhiZ[1] = 0.0040; + fProbabilityTest[2] = 0.02; fProbabilityPhiZ[2] = 0.0080; + fProbabilityTest[3] = 0.03; fProbabilityPhiZ[3] = 0.0120; + fProbabilityTest[4] = 0.04; fProbabilityPhiZ[4] = 0.0160; + fProbabilityTest[5] = 0.05; fProbabilityPhiZ[5] = 0.0199; + fProbabilityTest[6] = 0.06; fProbabilityPhiZ[6] = 0.0239; + fProbabilityTest[7] = 0.07; fProbabilityPhiZ[7] = 0.0279; + fProbabilityTest[8] = 0.08; fProbabilityPhiZ[8] = 0.0319; + fProbabilityTest[9] = 0.09; fProbabilityPhiZ[9] = 0.0359; + + fProbabilityTest[10] = 0.10; fProbabilityPhiZ[10] = 0.0398; + fProbabilityTest[11] = 0.11; fProbabilityPhiZ[11] = 0.0438; + fProbabilityTest[12] = 0.12; fProbabilityPhiZ[12] = 0.0478; + fProbabilityTest[13] = 0.13; fProbabilityPhiZ[13] = 0.0517; + fProbabilityTest[14] = 0.14; fProbabilityPhiZ[14] = 0.0557; + fProbabilityTest[15] = 0.15; fProbabilityPhiZ[15] = 0.0596; + fProbabilityTest[16] = 0.16; fProbabilityPhiZ[16] = 0.0636; + fProbabilityTest[17] = 0.17; fProbabilityPhiZ[17] = 0.0675; + fProbabilityTest[18] = 0.18; fProbabilityPhiZ[18] = 0.0714; + fProbabilityTest[19] = 0.19; fProbabilityPhiZ[19] = 0.0753; + + fProbabilityTest[20] = 0.20; fProbabilityPhiZ[20] = 0.0793; + fProbabilityTest[21] = 0.21; fProbabilityPhiZ[21] = 0.0832; + fProbabilityTest[22] = 0.22; fProbabilityPhiZ[22] = 0.0871; + fProbabilityTest[23] = 0.23; fProbabilityPhiZ[23] = 0.0910; + fProbabilityTest[24] = 0.24; fProbabilityPhiZ[24] = 0.0948; + fProbabilityTest[25] = 0.25; fProbabilityPhiZ[25] = 0.0987; + fProbabilityTest[26] = 0.26; fProbabilityPhiZ[26] = 0.1026; + fProbabilityTest[27] = 0.27; fProbabilityPhiZ[27] = 0.1064; + fProbabilityTest[28] = 0.28; fProbabilityPhiZ[28] = 0.1103; + fProbabilityTest[29] = 0.29; fProbabilityPhiZ[29] = 0.1141; + + fProbabilityTest[30] = 0.30; fProbabilityPhiZ[30] = 0.1179; + fProbabilityTest[31] = 0.31; fProbabilityPhiZ[31] = 0.1217; + fProbabilityTest[32] = 0.32; fProbabilityPhiZ[32] = 0.1255; + fProbabilityTest[33] = 0.33; fProbabilityPhiZ[33] = 0.1293; + fProbabilityTest[34] = 0.34; fProbabilityPhiZ[34] = 0.1331; + fProbabilityTest[35] = 0.35; fProbabilityPhiZ[35] = 0.1368; + fProbabilityTest[36] = 0.36; fProbabilityPhiZ[36] = 0.1406; + fProbabilityTest[37] = 0.37; fProbabilityPhiZ[37] = 0.1443; + fProbabilityTest[38] = 0.38; fProbabilityPhiZ[38] = 0.1480; + fProbabilityTest[39] = 0.39; fProbabilityPhiZ[39] = 0.1517; + + fProbabilityTest[40] = 0.40; fProbabilityPhiZ[40] = 0.1554; + fProbabilityTest[41] = 0.41; fProbabilityPhiZ[41] = 0.1591; + fProbabilityTest[42] = 0.42; fProbabilityPhiZ[42] = 0.1628; + fProbabilityTest[43] = 0.43; fProbabilityPhiZ[43] = 0.1664; + fProbabilityTest[44] = 0.44; fProbabilityPhiZ[44] = 0.1700; + fProbabilityTest[45] = 0.45; fProbabilityPhiZ[45] = 0.1736; + fProbabilityTest[46] = 0.46; fProbabilityPhiZ[46] = 0.1772; + fProbabilityTest[47] = 0.47; fProbabilityPhiZ[47] = 0.1808; + fProbabilityTest[48] = 0.48; fProbabilityPhiZ[48] = 0.1844; + fProbabilityTest[49] = 0.49; fProbabilityPhiZ[49] = 0.1879; + + fProbabilityTest[50] = 0.50; fProbabilityPhiZ[50] = 0.1915; + fProbabilityTest[51] = 0.51; fProbabilityPhiZ[51] = 0.1950; + fProbabilityTest[52] = 0.52; fProbabilityPhiZ[52] = 0.1985; + fProbabilityTest[53] = 0.53; fProbabilityPhiZ[53] = 0.2019; + fProbabilityTest[54] = 0.54; fProbabilityPhiZ[54] = 0.2054; + fProbabilityTest[55] = 0.55; fProbabilityPhiZ[55] = 0.2088; + fProbabilityTest[56] = 0.56; fProbabilityPhiZ[56] = 0.2123; + fProbabilityTest[57] = 0.57; fProbabilityPhiZ[57] = 0.2157; + fProbabilityTest[58] = 0.58; fProbabilityPhiZ[58] = 0.2190; + fProbabilityTest[59] = 0.59; fProbabilityPhiZ[59] = 0.2224; + + fProbabilityTest[60] = 0.60; fProbabilityPhiZ[60] = 0.2257; + fProbabilityTest[61] = 0.61; fProbabilityPhiZ[61] = 0.2291; + fProbabilityTest[62] = 0.62; fProbabilityPhiZ[62] = 0.2324; + fProbabilityTest[63] = 0.63; fProbabilityPhiZ[63] = 0.2357; + fProbabilityTest[64] = 0.64; fProbabilityPhiZ[64] = 0.2389; + fProbabilityTest[65] = 0.65; fProbabilityPhiZ[65] = 0.2422; + fProbabilityTest[66] = 0.66; fProbabilityPhiZ[66] = 0.2454; + fProbabilityTest[67] = 0.67; fProbabilityPhiZ[67] = 0.2486; + fProbabilityTest[68] = 0.68; fProbabilityPhiZ[68] = 0.2517; + fProbabilityTest[69] = 0.69; fProbabilityPhiZ[69] = 0.2549; + + fProbabilityTest[70] = 0.70; fProbabilityPhiZ[70] = 0.2580; + fProbabilityTest[71] = 0.71; fProbabilityPhiZ[71] = 0.2611; + fProbabilityTest[72] = 0.72; fProbabilityPhiZ[72] = 0.2642; + fProbabilityTest[73] = 0.73; fProbabilityPhiZ[73] = 0.2673; + fProbabilityTest[74] = 0.74; fProbabilityPhiZ[74] = 0.2703; + fProbabilityTest[75] = 0.75; fProbabilityPhiZ[75] = 0.2734; + fProbabilityTest[76] = 0.76; fProbabilityPhiZ[76] = 0.2764; + fProbabilityTest[77] = 0.77; fProbabilityPhiZ[77] = 0.2794; + fProbabilityTest[78] = 0.78; fProbabilityPhiZ[78] = 0.2823; + fProbabilityTest[79] = 0.79; fProbabilityPhiZ[79] = 0.2852; + + fProbabilityTest[80] = 0.80; fProbabilityPhiZ[80] = 0.2881; + fProbabilityTest[81] = 0.81; fProbabilityPhiZ[81] = 0.2910; + fProbabilityTest[82] = 0.82; fProbabilityPhiZ[82] = 0.2939; + fProbabilityTest[83] = 0.83; fProbabilityPhiZ[83] = 0.2967; + fProbabilityTest[84] = 0.84; fProbabilityPhiZ[84] = 0.2995; + fProbabilityTest[85] = 0.85; fProbabilityPhiZ[85] = 0.3023; + fProbabilityTest[86] = 0.86; fProbabilityPhiZ[86] = 0.3051; + fProbabilityTest[87] = 0.87; fProbabilityPhiZ[87] = 0.3078; + fProbabilityTest[88] = 0.88; fProbabilityPhiZ[88] = 0.3106; + fProbabilityTest[89] = 0.89; fProbabilityPhiZ[89] = 0.3133; + + fProbabilityTest[90] = 0.90; fProbabilityPhiZ[90] = 0.3159; + fProbabilityTest[91] = 0.91; fProbabilityPhiZ[91] = 0.3186; + fProbabilityTest[92] = 0.92; fProbabilityPhiZ[92] = 0.3212; + fProbabilityTest[93] = 0.93; fProbabilityPhiZ[93] = 0.3238; + fProbabilityTest[94] = 0.94; fProbabilityPhiZ[94] = 0.3264; + fProbabilityTest[95] = 0.95; fProbabilityPhiZ[95] = 0.3289; + fProbabilityTest[96] = 0.96; fProbabilityPhiZ[96] = 0.3315; + fProbabilityTest[97] = 0.97; fProbabilityPhiZ[97] = 0.3340; + fProbabilityTest[98] = 0.98; fProbabilityPhiZ[98] = 0.3365; + fProbabilityTest[99] = 0.99; fProbabilityPhiZ[99] = 0.3389; + + fProbabilityTest[100] = 1.00; fProbabilityPhiZ[100] = 0.3413; + fProbabilityTest[101] = 1.01; fProbabilityPhiZ[101] = 0.3438; + fProbabilityTest[102] = 1.02; fProbabilityPhiZ[102] = 0.3461; + fProbabilityTest[103] = 1.03; fProbabilityPhiZ[103] = 0.3485; + fProbabilityTest[104] = 1.04; fProbabilityPhiZ[104] = 0.3508; + fProbabilityTest[105] = 1.05; fProbabilityPhiZ[105] = 0.3531; + fProbabilityTest[106] = 1.06; fProbabilityPhiZ[106] = 0.3554; + fProbabilityTest[107] = 1.07; fProbabilityPhiZ[107] = 0.3577; + fProbabilityTest[108] = 1.08; fProbabilityPhiZ[108] = 0.3599; + fProbabilityTest[109] = 1.09; fProbabilityPhiZ[109] = 0.3621; + + fProbabilityTest[110] = 1.10; fProbabilityPhiZ[110] = 0.3643; + fProbabilityTest[111] = 1.11; fProbabilityPhiZ[111] = 0.3665; + fProbabilityTest[112] = 1.12; fProbabilityPhiZ[112] = 0.3686; + fProbabilityTest[113] = 1.13; fProbabilityPhiZ[113] = 0.3708; + fProbabilityTest[114] = 1.14; fProbabilityPhiZ[114] = 0.3729; + fProbabilityTest[115] = 1.15; fProbabilityPhiZ[115] = 0.3749; + fProbabilityTest[116] = 1.16; fProbabilityPhiZ[116] = 0.3770; + fProbabilityTest[117] = 1.17; fProbabilityPhiZ[117] = 0.3790; + fProbabilityTest[118] = 1.18; fProbabilityPhiZ[118] = 0.3810; + fProbabilityTest[119] = 1.19; fProbabilityPhiZ[119] = 0.3830; + + fProbabilityTest[120] = 1.20; fProbabilityPhiZ[120] = 0.3849; + fProbabilityTest[121] = 1.21; fProbabilityPhiZ[121] = 0.3869; + fProbabilityTest[122] = 1.22; fProbabilityPhiZ[122] = 0.3888; + fProbabilityTest[123] = 1.23; fProbabilityPhiZ[123] = 0.3907; + fProbabilityTest[124] = 1.24; fProbabilityPhiZ[124] = 0.3925; + fProbabilityTest[125] = 1.25; fProbabilityPhiZ[125] = 0.3944; + fProbabilityTest[126] = 1.26; fProbabilityPhiZ[126] = 0.3962; + fProbabilityTest[127] = 1.27; fProbabilityPhiZ[127] = 0.3980; + fProbabilityTest[128] = 1.28; fProbabilityPhiZ[128] = 0.3997; + fProbabilityTest[129] = 1.29; fProbabilityPhiZ[129] = 0.4015; + + fProbabilityTest[130] = 1.30; fProbabilityPhiZ[130] = 0.4032; + fProbabilityTest[131] = 1.31; fProbabilityPhiZ[131] = 0.4049; + fProbabilityTest[132] = 1.32; fProbabilityPhiZ[132] = 0.4066; + fProbabilityTest[133] = 1.33; fProbabilityPhiZ[133] = 0.4082; + fProbabilityTest[134] = 1.34; fProbabilityPhiZ[134] = 0.4099; + fProbabilityTest[135] = 1.35; fProbabilityPhiZ[135] = 0.4115; + fProbabilityTest[136] = 1.36; fProbabilityPhiZ[136] = 0.4131; + fProbabilityTest[137] = 1.37; fProbabilityPhiZ[137] = 0.4147; + fProbabilityTest[138] = 1.38; fProbabilityPhiZ[138] = 0.4162; + fProbabilityTest[139] = 1.39; fProbabilityPhiZ[139] = 0.4177; + + fProbabilityTest[140] = 1.40; fProbabilityPhiZ[140] = 0.4192; + fProbabilityTest[141] = 1.41; fProbabilityPhiZ[141] = 0.4207; + fProbabilityTest[142] = 1.42; fProbabilityPhiZ[142] = 0.4222; + fProbabilityTest[143] = 1.43; fProbabilityPhiZ[143] = 0.4236; + fProbabilityTest[144] = 1.44; fProbabilityPhiZ[144] = 0.4251; + fProbabilityTest[145] = 1.45; fProbabilityPhiZ[145] = 0.4265; + fProbabilityTest[146] = 1.46; fProbabilityPhiZ[146] = 0.4279; + fProbabilityTest[147] = 1.47; fProbabilityPhiZ[147] = 0.4292; + fProbabilityTest[148] = 1.48; fProbabilityPhiZ[148] = 0.4306; + fProbabilityTest[149] = 1.49; fProbabilityPhiZ[149] = 0.4319; + + fProbabilityTest[150] = 1.50; fProbabilityPhiZ[150] = 0.4332; + fProbabilityTest[151] = 1.51; fProbabilityPhiZ[151] = 0.4345; + fProbabilityTest[152] = 1.52; fProbabilityPhiZ[152] = 0.4357; + fProbabilityTest[153] = 1.53; fProbabilityPhiZ[153] = 0.4370; + fProbabilityTest[154] = 1.54; fProbabilityPhiZ[154] = 0.4382; + fProbabilityTest[155] = 1.55; fProbabilityPhiZ[155] = 0.4394; + fProbabilityTest[156] = 1.56; fProbabilityPhiZ[156] = 0.4406; + fProbabilityTest[157] = 1.57; fProbabilityPhiZ[157] = 0.4418; + fProbabilityTest[158] = 1.58; fProbabilityPhiZ[158] = 0.4429; + fProbabilityTest[159] = 1.59; fProbabilityPhiZ[159] = 0.4441; + + fProbabilityTest[160] = 1.60; fProbabilityPhiZ[160] = 0.4452; + fProbabilityTest[161] = 1.61; fProbabilityPhiZ[161] = 0.4463; + fProbabilityTest[162] = 1.62; fProbabilityPhiZ[162] = 0.4474; + fProbabilityTest[163] = 1.63; fProbabilityPhiZ[163] = 0.4484; + fProbabilityTest[164] = 1.64; fProbabilityPhiZ[164] = 0.4495; + fProbabilityTest[165] = 1.65; fProbabilityPhiZ[165] = 0.4505; + fProbabilityTest[166] = 1.66; fProbabilityPhiZ[166] = 0.4515; + fProbabilityTest[167] = 1.67; fProbabilityPhiZ[167] = 0.4525; + fProbabilityTest[168] = 1.68; fProbabilityPhiZ[168] = 0.4535; + fProbabilityTest[169] = 1.69; fProbabilityPhiZ[169] = 0.4545; + + fProbabilityTest[170] = 1.70; fProbabilityPhiZ[170] = 0.4554; + fProbabilityTest[171] = 1.71; fProbabilityPhiZ[171] = 0.4564; + fProbabilityTest[172] = 1.72; fProbabilityPhiZ[172] = 0.4573; + fProbabilityTest[173] = 1.73; fProbabilityPhiZ[173] = 0.4582; + fProbabilityTest[174] = 1.74; fProbabilityPhiZ[174] = 0.4591; + fProbabilityTest[175] = 1.75; fProbabilityPhiZ[175] = 0.4599; + fProbabilityTest[176] = 1.76; fProbabilityPhiZ[176] = 0.4608; + fProbabilityTest[177] = 1.77; fProbabilityPhiZ[177] = 0.4616; + fProbabilityTest[178] = 1.78; fProbabilityPhiZ[178] = 0.4625; + fProbabilityTest[179] = 1.79; fProbabilityPhiZ[179] = 0.4633; + + fProbabilityTest[180] = 1.80; fProbabilityPhiZ[180] = 0.4641; + fProbabilityTest[181] = 1.81; fProbabilityPhiZ[181] = 0.4649; + fProbabilityTest[182] = 1.82; fProbabilityPhiZ[182] = 0.4656; + fProbabilityTest[183] = 1.83; fProbabilityPhiZ[183] = 0.4664; + fProbabilityTest[184] = 1.84; fProbabilityPhiZ[184] = 0.4671; + fProbabilityTest[185] = 1.85; fProbabilityPhiZ[185] = 0.4678; + fProbabilityTest[186] = 1.86; fProbabilityPhiZ[186] = 0.4686; + fProbabilityTest[187] = 1.87; fProbabilityPhiZ[187] = 0.4693; + fProbabilityTest[188] = 1.88; fProbabilityPhiZ[188] = 0.4699; + fProbabilityTest[189] = 1.89; fProbabilityPhiZ[189] = 0.4706; + + fProbabilityTest[190] = 1.90; fProbabilityPhiZ[190] = 0.4713; + fProbabilityTest[191] = 1.91; fProbabilityPhiZ[191] = 0.4719; + fProbabilityTest[192] = 1.92; fProbabilityPhiZ[192] = 0.4726; + fProbabilityTest[193] = 1.93; fProbabilityPhiZ[193] = 0.4732; + fProbabilityTest[194] = 1.94; fProbabilityPhiZ[194] = 0.4738; + fProbabilityTest[195] = 1.95; fProbabilityPhiZ[195] = 0.4744; + fProbabilityTest[196] = 1.96; fProbabilityPhiZ[196] = 0.4750; + fProbabilityTest[197] = 1.97; fProbabilityPhiZ[197] = 0.4756; + fProbabilityTest[198] = 1.98; fProbabilityPhiZ[198] = 0.4761; + fProbabilityTest[199] = 1.99; fProbabilityPhiZ[199] = 0.4767; + + fProbabilityTest[200] = 2.00; fProbabilityPhiZ[200] = 0.4772; + fProbabilityTest[201] = 2.01; fProbabilityPhiZ[201] = 0.4778; + fProbabilityTest[202] = 2.02; fProbabilityPhiZ[202] = 0.4783; + fProbabilityTest[203] = 2.03; fProbabilityPhiZ[203] = 0.4788; + fProbabilityTest[204] = 2.04; fProbabilityPhiZ[204] = 0.4793; + fProbabilityTest[205] = 2.05; fProbabilityPhiZ[205] = 0.4798; + fProbabilityTest[206] = 2.06; fProbabilityPhiZ[206] = 0.4803; + fProbabilityTest[207] = 2.07; fProbabilityPhiZ[207] = 0.4808; + fProbabilityTest[208] = 2.08; fProbabilityPhiZ[208] = 0.4812; + fProbabilityTest[209] = 2.09; fProbabilityPhiZ[209] = 0.4817; + + fProbabilityTest[210] = 2.10; fProbabilityPhiZ[210] = 0.4821; + fProbabilityTest[211] = 2.11; fProbabilityPhiZ[211] = 0.4826; + fProbabilityTest[212] = 2.12; fProbabilityPhiZ[212] = 0.4830; + fProbabilityTest[213] = 2.13; fProbabilityPhiZ[213] = 0.4834; + fProbabilityTest[214] = 2.14; fProbabilityPhiZ[214] = 0.4838; + fProbabilityTest[215] = 2.15; fProbabilityPhiZ[215] = 0.4842; + fProbabilityTest[216] = 2.16; fProbabilityPhiZ[216] = 0.4846; + fProbabilityTest[217] = 2.17; fProbabilityPhiZ[217] = 0.4850; + fProbabilityTest[218] = 2.18; fProbabilityPhiZ[218] = 0.4854; + fProbabilityTest[219] = 2.19; fProbabilityPhiZ[219] = 0.4857; + + fProbabilityTest[220] = 2.20; fProbabilityPhiZ[220] = 0.4860966; + fProbabilityTest[221] = 2.21; fProbabilityPhiZ[221] = 0.4864474; + fProbabilityTest[222] = 2.22; fProbabilityPhiZ[222] = 0.4867906; + fProbabilityTest[223] = 2.23; fProbabilityPhiZ[223] = 0.4871263; + fProbabilityTest[224] = 2.24; fProbabilityPhiZ[224] = 0.4874545; + fProbabilityTest[225] = 2.25; fProbabilityPhiZ[225] = 0.4877755; + fProbabilityTest[226] = 2.26; fProbabilityPhiZ[226] = 0.4880894; + fProbabilityTest[227] = 2.27; fProbabilityPhiZ[227] = 0.4883962; + fProbabilityTest[228] = 2.28; fProbabilityPhiZ[228] = 0.4886962; + fProbabilityTest[229] = 2.29; fProbabilityPhiZ[229] = 0.4889893; + + fProbabilityTest[230] = 2.30; fProbabilityPhiZ[230] = 0.4892759; + fProbabilityTest[231] = 2.31; fProbabilityPhiZ[231] = 0.4895559; + fProbabilityTest[232] = 2.32; fProbabilityPhiZ[232] = 0.4898296; + fProbabilityTest[233] = 2.33; fProbabilityPhiZ[233] = 0.4900969; + fProbabilityTest[234] = 2.34; fProbabilityPhiZ[234] = 0.4903581; + fProbabilityTest[235] = 2.35; fProbabilityPhiZ[235] = 0.4906133; + fProbabilityTest[236] = 2.36; fProbabilityPhiZ[236] = 0.4908625; + fProbabilityTest[237] = 2.37; fProbabilityPhiZ[237] = 0.4911060; + fProbabilityTest[238] = 2.38; fProbabilityPhiZ[238] = 0.4913437; + fProbabilityTest[239] = 2.39; fProbabilityPhiZ[239] = 0.4915758; + + fProbabilityTest[240] = 2.40; fProbabilityPhiZ[240] = 0.4918025; + fProbabilityTest[241] = 2.41; fProbabilityPhiZ[241] = 0.4920237; + fProbabilityTest[242] = 2.42; fProbabilityPhiZ[242] = 0.4922397; + fProbabilityTest[243] = 2.43; fProbabilityPhiZ[243] = 0.4924506; + fProbabilityTest[244] = 2.44; fProbabilityPhiZ[244] = 0.4926564; + fProbabilityTest[245] = 2.45; fProbabilityPhiZ[245] = 0.4928572; + fProbabilityTest[246] = 2.46; fProbabilityPhiZ[246] = 0.4930531; + fProbabilityTest[247] = 2.47; fProbabilityPhiZ[247] = 0.4932443; + fProbabilityTest[248] = 2.48; fProbabilityPhiZ[248] = 0.4934309; + fProbabilityTest[249] = 2.49; fProbabilityPhiZ[249] = 0.4936128; + + fProbabilityTest[250] = 2.50; fProbabilityPhiZ[250] = 0.4937903; + fProbabilityTest[251] = 2.51; fProbabilityPhiZ[251] = 0.4939634; + fProbabilityTest[252] = 2.52; fProbabilityPhiZ[252] = 0.4941323; + fProbabilityTest[253] = 2.53; fProbabilityPhiZ[253] = 0.4942969; + fProbabilityTest[254] = 2.54; fProbabilityPhiZ[254] = 0.4944574; + fProbabilityTest[255] = 2.55; fProbabilityPhiZ[255] = 0.4946139; + fProbabilityTest[256] = 2.56; fProbabilityPhiZ[256] = 0.4947664; + fProbabilityTest[257] = 2.57; fProbabilityPhiZ[257] = 0.4949151; + fProbabilityTest[258] = 2.58; fProbabilityPhiZ[258] = 0.4950600; + fProbabilityTest[259] = 2.59; fProbabilityPhiZ[259] = 0.4952012; + + fProbabilityTest[260] = 2.60; fProbabilityPhiZ[260] = 0.4953388; + fProbabilityTest[261] = 2.61; fProbabilityPhiZ[261] = 0.4954729; + fProbabilityTest[262] = 2.62; fProbabilityPhiZ[262] = 0.4956035; + fProbabilityTest[263] = 2.63; fProbabilityPhiZ[263] = 0.4957308; + fProbabilityTest[264] = 2.64; fProbabilityPhiZ[264] = 0.4958547; + fProbabilityTest[265] = 2.65; fProbabilityPhiZ[265] = 0.4959754; + fProbabilityTest[266] = 2.66; fProbabilityPhiZ[266] = 0.4960930; + fProbabilityTest[267] = 2.67; fProbabilityPhiZ[267] = 0.4962074; + fProbabilityTest[268] = 2.68; fProbabilityPhiZ[268] = 0.4963189; + fProbabilityTest[269] = 2.69; fProbabilityPhiZ[269] = 0.4964274; + + fProbabilityTest[270] = 2.70; fProbabilityPhiZ[270] = 0.4965330; + fProbabilityTest[271] = 2.71; fProbabilityPhiZ[271] = 0.4966358; + fProbabilityTest[272] = 2.72; fProbabilityPhiZ[272] = 0.4967359; + fProbabilityTest[273] = 2.73; fProbabilityPhiZ[273] = 0.4968333; + fProbabilityTest[274] = 2.74; fProbabilityPhiZ[274] = 0.4969280; + fProbabilityTest[275] = 2.75; fProbabilityPhiZ[275] = 0.4970202; + fProbabilityTest[276] = 2.76; fProbabilityPhiZ[276] = 0.4971099; + fProbabilityTest[277] = 2.77; fProbabilityPhiZ[277] = 0.4971972; + fProbabilityTest[278] = 2.78; fProbabilityPhiZ[278] = 0.4972821; + fProbabilityTest[279] = 2.79; fProbabilityPhiZ[279] = 0.4973646; + + fProbabilityTest[280] = 2.80; fProbabilityPhiZ[280] = 0.4974449; + fProbabilityTest[281] = 2.81; fProbabilityPhiZ[281] = 0.4975229; + fProbabilityTest[282] = 2.82; fProbabilityPhiZ[282] = 0.4975988; + fProbabilityTest[283] = 2.83; fProbabilityPhiZ[283] = 0.4976726; + fProbabilityTest[284] = 2.84; fProbabilityPhiZ[284] = 0.4977443; + fProbabilityTest[285] = 2.85; fProbabilityPhiZ[285] = 0.4978140; + fProbabilityTest[286] = 2.86; fProbabilityPhiZ[286] = 0.4978818; + fProbabilityTest[287] = 2.87; fProbabilityPhiZ[287] = 0.4979476; + fProbabilityTest[288] = 2.88; fProbabilityPhiZ[288] = 0.4980116; + fProbabilityTest[289] = 2.89; fProbabilityPhiZ[289] = 0.4980738; + + fProbabilityTest[290] = 2.90; fProbabilityPhiZ[290] = 0.4981342; + fProbabilityTest[291] = 2.91; fProbabilityPhiZ[291] = 0.4981929; + fProbabilityTest[292] = 2.92; fProbabilityPhiZ[292] = 0.4982498; + fProbabilityTest[293] = 2.93; fProbabilityPhiZ[293] = 0.4983052; + fProbabilityTest[294] = 2.94; fProbabilityPhiZ[294] = 0.4983589; + fProbabilityTest[295] = 2.95; fProbabilityPhiZ[295] = 0.4984111; + fProbabilityTest[296] = 2.96; fProbabilityPhiZ[296] = 0.4984618; + fProbabilityTest[297] = 2.97; fProbabilityPhiZ[297] = 0.4985110; + fProbabilityTest[298] = 2.98; fProbabilityPhiZ[298] = 0.4985588; + fProbabilityTest[299] = 2.99; fProbabilityPhiZ[299] = 0.4986051; + + fProbabilityTest[300] = 3.00; fProbabilityPhiZ[300] = 0.4986501; + fProbabilityTest[301] = 3.01; fProbabilityPhiZ[301] = 0.4986938; + fProbabilityTest[302] = 3.02; fProbabilityPhiZ[302] = 0.4987361; + fProbabilityTest[303] = 3.03; fProbabilityPhiZ[303] = 0.4987772; + fProbabilityTest[304] = 3.04; fProbabilityPhiZ[304] = 0.4988171; + fProbabilityTest[305] = 3.05; fProbabilityPhiZ[305] = 0.4988558; + fProbabilityTest[306] = 3.06; fProbabilityPhiZ[306] = 0.4988933; + fProbabilityTest[307] = 3.07; fProbabilityPhiZ[307] = 0.4989297; + fProbabilityTest[308] = 3.08; fProbabilityPhiZ[308] = 0.4989650; + fProbabilityTest[309] = 3.09; fProbabilityPhiZ[309] = 0.4989992; + + fProbabilityTest[310] = 3.10; fProbabilityPhiZ[310] = 0.4990324; + fProbabilityTest[311] = 3.11; fProbabilityPhiZ[311] = 0.4990646; + fProbabilityTest[312] = 3.12; fProbabilityPhiZ[312] = 0.4990957; + fProbabilityTest[313] = 3.13; fProbabilityPhiZ[313] = 0.4991260; + fProbabilityTest[314] = 3.14; fProbabilityPhiZ[314] = 0.4991553; + fProbabilityTest[315] = 3.15; fProbabilityPhiZ[315] = 0.4991836; + fProbabilityTest[316] = 3.16; fProbabilityPhiZ[316] = 0.4992112; + fProbabilityTest[317] = 3.17; fProbabilityPhiZ[317] = 0.4992378; + fProbabilityTest[318] = 3.18; fProbabilityPhiZ[318] = 0.4992636; + fProbabilityTest[319] = 3.19; fProbabilityPhiZ[319] = 0.4992886; + + fProbabilityTest[320] = 3.20; fProbabilityPhiZ[320] = 0.4993129; + fProbabilityTest[321] = 3.21; fProbabilityPhiZ[321] = 0.4993363; + fProbabilityTest[322] = 3.22; fProbabilityPhiZ[322] = 0.4993590; + fProbabilityTest[323] = 3.23; fProbabilityPhiZ[323] = 0.4993810; + fProbabilityTest[324] = 3.24; fProbabilityPhiZ[324] = 0.4994024; + fProbabilityTest[325] = 3.25; fProbabilityPhiZ[325] = 0.4994230; + fProbabilityTest[326] = 3.26; fProbabilityPhiZ[326] = 0.4994429; + fProbabilityTest[327] = 3.27; fProbabilityPhiZ[327] = 0.4994623; + fProbabilityTest[328] = 3.28; fProbabilityPhiZ[328] = 0.4994810; + fProbabilityTest[329] = 3.29; fProbabilityPhiZ[329] = 0.4994991; + + fProbabilityTest[330] = 3.30; fProbabilityPhiZ[330] = 0.4995166; + fProbabilityTest[331] = 3.31; fProbabilityPhiZ[331] = 0.4995335; + fProbabilityTest[332] = 3.32; fProbabilityPhiZ[332] = 0.4995499; + fProbabilityTest[333] = 3.33; fProbabilityPhiZ[333] = 0.4995658; + fProbabilityTest[334] = 3.34; fProbabilityPhiZ[334] = 0.4995811; + fProbabilityTest[335] = 3.35; fProbabilityPhiZ[335] = 0.4995959; + fProbabilityTest[336] = 3.36; fProbabilityPhiZ[336] = 0.4996103; + fProbabilityTest[337] = 3.37; fProbabilityPhiZ[337] = 0.4996242; + fProbabilityTest[338] = 3.38; fProbabilityPhiZ[338] = 0.4996376; + fProbabilityTest[339] = 3.39; fProbabilityPhiZ[339] = 0.4996505; + + fProbabilityTest[340] = 3.40; fProbabilityPhiZ[340] = 0.4996631; + fProbabilityTest[341] = 3.41; fProbabilityPhiZ[341] = 0.4996752; + fProbabilityTest[342] = 3.42; fProbabilityPhiZ[342] = 0.4996869; + fProbabilityTest[343] = 3.43; fProbabilityPhiZ[343] = 0.4997982; + fProbabilityTest[344] = 3.44; fProbabilityPhiZ[344] = 0.4997091; + fProbabilityTest[345] = 3.45; fProbabilityPhiZ[345] = 0.4997197; + fProbabilityTest[346] = 3.46; fProbabilityPhiZ[346] = 0.4997299; + fProbabilityTest[347] = 3.47; fProbabilityPhiZ[347] = 0.4997398; + fProbabilityTest[348] = 3.48; fProbabilityPhiZ[348] = 0.4997493; + fProbabilityTest[349] = 3.49; fProbabilityPhiZ[349] = 0.4997585; + + fProbabilityTest[350] = 3.50; fProbabilityPhiZ[350] = 0.4997674; + fProbabilityTest[351] = 3.51; fProbabilityPhiZ[351] = 0.4997759; + fProbabilityTest[352] = 3.52; fProbabilityPhiZ[352] = 0.4997842; + fProbabilityTest[353] = 3.53; fProbabilityPhiZ[353] = 0.4997922; + fProbabilityTest[354] = 3.54; fProbabilityPhiZ[354] = 0.4998999; + fProbabilityTest[355] = 3.55; fProbabilityPhiZ[355] = 0.4998074; + fProbabilityTest[356] = 3.56; fProbabilityPhiZ[356] = 0.4998146; + fProbabilityTest[357] = 3.57; fProbabilityPhiZ[357] = 0.4998215; + fProbabilityTest[358] = 3.58; fProbabilityPhiZ[358] = 0.4998282; + fProbabilityTest[359] = 3.59; fProbabilityPhiZ[359] = 0.4998347; + + fProbabilityTest[360] = 3.60; fProbabilityPhiZ[360] = 0.4998409; + fProbabilityTest[361] = 3.61; fProbabilityPhiZ[361] = 0.4998469; + fProbabilityTest[362] = 3.62; fProbabilityPhiZ[362] = 0.4998527; + fProbabilityTest[363] = 3.63; fProbabilityPhiZ[363] = 0.4998583; + fProbabilityTest[364] = 3.64; fProbabilityPhiZ[364] = 0.4998637; + fProbabilityTest[365] = 3.65; fProbabilityPhiZ[365] = 0.4998689; + fProbabilityTest[366] = 3.66; fProbabilityPhiZ[366] = 0.4998739; + fProbabilityTest[367] = 3.67; fProbabilityPhiZ[367] = 0.4998787; + fProbabilityTest[368] = 3.68; fProbabilityPhiZ[368] = 0.4998834; + fProbabilityTest[369] = 3.69; fProbabilityPhiZ[369] = 0.4998879; + + fProbabilityTest[370] = 3.70; fProbabilityPhiZ[370] = 0.4998922; + fProbabilityTest[371] = 3.71; fProbabilityPhiZ[371] = 0.4999964; + fProbabilityTest[372] = 3.72; fProbabilityPhiZ[372] = 0.4999004; + fProbabilityTest[373] = 3.73; fProbabilityPhiZ[373] = 0.4999043; + fProbabilityTest[374] = 3.74; fProbabilityPhiZ[374] = 0.4999080; + fProbabilityTest[375] = 3.75; fProbabilityPhiZ[375] = 0.4999116; + fProbabilityTest[376] = 3.76; fProbabilityPhiZ[376] = 0.4999150; + fProbabilityTest[377] = 3.77; fProbabilityPhiZ[377] = 0.4999184; + fProbabilityTest[378] = 3.78; fProbabilityPhiZ[378] = 0.4999216; + fProbabilityTest[379] = 3.79; fProbabilityPhiZ[379] = 0.4999247; + + fProbabilityTest[380] = 3.80; fProbabilityPhiZ[380] = 0.4999276; + fProbabilityTest[381] = 3.81; fProbabilityPhiZ[381] = 0.4999305; + fProbabilityTest[382] = 3.82; fProbabilityPhiZ[382] = 0.4999333; + fProbabilityTest[383] = 3.83; fProbabilityPhiZ[383] = 0.4999359; + fProbabilityTest[384] = 3.84; fProbabilityPhiZ[384] = 0.4999385; + fProbabilityTest[385] = 3.85; fProbabilityPhiZ[385] = 0.4999409; + fProbabilityTest[386] = 3.86; fProbabilityPhiZ[386] = 0.4999433; + fProbabilityTest[387] = 3.87; fProbabilityPhiZ[387] = 0.4999456; + fProbabilityTest[388] = 3.88; fProbabilityPhiZ[388] = 0.4999478; + fProbabilityTest[389] = 3.89; fProbabilityPhiZ[389] = 0.4999499; + + fProbabilityTest[390] = 3.90; fProbabilityPhiZ[390] = 0.4999519; + fProbabilityTest[391] = 3.91; fProbabilityPhiZ[391] = 0.4999539; + fProbabilityTest[392] = 3.92; fProbabilityPhiZ[392] = 0.4999557; + fProbabilityTest[393] = 3.93; fProbabilityPhiZ[393] = 0.4999575; + fProbabilityTest[394] = 3.94; fProbabilityPhiZ[394] = 0.4999593; + fProbabilityTest[395] = 3.95; fProbabilityPhiZ[395] = 0.4999609; + fProbabilityTest[396] = 3.96; fProbabilityPhiZ[396] = 0.4999625; + fProbabilityTest[397] = 3.97; fProbabilityPhiZ[397] = 0.4999641; + fProbabilityTest[398] = 3.98; fProbabilityPhiZ[398] = 0.4999655; + fProbabilityTest[399] = 3.99; fProbabilityPhiZ[399] = 0.4999670; + + fProbabilityTest[400] = 4.00; fProbabilityPhiZ[400] = 0.4999683; + fProbabilityTest[401] = 4.01; fProbabilityPhiZ[401] = 0.4999696; + fProbabilityTest[402] = 4.02; fProbabilityPhiZ[402] = 0.4999709; + fProbabilityTest[403] = 4.03; fProbabilityPhiZ[403] = 0.4999721; + fProbabilityTest[404] = 4.04; fProbabilityPhiZ[404] = 0.4999733; + fProbabilityTest[405] = 4.05; fProbabilityPhiZ[405] = 0.4999744; + fProbabilityTest[406] = 4.06; fProbabilityPhiZ[406] = 0.4999755; + fProbabilityTest[407] = 4.07; fProbabilityPhiZ[407] = 0.4999765; + fProbabilityTest[408] = 4.08; fProbabilityPhiZ[408] = 0.4999775; + fProbabilityTest[409] = 4.09; fProbabilityPhiZ[409] = 0.4999784; + + fProbabilityTest[410] = 4.10; fProbabilityPhiZ[410] = 0.4999793; + fProbabilityTest[411] = 4.11; fProbabilityPhiZ[411] = 0.4999802; + fProbabilityTest[412] = 4.12; fProbabilityPhiZ[412] = 0.4999811; + fProbabilityTest[413] = 4.13; fProbabilityPhiZ[413] = 0.4999819; + fProbabilityTest[414] = 4.14; fProbabilityPhiZ[414] = 0.4999826; + fProbabilityTest[415] = 4.15; fProbabilityPhiZ[415] = 0.4999834; + fProbabilityTest[416] = 4.16; fProbabilityPhiZ[416] = 0.4999841; + fProbabilityTest[417] = 4.17; fProbabilityPhiZ[417] = 0.4999848; + fProbabilityTest[418] = 4.18; fProbabilityPhiZ[418] = 0.4999854; + fProbabilityTest[419] = 4.19; fProbabilityPhiZ[419] = 0.4999861; + + fProbabilityTest[420] = 4.20; fProbabilityPhiZ[420] = 0.4999867; + fProbabilityTest[421] = 4.21; fProbabilityPhiZ[421] = 0.4999872; + fProbabilityTest[422] = 4.22; fProbabilityPhiZ[422] = 0.4999878; + fProbabilityTest[423] = 4.23; fProbabilityPhiZ[423] = 0.4999883; + fProbabilityTest[424] = 4.24; fProbabilityPhiZ[424] = 0.4999888; + fProbabilityTest[425] = 4.25; fProbabilityPhiZ[425] = 0.4999893; + fProbabilityTest[426] = 4.26; fProbabilityPhiZ[426] = 0.4999898; + fProbabilityTest[427] = 4.27; fProbabilityPhiZ[427] = 0.4999902; + fProbabilityTest[428] = 4.28; fProbabilityPhiZ[428] = 0.4999907; + fProbabilityTest[429] = 4.29; fProbabilityPhiZ[429] = 0.4999911; + + fProbabilityTest[430] = 4.30; fProbabilityPhiZ[430] = 0.4999915; + fProbabilityTest[431] = 4.31; fProbabilityPhiZ[431] = 0.4999918; + fProbabilityTest[432] = 4.32; fProbabilityPhiZ[432] = 0.4999922; + fProbabilityTest[433] = 4.33; fProbabilityPhiZ[433] = 0.4999925; + fProbabilityTest[434] = 4.34; fProbabilityPhiZ[434] = 0.4999929; + fProbabilityTest[435] = 4.35; fProbabilityPhiZ[435] = 0.4999932; + fProbabilityTest[436] = 4.36; fProbabilityPhiZ[436] = 0.4999935; + fProbabilityTest[437] = 4.37; fProbabilityPhiZ[437] = 0.4999938; + fProbabilityTest[438] = 4.38; fProbabilityPhiZ[438] = 0.4999941; + fProbabilityTest[439] = 4.39; fProbabilityPhiZ[439] = 0.4999943; + + fProbabilityTest[440] = 4.40; fProbabilityPhiZ[440] = 0.4999946; + fProbabilityTest[441] = 4.41; fProbabilityPhiZ[441] = 0.4999948; + fProbabilityTest[442] = 4.42; fProbabilityPhiZ[442] = 0.4999951; + fProbabilityTest[443] = 4.43; fProbabilityPhiZ[443] = 0.4999953; + fProbabilityTest[444] = 4.44; fProbabilityPhiZ[444] = 0.4999955; + fProbabilityTest[445] = 4.45; fProbabilityPhiZ[445] = 0.4999957; + fProbabilityTest[446] = 4.46; fProbabilityPhiZ[446] = 0.4999959; + fProbabilityTest[447] = 4.47; fProbabilityPhiZ[447] = 0.4999961; + fProbabilityTest[448] = 4.48; fProbabilityPhiZ[448] = 0.4999963; + fProbabilityTest[449] = 4.49; fProbabilityPhiZ[449] = 0.4999964; + + fProbabilityTest[450] = 4.50; fProbabilityPhiZ[450] = 0.4999966; + fProbabilityTest[451] = 4.51; fProbabilityPhiZ[451] = 0.4999968; + fProbabilityTest[452] = 4.52; fProbabilityPhiZ[452] = 0.4999969; + fProbabilityTest[453] = 4.53; fProbabilityPhiZ[453] = 0.4999971; + fProbabilityTest[454] = 4.54; fProbabilityPhiZ[454] = 0.4999972; + fProbabilityTest[455] = 4.55; fProbabilityPhiZ[455] = 0.4999973; + fProbabilityTest[456] = 4.56; fProbabilityPhiZ[456] = 0.4999974; + fProbabilityTest[457] = 4.57; fProbabilityPhiZ[457] = 0.4999976; + fProbabilityTest[458] = 4.58; fProbabilityPhiZ[458] = 0.4999977; + fProbabilityTest[459] = 4.59; fProbabilityPhiZ[459] = 0.4999978; + + + // table to lookup probabilities from chi-square values at given degree of freedom + + fChi2Probability[0] = 0.99; + fChi2Probability[1] = 0.98; + fChi2Probability[2] = 0.95; + fChi2Probability[3] = 0.90; + fChi2Probability[4] = 0.80; + fChi2Probability[5] = 0.70; + fChi2Probability[6] = 0.50; + fChi2Probability[7] = 0.30; + fChi2Probability[8] = 0.20; + fChi2Probability[9] = 0.10; + fChi2Probability[10] = 0.05; + fChi2Probability[11] = 0.02; + fChi2Probability[12] = 0.01; + fChi2Probability[13] = 0.005; + fChi2Probability[14] = 0.002; + fChi2Probability[15] = 0.001; + + // the following table is taken from Bronstein/Semendjajew, + // "Taschenbuch der Mathematik", 24 Auflage, Harri Deutsch Verlag + // 1.1.2.10 Obere 100alpha-prozentige Werte Xhi2alpha der Chi2-Verteilung (s.5.2.3.) + + // Chi2[DegreeOfFreedom-1][pBin]; + fChi2[0][0] = 0.00016; fChi2[0][1] = 0.0006; fChi2[0][2] = 0.0039; fChi2[0][3] = 0.016; + fChi2[0][4] = 0.064 ; fChi2[0][5] = 0.148 ; fChi2[0][6] = 0.455 ; fChi2[0][7] = 1.07 ; + fChi2[0][8] = 1.64 ; fChi2[0][9] = 2.7 ; fChi2[0][10] = 3.8 ; fChi2[0][11] = 5.4 ; + fChi2[0][12] = 6.6 ; fChi2[0][13] = 7.9 ; fChi2[0][14] = 9.5 ; fChi2[0][15] = 10.83; + + fChi2[1][0] = 0.020; fChi2[1][1] = 0.040; fChi2[1][2] = 0.103; fChi2[1][3] = 0.211; + fChi2[1][4] = 0.446; fChi2[1][5] = 0.713; fChi2[1][6] = 1.386; fChi2[1][7] = 2.41 ; + fChi2[1][8] = 3.22 ; fChi2[1][9] = 4.6 ; fChi2[1][10] = 6.0 ; fChi2[1][11] = 7.8 ; + fChi2[1][12] = 9.2 ; fChi2[1][13] = 10.6 ; fChi2[1][14] = 12.4 ; fChi2[1][15] = 13.8 ; + + fChi2[2][0] = 0.115; fChi2[2][1] = 0.185; fChi2[2][2] = 0.352; fChi2[2][3] = 0.584; + fChi2[2][4] = 1.005; fChi2[2][5] = 1.424; fChi2[2][6] = 2.366; fChi2[2][7] = 3.67 ; + fChi2[2][8] = 4.64 ; fChi2[2][9] = 6.3 ; fChi2[2][10] = 7.8 ; fChi2[2][11] = 9.8 ; + fChi2[2][12] = 11.3 ; fChi2[2][13] = 12.8 ; fChi2[2][14] = 14.8 ; fChi2[2][15] = 16.3 ; + + fChi2[3][0] = 0.30; fChi2[3][1] = 0.43; fChi2[3][2] = 0.71; fChi2[3][3] = 1.06; + fChi2[3][4] = 1.65; fChi2[3][5] = 2.19; fChi2[3][6] = 3.36; fChi2[3][7] = 4.9 ; + fChi2[3][8] = 6.0 ; fChi2[3][9] = 7.8 ; fChi2[3][10] = 9.5 ; fChi2[3][11] = 11.7; + fChi2[3][12] = 13.3; fChi2[3][13] = 14.9; fChi2[3][14] = 16.9; fChi2[3][15] = 18.5; + + fChi2[4][0] = 0.55; fChi2[4][1] = 0.75; fChi2[4][2] = 1.14; fChi2[4][3] = 1.61; + fChi2[4][4] = 2.34; fChi2[4][5] = 3.00; fChi2[4][6] = 4.35; fChi2[4][7] = 6.1 ; + fChi2[4][8] = 7.3 ; fChi2[4][9] = 9.2 ; fChi2[4][10] = 11.1; fChi2[4][11] = 13.4; + fChi2[4][12] = 15.1; fChi2[4][13] = 16.8; fChi2[4][14] = 18.9; fChi2[4][15] = 20.5; + + fChi2[5][0] = 0.87; fChi2[5][1] = 1.13; fChi2[5][2] = 1.63; fChi2[5][3] = 2.20; + fChi2[5][4] = 3.07; fChi2[5][5] = 3.83; fChi2[5][6] = 5.38; fChi2[5][7] = 7.2 ; + fChi2[5][8] = 8.6 ; fChi2[5][9] = 10.6; fChi2[5][10] = 12.6; fChi2[5][11] = 15.0; + fChi2[5][12] = 16.8; fChi2[5][13] = 18.5; fChi2[5][14] = 20.7; fChi2[5][15] = 22.5; + + fChi2[6][0] = 1.24; fChi2[6][1] = 1.56; fChi2[6][2] = 2.17; fChi2[6][3] = 2.83; + fChi2[6][4] = 3.82; fChi2[6][5] = 4.67; fChi2[6][6] = 6.35; fChi2[6][7] = 8.4; + fChi2[6][8] = 9.8; fChi2[6][9] = 12.0; fChi2[6][10] = 14.1; fChi2[6][11] = 16.6; + fChi2[6][12] = 18.5; fChi2[6][13] = 20.3; fChi2[6][14] = 22.6; fChi2[6][15] = 24.3; + + fChi2[7][0] = 1.65; fChi2[7][1] = 2.03; fChi2[7][2] = 2.73; fChi2[7][3] = 3.49; + fChi2[7][4] = 4.59; fChi2[7][5] = 5.53; fChi2[7][6] = 7.34; fChi2[7][7] = 9.5; + fChi2[7][8] = 11.0; fChi2[7][9] = 13.4; fChi2[7][10] = 15.5; fChi2[7][11] = 18.2; + fChi2[7][12] = 20.1; fChi2[7][13] = 22.0; fChi2[7][14] = 24.3; fChi2[7][15] = 26.1; + + fChi2[8][0] = 2.09; fChi2[8][1] = 2.53; fChi2[8][2] = 3.32; fChi2[8][3] = 4.17; + fChi2[8][4] = 5.38; fChi2[8][5] = 6.39; fChi2[8][6] = 8.34; fChi2[8][7] = 10.7; + fChi2[8][8] = 12.2; fChi2[8][9] = 14.7; fChi2[8][10] = 16.9; fChi2[8][11] = 19.7; + fChi2[8][12] = 21.7; fChi2[8][13] = 23.6; fChi2[8][14] = 26.1; fChi2[8][15] = 27.9; + + fChi2[9][0] = 2.56; fChi2[9][1] = 3.06; fChi2[9][2] = 3.94; fChi2[9][3] = 4.86; + fChi2[9][4] = 6.18; fChi2[9][5] = 7.27; fChi2[9][6] = 9.34; fChi2[9][7] = 11.8; + fChi2[9][8] = 13.4; fChi2[9][9] = 16.0; fChi2[9][10] = 18.3; fChi2[9][11] = 21.2; + fChi2[9][12] = 23.2; fChi2[9][13] = 25.2; fChi2[9][14] = 27.7; fChi2[9][15] = 29.6; + + fChi2[10][0] = 3.1 ; fChi2[10][1] = 3.6 ; fChi2[10][2] = 4.6 ; fChi2[10][3] = 5.6 ; + fChi2[10][4] = 7.0 ; fChi2[10][5] = 8.1 ; fChi2[10][6] = 10.3; fChi2[10][7] = 12.9; + fChi2[10][8] = 14.6; fChi2[10][9] = 17.3; fChi2[10][10] = 19.7; fChi2[10][11] = 22.6; + fChi2[10][12] = 24.7; fChi2[10][13] = 26.8; fChi2[10][14] = 29.4; fChi2[10][15] = 31.3; + + fChi2[11][0] = 3.6 ; fChi2[11][1] = 4.2 ; fChi2[11][2] = 5.2 ; fChi2[11][3] = 6.3 ; + fChi2[11][4] = 7.8 ; fChi2[11][5] = 9.0 ; fChi2[11][6] = 11.3; fChi2[11][7] = 14.0; + fChi2[11][8] = 15.8; fChi2[11][9] = 18.5; fChi2[11][10] = 21.0; fChi2[11][11] = 24.1; + fChi2[11][12] = 26.2; fChi2[11][13] = 28.3; fChi2[11][14] = 30.9; fChi2[11][15] = 32.9; + + fChi2[12][0] = 4.1 ; fChi2[12][1] = 4.8 ; fChi2[12][2] = 5.9 ; fChi2[12][3] = 7.0 ; + fChi2[12][4] = 8.6 ; fChi2[12][5] = 9.9 ; fChi2[12][6] = 12.3; fChi2[12][7] = 15.1; + fChi2[12][8] = 17.0; fChi2[12][9] = 19.8; fChi2[12][10] = 22.4; fChi2[12][11] = 25.5; + fChi2[12][12] = 27.7; fChi2[12][13] = 29.8; fChi2[12][14] = 32.5; fChi2[12][15] = 34.5; + + fChi2[13][0] = 4.7 ; fChi2[13][1] = 5.4 ; fChi2[13][2] = 6.6 ; fChi2[13][3] = 7.8 ; + fChi2[13][4] = 9.5 ; fChi2[13][5] = 10.8; fChi2[13][6] = 13.3; fChi2[13][7] = 16.2; + fChi2[13][8] = 18.2; fChi2[13][9] = 21.1; fChi2[13][10] = 23.7; fChi2[13][11] = 26.9; + fChi2[13][12] = 29.1; fChi2[13][13] = 31.3; fChi2[13][14] = 34.0; fChi2[13][15] = 36.1; + + fChi2[14][0] = 5.2 ; fChi2[14][1] = 6.0 ; fChi2[14][2] = 7.3 ; fChi2[14][3] = 8.5 ; + fChi2[14][4] = 10.3; fChi2[14][5] = 11.7; fChi2[14][6] = 14.3; fChi2[14][7] = 17.3; + fChi2[14][8] = 19.3; fChi2[14][9] = 22.3; fChi2[14][10] = 25.0; fChi2[14][11] = 28.3; + fChi2[14][12] = 30.6; fChi2[14][13] = 32.8; fChi2[14][14] = 35.6; fChi2[14][15] = 37.7; + + fChi2[15][0] = 5.8 ; fChi2[15][1] = 6.6 ; fChi2[15][2] = 8.0 ; fChi2[15][3] = 9.3 ; + fChi2[15][4] = 11.2; fChi2[15][5] = 12.6; fChi2[15][6] = 15.3; fChi2[15][7] = 18.4; + fChi2[15][8] = 20.5; fChi2[15][9] = 23.5; fChi2[15][10] = 26.3; fChi2[15][11] = 29.6; + fChi2[15][12] = 32.0; fChi2[15][13] = 34.3; fChi2[15][14] = 37.1; fChi2[15][15] = 39.3; + + fChi2[16][0] = 6.4 ; fChi2[16][1] = 7.3 ; fChi2[16][2] = 8.7 ; fChi2[16][3] = 10.1; + fChi2[16][4] = 12.0; fChi2[16][5] = 13.5; fChi2[16][6] = 16.3; fChi2[16][7] = 19.5; + fChi2[16][8] = 21.6; fChi2[16][9] = 24.8; fChi2[16][10] = 27.6; fChi2[16][11] = 31.0; + fChi2[16][12] = 33.4; fChi2[16][13] = 35.7; fChi2[16][14] = 38.6; fChi2[16][15] = 40.8; + + fChi2[17][0] = 7.0 ; fChi2[17][1] = 7.9 ; fChi2[17][2] = 9.4 ; fChi2[17][3] = 10.9; + fChi2[17][4] = 12.9; fChi2[17][5] = 14.4; fChi2[17][6] = 17.3; fChi2[17][7] = 20.6; + fChi2[17][8] = 22.8; fChi2[17][9] = 26.0; fChi2[17][10] = 28.9; fChi2[17][11] = 32.3; + fChi2[17][12] = 34.8; fChi2[17][13] = 37.2; fChi2[17][14] = 40.1; fChi2[17][15] = 42.3; + + fChi2[18][0] = 7.6 ; fChi2[18][1] = 8.6 ; fChi2[18][2] = 10.1; fChi2[18][3] = 11.7; + fChi2[18][4] = 13.7; fChi2[18][5] = 15.4; fChi2[18][6] = 18.3; fChi2[18][7] = 21.7; + fChi2[18][8] = 23.9; fChi2[18][9] = 27.2; fChi2[18][10] = 30.1; fChi2[18][11] = 33.7; + fChi2[18][12] = 36.2; fChi2[18][13] = 38.6; fChi2[18][14] = 41.6; fChi2[18][15] = 43.8; + + fChi2[19][0] = 8.3 ; fChi2[19][1] = 9.2 ; fChi2[19][2] = 10.9; fChi2[19][3] = 21.4; + fChi2[19][4] = 14.6; fChi2[19][5] = 16.3; fChi2[19][6] = 19.3; fChi2[19][7] = 22.8; + fChi2[19][8] = 25.0; fChi2[19][9] = 28.4; fChi2[19][10] = 31.4; fChi2[19][11] = 35.0; + fChi2[19][12] = 37.6; fChi2[19][13] = 40.0; fChi2[19][14] = 43.0; fChi2[19][15] = 45.3; + +} + + +void DGlobalTools::Dummy(){} + +void DGlobalTools::Swap(Float_t *a, Float_t *b){ + Float_t temp; + temp = *a; + *a = *b; + *b = temp; +} + +//______________________________________________________________________________ +// +float DGlobalTools::gMyAge() { + // another test + return 29.; +} + + +//______________________________________________________________________________ +// +float DGlobalTools::gPoly(float aArg ,float* p, int aOrder){ + float f = p[0]; + for (int k = 1; k < aOrder; k++){ + f += p[k] * pow(1.*aArg,1.*k); + } + return f; +} + + +//______________________________________________________________________________ +// +void DGlobalTools::OrderIndexDes(Int_t *aIndex, Float_t *aArg, Int_t aN) +{ + + // order an index vector, + // so that elements in another vector pointed at + // via the ordered vector are descending + // uses BubbleSort Algorithm, not good for large vectors + + Float_t a; + Int_t j, i, indxt; + + for(j = 1; j < aN; j++) { + indxt = aIndex[j]; + a = aArg[indxt]; + i = j - 1; + while(i>=0 && aArg[aIndex[i]] < a) { + aIndex[i+1] = aIndex[i]; + i--; + } + aIndex[i+1] = indxt; + } +} + +//______________________________________________________________________________ +// +void DGlobalTools::OrderIndexAsc(Int_t *aIndex, Float_t *aArg, Int_t aN) +{ + + // order an index vector, + // so that elements in another vector pointed at + // via the ordered vector are ascending + // uses BubbleSort Algorithm, not good for large vectors + + Float_t a; + Int_t j, i, indxt; + + for(j = 1; j < aN; j++) { + indxt = aIndex[j]; + a = aArg[indxt]; + i = j - 1; + while(i>=0 && aArg[aIndex[i]] > a) { + aIndex[i+1] = aIndex[i]; + i--; + } + aIndex[i+1] = indxt; + } +} + +//______________________________________________________________________________ +// +float DGlobalTools::Poly(float* pArg, float* pParameter) +{ + return poly(pArg[0], pParameter, fNparameter-1); +} + +//______________________________________________________________________________ +// +float DGlobalTools::poly(float aArg ,float* p, int aOrder) +{ + float f = p[0]; + for (int k = 1; k < aOrder; k++){ + f += p[k] * pow(1.*aArg,1.*k); + } + return f; +} + +//______________________________________________________________________________ +// +void DGlobalTools::SetParameter(float* aParameter, int aN){ + fNparameter = aN; + for(int k = 0; k < aN; k++) + fParameter[k] = aParameter[k]; +} + +//______________________________________________________________________________ +// +void DGlobalTools::Confidence(int tGoodN, int tTotalN, float tConfidenceLimit, + float& tUpperError, float& tLowerError) +{ + // code borrowed from Lee Holloway (UofI/CDF) + // 980227 via William to me, original in FORTRAN + // compute probability limits from confidence level + + float b[2]; // = {0.8415, 0.1585} is set by Confidence Level + b[0] = (1.+ tConfidenceLimit) / 2; + b[1] = (1.- tConfidenceLimit) / 2; + + // set up limits and check for special cases + int lim[2]; + lim[0] = tGoodN - 1; + lim[1] = tGoodN; + + float ans[2]; + float p, d, r, s, term, tmp; + float eye, entot; + + entot = 1.*tTotalN; + + if (tGoodN == 0) + ans[0] = 0.; + if (tGoodN == tTotalN) + ans[1] = 1.; + + if (tGoodN != 0 && tGoodN != tTotalN) { + for (int k = 0; k < 2; k++) { + d = 1.; + p = 1.; + s = 0.; + for (int j = 0; j < 20; j++){ + // d = sign(d/2, s-b[k]); + d = (s-b[k] >= 0) ? fabs(d/2) : -1.*fabs(d/2); + p += d; + r = log( p / (1. - p) ); + term = tTotalN * log( 1 - p ); + s = exp( term ); + for (int i = 1; i <= lim[k]; i++){ + eye = 1.*i; + tmp = (entot + 1. - eye) / eye; + term += r + log( tmp ); // log() is the natural logarithm + s += exp( term ); + } + } + ans[k] = p; + } + } + tLowerError = ans[0]; + tUpperError = ans[1]; +} + +//______________________________________________________________________________ +// +double DGlobalTools::ProbabilityIntegral(double z) +{ + // returns the value Phi(z)=1/sqrt(2pi) * Int_-inf^z dx exp(-0.5 * x2) + // this is a lookup table + + double tProbabilityPhiZ =0.; + + int tProbabilityN = 460; + + int k = 0; + int tFound = 0; + + if(fabs(z) > 4.59) + tProbabilityPhiZ = 0.5; + else { + while( tFound==0 && k < tProbabilityN) { + if(fabs(z) >= fProbabilityTest[k] && fabs(z) < fProbabilityTest[k+1]) { + tProbabilityPhiZ = fProbabilityPhiZ[k]; + tFound = 1; + } + k++; + + } + } + + return tProbabilityPhiZ; + +} + +//______________________________________________________________________________ +// +double DGlobalTools::Chi2ToProbability(int tDoF, double tChi2) +{ + // chi-square characterizes the deviation between an approximation and measurements. + // the approximation has a degree of freedom. + // the measurements are normal distributed around measurement mean. + // The distribution of chi-squares at the degree of freedom is known. + // here: the probability for the event with this chi2 to be combatible with the + // approximation is the area from chi2 to infinite under the chi2-distribution curve. + // it is tabulated in e.g. Bronstein Semendjajew, 1.1.2.10 p. 21 + + int tDoFMax = 20; // this value has to fit to the size of the array + int pBinLimit = 16; // dito + int pBin; + if (tDoF <= tDoFMax && tDoF >=1) { + pBin = 0; + while(pBin < pBinLimit-1 && fChi2[tDoF-1][pBin] < tChi2 ) + pBin++; + return fChi2Probability[pBin]; + } else { + printf(" Degree of Freedom out of bounds\n"); + return 0; + } +} + +//______________________________________________________________________________ +// +double DGlobalTools::CLof7LegendrePol( double *x, double *coeff) +{ + // Return the value of a combination of Legendre polynoms, evaluated at x. + // The linear combination includes the 1st seventh polynoms + // with the provided coefficients. + // x SHALL BE BETWEEN -1 and 1 otherwise return 0.! + // + // JB 2014/04/10 + + x[0] /= coeff[0]; + + if(x[0]<-1 || 10 ) detEff = trackMultiplicity[iMult-1] * efficiencyPlane[iPlane]; + else detEff = 0.; + tempMultiplicity[iMult] = noDetEff + detEff; + //cout << " | mult " << iMult << " (no det " << noDetEff << ", det " << detEff << ")"; + } + //cout << endl << " current Sum:"; + for (Int_t iMult=0; iMult<=iPlane+1; iMult++) { + trackMultiplicity[iMult] = tempMultiplicity[iMult]; + //cout << " | mult " << iMult << " -> " << trackMultiplicity[iMult]; + } + //cout << endl; + } + + return; + +} + +//______________________________________________________________________________ +// + +void DGlobalTools::ComputeStripPosition( Int_t mapping, Int_t col, Int_t lin, Double_t &u, Double_t &v, Double_t &w, Int_t stripsNu, Int_t stripsNv, Double_t pitchU, Double_t pitchV, Double_t pitchW) +{ + + // Compute the 3D position of the strip at column "col" and line "lin", + // set the values in the "u, v, w" variables. + // The strip position depends on the mapping, look below. + // + // BEWARE: if you add a new case here, add it as weel in ComputeStripPosition_UVToColRow + // + // JB 2012/11/21 + // Modified CLM 2012/11/24 correction for P31 of M32ter + // Modified AB 2015/03/31 new case 7 adapted to M22thrb6,7 + // => copied from DPlane on 2015/04/01 + + switch (mapping) { + + // When pixels are organized on an orthogonal grid + case 1: + default: + { + u = ((2*col - stripsNu + 1 ) * pitchU)/2 ; + //printf( " u = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", col, stripsNu, pitchU, (2*col - stripsNu + 1 ), pitchU/2, u); + v = ((2*lin - stripsNv + 1 ) * pitchV)/2 ; + //printf( " v = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", lin, stripsNv, pitchV, (2*lin - stripsNv + 1 ), pitchV/2, v); + break; + } + case 2: + { + // When pixels are staggered from one column to the other + u = ((2*col - stripsNu + 1 ) * pitchU)/2 ; + + //if ( col%2 == 0 ) v = (((lin - stripsNv/2.0 + 1./2. ) * pitchV)) + 0.30 * pitchV; //clm 2012.11.24 + if ( col%2 != 0 ) v = (((lin - stripsNv/2.0 + 1./2. ) * pitchV)) + 0.30 * pitchV; //clm 2012.11.24 + else v = (((lin - stripsNv/2.0 + 1./2. ) * pitchV)) - 0.19 * pitchV; //clm 2012.11.24 + break; + } + case 3: + { + //Clm Mapping For M32 L8_2 + if ( lin==7 && col == 10) u = ((2*col - stripsNu + 1 ) * pitchU)/2 ; + else u = -9999; //((2*col+2 - stripsNu + 1 ) * pitchU)/2 ; + v = ((2*lin - stripsNv + 1 ) * pitchV)/2 ; + break; + } + case 4: + { + // MonteCarlo Simulation. // LC 2014/01/10. + u = ((2.*col - stripsNu + 2. ) * pitchU)/2. ; // LC 2015/02/17 : +2 commented + //printf( " u = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", col, stripsNu, pitchU, (2*col - stripsNu + 1 ), pitchU/2, u); + v = ((2.*lin - stripsNv + 2. ) * pitchV)/2. ; // LC 2015/02/17 : +2 commented + //printf( " v = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", lin, stripsNv, pitchV, (2*lin - stripsNv + 1 ), pitchV/2, v); + break; + } + case 5: + { + //Mapping FSBB + u = (2*col + 1 - stripsNu) * pitchU/2.0; + double fraction = 0.25; + //double fraction = 0.75; + if ( col%2 == 0 ) v = 0.5*(stripsNv - 2*lin - 2*(fraction )) * pitchV; + else v = 0.5*(stripsNv - 2*lin - 2*(1 - fraction)) * pitchV; + break; + } + case 6: + { + //Mapping FSBB-bis + u = (2*col + 1 - stripsNu) * pitchU/2.0; + //double fraction = 0.25; + double fraction = 0.75; + if ( col%2 == 0 ) v = 0.5*(stripsNv - 2*lin - 2*(fraction )) * pitchV; + else v = 0.5*(stripsNv - 2*lin - 2*(1 - fraction)) * pitchV; + break; + } + case 7: + { + //M22-THRB7 and B6 -> set the matrix type and Mapping accordingly in the config file ! + u = ((2*col - stripsNu + 1 ) * pitchU)/2 ; + if ( col%2 == 0 ) v = (((lin - stripsNv/2.0 + 1./2. ) * pitchV)) - 0.50 * pitchV; //correct +0.5 + else v = (((lin - stripsNv/2.0 + 1./2. ) * pitchV)) - 0.00 * pitchV; //correct -0.5 + //cout<<" DPlane::ComputeStripPosition "< N(%d,%d), pitch(%.1f,%.1f), (%d, %d): %.1f, %.1f\n", stripsNu, stripsNv, pitchU, pitchV, col, lin, u, v); + +} + +//______________________________________________________________________________ +// +void DGlobalTools::ComputeStripPosition_UVToColRow( Int_t mapping, Double_t u, Double_t v, double &col, double &lin, Int_t stripsNu, Int_t stripsNv, Double_t pitchU, Double_t pitchV) +{ + + // Compute the 2D position of a strip in the variables u and v to the set of variables column and line + // The strip position depends on the mapping, look below. + // + // BEWARE: if you add a new case here, add it as weel in ComputeStripPosition + // + // AP 2014/06/26 + // Modified AB 2015/03/31 new case 7 adapted to M22thrb6,7 + // => copied from DPlane on 2015/04/01 + + //cout << pitchU << " " << pitchV << endl; + + switch (mapping) { + // When pixels are organized on an orthogonal grid + case 1: + default: + { + col = (u/pitchU) + ((stripsNu - 1)/2.); + lin = (v/pitchV) + ((stripsNv - 1)/2.); + break; + } + case 2: + { + // When pixels are staggered from one column to the other + col = (u/pitchU) + ((stripsNu - 1)/2.); + int IntCol = RoundOff(col); + if(IntCol%2 != 0) lin = (v/pitchV) + ((stripsNv - 1)/2.) - 0.30; + else lin = (v/pitchV) + ((stripsNv - 1)/2.) + 0.19; + break; + } + case 3: + { + //Clm Mapping For M32 L8_2 + col = (u/pitchU) + ((stripsNu - 1)/2.); + lin = (v/pitchV) + ((stripsNv - 1)/2.); + break; + } + case 4: + { + // MonteCarlo Simulation. // LC 2014/01/10. + col = (u/pitchU) + ((stripsNu /*- 2*/)/2.); // LC 2015/02/17 : -2 commented + lin = (v/pitchV) + ((stripsNv /*- 2*/)/2.); // LC 2015/02/17 : -2 commented + break; + } + case 5: + { + //Mapping FSBB + col = (u/pitchU) + ((stripsNu - 1)/2.); + + //double fraction = 0.50; + //lin = ((stripsNv - 2*(fraction ))/2.0) - (v/pitchV); + + double fraction = 0.25; + int IntCol = RoundOff(col); + if(IntCol%2 == 0) lin = ((stripsNv - 2*(fraction ))/2.0) - (v/pitchV); + else lin = ((stripsNv - 2*(1 - fraction))/2.0) - (v/pitchV); + + break; + } + case 6: + { + //Mapping FSBB-bis + col = (u/pitchU) + ((stripsNu - 1)/2.); + + //double fraction = 0.50; + //lin = ((stripsNv - 2*(fraction ))/2.0) - (v/pitchV); + + double fraction = 0.75; + int IntCol = RoundOff(col); + if(IntCol%2 == 0) lin = ((stripsNv - 2*(fraction ))/2.0) - (v/pitchV); + else lin = ((stripsNv - 2*(1 - fraction))/2.0) - (v/pitchV); + + break; + } + case 7: + { + //M22-THRB7 and B6 -> set the matrix type and Mapping accordingly in the config file ! + col = (u/pitchU) + ((stripsNu - 1)/2.); + if(int(col)%2 == 0) lin = (v/pitchV) + ((stripsNv - 1)/2.) + 0.50; //correct -0.5 + else lin = (v/pitchV) + ((stripsNv - 1)/2.) + 0.0; //correct +0.5 + //cout<<" DPlane::ComputeStripPosition_UVToColRow "<Data(); + +} + //______________________________________________________________________________ +// +void DGlobalTools::LocalizeDirName( TString *inputString) { + + // Replace "/" or "\\" characters in path name for directories + // with the correct charachter according to the system used + // + // JB 2011/07/07 + + TString windowsSep = "\\"; + TString unixSep = "/"; + + // By default we turn any \ into a / for LINUX/UNIX + TString searchedStr = windowsSep; + TString replacementStr = unixSep; + + // Is system is WINDOWS, we switch the strings + TString sysType = gSystem->GetBuildArch(); + if( sysType.Contains("win") || sysType.Contains("WIN") ) { + searchedStr = unixSep; + replacementStr = windowsSep; + } + + //cout << "Input string: " << inputString << endl; + + inputString->ReplaceAll( searchedStr.Data(), replacementStr.Data()); + + //cout << "Output string: " << inputString->Data() << endl; + +} + + +//______________________________________________________________________________ +// +double DGlobalTools::BuildVertex( double *point11, double *point12, double *point21, double *point22, double *vertex) { + + // Compute the point of closest approach (or vertex) between two straight lines. + // Inputs are made of two 3D points (vectors of 3 values) of each line: + // line 1: point11, point12; + // line 2: point21, point22. + // Output is a point made up of a vector of 3 coordinates. + // In the compuation is impossible (div by 0), returns (0,0,0). + // Return the shortest distance between the two lines (0. if no computation). + // + // Author: Pierre HENRIQUET, 2011 + // Adapted by JB, 2011/07/26 + + Int_t debug = 0; + + // output + vertex[0] = vertex[1] = vertex[2] = 0.; + double smallestDist = 0.; + + // inputs + double *A = point11; + double *B = point12; + double *C = point21; + double *D = point22; + + if(debug) printf("Inputs: line1{ (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f)}, line2{ (%.1f,%.1f,%.1f), (%.1f,%.1f,%.1f)}\n", A[0],A[1],A[2], B[0],B[1],B[2], C[0],C[1],C[2], D[0],D[1],D[2]); + + // ==================== + // Nothing was changed from the original version below this line + + double AB[3] = {B[0]-A[0],B[1]-A[1],B[2]-A[2]}; + double CD[3] = {D[0]-C[0],D[1]-C[1],D[2]-C[2]}; + double BC[3] = {C[0]-B[0],C[1]-B[1],C[2]-B[2]}; + + double ABvectCD[3]; + ABvectCD[0] = AB[1]*CD[2]-AB[2]*CD[1]; + ABvectCD[1] = AB[2]*CD[0]-AB[0]*CD[2]; + ABvectCD[2] = AB[0]*CD[1]-AB[1]*CD[0]; + double NormABvectCD = sqrt(pow(ABvectCD[0],2)+pow(ABvectCD[1],2)+pow(ABvectCD[2],2)); + + if (NormABvectCD!=0. && ABvectCD[1]!=0. && CD[0]!=0.) + { + + double n[3]; + n[0] = ABvectCD[0]/NormABvectCD; + n[1] = ABvectCD[1]/NormABvectCD; + n[2] = ABvectCD[2]/NormABvectCD; + + double distance = BC[0]*n[0]+BC[1]*n[1]+BC[2]*n[2]; + + double Bprime[3]; + Bprime[0] = distance*n[0] + B[0]; + Bprime[1] = distance*n[1] + B[1]; + Bprime[2] = distance*n[2] + B[2]; + + double U = C[2]*CD[0]-CD[2]*C[0]; + double V = Bprime[2]*AB[0]-AB[2]*Bprime[0]; + + double P1[3]; + P1[0] = (CD[0]*V-AB[0]*U)/(-1.*ABvectCD[1]); + P1[1] = (CD[1]*(P1[0]-C[0])/CD[0])+C[1]; + P1[2] = (CD[2]*(P1[0]-C[0])/CD[0])+C[2]; + + double P2[3]; + P2[0] = P1[0]+B[0]-Bprime[0]; + P2[1] = P1[1]+B[1]-Bprime[1]; + P2[2] = P1[2]+B[2]-Bprime[2]; + + vertex[0] = (P1[0]+P2[0])/2.; + vertex[1] = (P1[1]+P2[1])/2.; + vertex[2] = (P1[2]+P2[2])/2.; + + smallestDist = sqrt( (P1[0]-P2[0])*(P1[0]-P2[0])+(P1[1]-P2[1])*(P1[1]-P2[1])+(P1[2]-P2[2])*(P1[2]-P2[2]) ); + + } + else + { + printf("BuildVertex: WARNING NormABvectCD=%f, ABvectCD[1]=%f, CD[0]=%f --> returning distance = -1 and position 0,0,0!!\n", NormABvectCD, ABvectCD[1], CD[0]); + return -1; + } + // ==================== + if(debug) printf("Output: vertex (%.1f,%.1f,%.1f), distance %f\n", vertex[0],vertex[1],vertex[2], smallestDist); + + return smallestDist; +} + +//______________________________________________________________________________ +// +Double_t DGlobalTools::BuildVertex( DR3 &pointA1, DR3 &pointA2, DR3 &pointB1, DR3 &pointB2, DR3 &intersection) +{ + // VR 2014/06/29 + + // inputs + Double_t A[3] ; + pointA1.Convert2DoubleArray(A) ; + Double_t B[3] ; + pointA2.Convert2DoubleArray(B) ; + Double_t C[3] ; + pointB1.Convert2DoubleArray(C) ; + Double_t D[3] ; + pointB2.Convert2DoubleArray(D) ; + Double_t I[3]; + + Double_t distance = BuildVertex(A, B, C, D, I); + + intersection.SetValue(I); + + return distance; + +} +//______________________________________________________________________________ +// +void DGlobalTools::SetVetoPixel( int noiseRun) { + + // Match the corresponding vetoFunction with the noiseRun specified. + // If no matching is found, the function pointer stays empty which + // will result in no veto. + // + // Created JB 2012/03/11 + + if( noiseRun == 26166 ) + { + printf( " VETO PIXELS : configuration is IPNL telescope for GANIL 07.2012, RSB 8, 0.1%% over 10.000 evnts (run26166 )\n"); + VetoPixel = vetoPixel_IPNLtelescopeV01; + } + else if( noiseRun == 26167 ) + { + printf( " VETO PIXELS : configuration is IPNL telescope for HIT 12.2012, RSB 8, 0.1%% over 10.000 evnts (run1)\n"); + VetoPixel = vetoPixel_IPNLtelescopeV02; + } + else if( noiseRun == 26168 ) + { + printf( " VETO PIXELS : configuration is IPNL telescope for GSI 08.2012, RSB 8, 0.1%% over 10.000 evnts (run21+51)\n"); + VetoPixel = vetoPixel_IPNLtelescopeV03; + } + else if( noiseRun == 26169 ) + { + printf( " VETO PIXELS : configuration is IPNL telescope for GSI 08.2012, RSB 8, 0.01%% over 1.000.000 evnts (run51+21) EXCEPT for planes 1Left and 1Right 1%%\n"); + VetoPixel = vetoPixel_IPNLtelescopeV04; + } + else if( noiseRun == 26170 ) + { + printf( " VETO PIXELS : configuration is IPNL telescope for GSI 08.2012, RSB 6, 0.01%% over 1.000.000 evnts (run53) EXEPT for planes 1Left and 1Right (using 26169)\n"); + VetoPixel = vetoPixel_IPNLtelescopeV05; + } + else if( noiseRun == 26171 ) + { + printf( " VETO PIXELS : configuration is IPNL telescope for HIT2 04.2013, RSB 8, 0.01%% over 1.000.000 evnts (run55) EXEPT for planes 1Left and 1Right (using 26169)\n"); + VetoPixel = vetoPixel_IPNLtelescopeV06; + } + else if( noiseRun == 26180 ) + { + printf( " VETO PIXELS : configuration is IPNL new telescope for GANIL 04.2014, RSB 8, 0.01%% over 180.000 evnts (runs 100-103)\n"); + VetoPixel = vetoPixel_IPNLtelescopeV10; + } + else if ( noiseRun == 26666 ) { + printf( " VETO PIXELS : configuration is MIMOSA 26 telescope (run 26666)\n"); + VetoPixel = vetoPixel_Mi26telescope; + } + else if ( noiseRun == 28666 ) { + printf( " VETO PIXELS : configuration is MIMOSA 28 telescope (run 28666)\n"); + VetoPixel = vetoPixel_Mi28telescope; + } + else if ( noiseRun == 128666 ) { + printf( " VETO PIXELS : configuration is MIMOSA 28 - GSI telescope (run 128666)\n"); + VetoPixel = vetoPixel_Mi28telescopeGSI; + } + else if ( noiseRun == 26667 ) { + printf( " VETO PIXELS : configuration is MIMOSA 26 - Aarhus (run 26667)\n"); + VetoPixel = vetoPixel_Mi26Aarhus; + } + else if ( noiseRun == 700 ) { + printf( " VETO PIXELS : configuration is MIMOSA 26 - SOLEIL (run 700)\n"); + VetoPixel = vetoPixel_Mi26SOLEIL; + } + else if ( noiseRun == 28010 ) { + printf( " VETO PIXELS : configuration is MIMOSA 28 - SITRINEO IPHC - run 10\n"); + VetoPixel = vetoPixel_SITRINEO_IPHC; + } + else { + printf( " no VETO PIXELS used.\n"); + VetoPixel = NULL; + } + +} +//______________________________________________________________________________ +// +double DGlobalTools::scatteringAngle(string particle, + double momentum, + string material, + double thickness, + bool verbose) { + + // Return the theta_rms of multiple scattering + // for a given momentum, thickness and material + // + // Note that: + // * momentum unit is GeV/c. + // * thickness unit is microns (um). + // + // If particle or material unknown, return 0. + // + // JB 2012/10/31 + + std::map mass; // in GeV/c2 + std::map charge; // in units of electron charge + mass["electron"] = 511e-6; + charge["electron"] = 1; + mass["pion"] = 0.1396; + charge["pion"] = 1; + mass["kaon"] = 0.4937; + charge["kaon"] = 1; + mass["proton"] = 0.9383; + charge["proton"] = 1; + mass["muon"] = 105.66e-6; + charge["muon"] = 1; + + std::map X0; // um + X0["copper"] = 1.43e+4; + X0["silicon"] = 9.36e+4; + X0["aluminum"] = 8.8900e+4; + X0["beryllium"] = 35.28e+4; + X0["epoxy"] = 30.e+4; + X0["kapton"] = 28.e+4; + X0["glass"] = 12.30e+4; + X0["nai"] = 2.59e+4; + X0["csi"] = 1.86e+4; + X0["tungsten"] = 0.35e+4; + X0["iron"] = 1.76e+4; + X0["water"] = 36.08e+4; + X0["DryAir"] = 30.39e+7; + X0["Vacuum"] = 1.00e+20; + X0["mylar"] = 28.7e+4; + X0["CarbonFiber"] = 23.7e+4; + + if(mass.count(particle)<1 /*mass[particle]<=0.*/ ) { + fprintf( stderr, "Particle type %s is unknown!\n", particle.data()); + cout << "Paricle should be: "; + for( map::iterator i=mass.begin(); i!=mass.end(); ++i) cout << (*i).first << " "; + cout << endl; + + assert(false); + } + + if(X0.count(material)<1 ) { + fprintf( stderr, "Material type %s is unknown!\n", material.data()); + cout << "Material should be: "; + for(map::iterator i=X0.begin(); i!=X0.end(); ++i) cout << (*i).first << " "; + cout << endl; + + assert(false); + } + + double energy = sqrt(pow(mass[particle],2.) + pow(momentum,2.)); + double beta = momentum/energy; + double sigMS = (0.0136/(beta*momentum))*charge[particle]*sqrt(thickness/X0[material])*(1.+0.038*log(thickness/X0[material])); + + if(verbose) { + printf("\n ========= mult. scat. ==========\n"); + printf(" %s of energy %e GeV, momentum %e GeV/c, beta %e\n", particle.data(), energy, momentum, beta); + printf(" particle is %s ==> beta*p = %ex%e = %e\n", particle.data(), beta, momentum, beta*momentum); + printf(" in %s of thickness %.0f um, X0=%f um\n", material.data(), thickness, X0[material]); + printf(" ==> Theta_rms = %e rad (%e deg)\n\n", sigMS,sigMS*(180.0/TMath::Pi())); + } + + return sigMS; + +} +//______________________________________________________________________________ +// +double DGlobalTools::Getb(string particle, + string material, + double momentum, + double thickness) +{ + + //Implementing multiple scattering including non-gaussian tails as in + //PR Vol 89, Number 6, March 15, 1953 + //the b parameter is material dependent (material type and thickness), + //as well as particle dependent (it velocity beta) + //Use equation (22) of that paper to evaluate it + + double alpha = 7.297352568e-3; + double mass; + int charge; + + if(TString("electron") == TString(particle.data())) { + mass = 511e-6; + charge = 1; + } + else if(TString("pion") == TString(particle.data())) { + mass = 0.1396; + charge = 1; + } + else if(TString("kaon") == TString(particle.data())) { + mass = 0.4937; + charge = 1; + } + else if(TString("proton") == TString(particle.data())) { + mass = 0.9383; + charge = 1; + } + else { + cout << endl; + cout << "Specified particle " << particle.data() << " is not include in our data base." << endl; + cout << " - electron" << endl; + cout << " - pion" << endl; + cout << " - kaon" << endl; + cout << " - proton" << endl; + cout << "Check your inputs. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + //Matrial properties + int Z; //atomic number + double A; //atomic weight, gr/mol + double rho; //density, in gr/cm^3 + + if(TString("copper") == TString(material.data())) { + Z = 29; + A = 63.546000; + rho = 8.960; + } + else if(TString("silicon") == TString(material.data())) { + Z = 14; + A = 28.085500; + rho = 2.330; + } + else if(TString("aluminum") == TString(material.data())) { + Z = 13; + A = 26.981539; + rho = 2.700; + } + else if(TString("beryllium") == TString(material.data())) { + Z = 4; + A = 9.012182; + rho = 1.848; + } + else if(TString("tungsten") == TString(material.data())) { + Z = 74; + A = 183.840000; + rho = 19.300; + } + else if(TString("iron") == TString(material.data())) { + Z = 26; + A = 55.845000; + rho = 7.870; + } + else if(TString("DryAir") == TString(material.data())) { + double ZOA = 0.49919; + A = 28.97; + rho = 1.205e-3; + Z = ZOA*A; + } + else if(TString("Vacuum") == TString(material.data())) { + double ZOA = 0.49919; + A = 28.97; + rho = 1.0e-12; + Z = ZOA*A; + } + else { + cout << endl; + cout << "Specified material " << material.data() << " is not include in our data base." << endl; + cout << " - copper" << endl; + cout << " - silicom" << endl; + cout << " - aluminium" << endl; + cout << " - beryllium" << endl; + cout << " - tungsten" << endl; + cout << " - iron" << endl; + cout << " - DryAir" << endl; + cout << " - Vacuum" << endl; + cout << "Check your inputs. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + double energy = sqrt(pow(mass,2) + pow(momentum,2)); + double beta = momentum/energy; + double t = thickness*1.0e-4*rho; + + double b = ((6680*t)/pow(beta,2))*(((Z+1)*pow(Z,1/3.0)*pow((float)charge,2))/(A*(1.0 + 3.34*pow(alpha,2)))); + b = TMath::Log(b); + + return b; + +} +//______________________________________________________________________________ +// +double DGlobalTools::GetBfromb(double b) +{ + + //Implementing multiple scattering including non-gaussian tails as in + //PR Vol 89, Number 6, March 15, 1953 + //B is an expansion parameter for corrections to the MS Gaussian model. + //See Eq. (25) of the paper. + //The B parameter is a function of b as in equation (23) of the paper. + //This function solves the transcendental equation using the Newton + //iterative method + + double epsilon = 1.0e-8; + + double B0 = b; + while(B0 < 1) { + B0 *= 10; + } + + double Bn = B0; + double Bnp1 = (Bn/(Bn-1))*(TMath::Log(Bn) + b - 1.0); + + while(TMath::Abs(Bnp1 - Bn) > epsilon) { + Bn = Bnp1; + Bnp1 = (Bn/(Bn-1))*(TMath::Log(Bn) + b - 1.0); + } + + return Bnp1; + +} +//______________________________________________________________________________ +// +double DGlobalTools::Getf0(double Theta) +{ + + //Implementing multiple scattering including non-gaussian tails as in + //PR Vol 89, Number 6, March 15, 1953 + //Guassian component of the MS model, the f0 function of Eq. (25) of the paper + + //Theta is actually the ratio Theta = theta_space/(sqrt(2)*theta_0), + //Where: theta_space is the spatial scattering angle and theta_0 is the + //RMS of the guassian model of the scattering angle + + return 2.0*TMath::Exp(-pow(Theta,2)); + +} +//______________________________________________________________________________ +// +void DGlobalTools::Getf1Andf2(double Theta, + double& f1, + double& f2) +{ + + //Implementing multiple scattering including non-gaussian tails as in + //PR Vol 89, Number 6, March 15, 1953 + //This function returns the corrections to the Gaussian behaviour of the MS, + //the functions f1 and f2 of Eq. (25) of the paper. + //In this function there is no analytical implementation, but a linear + //interpolarion of the calculated points shown in table II of the paper. + + //Theta is actually the ratio Theta = theta_space/(sqrt(2)*theta_0), + //Where: theta_space is the spatial scattering angle and theta_0 is the + //RMS of the guassian model of the scattering angle + + const int Npoints(29); + + double Theta_Values[Npoints]; + double F1_Values[Npoints]; + double F2_Values[Npoints]; + int counter = 0; + Theta_Values[counter] = 0.0; F1_Values[counter] = 0.8456; F2_Values[counter] = 2.4929; + counter++; + Theta_Values[counter] = 0.2; F1_Values[counter] = 0.7038; F2_Values[counter] = 2.0694; + counter++; + Theta_Values[counter] = 0.4; F1_Values[counter] = 0.3437; F2_Values[counter] = 1.0488; + counter++; + Theta_Values[counter] = 0.6; F1_Values[counter] = -0.0777; F2_Values[counter] = -0.0044; + counter++; + Theta_Values[counter] = 0.8; F1_Values[counter] = -0.3981; F2_Values[counter] = -0.6068; + counter++; + Theta_Values[counter] = 1.0; F1_Values[counter] = -0.5285; F2_Values[counter] = -0.6359; + counter++; + Theta_Values[counter] = 1.2; F1_Values[counter] = -0.4770; F2_Values[counter] = -0.3086; + counter++; + Theta_Values[counter] = 1.4; F1_Values[counter] = -0.3183; F2_Values[counter] = 0.0525; + counter++; + Theta_Values[counter] = 1.6; F1_Values[counter] = -0.1396; F2_Values[counter] = 0.2423; + counter++; + Theta_Values[counter] = 1.8; F1_Values[counter] = -0.0006; F2_Values[counter] = 0.2386; + counter++; + Theta_Values[counter] = 2.0; F1_Values[counter] = 0.0782; F2_Values[counter] = 0.1316; + counter++; + Theta_Values[counter] = 2.2; F1_Values[counter] = 0.1054; F2_Values[counter] = 0.0196; + counter++; + Theta_Values[counter] = 2.4; F1_Values[counter] = 0.1008; F2_Values[counter] = -0.0467; + counter++; + Theta_Values[counter] = 2.6; F1_Values[counter] = 0.08262; F2_Values[counter] = -0.0649; + counter++; + Theta_Values[counter] = 2.8; F1_Values[counter] = 0.06247; F2_Values[counter] = -0.0546; + counter++; + Theta_Values[counter] = 3.0; F1_Values[counter] = 0.04550; F2_Values[counter] = -0.03568; + counter++; + Theta_Values[counter] = 3.2; F1_Values[counter] = 0.03288; F2_Values[counter] = -0.01923; + counter++; + Theta_Values[counter] = 3.4; F1_Values[counter] = 0.02402; F2_Values[counter] = -0.00847; + counter++; + Theta_Values[counter] = 3.6; F1_Values[counter] = 0.01791; F2_Values[counter] = -0.00264; + counter++; + Theta_Values[counter] = 3.8; F1_Values[counter] = 0.01366; F2_Values[counter] = 0.00005; + counter++; + + Theta_Values[counter] = 4.0; F1_Values[counter] = 10.638e-3; F2_Values[counter] = 1.0741e-3; + counter++; + Theta_Values[counter] = 4.5; F1_Values[counter] = 6.140e-3; F2_Values[counter] = 1.2294e-3; + counter++; + Theta_Values[counter] = 5.0; F1_Values[counter] = 3.831e-3; F2_Values[counter] = 0.8326e-3; + counter++; + Theta_Values[counter] = 5.5; F1_Values[counter] = 2.527e-3; F2_Values[counter] = 0.5368e-3; + counter++; + Theta_Values[counter] = 6.0; F1_Values[counter] = 1.739e-3; F2_Values[counter] = 0.3495e-3; + counter++; + Theta_Values[counter] = 7.0; F1_Values[counter] = 0.9080e-3; F2_Values[counter] = 0.1584e-3; + counter++; + Theta_Values[counter] = 8.0; F1_Values[counter] = 0.5211e-3; F2_Values[counter] = 0.0783e-3; + counter++; + Theta_Values[counter] = 9.0; F1_Values[counter] = 0.3208e-3; F2_Values[counter] = 0.0417e-3; + counter++; + Theta_Values[counter] = 10.0; F1_Values[counter] = 0.2084e-3; F2_Values[counter] = 0.0237e-3; + counter++; + + if(Theta > Theta_Values[Npoints-1]) { + cout << endl; + cout << "Currently only able to evaluate functions up to Theta = 10. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + for(int i=0;i= Theta_Values[i] && + Theta < Theta_Values[i+1]) { + + double a_f1 = (F1_Values[i+1] - F1_Values[i])/(Theta_Values[i+1] - Theta_Values[i]); + double b_f1 = F1_Values[i+1] - a_f1*Theta_Values[i+1]; + f1 = a_f1*Theta + b_f1; + + double a_f2 = (F2_Values[i+1] - F2_Values[i])/(Theta_Values[i+1] - Theta_Values[i]); + double b_f2 = F2_Values[i+1] - a_f2*Theta_Values[i+1]; + f2 = a_f2*Theta + b_f2; + + break; + } + } + + return; + +} +//______________________________________________________________________________ +// +double DGlobalTools::GetDistribution(double Theta, + double B) +{ + + //Implementing multiple scattering including non-gaussian tails as in + //PR Vol 89, Number 6, March 15, 1953 + //This function returns the full distribution of spatial scattering angle + // f(theta_space)(theta_space)d_theta_space = (Theta)(d_Theta)[f0(Theta) + Be-1*f1(Theta) + Be-2*f2(Theta)] + // B is the parameter described in Function GetBfromb(double b) + + //Theta is actually the ratio Theta = theta_space/(sqrt(2)*theta_0), + //Where: theta_space is the spatial scattering angle and theta_0 is the + //RMS of the guassian model of the scattering angle + + double f0 = Getf0(Theta); + double f1,f2; + Getf1Andf2(Theta,f1,f2); + + double f = f0 + (f1/B) + (f2/pow(B,2)); + + return f; + +} +//______________________________________________________________________________ +// +int DGlobalTools::RoundOff(double a) +{ + + int a_int = int(a); + double delta = a - a_int; + if(delta < 0.5) return a_int; + else return a_int + 1; + +} +//______________________________________________________________________________ +// +//NEXT FUNCTIONS ADDED BY JH (4/4/2018) FOR FITTING PURPOSES IN MRAW::XRAYANALYSIS + + + +//==================================================================================================================================================== +double DGlobalTools::fpeaks(double *x, double *par, int npeaks) +{ + + // Gaussian Peaks fitting function + double result = 0; + for(int p=0; p -alpha) result = exp(-0.5*pow(frac,2)); + else result = A*pow(B-frac,-n); + result *= N; + + return result; + +} +//==================================================================================================================================================== +double DGlobalTools::BifurcatedCBfunction(double x, + double mean, + double sigmaL, + double sigmaR, + double alpha, + double n) +{ + // Crystal ball function (https://en.wikipedia.org/wiki/Crystal_Ball_function) + + double absalpha = TMath::Abs(alpha); + double fracL = (x-mean)/sigmaL; + double fracR = (x-mean)/sigmaR; + double A = pow(n/absalpha,n)*exp(-pow(absalpha,2)/2); + double B = (n/absalpha) - absalpha; + + double C = sigmaL*(n/absalpha)*(1/(n-1))*exp(-0.5*pow(absalpha,2)); + double DL = sigmaL*sqrt(0.5*TMath::Pi())*(TMath::Erf(absalpha/sqrt(2))); + double DR = sigmaR*sqrt(0.5*TMath::Pi()); + double N = 1.0/(C + DL + DR); + + double result = 0.0; + if(x-mean >= 0.0) result = exp(-0.5*pow(fracR,2)); + else { + if(fracL > -alpha) result = exp(-0.5*pow(fracL,2)); + else result = A*pow(B-fracL,-n); + } + result *= N; + + return result; + +} + + + +//==================================================================================================================================================== +double DGlobalTools::DoublePeakCBFitFunction55Fe(double x, + double mean1, + double mean2, + double sigma1, + double sigma2, + double alpha1, + double alpha2, + double n1, + double n2, + double N1, + double N2) +{ + + // model to fit the two lines of the Fe55 source with two CB functions with the same + // sigma, alpha, n and mean values differing by the same amount as te Kalpha and Kbeta lines + // The N1 and N2 parameters are the number of events of each peak + +/* double mean1 = mean; + double mean2 = mean1*(6.49045/5.89502); + double sigma1 = sigma; + double sigma2 = sigma; + double alpha1 = alpha; + double alpha2 = alpha; + double n1 = n; + double n2 = n;*/ + + double result = 0.0; + result += N1*DGlobalTools::CBfunction(x,mean1,sigma1,alpha1,n1); + result += N2*DGlobalTools::CBfunction(x,mean2,sigma2,alpha2,n2); + + return result; + +} +//==================================================================================================================================================== +double DGlobalTools::fpeaksCB55Fe(double *x, double *par) +{ + + //fit function to fit the + + //parameter list + //par[0] = mean; + //par[1] = sigma + //par[2] = alpha + //par[3] = n + //par[4] = N1 + //par[5] = N2 + + double mean1 = par[0]; + double mean2 = par[1]; + double sigma1 = par[2]; + double sigma2 = par[3]; + double alpha1 = par[4]; + double alpha2 = par[5]; + double n1 = par[6]; + double n2 = par[7]; + double N1 = par[8]; + double N2 = par[9]; + + return DGlobalTools::DoublePeakCBFitFunction55Fe(x[0],mean1,mean2,sigma1,sigma2,alpha1,alpha2,n1,n2,N1,N2); + +} +//==================================================================================================================================================== +double DGlobalTools::DoublePeakBifurcatedCBFitFunction55Fe(double x, + double mean1, + double mean2, + double sigmaL1, + double sigmaL2, + double sigmaR1, + double sigmaR2, + double alpha1, + double alpha2, + double n1, + double n2, + double N1, + double N2) +{ + + // model to fit the two lines of the Fe55 source with two CB functions with the same + // sigma, alpha, n and mean values differing by the same amount as te Kalpha and Kbeta lines + // The N1 and N2 parameters are the number of events of each peak + +/* double mean1 = mean; + double mean2 = mean1*(6.49045/5.89502); + double sigmaL1 = sigmaL; + double sigmaL2 = sigmaL; + double sigmaR1 = sigmaR; + double sigmaR2 = sigmaR; + double alpha1 = alpha; + double alpha2 = alpha; + double n1 = n; + double n2 = n;*/ + //mean2 = mean1*(6.49045/5.89502); + + double result = 0.0; + result += N1*DGlobalTools::BifurcatedCBfunction(x,mean1,sigmaL1,sigmaR1,alpha1,n1); + result += N2*DGlobalTools::BifurcatedCBfunction(x,mean2,sigmaL2,sigmaR2,alpha2,n2); + + return result; + +} +//==================================================================================================================================================== +double DGlobalTools::fpeaksBifurcatedCB55Fe(double *x, double *par) +{ + + //fit function to fit the + + //parameter list + //par[0] = mean; + //par[1] = sigmaL + //par[2] = sigmaR + //par[3] = alpha + //par[4] = n + //par[5] = N1 + //par[6] = N2 + + double mean1 = par[0]; + double mean2 = par[1]; + double sigmaL1= par[2]; + double sigmaL2= par[3]; + double sigmaR1= par[4]; + double sigmaR2= par[5]; + double alpha1 = par[6]; + double alpha2 = par[7]; + double n1 = par[8]; + double n2 = par[9]; + double N1 = par[10]; + double N2 = par[11]; + + return DGlobalTools::DoublePeakBifurcatedCBFitFunction55Fe(x[0],mean1, mean2, sigmaL1, sigmaL2, sigmaR1, sigmaR2, alpha1, alpha2, n1, n2, N1, N2); + +} + +//==================================================================================================================================================== diff --git a/src/DHelix.cxx b/src/DHelix.cxx new file mode 100644 index 0000000..547e26d --- /dev/null +++ b/src/DHelix.cxx @@ -0,0 +1,72 @@ +//**********************************************************************************// +//Autor: Daniel Cuesta +//Purpose of Class : +// Holds all the modules needed to define and work with Helix +//***********************************************************************************// +// /!\ /!\ /!\ WORK IN PROGRESS/!\/!\ /!\* +//**********************************************************************************// +#include "DHelix.h" +#include "DR3.h" + +ClassImp(DHelix) // Description of a Hit + +DHelix::DHelix(){ + fTransverseMomentum = -999; + fDrho = -999; + fPhi0 = -999; + fDz = -999; + fTanLambda = -999; + fPhi = -999; + fMagneticField = -999; +} +//=========================================================================================================== +DHelix::DHelix(DR3 PivotPosition,double TransverseMomentum,double phi0,double drho,double dz,double TanLambda,double MagneticField) +{ + fTransverseMomentum = TransverseMomentum; + fPhi0 = phi0; + fDrho = drho; + fDz = dz; + fTanLambda = TanLambda; + fMagneticField = MagneticField; + fPivotPosition = PivotPosition; + return; +} +DHelix::~DHelix(){ + return; +} +//=========================================================================================================== +DR3 DHelix::GetHelixPosition(double phi) +{ + double alpha = 1./(0.3*fMagneticField); + // double alpha = 1./(3e8*fMagneticField); + double k = -1./fTransverseMomentum; + + (fHelixPosition)(0)= ((fDrho*cos(fPhi0))+(alpha/k)*(cos(fPhi0)-cos(fPhi0+phi))); + (fHelixPosition)(1)= ((fDrho*sin(fPhi0))+(alpha/k)*(sin(fPhi0)-sin(fPhi0+phi))); + (fHelixPosition)(2)= (fDz-(alpha/k)*(fTanLambda*phi)); + +return fHelixPosition; +} +//=========================================================================================================== +void DHelix::SetAllParameters(Double_t *par) +{ + fTransverseMomentum = 1./par[0]; + fPhi0 = par[1]; + fTanLambda = par[2]; + fDrho = par[3]; + fDz = par[4]; + + return; +} +//=========================================================================================================== +void DHelix::SetAllParameters(double TransverseMomentum,double phi0,double drho,double dz,double TanLambda) +{ + fTransverseMomentum = TransverseMomentum; + fPhi0 = phi0; + fTanLambda = drho; + fDrho = dz; + fDz = TanLambda; + + return; +} +//=========================================================================================================== diff --git a/src/DHelixFitter.cxx b/src/DHelixFitter.cxx new file mode 100644 index 0000000..c0be8bd --- /dev/null +++ b/src/DHelixFitter.cxx @@ -0,0 +1,440 @@ +//**********************************************************************************// +//Autor: Daniel Cuesta +//Purpose of Class : +// Holds all the modules needed to perform Helix fitting +// - GetHelixParameter : Perform Helix fitting with Hits give in Arguments +// Sub modules of GetHelixParameter +// -- GetResidual : Give residual for the Chisquare minimization +// -- BuiltCovarianceMatrix : Built Covariance matrix +// -- GetIntersectionHelixPlane : Get intersection of the helix with the sensor plane +// for a given set of parameter +//***********************************************************************************// +// /!\ /!\ /!\ WORK IN PROGRESS/!\/!\ /!\* +//**********************************************************************************// + +#include "DHelixFitter.h" +#include +#include +#include +#include +DHelixFitter* DHelixFitter::fgInstance = 0; +ClassImp(DHelixFitter) + +DHelixFitter::DHelixFitter(DTracker *Tracker) +{ + tTracker=Tracker; + fgInstance=this; +return; +} +DHelixFitter::~DHelixFitter(){ + return; +} +//=========================================================================================================== +TVector3 DHelixFitter::GetHelixParameter(vector ListOfHits){ + // DHelixFitter *aHelixFitter = new DHelixFitter(); + std::cout << "GetHelixParameter" << '\n'; + aHelix = new DHelix(); + aHelix->SetMagneticField(1.5); + ListOfHitsToFitted_1 = ListOfHits[0]; + ListOfHitsToFitted_2 = ListOfHits[1]; + SensorId_1 = ListOfHits[2].X(); + SensorId_2 = ListOfHits[2].Y(); + double c = 3e8; + alpha = 1./(0.3*1.5); + dphi = (TMath::Pi()/1000.); + eps = 1e-1; + phi0 = 0; + RootFind = 1e6; + + double Pi=TMath::Pi(); + + TMinuit *ptMinuit = new TMinuit(5); //initialize TMinuit + ptMinuit->SetPrintLevel(0); + // set the user function that calculates chi_square (the value to minimize) + ptMinuit->SetFCN(FCNHelix_ChiSquare); + + Double_t arglist[10]; + Int_t ierflg = 0; + + arglist[0] = 1; + ptMinuit->mnexcm("SET ERR", arglist ,1,ierflg); + double m_phi0=0.; + double m_drho=0.; + double m_dz=0.; + // Set starting values and step sizes for parameters + static Double_t vstart[5] = {53.22,m_phi0,0.36,m_drho,m_dz}; + // static Double_t vstart[5] = {53.,m_phi0,TMath::Tan((1-0.85)*Pi/2),m_drho,m_dz}; + static Double_t step[5] = {1.,0.01,TMath::Tan(0.01*Pi/2.),0.001,0.1}; + ptMinuit->mnparm(0, "k", vstart[0], step[0],10.,100.,ierflg); + ptMinuit->mnparm(1, "phi0", vstart[1], step[1],0.,4*Pi,ierflg); + ptMinuit->mnparm(2, "lambda", vstart[2], step[2],0.2,TMath::Tan(0.95*Pi/2),ierflg); + // ptMinuit->mnparm(2, "lambda", vstart[2], step[2],TMath::Tan((1-0.99)*Pi/2),TMath::Tan((1-0.7)*Pi/2),ierflg); + ptMinuit->mnparm(3, "drho", vstart[3], step[3], -2e-2,2e-2,ierflg); + ptMinuit->mnparm(4, "dz", vstart[4], step[4], -0.4,0.4,ierflg); + // ptMinuit->FixParameter(0); + // ptMinuit->FixParameter(1); + // ptMinuit->FixParameter(2); + // ptMinuit->FixParameter(3); + // ptMinuit->FixParameter(4); + + std::cout << "INSIDE DHelixFitter" << '\n'; + std::cout << "Position 1 X = "<< ListOfHits[0].X() << "[mm]" + << ", Y = "<< ListOfHits[0].Y() << "[mm]" + << ", Z = "<< ListOfHits[0].Z() << "[mm]" << '\n'; + std::cout << "Position 2 X = "<< ListOfHits[1].X() << "[mm]" + << ", Y = "<< ListOfHits[1].Y() << "[mm]" + << ", Z = "<< ListOfHits[1].Z() << "[mm]" << '\n'; + + std::cout << "Sensor Id 1 = "<mnstat(amin,edm,errdef,nvpar,nparx,icstat); + + cout << "\n"; + cout << " Minimum chi square = " << amin << "\n"; + // std::cout << "Probability = " << TMath::Prob(amin, 5)<<'\n'; + cout << " Estimated vert. distance to min. = " << edm << "\n"; + cout << " Number of variable parameters = " << nvpar << "\n"; + cout << " Highest number of parameters defined by user = " << nparx << "\n"; + cout << " Status of covariance matrix = " << icstat << "\n"; + + double fParamValbis; + double fParamErrbis; + ptMinuit->GetParameter(0,fParamValbis,fParamErrbis); + double k =fParamValbis; + cout << "K =" << fParamValbis << "\n"; + std::cout << "Momemtum[GeV] = "<<1./k << '\n'; + TVector3 HelixParameter(1./k,amin,0.); + + return HelixParameter; +} +//=========================================================================================================== +void FCNHelix_ChiSquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag){ + DHelixFitter::Instance()->Helix_ChiSquare(npar, gin, f, par , iflag); + return; +} +//=========================================================================================================== +void DHelixFitter::Helix_ChiSquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag){ + chisquare = 0.; + TMatrixD CovarianceMatrix; + TMatrixD Residual; + Residual.ResizeTo(3,1); + TMatrixD Residual_T; + Residual_T.ResizeTo(1,3); + TMatrixD StepMatrix; + StepMatrix.ResizeTo(1,3); + TMatrixD ChisquareMatrix; + ChisquareMatrix.ResizeTo(3,3); + int NbFittedPoints=3; + for(int i=0;iGetPhi0()<< '\n'; + DR3 HelixPosXYZFitted = aHelix->GetHelixPosition(aHelix->GetPhi0());//careful now is meters + // std::cout << "C'est pas Get HelixPosition " << '\n'; + Result(0,0) = x-(HelixPosXYZFitted)(0)/1000; + Result(1,0) = y-(HelixPosXYZFitted)(1)/1000; + Result(2,0) = z-(HelixPosXYZFitted)(2)/1000; + }else{ + aPlane = tTracker->GetPlane(SensorId+1); + Dprec = aPlane->GetPrecAlignment(); + phi = GetIntersectionHelixPlane(aPlane,aHelix); + if(phi<0) phi = 2*TMath::Pi()-abs(phi); + std::cout << "Phi Inside GetResidual = "<GetHelixPosition(phi);//careful now is meters + (HelixPosXYZFitted)(0)=(HelixPosXYZFitted)(0)*1e6; + (HelixPosXYZFitted)(1)=(HelixPosXYZFitted)(1)*1e6; + (HelixPosXYZFitted)(2)=(HelixPosXYZFitted)(2)*1e6;//Now in um + // std::cout << "--------oooo00OO00oooo-----oooo00OO00oooo" << '\n'; + // std::cout << "-----oo0OO0oo----POSITION MODELIZE-----oo0OO0oo----" << '\n'; + // std::cout << "SensorId = "<< SensorId << '\n'; + // std::cout << "Phi = "< X = "<< (HelixPosXYZFitted)(0) + // << " PosXYZ -> Y = "<< (HelixPosXYZFitted)(1) + // << " PosXYZ -> Z = "<< (HelixPosXYZFitted)(2)<< '\n'; + + DR3 HelixPosXYZMeasured(x*1000,y*1000,z*1000);//in um + // DR3 HelixPosXYZMeasured(x*1000.,y*1000.,z*1000);//in micrometers + // DR3 HelixPosXYZMeasured(x,y,z);//in micrometers + + // std::cout << "-----oo0OO0oo----POSITION MEASURED-----oo0OO0oo----" << '\n'; + // std::cout << "PosXYZ -> X = "<< (HelixPosXYZMeasured)(0) + // << " PosXYZ -> Y = "<< (HelixPosXYZMeasured)(1) + // << " PosXYZ -> Z = "<< (HelixPosXYZMeasured)(2)<< '\n'; + DR3 HelixPosUVWFitted = Dprec->TransformHitToPlane(HelixPosXYZFitted);//Return micrometers + DR3 HelixPosUVWMeasured = Dprec->TransformHitToPlane(HelixPosXYZMeasured);//Return micrometers + std::cout << "-----oo0OO0oo----LOCAL POSITION MODELIZE-----oo0OO0oo----" << '\n'; + std::cout << "PosUVW -> U = "<< (HelixPosUVWFitted)(0) + << " PosUVW -> V = "<< (HelixPosUVWFitted)(1) + << " PosUVW -> W = "<< (HelixPosUVWFitted)(2)<< '\n'; + std::cout << "-----oo0OO0oo----LOCAL POSITION MEASURED-----oo0OO0oo----" << '\n'; + std::cout << "PosUVW -> U = "<< (HelixPosUVWMeasured)(0) + << " PosUVW -> V = "<< (HelixPosUVWMeasured)(1) + << " PosUVW -> W = "<< (HelixPosUVWMeasured)(2)<< '\n'; + Result(0,0) = ((HelixPosUVWMeasured)(0)-(HelixPosUVWFitted)(0))/1000;//Result in millimeters + Result(1,0) = ((HelixPosUVWMeasured)(1)-(HelixPosUVWFitted)(1))/1000; + Result(2,0) = ((HelixPosUVWMeasured)(2)-(HelixPosUVWFitted)(2))/1000; + // } + } + Result.Print(); + return Result; +} +//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>> +double DHelixFitter::GetIntersectionHelixPlane(DPlane *aPlane, DHelix *aHelix) +{ + double PositionLimit = .1; + double DeltaPhiLimit = 0.001; + double phi = 0.; + Dprec = aPlane->GetPrecAlignment(); + bool HaveSolution = false; + int RootFinderCounter = 0.; + int RootFinderCounterLimit = 10; + Dprec = aPlane->GetPrecAlignment(); + while((HaveSolution == false) && RootFinderCounterGetHelixPosition(phi);//Return meters + (HelixPosXYZ)(0) = (HelixPosXYZ)(0)*1e6; + (HelixPosXYZ)(1) = (HelixPosXYZ)(1)*1e6; + (HelixPosXYZ)(2) = (HelixPosXYZ)(2)*1e6; + HelixPosUVW = Dprec->TransformHitToPlane(HelixPosXYZ);//Return micrometers + double W = (HelixPosUVW)(2)/1000;// in millimeters + if(fabs(W)>PositionLimit){ + double Wprime = GetWprime(phi,aHelix,aPlane); + if(Wprime == 0) continue; + phi -= W/(Wprime); + RootFinderCounter++; + }else{ + HaveSolution=true; + std::cout << "Solution Founded" << '\n'; + // std::cout << "Phi founded = "<mnparm(0, "R", Vstart[0], Step[0],-1e5,1e5,Ierflg); + ptMinuit->mnparm(1, "a", Vstart[1], Step[1],-1e5,1e5,Ierflg); + ptMinuit->mnparm(2, "b", Vstart[2], Step[2],-1e5,1e5,Ierflg); + + ptMinuit->mnparm(3, "X1", 0.0, Step[3],-1.,1.,Ierflg); + ptMinuit->mnparm(4, "Y1", 0.0, Step[4],-1.,1.,Ierflg); + + ptMinuit->mnparm(5, "X2", r1.X(), Step[5],-1.,1.,Ierflg); + ptMinuit->mnparm(6, "Y2", r1.Y(), Step[6],-1.,1.,Ierflg); + + ptMinuit->mnparm(7, "X3", r2.X(), Step[7],-1.,1.,Ierflg); + ptMinuit->mnparm(8, "Y3", r2.Y(), Step[8],-1.,1.,Ierflg); + + for(int i = 3; i<9;i++){ + ptMinuit->FixParameter(i); + } + Arglist[0] = 500; //Max calls + Arglist[1] = 1.; //TOLERANCE + ptMinuit->mnexcm("MIGRAD", Arglist ,2,Ierflg); + + // Print results + cout << "\nPrint results from minuit\n"; + double fParamValbis; + double fParamErrbis; + ptMinuit->GetParameter(0,fParamValbis,fParamErrbis); + rfit=fParamValbis; + cout << "R=" << fParamValbis << "\n"; + ptMinuit->GetParameter(1,fParamValbis,fParamErrbis); + afit=fParamValbis; + cout << "a =" << fParamValbis << "\n"; + ptMinuit->GetParameter(2,fParamValbis,fParamErrbis); + bfit=fParamValbis; + cout << "b =" << fParamValbis << "\n"; + TVector3 CircleParam(afit,bfit,rfit); + + return CircleParam; +} +//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>> +Double_t Circle_Fit(double x,double y,double *par) +{ + double value=par[0]-sqrt( pow(x-par[1],2)+pow(y-par[2],2) ); + return value; +} +//<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>> +void calc_chi_square_Circle(Int_t &npar, Double_t *gin, Double_t &f, Double_t *par, Int_t iflag) +{ + + double chisq = 0; + double x,y,z; + double errorz=0.001; + int iNum=3; + for (int i=0;i2 +// Last Modified: JB, 2010/11/25 Use new DPrecAlign mechanism from DPlane +// Last Modified: JB, 2011/07/21 in Analyse, seed pixel management for large clusters +// Last Modified: JB, 2011/07/21 new method distance to a point +// Last Modified: JB, 2012/05/11 cluster max size extended to 500 +// Last Modified: JB, 2012/08/18 update of Analyse with DStrip objects +// Last Modified, JB+SS 2013/06/23 update of Analyse with DPixel objects +// Last Modified: BH 2013/08/20, warning corrections from clang +// Last Modified: JB, 2013/09/29 Analyse(*DPixel) +// Last Modified: JB, 2013/11/08 Analyse(*DPixel) and Analyse(*DStrip) +// Last Modified: VR, 2014/07/16 Add field ClusterLimitRadius and create DHit::Analyse_2_cog() +// Last Modified: VR, 2014/08/28 add mecanism to keep untracked hits from last event +// Last Modified: LC, 2014/12/08 add copy operator to save mini-vectors Hits. (See DLadder::MakeMiniVectors) +// Last Modified: LC, 2014/12/15 class DHitMonteCarlo included in class DHit +// Last Modified: LC, 2014/12/15 Now, DHit contains a new vector of MC Info : std::vector _monteCarloInfo +// Last Modified: AP, 2015/05/21 The iterative clustering algorithm (Analyse_Iterative), now identifies big clusters +// with high pixel multiplicity (> 100) which are caused maybe by nuclear interactions. +// The pixels in these big clusters are excluded from futher analysis. +// Last Modified: JB, 2015/05/25 Hit timestamp added +// Last Modified: JB, 2015/05/26 usage of TimeLimit between seed and neighbours +// Last Modified: AP, 2015/07/30 added a new private variable fMCPartID for simulation purposes with the ID number of the particle generating the hit +// Last Modified: AP, 2015/07/30 added a couple of functions SetMCPartID and GetMCPartID to set and get fMCPartID +// Last Modified: AP, 2016/07/28 added a new private variable fStripsFromMCPartID for simulation purposes with the number of strips/pixels from MC particle fMCPartID +// Last Modified: AP, 2016/07/28 added a couple of functions SetStripsFromMCPartID and GetStripsFromMCPartID to set and get fStripsFromMCPartID +// Last Modified: AP, 2017/05/09 added a function DoMCA to perform main component analysis + + //////////////////////////////////////////////////////////// + // // + // Class Description of DHit // + // + // When Plane readout mode is < 100 (no zero suppression) + // call Analyse( GetStrip( stPhys)) + // When Plane readout mode is >= 100 (zero suppression) + // HitFinder == 0 => Analyse( seed, fListOfPixels) + // HitFinder == 1 => Analyse_Interative( seed, fListOfPixels) + // HitFinder == 2 => Analyse_2_cgo( seed, fListOfPixels) + // + //////////////////////////////////////////////////////////// + +#include "DHit.h" +#include "DTrack.h" +#include "DPlane.h" +#include "DCut.h" +#include "DR3.h" +#include "DStrip.h" +#include "DSetup.h" +#include "DGlobalTools.h" + +//extern int fopen_lockfile(); // JB, removed for inline compilation +//extern FILE * VG_Lockfile; + + +ClassImp(DHit) // Description of a Hit + +//______________________________________________________________________________ +// +DHit::DHit() +{ + // DHit default ctr + fIsFromPreviousEvent = 0; // VR 2014.08.28 + fIfMonteCarlo = 0; // LC 2014/12/15 + fMCHitID = -1; // AP 2015/07/30 + fStripsFromMCHitID = 0; // AP 2016/07/28 + fStripsInClusterFound = 0; + fNormMaxStd = -1000; // AP 2017/05/09 + fNormMinStd = -1000; // AP 2017/05/09 + fMainAxisPhi = -1000; // AP 2017/05/09 +} +//______________________________________________________________________________ +// +DHit::DHit(DR3 &aPosition, DPlane& aPlane, Int_t aHitNumber) +{ + // DHit constructor + // + // Last Modified: JB 2009/05/22 + + fHitNumber = aHitNumber; + fFound = kFALSE; // JB 2009/05/22 + + if(fHitNumber>0) { + fPositionHit = new DR3(aPosition); + fPositionHitCG = new DR3(aPosition); + fPositionHitEta = new DR3(aPosition); + fPositionHitCG33 = new DR3(aPosition); + fPositionHitCG22 = new DR3(aPosition); + fPositionHitEta22 = new DR3(aPosition); + fResolutionHit = new DR3(0.0,0.0,0.0); + + fPlane = &aPlane; + fDebugHit = fPlane->GetDebug(); + fCut = fPlane->GetCut(); + fClusterPulseSum = 0.0; + fClusterLimit = new DR3(fCut->GetClusterLimit()); + fClusterLimitRadius = fCut->GetClusterLimitRadius(); + + fStripPitch = &fPlane->GetStripPitch(); + fStripsInClusterArea = fCut->GetStripsInClusterArea(); + + fPositionAlgorithm = fPlane->GetSetup().GetPlanePar(fPlane->GetPlaneNumber()).HitPositionAlgorithm; + fStripsInClusterDemanded = 0; + + //fTableSize = 700;// VR 2014.08.28 + fTableSize = (fPlane->GetSetup()).GetPlanePar(fPlane->GetPlaneNumber()).MaxNStrips; + + tPixelIndexList = new Int_t[fTableSize]; //AP 2016/07/28 + fStripIndexArray = new Int_t[fTableSize]; // sufficient big, [fStripsInClusterArea]; + fStripIndex = new Int_t[fTableSize]; // JB 2009/05/12 + fStripPulseHeight = new Float_t[fTableSize]; // [fStripsInClusterArea]; + fStripNoise = new Float_t[fTableSize]; // YV 27/11/09 + fStripDistanceU = new Float_t[fTableSize]; // [fStripsInClusterArea]; + fStripDistanceV = new Float_t[fTableSize]; // [fStripsInClusterArea]; + fSNneighbour = -1.0; + + fStoNover2 = 0; // MB/12/11/2010 + fIsFromPreviousEvent = 0;// VR 2014.08.28 + fTimestamp = 0; // JB 2015/05/25 + } + + // Hit Monte Carlo + fIfMonteCarlo = 0; + + fMCHitID = -1; // AP 2015/07/30 + fStripsFromMCHitID = 0; // AP 2016/07/28 + fStripsInClusterFound = 0; + + fNormMaxStd = -1000; // AP 2017/05/09 + fNormMinStd = -1000; // AP 2017/05/09 + fMainAxisPhi = -1000; // AP 2017/05/09 + +} +//______________________________________________________________________________ +// +DHit::DHit(DR3 &aPosition, DPlane& aPlane, Int_t aHitNumber, std::vector& monteCarloVector) +{ + // DHit constructor + // + // Last Modified: JB 2009/05/22 + + fHitNumber = aHitNumber; + fFound = kFALSE; // JB 2009/05/22 + + if(fHitNumber>0) { + fPositionHit = new DR3(aPosition); + fPositionHitCG = new DR3(aPosition); + fPositionHitEta = new DR3(aPosition); + fPositionHitCG33 = new DR3(aPosition); + fPositionHitCG22 = new DR3(aPosition); + fPositionHitEta22 = new DR3(aPosition); + fResolutionHit = new DR3(0.0,0.0,0.0); + + fPlane = &aPlane; + fDebugHit = fPlane->GetDebug(); + fCut = fPlane->GetCut(); + fClusterPulseSum = 0.0; + fClusterLimit = new DR3(fCut->GetClusterLimit()); + fClusterLimitRadius = fCut->GetClusterLimitRadius(); + + fStripPitch = &fPlane->GetStripPitch(); + fStripsInClusterArea = fCut->GetStripsInClusterArea(); + + fPositionAlgorithm = fPlane->GetSetup().GetPlanePar(fPlane->GetPlaneNumber()).HitPositionAlgorithm; + fStripsInClusterDemanded = 0; + + //fTableSize = 500;// VR 2014.08.28 + fTableSize = (fPlane->GetSetup()).GetPlanePar(fPlane->GetPlaneNumber()).MaxNStrips; + + tPixelIndexList = new Int_t[fTableSize]; //AP 2016/07/28 + fStripIndexArray = new Int_t[fTableSize]; // sufficient big, [fStripsInClusterArea]; + fStripIndex = new Int_t[fTableSize]; // JB 2009/05/12 + fStripPulseHeight = new Float_t[fTableSize]; // [fStripsInClusterArea]; + fStripNoise = new Float_t[fTableSize]; // YV 27/11/09 + fStripDistanceU = new Float_t[fTableSize]; // [fStripsInClusterArea]; + fStripDistanceV = new Float_t[fTableSize]; // [fStripsInClusterArea]; + fSNneighbour = -1.0; + + fStoNover2 = 0; // MB/12/11/2010 + fIsFromPreviousEvent = 0;// VR 2014.08.28 + fTimestamp = 0; // JB 2015/05/25 + } + + // Hit Monte Carlo + fIfMonteCarlo = 1; + _monteCarloInfo = monteCarloVector; // LC 2014/12/15 + + fMCHitID = -1; // AP 2015/07/30 + fStripsFromMCHitID = 0; // AP 2016/07/28 + fStripsInClusterFound = 0; + + fNormMaxStd = -1000; // AP 2017/05/09 + fNormMinStd = -1000; // AP 2017/05/09 + fMainAxisPhi = -1000; // AP 2017/05/09 + +} +//______________________________________________________________________________ +// +void DHit::copy(DHit* aHit, DPlane* aPlane) // Copy with minimal information (For mini-vectors alignement) +{ + fPlane = aPlane; + fFound = kFALSE; // JB 2009/05/22 + fPositionHit = new DR3(*aHit->GetPositionCG()); + fPositionHitCG = new DR3(*aHit->GetPositionCG()); + //fPositionHitEta = new DR3(*aHit->GetPositionCG()); + //fPositionHitCG33 = new DR3(*aHit->GetPositionCG()); + //fPositionHitCG22 = new DR3(*aHit->GetPositionCG()); + //fPositionHitEta22 = new DR3(*aHit->GetPositionCG()); + + fDebugHit = fPlane->GetDebug(); + fIfMonteCarlo = 0; + //Next : Commented to reduce memory consumption + /* + fCut = fPlane->GetCut(); + fClusterPulseSum = 0.0; + fClusterLimit = new DR3(fCut->GetClusterLimit()); + + fStripPitch = &fPlane->GetStripPitch(); + fStripsInClusterArea = fCut->GetStripsInClusterArea(); + + fPositionAlgorithm = fPlane->GetSetup().GetPlanePar(fPlane->GetPlaneNumber()).HitPositionAlgorithm; + fStripsInClusterDemanded = 0; + */ + /* + tPixelIndexList = new Int_t[fTableSize]; //AP 2016/07/28 + fStripIndexArray = new Int_t[500]; // sufficient big, [fStripsInClusterArea]; + fStripIndex = new Int_t[500]; // JB 2009/05/12 + fStripPulseHeight = new Float_t[500]; // [fStripsInClusterArea]; + fStripNoise = new Float_t[500]; // YV 27/11/09 + fStripDistanceU = new Float_t[500]; // [fStripsInClusterArea]; + fStripDistanceV = new Float_t[500]; // [fStripsInClusterArea]; + fSNneighbour = -1.0; + */ + //fStoNover2 = 0; // MB/12/11/2010 + + fMCHitID = -1; // AP 2015/07/30 + fStripsFromMCHitID = 0; // AP 2016/07/28 + fStripsInClusterFound = 0; + + fNormMaxStd = -1000; // AP 2017/05/09 + fNormMinStd = -1000; // AP 2017/05/09 + fMainAxisPhi = -1000; // AP 2017/05/09 + +} +//______________________________________________________________________________ +// +void DHit::clone(DHit *original, Bool_t fullCopy)// VR 2014.08.28 +{ + fDebugHit = original->fDebugHit; + //fHitNumber = original->fHitNumber; + fFound = original->fFound; + fPositionAlgorithm = original->fPositionAlgorithm; + fPlane = original->fPlane; + *fPositionHit = *(original->fPositionHit); + *fPositionHitCG = *(original->fPositionHitCG); + *fPositionHitEta = *(original->fPositionHitEta); + *fPositionHitCG33 = *(original->fPositionHitCG33); + *fPositionHitCG22 = *(original->fPositionHitCG22); + *fPositionHitEta22 = *(original->fPositionHitEta22); + fSeedU = original->fSeedU; + fSeedV = original->fSeedV; + fClusterPulseSum = original->fClusterPulseSum; + fClusterAreaPulseSum = original->fClusterAreaPulseSum; + fClusterSignalToNoise = original->fClusterSignalToNoise; + fClusterNoiseAverage = original->fClusterNoiseAverage; + fStripsInClusterFound = original->fStripsInClusterFound; + fStripsInClusterArea = original->fStripsInClusterArea; + *fClusterLimit = *(original->fClusterLimit); + fClusterLimitRadius = original->fClusterLimitRadius; + fSeed = original->fSeed ; + fPSeed = original->fPSeed; + fCut = original->fCut; + fStripPitch = original->fStripPitch; + fPhSeed = original->fPhSeed; + fPosSeed = original->fPosSeed; + fPhLofSeed = original->fPhLofSeed; + fPosLofSeed = original->fPosLofSeed; + fPhRofSeed = original->fPhRofSeed; + fPosRofSeed = original->fPosRofSeed; + fIndexSeed = original->fIndexSeed; + fIndexLofSeed = original->fIndexLofSeed; + fIndexRofSeed = original->fIndexRofSeed; + fPhLeft = original->fPhLeft; + fPosLeft = original->fPosLeft; + fPhRight = original->fPhRight; + fPosRight = original->fPosRight; + fIndexLeft = original->fIndexLeft; + fIndexRight = original->fIndexRight; + fStoNover2 = original->fStoNover2; + fStripsInClusterDemanded = original->fStripsInClusterDemanded; + fChargeFractionDensity = original->fChargeFractionDensity; + fSNneighbour = original->fSNneighbour; + fSNseed = original->fSNseed; + fSeedPulseHeight = original->fSeedPulseHeight; + fSeedNoise = original->fSeedNoise; + fTimestamp = original->fTimestamp; // JB 2015/05/25 + fIsFromPreviousEvent = original->fIsFromPreviousEvent; + fIfMonteCarlo = original->fIfMonteCarlo; + _monteCarloInfo = original->_monteCarloInfo; // LC 2014/12/15 + fMCHitID = original->fMCHitID; // AP 2016/07/28 + fStripsFromMCHitID = original->fStripsFromMCHitID; // AP 2016/07/28 + + fNormMaxStd = original->fNormMaxStd; // AP 2017/05/09 + fNormMinStd = original->fNormMinStd; // AP 2017/05/09 + fMainAxisPhi = original->fMainAxisPhi; // AP 2017/05/09 + + + if(fullCopy) + { + for (Int_t i=0 ; ifStripNoise[i]; + tPixelIndexList[i] = original->tPixelIndexList[i]; //AP 2016/07/28 + fStripIndexArray[i] = original->fStripIndexArray[i]; + fStripIndex[i] = original->fStripIndex[i]; + fStripPulseHeight[i] = original->fStripPulseHeight[i]; + fStripDistanceU[i] = original->fStripDistanceU[i]; + fStripDistanceV[i] = original->fStripDistanceV[i]; + } + } +} + +//______________________________________________________________________________ +// +DHit::~DHit() +{ + + // DHit default destructor + + delete fPositionHit; + delete fPositionHitCG; + delete fPositionHitEta; + delete fPositionHitCG33; + delete fPositionHitCG22; + delete fPositionHitEta22; + + delete fClusterLimit; + + /* + if(fClusterLimit) delete fClusterLimit; + if(fSeed) delete fSeed; + if(fStripPitch) delete fStripPitch; + if(fCut) delete fCut; + */ + + delete tPixelIndexList; + delete fStripIndexArray; + delete fStripIndex; + delete fStripPulseHeight; + delete fStripNoise; //YV 15/10/09 + delete fStripDistanceU; + delete fStripDistanceV; + + _monteCarloInfo.clear(); + +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionUhitCG() const +{ + Float_t tUhitPos; + tUhitPos = (*fPositionHitCG)(0); + return tUhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionVhitCG() const +{ + Float_t tVhitPos; + tVhitPos = (*fPositionHitCG)(1); + return tVhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionWhitCG() const +{ + Float_t tWhitPos; + tWhitPos = (*fPositionHitCG)(2); + return tWhitPos; +} + + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionUhitEta() const +{ + Float_t tUhitPos; + tUhitPos = (*fPositionHitEta)(0); + return tUhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionVhitEta() const +{ + Float_t tVhitPos; + tVhitPos = (*fPositionHitEta)(1); + return tVhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionUhitCG33() const +{ + Float_t tUhitPos; + tUhitPos = (*fPositionHitCG33)(0); + return tUhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionVhitCG33() const +{ + Float_t tVhitPos; + tVhitPos = (*fPositionHitCG33)(1); + return tVhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionUhitCG22() const +{ + Float_t tUhitPos; + tUhitPos = (*fPositionHitCG22)(0); + return tUhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionVhitCG22() const +{ + Float_t tVhitPos; + tVhitPos = (*fPositionHitCG22)(1); + return tVhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionUhitEta22() const +{ + Float_t tUhitPos; + tUhitPos = (*fPositionHitEta22)(0); + return tUhitPos; +} + +//______________________________________________________________________________ +// +Float_t DHit::GetPositionVhitEta22() const +{ + Float_t tVhitPos; + tVhitPos = (*fPositionHitEta22)(1); + return tVhitPos; +} +//______________________________________________________________________________ +// +Float_t DHit::GetPositionUhit() const +{ + Float_t tUhitPos; + + tUhitPos = (*fPositionHit)(0); + + return tUhitPos; +} +//______________________________________________________________________________ +// +Float_t DHit::GetPositionVhit() const +{ + Float_t tVhitPos; + + tVhitPos = (*fPositionHit)(1); + + return tVhitPos; +} +//______________________________________________________________________________ +// +Float_t DHit::GetResolutionUhit() const +{ + Float_t tUhitRes; + + tUhitRes = (*fResolutionHit)(0); + + return tUhitRes; +} +//______________________________________________________________________________ +// +Float_t DHit::GetResolutionVhit() const +{ + Float_t tVhitRes; + + tVhitRes = (*fResolutionHit)(1); + + return tVhitRes; +} +//______________________________________________________________________________ +// +void DHit::SetResolutionUVhit(Float_t resolutionU, + Float_t resolutionV) { + + fResolutionHit->SetValue(resolutionU,resolutionV,0.0); + + return; +} +//______________________________________________________________________________ +// +Float_t DHit::GetPositionWhit() const +{ + Float_t tWhitPos; + + tWhitPos = (*fPositionHit)(2); + + return tWhitPos; +} + + + +// //______________________________________________________________________________ +// // +// Removed bu JB, 2009/05/12 +// Float_t DHit::GetPulseHeight(Int_t tStripIndex) +// { +// if (tStripIndex < fSeed->GetNeighbourCount() && tStripIndex >= 0) +// return fSeed->GetNeighbour(tStripIndex)->GetPulseHeight(); +// else { +// printf("WARNING DHit, request to non-existent strip neighbour"); +// return 0.; +// } +// } + +//______________________________________________________________________________ +// +Float_t DHit::Distance( DHit *aHit) { + // Return the distance between this hit and the pointed hit + // the pointed hit position (from another plane) is extrapolated to the plane of this hit + // assuming a flat slope + // + // JB, 2009/05/21 + // Modified: JB, 2010/11/25, use new method to transform from one plane to the other + + // Get position in the plane of the foreign hit + DR3 hitPosition( *(aHit->GetPosition()) ); + // printf(" hitPos(plane %d) = %f, %f\n", aHit->GetPlane()->GetPlaneNumber(), hitPosition(0), hitPosition(1)); + // Transform position in tracker (XYZ) frame + hitPosition = aHit->GetPlane()->PlaneToTracker( hitPosition); + //printf(" hitPos(tracker) = %f, %f\n", hitPosition(0), hitPosition(1)); + // Transform position in UV frame of this hit plane + hitPosition = fPlane->TrackerToPlane( hitPosition); + // printf(" hitPos(plane %d) = %f, %f\n", fPlane->GetPlaneNumber(), hitPosition(0), hitPosition(1)); + + // Now compute the distance beetween the two hits + hitPosition -= *(GetPosition()); + + // Insure that z position is 0 for 2D length computation + hitPosition.SetValue( hitPosition(0), hitPosition(1), (Float_t)0.); + //printf(" dist = %f, %f, %f = %f\n", hitPosition(0), hitPosition(1), hitPosition(2), hitPosition.Length()); + + return hitPosition.Length(); +} + +//______________________________________________________________________________ +// +Float_t DHit::DistanceMC( DHit *aHit) { + // Return the distance between this hit and the pointed hit + // the pointed hit position (from another plane) is extrapolated to the plane of this hit + // assuming a flat slope + // + // JB, 2009/05/21 + // Modified: JB, 2010/11/25, use new method to transform from one plane to the other + + // Get position in the plane of the foreign hit + DR3 hitPosition( aHit->GetMonteCarloPosition() ); + // printf(" hitPos(plane %d) = %f, %ftPixelIndexList\n", aHit->GetPlane()->GetPlaneNumber(), hitPosition(0), hitPosition(1)); + // Transform position in tracker (XYZ) frame + hitPosition = aHit->GetPlane()->PlaneToTracker( hitPosition); + //printf(" hitPos(tracker) = %f, %f\n", hitPosition(0), hitPosition(1)); + // Transform position in UV frame of this hit plane + hitPosition = fPlane->TrackerToPlane( hitPosition); + // printf(" hitPos(plane %d) = %f, %f\n", fPlane->GetPlaneNumber(), hitPosition(0), hitPosition(1)); + + // Now compute the distance beetween the two hits + hitPosition -= *(GetPosition()); + + // Insure that z position is 0 for 2D length computation + hitPosition.SetValue( hitPosition(0), hitPosition(1), (Float_t)0.); + //printf(" dist = %f, %f, %f = %f\n", hitPosition(0), hitPosition(1), hitPosition(2), hitPosition.Length()); + + return hitPosition.Length(); +} + +//______________________________________________________________________________ +// +Float_t DHit::Distance( DTrack *aTrack) { + // Return the distance between this hit and the pointed track impact in the plane + // + // JB, 2009/06/26 + + DR3 impactPosition( aTrack->Intersection( fPlane) ); + impactPosition -= *(GetPosition()); + + // Insure that z position is 0 for 2D length computation + impactPosition.SetValue( impactPosition(0), impactPosition(1), (Float_t)0.); + //printf(" dist = %f, %f, %f = %f\n", hitPosition(0), hitPosition(1), hitPosition(2), hitPosition.Length()); + + return impactPosition.Length(); +} + +//______________________________________________________________________________ +// +Float_t DHit::DistanceMC( DTrack *aTrack) { + // Return the distance between this hit and the pointed track impact in the plane + // + // JB, 2009/06/26 + + DR3 impactPosition( aTrack->Intersection( fPlane) ); + impactPosition -= GetMonteCarloPosition(); + + // Insure that z position is 0 for 2D length computation + impactPosition.SetValue( impactPosition(0), impactPosition(1), (Float_t)0.); + //printf(" dist = %f, %f, %f = %f\n", hitPosition(0), hitPosition(1), hitPosition(2), hitPosition.Length()); + + return impactPosition.Length(); +} + +//______________________________________________________________________________ +// +Float_t DHit::Distance( DR3 *aPoint) { + // Return the distance between this hit and the point + // which coordinates are assumed to be given in the frame of the hit plane. + // + // JB, 2011/07/25 + + DR3 aPosition( *aPoint ); + aPosition -= *(GetPosition()); + + // Insure that z position is 0 for 2D length computation + aPosition.SetValue( aPosition(0), aPosition(1), (Float_t)0.); + //printf(" dist = %f, %f, %f = %f\n", hitPosition(0), hitPosition(1), hitPosition(2), hitPosition.Length()); + + return aPosition.Length(); +} + +//______________________________________________________________________________ +// +Float_t DHit::DistanceMC( DR3 *aPoint) { + // Return the distance between this hit and the point + // which coordinates are assumed to be given in the frame of the hit plane. + // + // JB, 2011/07/25 + + DR3 aPosition( *aPoint ); + aPosition -= GetMonteCarloPosition(); + + // Insure that z position is 0 for 2D length computation + aPosition.SetValue( aPosition(0), aPosition(1), (Float_t)0.); + //printf(" dist = %f, %f, %f = %f\n", hitPosition(0), hitPosition(1), hitPosition(2), hitPosition.Length()); + + return aPosition.Length(); +} + +//______________________________________________________________________________ +// +Bool_t DHit::Analyse(DStrip* aStrip) +{ + // Construct a hit (or cluster) from a seed strip: + // 1) try to associate all neighbouring strips that pass selection cut + // 2) check the build hit passes all selections + // 3) order the array fStripIndexArray of neighbours by decreasing pulseheight + // 4) compute cluster charge, noise and position + // + // Return a boolean: kTRUE if hit is selected, kFalse otherwise + // + // re-organized a little bit by JB, 2007 June + // Different CoGs and Etas added by JB, 2007 Nov + // Realeasing (Found=false) neighbour strips for rejected hit, JB 2012/08/18 + // Storing noise of strips, JB 2012/08/19 + + fFound = kFALSE; // JB 2009/05/22 + fSeed = aStrip; + fPSeed = NULL; + + DStrip *aNeighbour; + Bool_t valid = kFALSE; // default return value + Bool_t tDigital = fPlane->GetStripResponseSetting(); + Int_t tStripIndex; + Int_t tStripsInClusterPossible = 0; // remove a warning + + fPositionHitCG->Zero(); // clear the position + fPositionHitEta->Zero(); + fPositionHitEta22->Zero(); // JB 2010/12/8 + fPositionHit->Zero(); + fClusterSignalToNoise = 0.0; + + fSNseed = fSeed->GetPulseHeightToNoise(); // JB 2013/11/08 + fSeedPulseHeight = fSeed->GetPulseHeight(); // Note that seed might change + fSeedNoise = fSeed->GetNoise(); + + fSeedU = fSeed->GetPosition()(0); + fSeedV = fSeed->GetPosition()(1); + fIndexSeed = fSeed->GetStripIndex(); + + // here, the neighbourhood of strips is assumed to be ordered, + // at index 0 is the seed, to higher indices + // the neighbourstrips are further away from the seed. + + Float_t tClusterAreaNoise = 0.; + fClusterAreaPulseSum = 0.; // area means the cluster except the seed + fClusterPulseSum = fSeed->GetPulseHeight(); + fClusterNoiseAverage = (fSeed->GetNoise())*(fSeed->GetNoise()); // => so it's only a seed strip in the beginning + fStripsInClusterFound = 1; + fSeed->SetFound(kTRUE); + + if (fStripsInClusterDemanded >0) // exact number demanded + tStripsInClusterPossible = fStripsInClusterDemanded; + if (fStripsInClusterDemanded == 0) // free number allowed + tStripsInClusterPossible = fSeed->GetNeighbourCount(); + + fStripIndexArray[0] = 0; // store seed index + //fStripIndex[0] = fPSeed->GetPixelIndex(); // store seed index, JB 2009/05/12 + fStripIndex[0] = fSeed->GetStripIndex(); // store seed index,changing the previous line YV 27/11/09 + fStripPulseHeight[0] = fSeed->GetPulseHeight(); // store seed pulseheight + fStripNoise[0] = fSeed->GetNoise(); // JB 2012/08/19 + fStripDistanceU[0] = 0.; // distance seed to seed = 0. + fStripDistanceV[0] = 0.; // distance seed to seed = 0. + + //=============== + // associate neighbouring strip + //=============== + tStripIndex = 1; // start with the first neighbour, in the geometric ordered neighbourhood, avoid 0 because it is the strip itself! + + if(fDebugHit>1) printf(" DHit: analyse seed strip %d (pixel %d) (q=%f) with possibly %d neighbours\n", fIndexSeed, fSeed->GetPixelIndex(), fSeed->GetPulseHeight(), tStripsInClusterPossible); + + while ( tStripIndex < tStripsInClusterPossible ) { // Loop on all possible neighbouring strips + // get the neighbour + aNeighbour = fSeed->GetNeighbour(tStripIndex); + if(fDebugHit>2) printf( " testing neighbour %d (strip index %d), found=%d\n", tStripIndex, aNeighbour->GetStripIndex(), aNeighbour->Found()); + //-------------------------------------------------- + if(!(aNeighbour->Found())){ // to avoid doublecounting of the same pixels + + fClusterAreaPulseSum += aNeighbour->GetPulseHeight(); + tClusterAreaNoise +=(aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + // clear + fStripIndexArray[tStripIndex] = tStripIndex; // put strip index in array + fStripIndex[tStripIndex] = aNeighbour->GetStripIndex(); // this is the index in the matrix, JB 2009/05/12 + fStripPulseHeight[tStripIndex] = aNeighbour->GetPulseHeight(); + fStripNoise[tStripIndex] = aNeighbour->GetNoise(); // JB 2012/08/19 + fStripDistanceU[tStripIndex] = fSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[tStripIndex] = fSeed->DistanceV(aNeighbour->GetPosition()); + // check whether strip has sufficient pulsheight-to-noise ratio + // and whether it is inside the geometrical cluster limits. + + fStripsInClusterFound++; + // increment counter of continous adjacent strips + aNeighbour->SetFound(kTRUE); + if( fDebugHit>1) printf(" neighbour %d at index %d added as %dth pixel with noise %.1f and pulseheight %.1f!\n", tStripIndex, aNeighbour->GetStripIndex(), fStripsInClusterFound-1, fStripNoise[tStripIndex], fStripPulseHeight[tStripIndex]); + fClusterNoiseAverage += (aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterPulseSum += aNeighbour->GetPulseHeight(); + //---abesson september 2005 + //(fSeed->GetSetup())->GetPlanePar(fPlane->GetPlaneNumber()).Readout; // do nothing, to be checked BH 2013/08/20 + } // end if pixel already counted + + else { + //--instead of pixels taking part in other clusters put null charge + fStripIndexArray[tStripIndex] = tStripIndex; // put strip index in array + fStripPulseHeight[tStripIndex] = 0.; + fStripsInClusterFound++; + } + + tStripIndex++; // increment the strip index counter + + } // End Loop on all possible neighbouring strips + + + //============= + // order pixels + //============= + if(fPlane->GetAnalysisMode()!=3){ // skip for binary pixel output, JB 2013/11/05 + DGlobalTools aTool; // JB 2011/07/18 + aTool.OrderIndexDes(&fStripIndexArray[0], &fStripPulseHeight[0], tStripIndex-1); + if( fDebugHit>1) { + printf("DHit: Analyse after %d strips ordering by pulseheight:\n", fStripsInClusterFound); + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + printf(" neighbour %d/%d/%d at strip index %d found with noise %.1f and pulseheight %.1f!\n", iStripIndex, fStripIndex[iStripIndex], fStripIndexArray[iStripIndex], fSeed->GetNeighbour(fStripIndexArray[iStripIndex])->GetStripIndex(), fStripNoise[fStripIndexArray[iStripIndex]], fStripPulseHeight[fStripIndexArray[iStripIndex]]); + } + } + } // end skip for binary pixel output + + //============== + // Additional properties + //============== + // The number of strips in the cluster and the cluster charge sum are now known + // Depending wether the noise is calculated or not, + // the SN ratio is a real ratio or simply the charge + // JB 2010/10/05 and 2010/10/15 to separately compute Cluster and Area values + + tClusterAreaNoise = sqrt(tClusterAreaNoise); + + if (fClusterNoiseAverage > 0.5) { + fClusterSignalToNoise = fClusterPulseSum / sqrt(fClusterNoiseAverage); + } + else { + fClusterSignalToNoise = fClusterPulseSum; + } + + if (tClusterAreaNoise > 0.5) { + fSNneighbour = fClusterAreaPulseSum / tClusterAreaNoise; + } + else { + fSNneighbour = fClusterAreaPulseSum; + } + + if(fDebugHit>1) printf(" DHit:Analyse potential hit has : PulseSum=%f, areaPulseSum=%f, noise=%f, areaNoise=%f, clusterSignalToNoise=%f, areaSignalToNoise=%f cut %f, # pixels=%d within? [%d, %d]\n", fClusterPulseSum, fClusterAreaPulseSum, fClusterNoiseAverage, tClusterAreaNoise, fClusterSignalToNoise, fSNneighbour, fCut->GetNeighbourPulseHeightToNoise(), fStripsInClusterFound, fCut->GetStripsInClusterMin(), fCut->GetStripsInClusterMax()); + + + //============== + // Select or not the hit + //============== + + if( fSNneighbour >= fCut->GetNeighbourPulseHeightToNoise() + && fCut->GetStripsInClusterMin() <= fStripsInClusterFound + && fStripsInClusterFound <= fCut->GetStripsInClusterMax() + ){ + valid = kTRUE; + + fTimestamp = 0.; // JB 2017/10/13 + + //=============== + // Compute hit position + //=============== + + // start to calculate the exact hit position, which is in first order the seed strip position + (*fPositionHit)(0) = (fSeed->GetPosition())(0); + (*fPositionHit)(1) = (fSeed->GetPosition())(1); + (*fPositionHit)(2) = (fSeed->GetPosition())(2); + + // This is the container (3D distance) for the correction to be computed with different algorithm + DR3 tCorrection ; tCorrection.SetValue(0.,0.,0.); + DR3 tCorTemp ; + + + //=============== + //---- for planes using STRIPS: + // + // ref plane condition removed by JB, 2007 June + //if(fPlane->GetStatus()<3 && fPlane->GetAnalysisMode()<2){ // select reference planes only + if(fPlane->GetAnalysisMode()<2){ // select STRIP planes + + fPhSeed = fSeed->GetPulseHeight(); + fPosSeed = fSeedU; + fPhRofSeed = fSeed->GetNeighbour(1)->GetPulseHeight(); + fPhLofSeed = fSeed->GetNeighbour(2)->GetPulseHeight(); + fPosRofSeed = (fSeed->GetNeighbour(1)->GetPosition())(0); + fPosLofSeed = (fSeed->GetNeighbour(2)->GetPosition())(0); + fIndexRofSeed = fSeed->GetNeighbour(1)->GetStripIndex(); + fIndexLofSeed = fSeed->GetNeighbour(2)->GetStripIndex(); + fIndexSeed = fSeed->GetStripIndex(); + + Float_t tSeedSign = fPhSeed/fabs(fPhSeed); + + if ( tSeedSign*fPhLofSeed > tSeedSign*fPhRofSeed ) { + fPhLeft = fPhLofSeed; + fPhRight = fPhSeed; + fPosLeft = fPosLofSeed; + fPosRight = fPosSeed; + fIndexLeft = fIndexLofSeed; + fIndexRight = fIndexSeed; + } else { + fPhLeft = fPhSeed; + fPhRight = fPhRofSeed; + fPosLeft = fPosSeed; + fPosRight = fPosRofSeed; + fIndexLeft = fIndexSeed; + fIndexRight = fIndexRofSeed; + } + + + // Charge Fraction algorithm optimizes hit position, comprises other known algorithms like + // center of gravitiy : weight_k = charge fraction + // 2 strip linear eta algorithm : center of gravity with 2 strips in cluster + // 2 strip non-linear eta : 2 strips, weights calculated from charge fraction distribution on strips + + Float_t tChargeFraction, aWeight ; + + TH1F *tChargeFractionDensityData; + Int_t tDensityBinsN, tBin; + Float_t tLL, tUL; + + Int_t tClusterType; + Int_t tHk; + + tClusterType = 2; + Float_t tDistU; + if(fPositionAlgorithm==1){ + if(fPhLeft < fPhRight){ + tChargeFraction = fPhLeft / (fPhLeft+fPhRight); // seed is on right + aWeight = tChargeFraction; // this is C.o.G. Method + tDistU = fPosRight-fPosLeft; + }else { + tChargeFraction = fPhRight / (fPhLeft+fPhRight); // seed is right + aWeight = tChargeFraction; // this is C.o.G. Method + tDistU = -fPosRight+fPosLeft; + } + tCorTemp.SetValue(tDistU,(Float_t)0.,(Float_t)0.) ; + tCorTemp *= aWeight ; + + tCorrection += tCorTemp ; + + // assign the digital strip position + *fPositionHitCG = *fPositionHit ; + // and now change u-value with CoG correction + (*fPositionHitCG) -= tCorrection ; + (*fPositionHit) = (*fPositionHitCG) ; // needed if CoG is used + } + + if ( tDigital ){ + if(fDebugHit>1) { + printf("DHit.cxx:evaluateHitCluster = Digital response only set (forgot about etaXXX.root file?) for plane %d \n",fPlane->GetPlaneNumber()); + } + + } + + else if ( fPositionAlgorithm==2){ + + tCorrection.SetValue(0.,0.,0.); + // treat seed and strip with next highest pulse (2 strips): + if(fPhLeft < fPhRight){ + tChargeFraction = fPhLeft / (fPhLeft+fPhRight); // seed is right + tDistU = fPosRight-fPosLeft; + + }else { + tChargeFraction = fPhRight / (fPhLeft+fPhRight); // seed is right + tDistU = -fPosRight+fPosLeft; + } + tHk = 1 + (tClusterType-2)*2; // so tHk = 1?? + tChargeFractionDensityData = fPlane->GetChargeFractionDensity(tHk); + tDensityBinsN = tChargeFractionDensityData->GetNbinsX(); + tLL = tChargeFractionDensityData->GetXaxis()->GetXmin(); + tUL = tChargeFractionDensityData->GetXaxis()->GetXmax(); + tBin = (Int_t)( (tChargeFraction-tLL) * tDensityBinsN/(tUL-tLL) ); + + if (tBin>tDensityBinsN) tBin = tDensityBinsN - 50; + if (tBin<0) tBin = 50; + + aWeight = tChargeFractionDensityData->GetBinContent(tBin); + tCorTemp.SetValue(tDistU,(Float_t)0.,(Float_t)0.) ; + tCorTemp *= aWeight ; + + tCorrection += tCorTemp ; + (*fPositionHit) -= tCorrection; + + } //end of if PositionAlgorithm ==2 + } // end select STRIP planes + + + //=============== + //--- for PIXEL planes + // + else { + + //================== + //Center of gravity with all the neighbours + // pay attention that pixels are ordered geometricaly from one corner to the other in the fStripDistanceU/V arrays + + tCorrection.SetValue( 0., 0., 0.); + Float_t tClusterPulseSum = 0.; + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + tCorTemp.SetValue( ((fSeed->GetPosition())(0)-fStripDistanceU[iStripIndex])*fStripPulseHeight[iStripIndex], + ((fSeed->GetPosition())(1)-fStripDistanceV[iStripIndex])*fStripPulseHeight[iStripIndex], + 0); + tCorrection += tCorTemp; + tClusterPulseSum += fStripPulseHeight[iStripIndex]; + //printf("DHit::Analyse plane %d, hit %2d, strip %2d, corr(%.2f, %.2f)=dist(%.2f, %.2f)*%.0f/%.0f\n", fPlane->GetPlaneNumber(), fHitNumber, iStripIndex, tCorrection(0), tCorrection(1), fStripDistanceU[iStripIndex], fStripDistanceV[iStripIndex], fStripPulseHeight[iStripIndex], tClusterPulseSum); + } + + *fPositionHitCG = tCorrection/tClusterPulseSum; + + //================== + //Center of gravity restricted to a 3x3 cluster + + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster33PulseSum = 0.; + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + if( fabs(fStripDistanceU[iStripIndex])<=fSeed->GetPlane()->GetStripPitch()(0) + && fabs(fStripDistanceV[iStripIndex])<=fSeed->GetPlane()->GetStripPitch()(1) + ) { // check neighbours is at most at 1 pitch from seed + tCorTemp.SetValue( ((fSeed->GetPosition())(0)-fStripDistanceU[iStripIndex])*fStripPulseHeight[iStripIndex], + ((fSeed->GetPosition())(1)-fStripDistanceV[iStripIndex])*fStripPulseHeight[iStripIndex], + 0); + tCorrection += tCorTemp; + tCluster33PulseSum += fStripPulseHeight[iStripIndex]; + //printf("DHit::Analyse plane %d, hit %2d, strip %2d, corr(%.2f, %.2f)=dist(%.2f, %.2f)*%.0f/%.0f\n", fPlane->GetPlaneNumber(), fHitNumber, iStripIndex, tCorrection(0), tCorrection(1), fStripDistanceU[iStripIndex], fStripDistanceV[iStripIndex], fStripPulseHeight[iStripIndex], tCluster33PulseSum); + } + } + *fPositionHitCG33 = tCorrection/tCluster33PulseSum; + + + //================== + //Center of gravity restricted 2x2 neighbours with the highest charge, JB Nov 2007 + // 2x2 includes the seed + + // The index of the neighbours with the highest charges are ordered in fStripIndexArray + + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster22PulseSum = 0.; + Int_t tOrderedIndex; + for( Int_t iStripIndex=0; iStripIndex < 4; iStripIndex++ ) { + tOrderedIndex = fStripIndexArray[iStripIndex]; + tCorTemp.SetValue( (fSeed->GetPosition()(0)-fStripDistanceU[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + (fSeed->GetPosition()(1)-fStripDistanceV[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + 0); + tCorrection += tCorTemp; + tCluster22PulseSum += fStripPulseHeight[tOrderedIndex]; + } + *fPositionHitCG22 = tCorrection/tCluster22PulseSum; + + + //================== + //Eta algorithm 3x3 + // correct the 3x3 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + if ( tDigital ){ // check info file was there and Eta is available + if(fDebugHit>1) { + printf(" DHit.cxx:evaluateHitCluster = Digital or CoG response only set for plane %d (forgot about etaXXX.root file?)\n",fPlane->GetPlaneNumber()); + } + } + else { + + TH1 *tEtaIntU = fPlane->GetEtaIntU(); + TH1 *tEtaIntV = fPlane->GetEtaIntV(); + Int_t iBinU = tEtaIntU->FindBin( (*fPositionHitCG33-*fPositionHit)(0) ); + Int_t iBinV = tEtaIntV->FindBin( (*fPositionHitCG33-*fPositionHit)(1) ); + Double_t corrU=0., corrV=0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU->GetNbinsX() ) corrU = tEtaIntU->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV->GetNbinsX() ) corrV = tEtaIntV->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + + *fPositionHitEta = *fPositionHit + tCorrection; + } + + //================== + //Eta algorithm 2x2 + // correct the 2x2 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + if ( tDigital ){ // check info file was there and Eta is available + if(fDebugHit>1) { + printf(" DHit.cxx:evaluateHitCluster = Digital or CoG response only set for plane %d (forgot about etaXXX.root file?)\n",fPlane->GetPlaneNumber()); + } + } + else { + + TH1 *tEtaIntU2 = fPlane->GetEtaIntU2(); + TH1 *tEtaIntV2 = fPlane->GetEtaIntV2(); + Int_t iBinU = tEtaIntU2->FindBin( (*fPositionHitCG22-*fPositionHit)(0) ); + Int_t iBinV = tEtaIntV2->FindBin( (*fPositionHitCG22-*fPositionHit)(1) ); + Double_t corrU=0., corrV=0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU2->GetNbinsX() ) corrU = tEtaIntU2->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV2->GetNbinsX() ) corrV = tEtaIntV2->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + + *fPositionHitEta22 = *fPositionHit + tCorrection; + } + + //================== + //Analog head-tail algorithm + // Algorithm used for large incident angle when seed contains little info on position + // Relies on the extreme pixels on the left and right + // tCorrection.SetValue( (fStripDistanceU[iLeft]+fStripDistanceU[iRight])/2., , 0.); + // *fPositionhitAHT = *fPositionHit - tCorrection; + + //================== + // Now choose which position is stored + if( fPositionAlgorithm==1 ) { // Center of Gravity + *fPositionHit = *fPositionHitCG; + } + else if( fPositionAlgorithm==11 ) { // Center of gravity on 3x3 + *fPositionHit = *fPositionHitCG33; + } + else if( fPositionAlgorithm==12 ) { // Center of gravity on 2x2 + *fPositionHit = *fPositionHitCG22; + } + else if( fPositionAlgorithm==2 ) { // Eta corrected from CoG 3x3 + *fPositionHit = *fPositionHitEta; + } + else if( fPositionAlgorithm==22 ) { // Eta corrected from CoG 2x2 + *fPositionHit = *fPositionHitEta22; + } + else { + printf("-*-*- WARNING: algorithm %d for position unknown, taking digital position\n", fPositionAlgorithm); + } + + } // end of PIXEL planes + + if(fDebugHit>1) printf(" hit selected with %d pixels\n", fStripsInClusterFound); + + } // end if hit selected + + // ======================== + else{ // hit rejected + valid = kFALSE; + if(fDebugHit>1) printf(" hit rejected, releasing %d pixels\n", fStripsInClusterFound-1); + + // Release the neighbouring Strips associated to the seed + // only the tested seed (Index=0) is not released + // JB 2012/08/18 + for( Int_t iStripIndex=1; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { // loop over associated strips + if(fDebugHit>2) printf(" DHit.cxx:Analyse releasing neighbour strip %d at index %d\n", iStripIndex, fStripIndex[iStripIndex]); + fSeed->GetNeighbour(iStripIndex)->SetFound(kFALSE); + } // end loop over associated strips + + } + + return valid; +} + +//______________________________________________________________________________ +// +Bool_t DHit::Analyse_Iterative(DStrip* aStrip, bool &IsBigCluster, int MaxClusterSize) +{ + // Construct a hit (or cluster) from a seed strip: + // 1) try to associate all neighbouring strips that pass selection cut + // 2) check the build hit passes all selections + // 3) order the array fStripIndexArray of neighbours by decreasing pulseheight + // 4) compute cluster charge, noise and position + // + // Return a boolean: kTRUE if hit is selected, kFalse otherwise + // + // re-organized a little bit by JB, 2007 June + // Different CoGs and Etas added by JB, 2007 Nov + // Realeasing (Found=false) neighbour strips for rejected hit, JB 2012/08/18 + // Storing noise of strips, JB 2012/08/19 + + fFound = kFALSE; // JB 2009/05/22 + fSeed = aStrip; + + DStrip *aNeighbour; + DStrip *aPixel; + Bool_t valid = kFALSE; // default return value + Bool_t tDigital = fPlane->GetStripResponseSetting(); + Int_t tStripIndex; + Int_t tStripsInClusterPossible = 0; // remove a warning + + fPositionHitCG->Zero(); // clear the position + fPositionHitEta->Zero(); + fPositionHitEta22->Zero(); // JB 2010/12/8 + fPositionHit->Zero(); + fClusterSignalToNoise = 0.0; + + fSNseed = fSeed->GetPulseHeightToNoise(); // JB 2013/11/08 + fSeedPulseHeight = fSeed->GetPulseHeight(); // Note that seed might change + fSeedNoise = fSeed->GetNoise(); + + fSeedU = fSeed->GetPosition()(0); + fSeedV = fSeed->GetPosition()(1); + fIndexSeed = fSeed->GetStripIndex(); + + // here, the neighbourhood of strips is assumed to be ordered, + // at index 0 is the seed, to higher indices + // the neighbourstrips are further away from the seed. + + Float_t tClusterAreaNoise = 0.; + fClusterAreaPulseSum = 0.; // area means the cluster except the seed + fClusterPulseSum = fSeed->GetPulseHeight(); + fClusterNoiseAverage = (fSeed->GetNoise())*(fSeed->GetNoise()); // => so it's only a seed strip in the beginning + fStripsInClusterFound = 1; + fSeed->SetFound(kTRUE); + + if (fStripsInClusterDemanded >0) // exact number demanded + tStripsInClusterPossible = fStripsInClusterDemanded; + if (fStripsInClusterDemanded == 0) // free number allowed + tStripsInClusterPossible = fSeed->GetNeighbourCount(); + + fStripIndexArray[0] = 0; // store seed index + fStripIndex[0] = fSeed->GetStripIndex(); // store seed index,changing the previous line YV 27/11/09 + fStripPulseHeight[0] = fSeed->GetPulseHeight(); // store seed pulseheight + fStripNoise[0] = fSeed->GetNoise(); // JB 2012/08/19 + fStripDistanceU[0] = 0.0; // distance seed to seed = 0. + fStripDistanceV[0] = 0.0; // distance seed to seed = 0. + + //=============== + // associate neighbouring strip + //=============== + tStripIndex = 1; // start with the first neighbour, in the geometric ordered neighbourhood, avoid 0 because it is the strip itself! + + if(fDebugHit>1) printf(" DHit: analyse seed strip %d (pixel %d) (q=%f) with possibly %d neighbours\n", fIndexSeed, fSeed->GetPixelIndex(), fSeed->GetPulseHeight(), tStripsInClusterPossible); + + if( fPlane->GetAnalysisMode() < 2) { // if analog strip readout + while ( tStripIndex < tStripsInClusterPossible ) { // Loop on all possible neighbouring strips + // get the neighbour + aNeighbour = fSeed->GetNeighbour(tStripIndex); + if(fDebugHit>2) printf( " testing neighbour %d (strip index %d), found=%d\n", tStripIndex, aNeighbour->GetStripIndex(), aNeighbour->Found()); + //-------------------------------------------------- + if(!(aNeighbour->Found())){ // to avoid doublecounting of the same pixels + + fClusterAreaPulseSum += aNeighbour->GetPulseHeight(); + tClusterAreaNoise +=(aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + // clear + fStripIndexArray[tStripIndex] = tStripIndex; // put strip index in array + fStripIndex[tStripIndex] = aNeighbour->GetStripIndex(); // this is the index in the matrix, JB 2009/05/12 + fStripPulseHeight[tStripIndex] = aNeighbour->GetPulseHeight(); + fStripNoise[tStripIndex] = aNeighbour->GetNoise(); // JB 2012/08/19 + fStripDistanceU[tStripIndex] = fSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[tStripIndex] = fSeed->DistanceV(aNeighbour->GetPosition()); + // check whether strip has sufficient pulsheight-to-noise ratio + // and whether it is inside the geometrical cluster limits. + + fStripsInClusterFound++; + // increment counter of continous adjacent strips + aNeighbour->SetFound(kTRUE); + if( fDebugHit>1) printf(" neighbour %d at index %d added as %dth pixel with noise %.1f and pulseheight %.1f!\n", tStripIndex, aNeighbour->GetStripIndex(), fStripsInClusterFound-1, fStripNoise[tStripIndex], fStripPulseHeight[tStripIndex]); + fClusterNoiseAverage += (aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterPulseSum += aNeighbour->GetPulseHeight(); + //---abesson september 2005 + //(fSeed->GetSetup())->GetPlanePar(fPlane->GetPlaneNumber()).Readout; // do nothing, to be checked BH 2013/08/20 + } // end if pixel already counted + else { + //--instead of pixels taking part in other clusters put null charge + fStripIndexArray[tStripIndex] = tStripIndex; // put strip index in array + fStripPulseHeight[tStripIndex] = 0.; + fStripsInClusterFound++; + } + + tStripIndex++; // increment the strip index counter + + } // End Loop on all possible neighbouring strips + } // end if analog strip readout + else { //if pixel analog or binary readout + //Doing a different cultering for binary readout using a iterative algorithm (most likely not optimal) + + int seedIdx = fSeed->GetStripIndex(); + int seedCol = seedIdx%fPlane->GetStripsNu(); + int seedRow = seedIdx/fPlane->GetStripsNu(); + + if(fPlane->GetAnalysisMode() == 2 && (seedCol == 0 && seedRow == 0)) return kFALSE; + + std::vector _TheClusterPixelsList; + _TheClusterPixelsList.clear(); + _TheClusterPixelsList.push_back(seedIdx); + + if(fDebugHit>1) { + cout << endl; + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Seed pixel = " << fSeed->GetStripIndex() << " at (col,lin) = (" << seedCol << "," << seedRow << ")"; + if(fPlane->GetAnalysisMode() == 2) cout << ", charge = " << fSeed->GetPulseHeight() << ", S/N = " << fSeed->GetPulseHeightToNoise(); + cout << ". Initial cluster size = " << _TheClusterPixelsList.size() << endl; + cout << endl; + } + + //SON cut for pixels in case of analog output + float SON_cut = 3.5; + + //Define a region of interest (ROI) to look for pixels to add to the seed pixel + int delta_col_ROI = 50; + int delta_row_ROI = delta_col_ROI; + std::vector _ROIlist; + _ROIlist.clear(); + for(int icol=0;icol fPlane->GetStripsNu()) continue; + + for(int irow=0;irow fPlane->GetStripsNv()) continue; + + if(testRow == seedRow && testCol == seedRow) continue; + + int testIdx = testCol + testRow*fPlane->GetStripsNu(); + aNeighbour = fPlane->GetStrip(testIdx); + + if(aNeighbour == NULL) { + cout << "WARNING:: Index " << testIdx << " is out of bounds!!!" << endl; + continue; + } + if(aNeighbour->Found()) continue; + //Only consider pixels with a minimum S/N in case of analog output sensors + if(fPlane->GetAnalysisMode() == 2 && aNeighbour->GetPulseHeightToNoise() < SON_cut) continue; + + _ROIlist.push_back(testIdx); + } + } + + if(fDebugHit>1) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Added " << _ROIlist.size() << " pixel to the ROI list." + << endl; + cout << endl; + } + + //Start iterations to include pixels neighbours to already included pixels in cluster + //Stop when no more neighbours are found + int iteration_counter = 0; + std::vector _FiredPixelsList; + do { + _FiredPixelsList.clear(); + + //Check for pixels neighbour to already included pixels + for(Int_t iPix = 0; iPix < int(_ROIlist.size()); iPix++) { // being loop over ROI pixels + aNeighbour = fPlane->GetStrip(_ROIlist[iPix]); + + int testIdx = aNeighbour->GetStripIndex(); + int testCol = testIdx%fPlane->GetStripsNu(); + int testRow = testIdx/fPlane->GetStripsNu(); + + //Now check if test pixel is neighbour to any pixel already included in cluster + for(int iPixClus=0; iPixClus < int(_TheClusterPixelsList.size()); iPixClus++) { // begin loop over pixel already included to cluster + if(_ROIlist[iPix] == _TheClusterPixelsList[iPixClus]) continue; + aPixel = fPlane->GetStrip(_TheClusterPixelsList[iPixClus]); + + int clusIdx = aPixel->GetStripIndex(); + int clusCol = clusIdx%fPlane->GetStripsNu(); + int clusRow = clusIdx/fPlane->GetStripsNu(); + + int deltaRow = abs(clusRow - testRow); + int deltaCol = abs(clusCol - testCol); + if((deltaRow == 1 && deltaCol == 0) || //pixel to the right/left + (deltaRow == 0 && deltaCol == 1) || //pixel at the top/bottom + (deltaRow == 1 && deltaCol == 1) //pixel at diagonal + ) { + + //Check if this pixel has been already added to the list of fired pixels + bool IsNotAlreadyIn = true; + for(int iNewPix=0; iNewPix < int(_FiredPixelsList.size()); iNewPix++) { + if(_ROIlist[iPix] == _FiredPixelsList[iNewPix]) { + IsNotAlreadyIn = false; + break; + } + } + if(IsNotAlreadyIn) _FiredPixelsList.push_back(_ROIlist[iPix]); + } + } // end loop over pixel already included to cluster + } //end loop over ROI pixels + + //Now add the found pixels to the cluster and remove them from the ROI list + if(fDebugHit>1) cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Found " << _FiredPixelsList.size() << " new pixels around seed pixel at iteration " << iteration_counter+1 << "!!!" << endl; + for(int iNewPix=0; iNewPix < int(_FiredPixelsList.size()); iNewPix++) { //begin loop over new cluster pixels + _TheClusterPixelsList.push_back(_FiredPixelsList[iNewPix]); + + if(fDebugHit>1) { + aPixel = fPlane->GetStrip(_FiredPixelsList[iNewPix]); + int clusIdx = aPixel->GetStripIndex(); + int clusCol = clusIdx%fPlane->GetStripsNu(); + int clusRow = clusIdx/fPlane->GetStripsNu(); + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Adding pixel " << _FiredPixelsList[iNewPix] << " at (col,lin) = (" << clusCol << "," << clusRow << ")"; + if(fPlane->GetAnalysisMode() == 2) cout << ", charge = " << aPixel->GetPulseHeight() << ", S/N = " << aPixel->GetPulseHeightToNoise(); + cout << endl; + } + + for(Int_t iPix = 0; iPix < int(_ROIlist.size()); iPix++) { // being loop over ROI pixels + if(_FiredPixelsList[iNewPix] == _ROIlist[iPix]) { + _ROIlist.erase(_ROIlist.begin() + iPix); + break; + } + } //end loop over ROI pixels + + } //end loop over new cluster pixels + if(fDebugHit>1 && int(_FiredPixelsList.size()) > 0) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Cluster size increased to " << _TheClusterPixelsList.size() << " at iteration " << iteration_counter+1 << endl; + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". ROI list size reduced to " << _ROIlist.size() << " at iteration " << iteration_counter+1 << endl; + } + if(fDebugHit>1) cout << endl; + + iteration_counter++; + } + while(int(_FiredPixelsList.size()) > 0); + _FiredPixelsList.clear(); + _ROIlist.clear(); + + if(fDebugHit>1) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Final cluster size is " << _TheClusterPixelsList.size() << " after " << iteration_counter << " iterations!" << endl; + cout << endl; + } + + + //Excluding repeated pixel. Only keeping the ones with the lowest time-stamp: + std::vector _TheClusterPixelsList_NotRepeated; + _TheClusterPixelsList_NotRepeated.clear(); + std::vector _TheClusterPixelsList_Repeated; + _TheClusterPixelsList_Repeated.clear(); + std::vector _TheClusterPixelsList_All; + _TheClusterPixelsList_All.clear(); + for(int iPixClus1=0; iPixClus1 < int(_TheClusterPixelsList.size()); iPixClus1++) { + _TheClusterPixelsList_All.push_back(_TheClusterPixelsList[iPixClus1]); + int clusIdx = (fPlane->GetStrip(_TheClusterPixelsList[iPixClus1]))->GetStripIndex(); + int theRow = clusIdx%fPlane->GetStripsNu(); + int theCol = clusIdx/fPlane->GetStripsNu(); + + //Only include in the list the pixels which are not repeated + bool IsNotRepeated = true; + for(int iPixClus2=0; iPixClus2 < int(_TheClusterPixelsList_NotRepeated.size()); iPixClus2++) { + int clusIdx2 = (fPlane->GetStrip(_TheClusterPixelsList[iPixClus2]))->GetStripIndex(); + int theRow2 = clusIdx2%fPlane->GetStripsNu(); + int theCol2 = clusIdx2/fPlane->GetStripsNu(); + + if(theRow == theRow2 && theCol == theCol2) { + if(fDebugHit>1) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Pixel " << iPixClus1+1 + << " in list at (col,lin) = (" << theCol << "," << theRow << ") is repated, the other pixel is at (col,lin) = (" + << theCol2 << "," << theRow2 << ")" + << endl; + } + //Repeated pixel + IsNotRepeated = false; + break; + } + } + //If the pixel is not already in list inclue it + if(IsNotRepeated) _TheClusterPixelsList_NotRepeated.push_back(_TheClusterPixelsList[iPixClus1]); + } + + //Fill list with the removed pixes + for(int iPixClus1=0; iPixClus1 < int(_TheClusterPixelsList.size()); iPixClus1++) { + bool IsRepeated = true; + for(int iPixClus2=0; iPixClus2 < int(_TheClusterPixelsList_NotRepeated.size()); iPixClus2++) { + if(_TheClusterPixelsList[iPixClus1] == _TheClusterPixelsList_NotRepeated[iPixClus2]) IsRepeated = false; + } + if(IsRepeated) _TheClusterPixelsList_Repeated.push_back(_TheClusterPixelsList[iPixClus1]); + } + //Declare all the pixels in the repeated list as found + for(int iPix=0;iPixGetStrip(_TheClusterPixelsList_Repeated[iPix]); + aNeighbour->SetFound(kTRUE); + } + _TheClusterPixelsList_Repeated.clear(); + + if(_TheClusterPixelsList.size() != _TheClusterPixelsList_NotRepeated.size() + && fDebugHit>1 + ) { + cout << endl; + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Cluster size previous to removing repeated pixels: " << _TheClusterPixelsList.size() + << ". Cluster size after removing repeated pixels: " << _TheClusterPixelsList_NotRepeated.size() + << ". Removed " << _TheClusterPixelsList.size() - _TheClusterPixelsList_NotRepeated.size() << " repated pixels!!!" + << endl; + cout << endl; + } + + //Now replace the ClusterPixelList by the one with the repeated pixels removed + _TheClusterPixelsList.clear(); + for(int iPixClus=0; iPixClus < int(_TheClusterPixelsList_NotRepeated.size()); iPixClus++) _TheClusterPixelsList.push_back(_TheClusterPixelsList_NotRepeated[iPixClus]); + _TheClusterPixelsList_NotRepeated.clear(); + + //Calculate the position of the center of gravity: + double COG_U = 0.0; + double COG_V = 0.0; + double TotH = 0.0; + for(int iPixClus=0; iPixClus < int(_TheClusterPixelsList.size()); iPixClus++) { + aNeighbour = fPlane->GetStrip(_TheClusterPixelsList[iPixClus]); + int clusIdx = aNeighbour->GetStripIndex(); + int clusRow = clusIdx%fPlane->GetStripsNu(); + int clusCol = clusIdx/fPlane->GetStripsNu(); + + double PixelU,PixelV,w,height; + fPlane->ComputeStripPosition(clusCol,clusRow, PixelU, PixelV, w); + height = aNeighbour->GetPulseHeight(); + + COG_U += PixelU*height; + COG_V += PixelV*height; + TotH += height; + } + COG_U /= TotH; + COG_V /= TotH; + + //Order the pixels depending of analog or digital output + for(int iii=2;iii<=int(_TheClusterPixelsList.size());iii++) { + for(int jjj=0;jjj<=int(_TheClusterPixelsList.size())-iii;jjj++) { + + if(fPlane->GetAnalysisMode() == 2) { + //In case of analog output arrange the pixels according to charge, + //from highest (seed pixels) to lowest + + double charge_jjj = (fPlane->GetStrip(_TheClusterPixelsList[jjj]))->GetPulseHeight(); + double charge_jjjp1 = (fPlane->GetStrip(_TheClusterPixelsList[jjj]))->GetPulseHeight(); + if(charge_jjj < charge_jjjp1) { + int aux_idx = _TheClusterPixelsList[jjj]; + _TheClusterPixelsList[jjj] = _TheClusterPixelsList[jjj+1]; + _TheClusterPixelsList[jjj+1] = aux_idx; + } + + } + else if(fPlane->GetAnalysisMode() == 3) { + //In case of digital output arrange the pixels according to their distance to the + //center of gravitiy, from closest (seed pixels) to farest + + double PixelU,PixelV,w; + int clusIdx, clusCol, clusRow; + + aNeighbour = fPlane->GetStrip(_TheClusterPixelsList[jjj]); + clusIdx = aNeighbour->GetStripIndex(); + clusRow = clusIdx%fPlane->GetStripsNu(); + clusCol = clusIdx/fPlane->GetStripsNu(); + fPlane->ComputeStripPosition(clusCol,clusRow, PixelU, PixelV, w); + double dist_jjj = sqrt(pow(COG_U - PixelU,2) + pow(COG_V - PixelV,2)); + + aNeighbour = fPlane->GetStrip(_TheClusterPixelsList[jjj+1]); + clusIdx = aNeighbour->GetStripIndex(); + clusRow = clusIdx%fPlane->GetStripsNu(); + clusCol = clusIdx/fPlane->GetStripsNu(); + fPlane->ComputeStripPosition(clusCol,clusRow, PixelU, PixelV, w); + double dist_jjjp1 = sqrt(pow(COG_U - PixelU,2) + pow(COG_V - PixelV,2)); + + if(dist_jjj > dist_jjjp1) { + int aux_idx = _TheClusterPixelsList[jjj]; + _TheClusterPixelsList[jjj] = _TheClusterPixelsList[jjj+1]; + _TheClusterPixelsList[jjj+1] = aux_idx; + } + } + + } + } + + std::vector *aList = fPlane->GetListOfPixels(); + int diff = 0 - aList->at(0)->GetPixelIndex(); + //cout << "i = " << 0 << ", index = " << aList->at(0)->GetPixelIndex() << ", diff = " << diff << endl; + //Hard-coded limit in the number of pixel in a cluster + //This is a way to identify cluster due to low-momentum heavy ions from fragmentation + //This should avoid crash of the code when such an event happends. This happends mainly + //for high fluxes (high trigger rates > 20kHz). + //int TheNpixelsLimit = 100; + int TheNpixelsLimit = MaxClusterSize; + if(int(_TheClusterPixelsList.size()) >= TheNpixelsLimit) { + IsBigCluster = true; + cout << endl; + double TheCol,TheLin; + fPlane->ComputeStripPosition_UVToColRow(COG_U,COG_V,TheCol,TheLin); + cout << " DHit: Analyse method found too many pixels in cluster, N-pixels = " << _TheClusterPixelsList.size() << " (Limit is set to config file value MaxNStrips " << TheNpixelsLimit + << "), for plane " << fPlane->GetPlaneNumber() << ". Seed pixel location is (col,lin) = (" << TheCol << "," << TheLin << ")" << endl; + cout << " DHit: It is likely a cluster of low-momentum heavy ion from fragmentation. Excluding pixels from further analysis" << endl; + + for(int iPix=0;iPixGetStrip(_TheClusterPixelsList_All[iPix]); + + if( fDebugHit>1) { + int clusIdx = aNeighbour->GetStripIndex(); + int clusRow = clusIdx%fPlane->GetStripsNu(); + int clusCol = clusIdx/fPlane->GetStripsNu(); + + cout << " DHit:: idx = " << _TheClusterPixelsList_All[iPix] << ", (col,lin) = (" + << clusCol << "," << clusRow << ")" + << endl; + } + aNeighbour->SetFound(kTRUE); + aList->at(_TheClusterPixelsList_All[iPix] + diff)->SetFound(kTRUE); + } + _TheClusterPixelsList.clear(); + _TheClusterPixelsList_All.clear(); + + return false; + } + _TheClusterPixelsList_All.clear(); + + + //Now fillup the cluster + tClusterAreaNoise = 0.; + fClusterAreaPulseSum = 0.0; + fClusterPulseSum = 0.0; + fClusterNoiseAverage = 0.0; + fStripsInClusterFound = 0; + + fStripIndexArray[0] = 0; + fStripIndex[0] = 0.0; + fStripPulseHeight[0] = 0.0; + fStripNoise[0] = 0.0; + fStripDistanceU[0] = 0.0; + fStripDistanceV[0] = 0.0; + for(int iPix=0;iPixGetStrip(_TheClusterPixelsList[iPix]); + aNeighbour->SetFound(kTRUE); + aList->at(_TheClusterPixelsList[iPix] + diff)->SetFound(kTRUE); + + if(iPix >= fTableSize) continue; + + fClusterAreaPulseSum += aNeighbour->GetPulseHeight(); + tClusterAreaNoise +=(aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + + // clear + fStripIndexArray[iPix] = iPix; + fStripIndex[iPix] = aNeighbour->GetStripIndex(); + fStripPulseHeight[iPix] = aNeighbour->GetPulseHeight(); + fStripNoise[iPix] = aNeighbour->GetNoise(); + fStripDistanceU[iPix] = fSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[iPix] = fSeed->DistanceV(aNeighbour->GetPosition()); + // check whether strip has sufficient pulsheight-to-noise ratio + // and whether it is inside the geometrical cluster limits. + + fStripsInClusterFound++; + // increment counter of continous adjacent strips + if( fDebugHit>1) printf(" neighbour %d at index %d added as %dth pixel with noise %.1f and pulseheight %.1f!\n", + iPix, + aNeighbour->GetStripIndex(), + fStripsInClusterFound-1, + fStripNoise[iPix], + fStripPulseHeight[iPix]); + + fClusterNoiseAverage += (aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterPulseSum += aNeighbour->GetPulseHeight(); + + } // end loop over cluster pixels + _TheClusterPixelsList.clear(); + + } // end if pixel analog or binary readout + + + //============= + // order pixels + //============= + if(fPlane->GetAnalysisMode() < 2){ // skip for binary pixel output, JB 2013/11/05 + DGlobalTools aTool; // JB 2011/07/18 + aTool.OrderIndexDes(&fStripIndexArray[0], &fStripPulseHeight[0], tStripIndex-1); + if( fDebugHit>1) { + printf("DHit: Analyse after %d strips ordering by pulseheight:\n", fStripsInClusterFound); + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + printf(" neighbour %d/%d/%d at strip index %d found with noise %.1f and pulseheight %.1f!\n", iStripIndex, fStripIndex[iStripIndex], fStripIndexArray[iStripIndex], fSeed->GetNeighbour(fStripIndexArray[iStripIndex])->GetStripIndex(), fStripNoise[fStripIndexArray[iStripIndex]], fStripPulseHeight[fStripIndexArray[iStripIndex]]); + } + } + } // end skip for binary pixel output + + //============== + // Additional properties + //============== + // The number of strips in the cluster and the cluster charge sum are now known + // Depending wether the noise is calculated or not, + // the SN ratio is a real ratio or simply the charge + // JB 2010/10/05 and 2010/10/15 to separately compute Cluster and Area values + + tClusterAreaNoise = sqrt(tClusterAreaNoise); + + if(fClusterNoiseAverage > 0.5) fClusterSignalToNoise = fClusterPulseSum / sqrt(fClusterNoiseAverage); + else fClusterSignalToNoise = fClusterPulseSum; + + if (tClusterAreaNoise > 0.5) fSNneighbour = fClusterAreaPulseSum / tClusterAreaNoise; + else fSNneighbour = fClusterAreaPulseSum; + + if(fDebugHit>1) printf(" DHit:Analyse potential hit has : PulseSum=%f, areaPulseSum=%f, noise=%f, areaNoise=%f, clusterSignalToNoise=%f, areaSignalToNoise=%f cut %f, # pixels=%d within? [%d, %d]\n", + fClusterPulseSum, + fClusterAreaPulseSum, + fClusterNoiseAverage, + tClusterAreaNoise, + fClusterSignalToNoise, + fSNneighbour, + fCut->GetNeighbourPulseHeightToNoise(), + fStripsInClusterFound, + fCut->GetStripsInClusterMin(), + fCut->GetStripsInClusterMax()); + + + //============== + // Select or not the hit + //============== + + if(fSNneighbour >= fCut->GetNeighbourPulseHeightToNoise()){ + valid = kTRUE; + + if(fPlane->GetAnalysisMode() < 2) { + if(not(fStripsInClusterFound >= fCut->GetStripsInClusterMin() && fStripsInClusterFound <= fCut->GetStripsInClusterMax())) return kFALSE; + } + + //=============== + // Compute hit position + //=============== + + // start to calculate the exact hit position, which is in first order the seed strip position + (*fPositionHit)(0) = (fSeed->GetPosition())(0); + (*fPositionHit)(1) = (fSeed->GetPosition())(1); + (*fPositionHit)(2) = (fSeed->GetPosition())(2); + + // This is the container (3D distance) for the correction to be computed with different algorithm + DR3 tCorrection ; tCorrection.SetValue(0.,0.,0.); + DR3 tCorTemp ; + + + //=============== + //---- for planes using STRIPS: + // + // ref plane condition removed by JB, 2007 June + //if(fPlane->GetStatus()<3 && fPlane->GetAnalysisMode()<2){ // select reference planes only + if(fPlane->GetAnalysisMode() < 2) { // select STRIP planes + + fPhSeed = fSeed->GetPulseHeight(); + fPosSeed = fSeedU; + fPhRofSeed = fSeed->GetNeighbour(1)->GetPulseHeight(); + fPhLofSeed = fSeed->GetNeighbour(2)->GetPulseHeight(); + fPosRofSeed = (fSeed->GetNeighbour(1)->GetPosition())(0); + fPosLofSeed = (fSeed->GetNeighbour(2)->GetPosition())(0); + fIndexRofSeed = fSeed->GetNeighbour(1)->GetStripIndex(); + fIndexLofSeed = fSeed->GetNeighbour(2)->GetStripIndex(); + fIndexSeed = fSeed->GetStripIndex(); + + Float_t tSeedSign = fPhSeed/fabs(fPhSeed); + + if(tSeedSign*fPhLofSeed > tSeedSign*fPhRofSeed ) { + fPhLeft = fPhLofSeed; + fPhRight = fPhSeed; + fPosLeft = fPosLofSeed; + fPosRight = fPosSeed; + fIndexLeft = fIndexLofSeed; + fIndexRight = fIndexSeed; + } + else { + fPhLeft = fPhSeed; + fPhRight = fPhRofSeed; + fPosLeft = fPosSeed; + fPosRight = fPosRofSeed; + fIndexLeft = fIndexSeed; + fIndexRight = fIndexRofSeed; + } + + + // Charge Fraction algorithm optimizes hit position, comprises other known algorithms like + // center of gravitiy : weight_k = charge fraction + // 2 strip linear eta algorithm : center of gravity with 2 strips in cluster + // 2 strip non-linear eta : 2 strips, weights calculated from charge fraction distribution on strips + + Float_t tChargeFraction, aWeight ; + + TH1F *tChargeFractionDensityData; + Int_t tDensityBinsN, tBin; + Float_t tLL, tUL; + + Int_t tClusterType; + Int_t tHk; + + tClusterType = 2; + Float_t tDistU; + if(fPositionAlgorithm==1) { + if(fPhLeft < fPhRight) { + tChargeFraction = fPhLeft / (fPhLeft+fPhRight); // seed is on right + aWeight = tChargeFraction; // this is C.o.G. Method + tDistU = fPosRight-fPosLeft; + } + else { + tChargeFraction = fPhRight / (fPhLeft+fPhRight); // seed is right + aWeight = tChargeFraction; // this is C.o.G. Method + tDistU = -fPosRight+fPosLeft; + } + tCorTemp.SetValue(tDistU,(Float_t)0.,(Float_t)0.) ; + tCorTemp *= aWeight ; + + tCorrection += tCorTemp ; + + // assign the digital strip position + *fPositionHitCG = *fPositionHit ; + // and now change u-value with CoG correction + (*fPositionHitCG) -= tCorrection ; + (*fPositionHit) = (*fPositionHitCG) ; // needed if CoG is used + } + + if ( tDigital ){ + if(fDebugHit>1) { + printf("DHit.cxx:evaluateHitCluster = Digital response only set (forgot about etaXXX.root file?) for plane %d \n",fPlane->GetPlaneNumber()); + } + + } + + else if(fPositionAlgorithm == 2) { + + tCorrection.SetValue(0.,0.,0.); + // treat seed and strip with next highest pulse (2 strips): + if(fPhLeft < fPhRight){ + tChargeFraction = fPhLeft / (fPhLeft+fPhRight); // seed is right + tDistU = fPosRight-fPosLeft; + + }else { + tChargeFraction = fPhRight / (fPhLeft+fPhRight); // seed is right + tDistU = -fPosRight+fPosLeft; + } + tHk = 1 + (tClusterType-2)*2; // so tHk = 1?? + tChargeFractionDensityData = fPlane->GetChargeFractionDensity(tHk); + tDensityBinsN = tChargeFractionDensityData->GetNbinsX(); + tLL = tChargeFractionDensityData->GetXaxis()->GetXmin(); + tUL = tChargeFractionDensityData->GetXaxis()->GetXmax(); + tBin = (Int_t)( (tChargeFraction-tLL) * tDensityBinsN/(tUL-tLL) ); + + if (tBin>tDensityBinsN) tBin = tDensityBinsN - 50; + if (tBin<0) tBin = 50; + + aWeight = tChargeFractionDensityData->GetBinContent(tBin); + tCorTemp.SetValue(tDistU,(Float_t)0.,(Float_t)0.) ; + tCorTemp *= aWeight ; + + tCorrection += tCorTemp ; + (*fPositionHit) -= tCorrection; + + } //end of if PositionAlgorithm ==2 + } // end select STRIP planes + + + //=============== + //--- for PIXEL planes + // + else { + //================== + //Center of gravity with all the neighbours + // pay attention that pixels are ordered geometricaly from one corner to the other in the fStripDistanceU/V arrays + tCorrection.SetValue( 0., 0., 0.); + Float_t tClusterPulseSum = 0.; + for(Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++) { + tCorTemp.SetValue(((fSeed->GetPosition())(0)-fStripDistanceU[iStripIndex])*fStripPulseHeight[iStripIndex], + ((fSeed->GetPosition())(1)-fStripDistanceV[iStripIndex])*fStripPulseHeight[iStripIndex], + 0); + tCorrection += tCorTemp; + tClusterPulseSum += fStripPulseHeight[iStripIndex]; + } + *fPositionHitCG = tCorrection/tClusterPulseSum; + + //================== + //Center of gravity restricted to a 3x3 cluster + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster33PulseSum = 0.; + for(Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + if(fabs(fStripDistanceU[iStripIndex]) <= fSeed->GetPlane()->GetStripPitch()(0) && + fabs(fStripDistanceV[iStripIndex]) <= fSeed->GetPlane()->GetStripPitch()(1)) { + // check neighbours is at most at 1 pitch from seed + tCorTemp.SetValue(((fSeed->GetPosition())(0)-fStripDistanceU[iStripIndex])*fStripPulseHeight[iStripIndex], + ((fSeed->GetPosition())(1)-fStripDistanceV[iStripIndex])*fStripPulseHeight[iStripIndex], + 0); + tCorrection += tCorTemp; + tCluster33PulseSum += fStripPulseHeight[iStripIndex]; + //printf("DHit::Analyse plane %d, hit %2d, strip %2d, corr(%.2f, %.2f)=dist(%.2f, %.2f)*%.0f/%.0f\n", fPlane->GetPlaneNumber(), fHitNumber, iStripIndex, tCorrection(0), tCorrection(1), fStripDistanceU[iStripIndex], fStripDistanceV[iStripIndex], fStripPulseHeight[iStripIndex], tCluster33PulseSum); + } + } + *fPositionHitCG33 = tCorrection/tCluster33PulseSum; + + //================== + //Center of gravity restricted 2x2 neighbours with the highest charge, JB Nov 2007 + // 2x2 includes the seed + // The index of the neighbours with the highest charges are ordered in fStripIndexArray + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster22PulseSum = 0.; + Int_t tOrderedIndex; + for(Int_t iStripIndex=0; iStripIndex < 4; iStripIndex++ ) { + tOrderedIndex = fStripIndexArray[iStripIndex]; + tCorTemp.SetValue((fSeed->GetPosition()(0)-fStripDistanceU[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + (fSeed->GetPosition()(1)-fStripDistanceV[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + 0); + tCorrection += tCorTemp; + tCluster22PulseSum += fStripPulseHeight[tOrderedIndex]; + } + *fPositionHitCG22 = tCorrection/tCluster22PulseSum; + + //================== + //Eta algorithm 3x3 + // correct the 3x3 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + if(tDigital) { // check info file was there and Eta is available + if(fDebugHit>1) printf(" DHit.cxx:evaluateHitCluster = Digital or CoG response only set for plane %d (forgot about etaXXX.root file?)\n",fPlane->GetPlaneNumber()); + } + else { + TH1 *tEtaIntU = fPlane->GetEtaIntU(); + TH1 *tEtaIntV = fPlane->GetEtaIntV(); + Int_t iBinU = tEtaIntU->FindBin( (*fPositionHitCG33-*fPositionHit)(0) ); + Int_t iBinV = tEtaIntV->FindBin( (*fPositionHitCG33-*fPositionHit)(1) ); + Double_t corrU=0., corrV=0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU->GetNbinsX() ) corrU = tEtaIntU->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV->GetNbinsX() ) corrV = tEtaIntV->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + + *fPositionHitEta = *fPositionHit + tCorrection; + } + + //================== + //Eta algorithm 2x2 + // correct the 2x2 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + if(tDigital) { // check info file was there and Eta is available + if(fDebugHit>1) printf(" DHit.cxx:evaluateHitCluster = Digital or CoG response only set for plane %d (forgot about etaXXX.root file?)\n",fPlane->GetPlaneNumber()); + } + else { + TH1 *tEtaIntU2 = fPlane->GetEtaIntU2(); + TH1 *tEtaIntV2 = fPlane->GetEtaIntV2(); + Int_t iBinU = tEtaIntU2->FindBin( (*fPositionHitCG22-*fPositionHit)(0) ); + Int_t iBinV = tEtaIntV2->FindBin( (*fPositionHitCG22-*fPositionHit)(1) ); + Double_t corrU=0., corrV=0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU2->GetNbinsX() ) corrU = tEtaIntU2->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV2->GetNbinsX() ) corrV = tEtaIntV2->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + + *fPositionHitEta22 = *fPositionHit + tCorrection; + } + + //================== + //Analog head-tail algorithm + // Algorithm used for large incident angle when seed contains little info on position + // Relies on the extreme pixels on the left and right + // tCorrection.SetValue( (fStripDistanceU[iLeft]+fStripDistanceU[iRight])/2., , 0.); + // *fPositionhitAHT = *fPositionHit - tCorrection; + + //================== + // Now choose which position is stored + if(fPositionAlgorithm == 1) *fPositionHit = *fPositionHitCG; // Center of Gravity + else if(fPositionAlgorithm == 11) *fPositionHit = *fPositionHitCG33; // Center of gravity on 3x3 + else if(fPositionAlgorithm == 12) *fPositionHit = *fPositionHitCG22; // Center of gravity on 2x2 + else if(fPositionAlgorithm == 2) *fPositionHit = *fPositionHitEta; // Eta corrected from CoG 3x3 + else if(fPositionAlgorithm == 22) *fPositionHit = *fPositionHitEta22; // Eta corrected from CoG 2x2 + else { + printf("-*-*- WARNING: algorithm %d for position unknown, taking digital position\n", fPositionAlgorithm); + } + + } // end of PIXEL planes + + if(fDebugHit>1) printf(" hit selected with %d pixels\n", fStripsInClusterFound); + + } // end if hit selected + + // ======================== + else{ // hit rejected + valid = kFALSE; + if(fDebugHit>1) printf(" hit rejected, releasing %d pixels\n", fStripsInClusterFound-1); + + // Release the neighbouring Strips associated to the seed + // only the tested seed (Index=0) is not released + // JB 2012/08/18 + for( Int_t iStripIndex=1; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { // loop over associated strips + if(fDebugHit>2) printf(" DHit.cxx:Analyse releasing neighbour strip %d at index %d\n", iStripIndex, fStripIndex[iStripIndex]); + fSeed->GetNeighbour(iStripIndex)->SetFound(kFALSE); + } // end loop over associated strips + + } + + return valid; + +} +//______________________________________________________________________________ +// +Bool_t DHit::Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixels) +{ + // Valid for sparse data acquisition + // + // Construct a hit (or cluster) from a seed pixel and the list of all fired pixels: + // 1) try to associate all neighbouring strips that pass selection cut + // 2) check the build hit passes all selections + // 3) order the array fStripIndexArray of neighbours by decreasing pulseheight + // 4) compute cluster charge, noise and position + // + // Note that the behavior of this method is affected by the AnalysisMode chosen. + // + // Return a boolean: kTRUE if hit is selected, kFalse otherwise + // + // Constructed from the original Analyse( DStrip*) by JB, 2009 April 29 + // Last modified, JB 2009/05/12 + // Last Modified, RDM 2009/08/05 for Mimosa25 + // Last Modified, JB 2009/08/21 for binary output + // Last Modified, JB 2009/08/30 for cut on #strips in cluster + // Last Modified, JB 2009/09/01 for CoG 2x2 + // Last Modified, YV 2009/11/27 for estimation of noise + // Last Modified, JB 2010/10/05 automatic management of with or without noise + // Last Modified, JB 2010/10/15 correction of previous management for Area S/N + // Last Modified, MG 2010/06/28 corrected CGs computation + // Last Modified, MB 2010/11/12 include new counting on #pixels with SN>2 + // Last Modified, JB 2011/07/21 for binary ouput, allow to reallocate seed for large clusters + // Last Modified, JB 2011/11/07 test if pixels are considered twice as neighbours + // Last Modified, JB+SS 2013/06/23 manage timestamp cut for multiframe + // Last Modified, JB 2013/11/08 store initial seed information + // Last Modified, VR 2014/07/12 Condition to look for a new seed change : cogRow type Int_t -> Double_t + // Modified: JB 2015/05/26 to introduce timestamps and TimeLimit + + if(fDebugHit>2) cout << "DHit:: Starting Analyze of potential hit nb " << fHitNumber << endl; + fFound = kFALSE; // JB 2009/05/22 + fPSeed = aListOfPixels->at( aPixelIndexInList); + DPixel *aNeighbour; + DPixel *aPixel=NULL; + Bool_t pixelTwice = kFALSE; // test if a pixel is present twice in the neighbour list + Bool_t valid = kFALSE; // default return value + Bool_t tDigital = fPlane->GetStripResponseSetting(); + Int_t tStripIndex; + Int_t tStripsInClusterPossible = 0; // remove a warning + //Int_t tPixelIndexList[500]; + Int_t tTimeLimit = fPlane->GetTimeLimit(); // 2015/05/26 + + fPositionHitCG->Zero(); // clear the position + fPositionHitEta->Zero(); + fPositionHitEta22->Zero(); // JB 2010/12/8 + fPositionHit->Zero(); + fClusterSignalToNoise = 0.0; + + fSeedU = fPSeed->GetPosition()(0); + fSeedV = fPSeed->GetPosition()(1); + fIndexSeed = fPSeed->GetPixelIndex(); + + Int_t seedRow = fPSeed->GetPixelLine(); + Int_t seedCol = fPSeed->GetPixelColumn(); + Double_t cogRow = fPSeed->GetPixelLine(); //VR 2014/07/12 + Double_t cogCol = fPSeed->GetPixelColumn(); + Int_t rowDiffMax = (Int_t)((*fClusterLimit)(0)/fPSeed->GetSize()(0))/2; + Int_t colDiffMax = (Int_t)((*fClusterLimit)(1)/fPSeed->GetSize()(1))/2; + + Int_t iSeed = 0; + + // here, the neighbourhood of strips is assumed to be ordered, + // at index 0 is the seed, to higher indices + // the neighbourstrips are further away from the seed. + + Float_t tClusterAreaNoise = 0.; + fClusterAreaPulseSum = 0.; // area means the cluster except the seed + fClusterPulseSum = fPSeed->GetPulseHeight(); + fClusterNoiseAverage = (fPSeed->GetNoise())*(fPSeed->GetNoise()); // => so it's only a seed strip in the beginning + fStripsInClusterFound = 1; + fPSeed->SetFound(kTRUE); + + + if (fStripsInClusterDemanded >0) { // exact number demanded + tStripsInClusterPossible = fStripsInClusterDemanded; + } + else if (fStripsInClusterDemanded == 0) { // number from config file, JB 2009/08/21 + tStripsInClusterPossible = fCut->GetStripsInClusterArea(); //(Int_t)pow( fClusterLimit->Length()/(fPSeed->GetSize())(0)*2+1, 2), JB 2013/08/29 to match really a rectangle + } + else { // JB 2009/08/21 + printf("DHit::Analyse WARNING limit on the # pixels in cluster %d is UNKNOWN !!\n", fStripsInClusterDemanded ); + return false; + } + + tPixelIndexList[0] = aPixelIndexInList; + fStripIndexArray[0] = 0; // place seed in position 0 of neighbour + fStripIndex[0] = fPSeed->GetPixelIndex(); // store seed index, JB 2009/05/12 + fStripPulseHeight[0] = fPSeed->GetPulseHeight(); // store seed pulseheight + fStripNoise[0] = fPSeed->GetNoise(); // store seed noise //YV 27/11/09 + fSNseed = fPSeed->GetPulseHeightToNoise(); // JB 2013/11/08 + fSeedPulseHeight = fPSeed->GetPulseHeight(); // Note that seed might change + fSeedNoise = fPSeed->GetNoise(); + fStripDistanceU[0] = 0.; // distance seed to seed = 0. + fStripDistanceV[0] = 0.; // distance seed to seed = 0. + fStoNover2 = 0; // MB/12/11/2010 + + + //=============== + // associate neighbouring pixels to seed one + //=============== + if(fDebugHit>1) printf(" DHit:Analyse hit nb %d with seed pixel index %d (%d in list, r%d, c%d) (q=%f, time=%d) with possibly %d neighbours\n", fHitNumber, fIndexSeed, aPixelIndexInList, fPSeed->GetPixelLine(), fPSeed->GetPixelColumn(), fPSeed->GetPulseHeight(), fPSeed->GetTimestamp(), tStripsInClusterPossible); + + tStripIndex = 1; // start with the first neighbour, in the geometric ordered neighbourhood, avoid 0 because it is the seed itself! + for (Int_t iPix = 0; iPix < (Int_t)aListOfPixels->size(); iPix++){ // loop over hit pixels + + aNeighbour = aListOfPixels->at(iPix); + + // Test that the pixel is actually different from the seed + // (could happen in case of bad DAQ behaviour) + // If it happens, set as true but ignore as neighbour + if( aNeighbour->GetPixelIndex() == fPSeed->GetPixelIndex() ) { + aNeighbour->SetFound(kTRUE); + if( fDebugHit>1) printf(" neighbour %d at index %d (r%d, c%d) is identical as seed at index %d => set as found and ignore!\n", tStripIndex, aNeighbour->GetPixelIndex(), aNeighbour->GetPixelLine(), aNeighbour->GetPixelColumn(), fPSeed->GetPixelIndex()); + } + + // Test if the pixel can be associated to the seed + // inside the geometrical cluster limits + // and also in the time limit using the timestamp (which are all 0 if unavailable). + // JB+SS 2013/06/23 + // Geometrical limit test changed from a single 2D distance test + // to two 1D distance test. + // to JB 2013/08/29 to match really a rectangle + if ( !aNeighbour->Found() + //&& fPSeed->Distance( *aNeighbour) < fClusterLimit->Length() + && fabs(fPSeed->DistanceU(aNeighbour->GetPosition())) <= (*fClusterLimit)(0) + && fabs(fPSeed->DistanceV(aNeighbour->GetPosition())) <= (*fClusterLimit)(1) + //&& fPSeed->GetTimestamp() == aNeighbour->GetTimestamp() + && abs(fPSeed->GetTimestamp()-aNeighbour->GetTimestamp())<=tTimeLimit + ) + { // if neighbour pixel within limits + + // Additional test to avoid counting the same pixel twice + // JB 2011/11/07 + pixelTwice = kFALSE; + for ( Int_t jPix=0; jPixat( tPixelIndexList[ jPix] ); + //if(aNeighbour->GetPixelIndex() == aPixel->GetPixelIndex()) { + // pixelTwice = kTRUE; + // break; + //} + pixelTwice |= aNeighbour->GetPixelIndex() == aPixel->GetPixelIndex(); + } // end loop on currently found pixels + + if( !pixelTwice ) { // if pixel is not counted twice + + fClusterAreaPulseSum += aNeighbour->GetPulseHeight(); + tClusterAreaNoise +=(aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterNoiseAverage += (aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterPulseSum += aNeighbour->GetPulseHeight(); + tPixelIndexList[tStripIndex] = iPix; // store the index in the original list of pixels + fStripIndexArray[tStripIndex] = tStripIndex; // put neighbour index in array (not index of full pixel list) + fStripIndex[tStripIndex] = aNeighbour->GetPixelIndex(); // this is the index in the matrix, JB 2009/05/12 + fStripPulseHeight[tStripIndex] = aNeighbour->GetPulseHeight(); + fStripNoise[tStripIndex] = aNeighbour->GetNoise(); //YV 27/11/09 + fStripDistanceU[tStripIndex] = fPSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[tStripIndex] = fPSeed->DistanceV(aNeighbour->GetPosition()); + aNeighbour->SetFound(kTRUE); + if( fDebugHit>1) printf(" neighbour %d at index %d (r%d, c%d) with pulse %.1f, time %d and distance %.1f(u=%.1f, v=%.1f) (<%.1f(u=%.1f, v=%.1f)) found!\n", + tStripIndex, + aNeighbour->GetPixelIndex(), + aNeighbour->GetPixelLine(), + aNeighbour->GetPixelColumn(), + aNeighbour->GetPulseHeight(), + aNeighbour->GetTimestamp(), + fPSeed->Distance( *aNeighbour), + fPSeed->DistanceU(aNeighbour->GetPosition()), + fPSeed->DistanceV(aNeighbour->GetPosition()), + fClusterLimit->Length(), + (*fClusterLimit)(0), + (*fClusterLimit)(1)); + tStripIndex++; // increment the strip index counter + fStripsInClusterFound++; + + // For binary ouput, dynamically change the seed pixel if + // there are more than 4 pixels found already, + // and the current seed is distant by more than half of the defined cluster limit + // If so, then choose the seed as the pixel nearest to the center of gravity of all pixels + // JB 2011/07/21 + if( fPlane->GetAnalysisMode() == 3) { // if binary readout + aPixel=NULL; + Int_t iNewSeed = iSeed; + + //VR 2014/07/12 calcul in Double_t + cogRow = (Double_t(aNeighbour->GetPixelLine()) + cogRow * Double_t(fStripsInClusterFound-1)) / Double_t(fStripsInClusterFound); + cogCol = (Double_t(aNeighbour->GetPixelColumn()) + cogCol * Double_t(fStripsInClusterFound-1)) / Double_t(fStripsInClusterFound); + + if(fDebugHit>1) printf( "DHit::Analyze updating cog(%1.2f,%1.2f) / seed(%d,%d)\n", cogRow, cogCol, seedRow, seedCol); + + if( fStripsInClusterFound>4 && (abs(cogRow-Double_t(seedRow))>rowDiffMax || abs(cogCol-Double_t(seedCol))>colDiffMax) ) { // if condition to update seed + + if(fDebugHit>1) printf( "DHit::Analyze need to update the seed pixel cog(%1.2f,%1.2f) - seed(%d,%d) > max(%d,%d)\n", cogRow, cogCol, seedRow, seedCol, rowDiffMax, colDiffMax); + for( Int_t jPix=0; jPixat( tPixelIndexList[ jPix] ); + if( pow((cogRow-Double_t(aPixel->GetPixelLine())),2) + pow((cogCol-Double_t(aPixel->GetPixelColumn())),2) < pow((cogRow-Double_t(seedRow)),2)+pow((cogCol-Double_t(seedCol)),2)) { + iNewSeed = jPix; + fPSeed = aPixel; + seedRow = aPixel->GetPixelLine(); + seedCol = aPixel->GetPixelColumn(); + if(fDebugHit) printf( " new seed pixel %d at index %d (r%d,c%d)\n", iNewSeed, fPSeed->GetPixelIndex(), seedRow, seedCol); + } + } // end loop on currently found pixels + + } // end if condition to update seed + + if( iNewSeed != iSeed ) { // if seed was indeed changed + iSeed = iNewSeed; + iPix = -1; // will restart the loop over hit pixels + if(fDebugHit>1) printf( " restarting the loop over pixels\n"); + } + + } // end if binary readout + // END of dynamical change of the seed pixel + + } // end if pixel is not counted twice + + } // end if neighbour pixel within limits + + } // end loop over hit pixels + + if(fDebugHit>2) printf(" DHit:Analyse found %d valid neighbours\n", fStripsInClusterFound); + + + //============= + // order pixels + //============= + Int_t *nOfneighbours; + + // For analog readout + // re-order pixels from the highest charge to the lowest + if( fPlane->GetAnalysisMode() == 2 ) { // if analog readout + + DGlobalTools aTool; // JB 2011/07/18 + aTool.OrderIndexDes(&fStripIndexArray[0], &fStripPulseHeight[0], fStripsInClusterFound); + if( fDebugHit>2) { // display result of pixel ordering, JB 2009/05/12 + cout << " DHit:Analyse ordered list of " << fStripsInClusterFound << " pixels in candidate hit" << endl; + for( Int_t iPix=0; iPixGetAnalysisMode() == 3 ) { // if binary readout + + /* + // Redefine the seed as the one with the highest number of direct neighbours + // This is only needed when the dynamic seed reallocation is not used + // JB 2011/07/21 + nOfneighbours = new Int_t[fStripsInClusterFound]; + DPixel *aPixel=NULL, *bPixel=NULL; + for( Int_t iPix=0; iPixat( tPixelIndexList[ iPix] ); + for( Int_t jPix=0; jPix3) printf(" comparing pixels %d[%d] and %d[%d] in list of %d pixels\n", tPixelIndexList[ iPix], iPix, tPixelIndexList[ jPix], jPix, fStripsInClusterFound); + bPixel = aListOfPixels->at( tPixelIndexList[ jPix] ); + if(fDebugHit>3) printf(" comparing pixels %d[%d] (%d-%d) and %d[%d] (%d-%d) in list of %d pixels\n", tPixelIndexList[ iPix], iPix, aPixel->GetPixelLine(), aPixel->GetPixelColumn(), tPixelIndexList[ jPix], jPix, bPixel->GetPixelLine(), bPixel->GetPixelColumn(), fStripsInClusterFound); + // direct neighbours are defines as + // abs(difference in line) + abs(difference in column) = 1 + if( (abs(aPixel->GetPixelLine() - bPixel->GetPixelLine()) + + abs(aPixel->GetPixelColumn() - bPixel->GetPixelColumn()) ) == 1 ) { + nOfneighbours[ iPix] += 1; + } + } + if(fDebugHit>3) printf(" DHit::Analyse pixel %d has %d direct neighbours max%d\n", iPix, nOfneighbours[ iPix], nOfneighbours[ iSeed]); + if( nOfneighbours[ iPix] > nOfneighbours[ iSeed] || (nOfneighbours[ iPix] == nOfneighbours[ iSeed] && (aPixel->GetPixelColumn()at( tPixelIndexList[ iPix] )->GetPixelColumn() || aPixel->GetPixelLine()at( tPixelIndexList[ iSeed] )->GetPixelLine()) ) ) { // force lower lefter seed, JB 2009/09/07 + iSeed = iPix; + } + } // end loop on pixels + */ + + // swap previous info at index 0 with the one at index iSeed + // so that all arrays have seed info at index 0 + Int_t iTemp; + Float_t temp; + iTemp = tPixelIndexList[iSeed]; + tPixelIndexList[iSeed] = tPixelIndexList[0]; + tPixelIndexList[0] = iTemp; + iTemp = fStripIndexArray[iSeed]; + fStripIndexArray[iSeed] = fStripIndexArray[0]; + fStripIndexArray[0] = iTemp; + iTemp = fStripIndex[iSeed]; + fStripIndex[iSeed] = fStripIndex[0]; + fStripIndex[0] = iTemp; + temp = fStripPulseHeight[iSeed]; + fStripPulseHeight[iSeed] = fStripPulseHeight[0]; + fStripPulseHeight[0] = temp; + + // need to update some variables + // to take into account the new seed definition + fPSeed = aListOfPixels->at( tPixelIndexList[ 0] ); + fSeedU = fPSeed->GetPosition()(0); + fSeedV = fPSeed->GetPosition()(1); + fIndexSeed = fPSeed->GetPixelIndex(); + for( Int_t iPix=1; iPixat( tPixelIndexList[ iPix]); + fStripDistanceU[iPix] = fPSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[iPix] = fPSeed->DistanceV(aNeighbour->GetPosition()); + } + + if( fDebugHit>2 ) { + printf(" DHit:Analyse seed is now pixel %d in list, index %d, with %d direct neighbours\n", tPixelIndexList[ 0], fIndexSeed, fStripsInClusterFound); + } + + } // end if binary readout + + else { + printf("DHit::Analyse WARNING analysis mode %d UNKNOWN !!\n", fPlane->GetAnalysisMode() ); + return false; + } + + delete[] nOfneighbours; // remove memory leaks, BH 2013/08/21 + + //============== + // additional properties + //============== + // the number of strips in the cluster and the cluster charge sum are now known + // Depending wether the noise is calculated or not, + // the SN ratio is a real ratio or simply the charge + // JB 2010/10/05 and 2010/10/15 to separately compute Cluster and Area values + + tClusterAreaNoise = sqrt(tClusterAreaNoise); + + if (fClusterNoiseAverage > 0.5) { + fClusterSignalToNoise = fClusterPulseSum / sqrt(fClusterNoiseAverage); + } + else { + fClusterSignalToNoise = fClusterPulseSum; + } + if (tClusterAreaNoise > 0.5) { + fSNneighbour = fClusterAreaPulseSum / tClusterAreaNoise; + } + else { + fSNneighbour = fClusterAreaPulseSum; + } + + // Number of pixels with 2*pitch of the seed with S/N>2. + // MB/12/11/2010 + if( fPlane->GetAnalysisMode() <= 2 ) { + for( Int_t iPix=0; iPixat( tPixelIndexList[iPix] ); + if ( fPSeed->Distance( *aNeighbour) <= 2*(*fStripPitch)(0) && aNeighbour->GetPulseHeightToNoise() >= 2 ){ + fStoNover2++; + } + if(fDebugHit>1) cout<<" DHit:Analyse StoNover2 = "<Distance( *aNeighbour) = "<Distance( *aNeighbour)<<" SNR "<GetPulseHeightToNoise()<<" aNeighbour->GetFound() = "<< aNeighbour->Found()<GetTimestamp(); // JB 2015/05/25 + + if(fDebugHit>2) printf(" DHit:Analyse potential hit has : PulseSum=%f, areaPulseSum=%f, noise=%f, areaNoise=%f, clusterSignalToNoise=%f, areaSignalToNoise=%f cut %f, # pixels=%d within? [%d, %d], stover2=%d, time=%d\n", fClusterPulseSum, fClusterAreaPulseSum, fClusterNoiseAverage, tClusterAreaNoise, fClusterSignalToNoise, fSNneighbour, fCut->GetNeighbourPulseHeightToNoise(), fStripsInClusterFound, fCut->GetStripsInClusterMin(), fCut->GetStripsInClusterMax(), fStoNover2, fTimestamp); + + + //=============== + // Compute hit position + //=============== + + // start to calculate the exact hit position, which is in first order the seed strip position + (*fPositionHit)(0) = (fPSeed->GetPosition())(0); + (*fPositionHit)(1) = (fPSeed->GetPosition())(1); + (*fPositionHit)(2) = (fPSeed->GetPosition())(2); + + // This is the container (3D distance) for the correction to be computed with different algorithm + DR3 tCorrection ; tCorrection.SetValue(0.,0.,0.); + DR3 tCorTemp ; + + //=============== + //--- for PIXEL planes + // + if( fPlane->GetAnalysisMode() >= 2 ) { // if pixel mode + + // Cut on the charge or on the charge/noise (See above) + // Cut on # pixels in hit added, JB 2009/08/30 + + if( fSNneighbour >= fCut->GetNeighbourPulseHeightToNoise() + && fCut->GetStripsInClusterMin() <= fStripsInClusterFound + && fStripsInClusterFound <= fCut->GetStripsInClusterMax() + //&& fStoNover2 >=4 // MB 2010/11/12 + ){ + valid = kTRUE; + }else{ + valid = kFALSE; + } + + //RDM050809 for M25 begin +// Float_t cut1[2]; +// Float_t cut2[2]; +// if(fPlane->GetPlaneNumber()==1) {cut1[0]=0. ;cut1[1]=-2100.;cut2[0]=0.;cut2[1]=-2250.;} +// else if(fPlane->GetPlaneNumber()==2){cut1[0]=2000.;cut1[1]=0. ;cut2[0]=0.;cut2[1]=-2350.;} +// else if(fPlane->GetPlaneNumber()==3){cut1[0]= 450.;cut1[1]=-1800.;cut2[0]=0.;cut2[1]=-2350;} +// else if(fPlane->GetPlaneNumber()==4){cut1[0]=1700.;cut1[1]= -500.;cut2[0]=0.;cut2[1]=-2250;} + +// //for M24 +// if(fPlane->GetPlaneNumber()==1) {cut1[0]=1000.;cut1[1]=-1600.;cut2[0]=1800.;cut2[1]=-2250.;} +// else if(fPlane->GetPlaneNumber()==2){cut1[0]=2200.;cut1[1]=-600. ;cut2[0]=1800.;cut2[1]=-2350.;} +// else if(fPlane->GetPlaneNumber()==3){cut1[0]=1000.;cut1[1]=-1500.;cut2[0]=1800.;cut2[1]=-2350;} +// else if(fPlane->GetPlaneNumber()==4){cut1[0]=2000.;cut1[1]=-1000.;cut2[0]=2000.;cut2[1]=-2250;}*/ + +// if((fPSeed->GetPosition()(0)>cut1[0] || fPSeed->GetPosition()(0)GetPosition()(1)>cut2[0] || fPSeed->GetPosition()(1)GetPlaneNumber()<1 ) valid=kFALSE; + //RDM050809 for M25 end //in case you want to use this cut, put <5 instead of <1 in the last "if" line + + // now compute position correction wrt seed position depending on the required algorithm + if( valid) { + + if(fDebugHit>2) printf(" DHit:Analyse hit is valid!\n"); + + //================== + //Center of gravity with all the neighbours + // pay attention that pixels are ordered geometricaly from one corner to the other in the fStripDistanceU/V arrays + + tCorrection.SetValue( 0., 0., 0.); + Float_t tClusterPulseSum = 0.; + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + + // Computation without the fStripDistance array, MG 2010/06/28 + aNeighbour = aListOfPixels->at( tPixelIndexList[ iStripIndex]); + tCorTemp.SetValue( aNeighbour->GetPosition()(0)*aNeighbour->GetPulseHeight(), + aNeighbour->GetPosition()(1)*aNeighbour->GetPulseHeight(), 0); + tCorrection += tCorTemp; + tClusterPulseSum += aNeighbour->GetPulseHeight(); + + // "Old" computation with the fStripDistance array + /* + tCorTemp.SetValue( ((fPSeed->GetPosition())(0)-fStripDistanceU[iStripIndex])*fStripPulseHeight[iStripIndex], + ((fPSeed->GetPosition())(1)-fStripDistanceV[iStripIndex])*fStripPulseHeight[iStripIndex], + 0); + tCorrection += tCorTemp; + tClusterPulseSum += fStripPulseHeight[iStripIndex]; + */ + //printf("DHit::Analyse plane %d, hit %2d, strip %2d, corr(%.2f, %.2f)=dist(%.2f, %.2f)*%.0f/%.0f\n", fPlane->GetPlaneNumber(), fHitNumber, iStripIndex, tCorrection(0), tCorrection(1), fStripDistanceU[iStripIndex], fStripDistanceV[iStripIndex], fStripPulseHeight[iStripIndex], tClusterPulseSum); + } + + *fPositionHitCG = tCorrection/tClusterPulseSum; + fIfMonteCarlo = fPSeed->IfMonteCarlo(); + if(fIfMonteCarlo==1) _monteCarloInfo = fPSeed->GetMonteCarloInfo(); + //================== + //Center of gravity restricted to a 3x3 cluster + + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster33PulseSum = 0.; + + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + + if( fabs(fStripDistanceU[iStripIndex])<=fPSeed->GetSize()(0) + && fabs(fStripDistanceV[iStripIndex])<=fPSeed->GetSize()(1) ) { // check neighbours is at most at 1 pitch from seed + // Computation without the fStripDistance array, MG 2010/06/28 + aNeighbour = aListOfPixels->at( tPixelIndexList[ iStripIndex]); + tCorTemp.SetValue( aNeighbour->GetPosition()(0)*aNeighbour->GetPulseHeight(), + aNeighbour->GetPosition()(1)*aNeighbour->GetPulseHeight(), + 0); + tCorrection += tCorTemp; + tClusterPulseSum += aNeighbour->GetPulseHeight(); + + // "Old" computation with the fStripDistance array + /* + tCorTemp.SetValue( ((fPSeed->GetPosition())(0)-fStripDistanceU[iStripIndex])*fStripPulseHeight[iStripIndex], + ((fPSeed->GetPosition())(1)-fStripDistanceV[iStripIndex])*fStripPulseHeight[iStripIndex], + 0); + tCorrection += tCorTemp; + tClusterPulseSum += fStripPulseHeight[iStripIndex]; + */ + //printf("DHit::Analyse plane %d, hit %2d, strip %2d, corr(%.2f, %.2f)=dist(%.2f, %.2f)*%.0f/%.0f\n", fPlane->GetPlaneNumber(), fHitNumber, iStripIndex, tCorrection(0), tCorrection(1), fStripDistanceU[iStripIndex], fStripDistanceV[iStripIndex], fStripPulseHeight[iStripIndex], tCluster33PulseSum); + } + } + *fPositionHitCG33 = tCorrection/tCluster33PulseSum; + + + //================== + //Center of gravity restricted 2x2 neighbours with the highest charge, JB Nov 2007 + // 2x2 includes the seed + + // The index of the neighbours with the highest charges are ordered in fStripIndexArray + + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster22PulseSum = 0.; + Int_t tOrderedIndex; + for( Int_t iStripIndex=0; iStripIndex < TMath::Min( 4, fStripsInClusterFound); iStripIndex++ ) { // limit changed for sparsified data, JB 2009/09/01 + tOrderedIndex = fStripIndexArray[iStripIndex]; + tCorTemp.SetValue( (fPSeed->GetPosition()(0)-fStripDistanceU[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + (fPSeed->GetPosition()(1)-fStripDistanceV[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + 0); + tCorrection += tCorTemp; + tCluster22PulseSum += fStripPulseHeight[tOrderedIndex]; + } + *fPositionHitCG22 = tCorrection/tCluster22PulseSum; + + + //================== + //Eta algorithm 3x3 + // correct the 3x3 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + if ( tDigital ){ // check info file was there and Eta is available + if(fDebugHit>1 && (fPositionAlgorithm==2 || fPositionAlgorithm==22)) printf(" DHit.cxx:Analyse Digital or CoG response only set for plane %d (forgot about etaXXX.root file?)\n",fPlane->GetPlaneNumber()); + } + else { + + TH1 *tEtaIntU = fPlane->GetEtaIntU(); + TH1 *tEtaIntV = fPlane->GetEtaIntV(); + Int_t iBinU = tEtaIntU->FindBin( (*fPositionHitCG33-*fPositionHit)(0) ); + Int_t iBinV = tEtaIntV->FindBin( (*fPositionHitCG33-*fPositionHit)(1) ); + Double_t corrU=0., corrV=0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU->GetNbinsX() ) corrU = tEtaIntU->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV->GetNbinsX() ) corrV = tEtaIntV->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + if( fDebugHit>1) printf(" Eta correction/digital is (%.1f, %.1f)\n", corrU, corrV); + *fPositionHitEta = *fPositionHit + tCorrection; + + //================== + //Eta algorithm 2x2 + // correct the 2x2 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + tEtaIntU = fPlane->GetEtaIntU2(); + tEtaIntV = fPlane->GetEtaIntV2(); + iBinU = tEtaIntU->FindBin( (*fPositionHitCG22-*fPositionHit)(0) ); + iBinV = tEtaIntV->FindBin( (*fPositionHitCG22-*fPositionHit)(1) ); + corrU = corrV = 0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU->GetNbinsX() ) corrU = tEtaIntU->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV->GetNbinsX() ) corrV = tEtaIntV->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + + *fPositionHitEta22 = *fPositionHit + tCorrection; + + } // end if tDigital + + //================== + //Analog head-tail algorithm + // Algorithm used for large incident angle when seed contains little info on position + // Relies on the extreme pixels on the left and right + // tCorrection.SetValue( (fStripDistanceU[iLeft]+fStripDistanceU[iRight])/2., , 0.); + // *fPositionhitAHT = *fPositionHit - tCorrection; + + //================== + // Now choose which position is stored + if( fPositionAlgorithm==0 ) { // keep Seed position + } + else if( fPositionAlgorithm==1 ) { // Center of Gravity + *fPositionHit = *fPositionHitCG; + } + else if( fPositionAlgorithm==11 ) { // Center of gravity on 3x3 + *fPositionHit = *fPositionHitCG33; + } + else if( fPositionAlgorithm==12 ) { // Center of gravity on 2x2 + *fPositionHit = *fPositionHitCG22; + } + else if( fPositionAlgorithm==2 ) { // Eta corrected from CoG 3x3 + *fPositionHit = *fPositionHitEta; + } + else if( fPositionAlgorithm==22 ) { // Eta corrected from CoG 2x2 + *fPositionHit = *fPositionHitEta22; + } + else { + printf("-*-*- WARNING: algorithm %d for position unknown, taking digital position\n", fPositionAlgorithm); + } + if(fDebugHit>1) printf(" DHit.cxx:Analyse pos algo %d requested, seed[%d-%d]=(%.1f, %.1f), CG(%.1f, %.1f), CG33(%.1f, %.1f), eta(%.1f, %.1f), eta22(%.1f, %.1f)\n", fPositionAlgorithm, fPSeed->GetPixelLine(), fPSeed->GetPixelColumn(), fSeedU, fSeedV, (*fPositionHitCG)(0), (*fPositionHitCG)(1), (*fPositionHitCG33)(0), (*fPositionHitCG33)(1), (*fPositionHitEta)(0), (*fPositionHitEta)(1), (*fPositionHitEta22)(0), (*fPositionHitEta22)(1)); + + } //end if valid + + } // end if PIXEL mode + + + // Release the neighbouring Pixels associated to the seed if the pixel is finally not selected + // only the tested seed (Index=0) is not released + // JB 2009/05/10 + if( !valid ) { + if(fDebugHit>1) printf(" DHit.cxx:Analyse hit NOT selected, releasing %d pixels\n", fStripsInClusterFound-1); + for (Int_t iNeigh = 1; iNeigh < fStripsInClusterFound; iNeigh++){ // loop over associated pixels + if(fDebugHit>2) printf(" DHit.cxx:Analyse releasing pixel %d at index %d\n", iNeigh, fStripIndexArray[iNeigh]); + aListOfPixels->at(fStripIndexArray[iNeigh])->SetFound(kFALSE); + } // end loop over associated pixels + } // end if !valid + + else if(fDebugHit>1) { + printf(" hit nb %d selected with %d pixels\n", fHitNumber, fStripsInClusterFound); + } + + return valid; +} + +//______________________________________________________________________________ +// +Bool_t DHit::Analyse_2_cgo( Int_t aPixelIndexInList, std::vector *aListOfPixels) +{ + // Based on Analyse( Int_t aPixelIndexInList, vector *aListOfPixels) but + // Compute the center of gravity with floating point value in "pixel unit" + // Compare the ditance between cog to a pixel position (in pixel unit in floating point) with fClusterLimit to associate or not a pixel + // "Pixel unit" is choose for clarity (for debug this unity is more clear !) + // Hit is valid if fCut->GetStripsInClusterMin() <= fStripsInClusterFound && fCut->GetStripsInClusterMax() >= fStripsInClusterFound + // + // Construct a hit (or cluster) from a seed pixel and the list of all fired pixels: + // 1) try to associate all neighbouring strips that pass selection cut + // 2) check the build hit passes all selections + // 3) order the array fStripIndexArray of neighbours by decreasing pulseheight + // 4) compute cluster charge, noise and position + // + // Note that the behavior of this method is affected by the AnalysisMode chosen. + // + // Return a boolean: kTRUE if hit is selected, kFalse otherwise + // + // Constructed from the original Analyse( Int_t aPixelIndexInList, vector *aListOfPixels) by VR 2014/07/16 + // Modified: JB 2015/05/26 to introduce timestamps and TimeLimit + + fFound = kFALSE; // JB 2009/05/22 + fPSeed = aListOfPixels->at( aPixelIndexInList); + + DPixel *aNeighbour; + DPixel *aPixel=NULL; + Bool_t pixelTwice = kFALSE; // test if a pixel is present twice in the neighbour list + Bool_t valid = kFALSE; // default return value + Bool_t tDigital = fPlane->GetStripResponseSetting(); + Int_t tStripIndex; + //Int_t tPixelIndexList[500]; + + Int_t tTimeLimit = fPlane->GetTimeLimit(); // 2015/05/26 + + fPositionHitCG->Zero(); // clear the position + fPositionHitEta->Zero(); + fPositionHitEta22->Zero(); // JB 2010/12/8 + fPositionHit->Zero(); + fClusterSignalToNoise = 0.0; + + fSeedU = fPSeed->GetPosition()(0); + fSeedV = fPSeed->GetPosition()(1); + fIndexSeed = fPSeed->GetPixelIndex(); + + Float_t ClusterLimitRadiusPix = fClusterLimitRadius * 2 / (fPSeed->GetSize()(0)+fPSeed->GetSize()(1)); // assume square pixels !! + + DR3 cog(fPSeed->GetPixelLine(),fPSeed->GetPixelColumn(),0); //VR 2014/07/12 cog is in "pixels unit" for an easiest debug + + Int_t iSeed = 0; + + // here, the neighbourhood of strips is assumed to be ordered, + // at index 0 is the seed, to higher indices + // the neighbourstrips are further away from the seed. + + Float_t tClusterAreaNoise = 0.; + fClusterAreaPulseSum = 0.; // area means the cluster except the seed + fClusterPulseSum = fPSeed->GetPulseHeight(); + fClusterNoiseAverage = (fPSeed->GetNoise())*(fPSeed->GetNoise()); // => so it's only a seed strip in the beginning + fStripsInClusterFound = 1; + fPSeed->SetFound(kTRUE); + + + + tPixelIndexList[0] = aPixelIndexInList; + fStripIndexArray[0] = 0; // place seed in position 0 of neighbour + fStripIndex[0] = fPSeed->GetPixelIndex(); // store seed index, JB 2009/05/12 + fStripPulseHeight[0] = fPSeed->GetPulseHeight(); // store seed pulseheight + fStripNoise[0] = fPSeed->GetNoise(); // store seed noise //YV 27/11/09 + fSNseed = fPSeed->GetPulseHeightToNoise(); // JB 2013/11/08 + fSeedPulseHeight = fPSeed->GetPulseHeight(); // Note that seed might change + fSeedNoise = fPSeed->GetNoise(); + fStripDistanceU[0] = 0.; // distance seed to seed = 0. + fStripDistanceV[0] = 0.; // distance seed to seed = 0. + fStoNover2 = 0; // MB/12/11/2010 + + //=============== + // associate neighbouring pixels to seed one + //=============== + if(fDebugHit>1) printf(" DHit:Analyse_2_cgo seed pixel index %d (%d in list, r%d, c%d) (q=%f) with search radius max %1.2f [pixels unit] \n", fIndexSeed, aPixelIndexInList, fPSeed->GetPixelLine(), fPSeed->GetPixelColumn(), fPSeed->GetPulseHeight(), ClusterLimitRadiusPix); + + tStripIndex = 1; // start with the first neighbour, in the geometric ordered neighbourhood, avoid 0 because it is the seed itself! + for (Int_t iPix = 0; iPix < (Int_t)aListOfPixels->size(); iPix++) + { // loop over hit pixels + + aNeighbour = aListOfPixels->at(iPix); + // Test if the pixel can be associated to the seed + // inside the geometrical cluster limits + // and also in the time limit using the timestamp (which are all 0 if unavailable). + // JB+SS 2013/06/23 + // Geometrical limit test changed from a single 2D distance test + // to two 1D distance test. + // to JB 2013/08/29 to match really a rectangle + if ( !aNeighbour->Found() + //&& fPSeed->GetTimestamp() == aNeighbour->GetTimestamp() + && abs(fPSeed->GetTimestamp()-aNeighbour->GetTimestamp())<=tTimeLimit + ) + { // if neighbour pixel pass first test_delta_Col + if ( sqrt(pow((cog(0)-Float_t(aNeighbour->GetPixelLine())),2) + pow((cog(1)-Float_t(aNeighbour->GetPixelColumn())),2)) <= ClusterLimitRadiusPix) + { // is in radius ? + + // Additional test to avoid counting the same pixel twice + // JB 2011/11/07 + pixelTwice = kFALSE; + for ( Int_t jPix=0; jPixat( tPixelIndexList[ jPix] ); + //if(aNeighbour->GetPixelIndex() == aPixel->GetPixelIndex()) { + // pixelTwice = kTRUE; + // break; + //} + pixelTwice &= aNeighbour->GetPixelIndex() == aPixel->GetPixelIndex(); + } // end loop on currently found pixels + + if( !pixelTwice ) + { // if pixel is not counted twice + + fClusterAreaPulseSum += aNeighbour->GetPulseHeight(); + tClusterAreaNoise +=(aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterNoiseAverage += (aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterPulseSum += aNeighbour->GetPulseHeight(); + tPixelIndexList[tStripIndex] = iPix; // store the index in the original list of pixels + fStripIndexArray[tStripIndex] = tStripIndex; // put neighbour index in array (not index of full pixel list) + fStripIndex[tStripIndex] = aNeighbour->GetPixelIndex(); // this is the index in the matrix, JB 2009/05/12 + fStripPulseHeight[tStripIndex] = aNeighbour->GetPulseHeight(); + fStripNoise[tStripIndex] = aNeighbour->GetNoise(); //YV 27/11/09 + fStripDistanceU[tStripIndex] = fPSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[tStripIndex] = fPSeed->DistanceV(aNeighbour->GetPosition()); + aNeighbour->SetFound(kTRUE); + if( fDebugHit>1) printf(" neighbour %d at index %d (r%d, c%d) with pulse %1.2f and distance %1.2f [pixels] (u=%1.2f, v=%1.2f) (<%1.2f) [pixels] found!\n", + tStripIndex, + aNeighbour->GetPixelIndex(), + aNeighbour->GetPixelLine(), + aNeighbour->GetPixelColumn(), + aNeighbour->GetPulseHeight(), + sqrt(pow(cog(0)-Float_t(aNeighbour->GetPixelLine()),2)+pow(cog(1)-Float_t(aNeighbour->GetPixelColumn()),2)), + fabs(cog(0)-Float_t(aNeighbour->GetPixelLine())), + fabs(cog(1)-Float_t(aNeighbour->GetPixelColumn())), + ClusterLimitRadiusPix); + tStripIndex++; // increment the strip index counter + fStripsInClusterFound++; + + // For binary ouput, dynamically change the seed pixel if + // there are more than 4 pixels found already, + // and the current seed is distant by more than half of the defined cluster limit + // If so, then choose the seed as the pixel nearest to the center of gravity of all pixels + // JB 2011/07/21 + if( fPlane->GetAnalysisMode() == 3) + { // if binary readout + aPixel=NULL; + + //VR 2014/07/12 calcul in Double_t + if(fDebugHit>1) printf( " updating cog : (%1.2f,%1.2f) -> ",cog(0), cog(1)); + cog(0) = (Double_t(aNeighbour->GetPixelLine()) + cog(0) * Double_t(fStripsInClusterFound-1)) / Double_t(fStripsInClusterFound); + cog(1) = (Double_t(aNeighbour->GetPixelColumn()) + cog(1) * Double_t(fStripsInClusterFound-1)) / Double_t(fStripsInClusterFound); + if(fDebugHit>1) printf( "(%1.2f,%1.2f) \n", cog(0), cog(1)); + + + } // end if binary readout + // END of dynamical change of the seed pixel + + } // end if pixel is not counted twice + + } // end if neighbour pixel in search radius + else + { + if( fDebugHit>1) printf(" neighbour %d at index %d (r%d, c%d) with pulse %1.2f and distance %1.2f [pixels] (u=%1.2f, v=%1.2f) (>%1.2f) [pixels] to far away !\n", + tStripIndex, + aNeighbour->GetPixelIndex(), + aNeighbour->GetPixelLine(), + aNeighbour->GetPixelColumn(), + aNeighbour->GetPulseHeight(), + sqrt(pow(cog(0)-Float_t(aNeighbour->GetPixelLine()),2)+pow(cog(1)-Float_t(aNeighbour->GetPixelColumn()),2)), + fabs(cog(0)-Float_t(aNeighbour->GetPixelLine())), + fabs(cog(1)-Float_t(aNeighbour->GetPixelColumn())), + ClusterLimitRadiusPix); + } + }// end if neighbour pixel pass pre-tests + + } // end loop over hit pixels + + if(fDebugHit>2) printf(" DHit:Analyse_2_cgo found %d valid neighbours\n", fStripsInClusterFound); + + + //============= + // order pixels + //============= + Int_t *nOfneighbours = new Int_t[fStripsInClusterFound]; + + // For analog readout + // re-order pixels from the highest charge to the lowest + if( fPlane->GetAnalysisMode() == 2 ) + { // if analog readout + + DGlobalTools aTool; // JB 2011/07/18 + aTool.OrderIndexDes(&fStripIndexArray[0], &fStripPulseHeight[0], fStripsInClusterFound); + if( fDebugHit>2) { // display result of pixel ordering, JB 2009/05/12 + cout << " DHit:Analyse_2_cgo ordered list of " << fStripsInClusterFound << " pixels in candidate hit" << endl; + for( Int_t iPix=0; iPixGetAnalysisMode() == 3 ) + { // if binary readout + + /* + // Redefine the seed as the one with the highest number of direct neighbours + // This is only needed when the dynamic seed reallocation is not used + // JB 2011/07/21 + DPixel *aPixel=NULL, *bPixel=NULL; + for( Int_t iPix=0; iPixat( tPixelIndexList[ iPix] ); + for( Int_t jPix=0; jPix3) printf(" comparing pixels %d[%d] and %d[%d] in list of %d pixels\n", tPixelIndexList[ iPix], iPix, tPixelIndexList[ jPix], jPix, fStripsInClusterFound); + bPixel = aListOfPixels->at( tPixelIndexList[ jPix] ); + if(fDebugHit>3) printf(" comparing pixels %d[%d] (%d-%d) and %d[%d] (%d-%d) in list of %d pixels\n", tPixelIndexList[ iPix], iPix, aPixel->GetPixelLine(), aPixel->GetPixelColumn(), tPixelIndexList[ jPix], jPix, bPixel->GetPixelLine(), bPixel->GetPixelColumn(), fStripsInClusterFound); + // direct neighbours are defines as + // abs(difference in line) + abs(difference in column) = 1 + if( (abs(aPixel->GetPixelLine() - bPixel->GetPixelLine()) + + abs(aPixel->GetPixelColumn() - bPixel->GetPixelColumn()) ) == 1 ) { + nOfneighbours[ iPix] += 1; + } + } + if(fDebugHit>3) printf(" DHit::Analyse_2_cgo pixel %d has %d direct neighbours max%d\n", iPix, nOfneighbours[ iPix], nOfneighbours[ iSeed]); + if( nOfneighbours[ iPix] > nOfneighbours[ iSeed] || (nOfneighbours[ iPix] == nOfneighbours[ iSeed] && (aPixel->GetPixelColumn()at( tPixelIndexList[ iPix] )->GetPixelColumn() || aPixel->GetPixelLine()at( tPixelIndexList[ iSeed] )->GetPixelLine()) ) ) { // force lower lefter seed, JB 2009/09/07 + iSeed = iPix; + } + } // end loop on pixels + */ + + // swap previous info at index 0 with the one at index iSeed + // so that all arrays have seed info at index 0 + Int_t iTemp; + Float_t temp; + iTemp = tPixelIndexList[iSeed]; + tPixelIndexList[iSeed] = tPixelIndexList[0]; + tPixelIndexList[0] = iTemp; + iTemp = fStripIndexArray[iSeed]; + fStripIndexArray[iSeed] = fStripIndexArray[0]; + fStripIndexArray[0] = iTemp; + iTemp = fStripIndex[iSeed]; + fStripIndex[iSeed] = fStripIndex[0]; + fStripIndex[0] = iTemp; + temp = fStripPulseHeight[iSeed]; + fStripPulseHeight[iSeed] = fStripPulseHeight[0]; + fStripPulseHeight[0] = temp; + + // need to update some variables + // to take into account the new seed definition + fPSeed = aListOfPixels->at( tPixelIndexList[ 0] ); + fSeedU = fPSeed->GetPosition()(0); + fSeedV = fPSeed->GetPosition()(1); + fIndexSeed = fPSeed->GetPixelIndex(); + for( Int_t iPix=1; iPixat( tPixelIndexList[ iPix]); + fStripDistanceU[iPix] = fPSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[iPix] = fPSeed->DistanceV(aNeighbour->GetPosition()); + } + + if( fDebugHit>2 ) + { + printf(" DHit:Analyse_2_cgo seed is now pixel %d in list, index %d, with %d direct neighbours\n", tPixelIndexList[ 0], fIndexSeed, nOfneighbours[ iSeed]); + } + + } // end if binary readout + + else { + printf("DHit::Analyse_2_cgo WARNING analysis mode %d UNKNOWN !!\n", fPlane->GetAnalysisMode() ); + return false; + } + + delete[] nOfneighbours; // remove memory leaks, BH 2013/08/21 + + //============== + // additional properties + //============== + // the number of strips in the cluster and the cluster charge sum are now known + // Depending wether the noise is calculated or not, + // the SN ratio is a real ratio or simply the charge + // JB 2010/10/05 and 2010/10/15 to separately compute Cluster and Area values + + tClusterAreaNoise = sqrt(tClusterAreaNoise); + + if (fClusterNoiseAverage > 0.5) { + fClusterSignalToNoise = fClusterPulseSum / sqrt(fClusterNoiseAverage); + } + else { + fClusterSignalToNoise = fClusterPulseSum; + } + if (tClusterAreaNoise > 0.5) { + fSNneighbour = fClusterAreaPulseSum / tClusterAreaNoise; + } + else { + fSNneighbour = fClusterAreaPulseSum; + } + + // Number of pixels with 2*pitch of the seed with S/N>2. + // MB/12/11/2010 + if( fPlane->GetAnalysisMode() <= 2 ) { + for( Int_t iPix=0; iPixat( tPixelIndexList[iPix]); + if ( fPSeed->Distance( *aNeighbour) <= 2*(*fStripPitch)(0) && fPSeed->GetPulseHeightToNoise() >= 2 ){ + fStoNover2++; + } + if(fDebugHit>1) cout<<" DHit:Analyse_2_cgo StoNover2 = "<Distance( *aNeighbour) = "<Distance( *aNeighbour)<<" fPSeed->GetFound() = "<< fPSeed->Found()<GetTimestamp(); // JB 2015/05/25 + + if(fDebugHit>2) printf(" DHit:Analyse potential hit has : PulseSum=%f, areaPulseSum=%f, noise=%f, areaNoise=%f, clusterSignalToNoise=%f, areaSignalToNoise=%f cut %f, # pixels=%d within? [%d, %d], stover2=%d, time=%d\n", fClusterPulseSum, fClusterAreaPulseSum, fClusterNoiseAverage, tClusterAreaNoise, fClusterSignalToNoise, fSNneighbour, fCut->GetNeighbourPulseHeightToNoise(), fStripsInClusterFound, fCut->GetStripsInClusterMin(), fCut->GetStripsInClusterMax(), fStoNover2, fTimestamp); + + + //=============== + // Compute hit position + //=============== + + // start to calculate the exact hit position, which is in first order the seed strip position + (*fPositionHit)(0) = (fPSeed->GetPosition())(0); + (*fPositionHit)(1) = (fPSeed->GetPosition())(1); + (*fPositionHit)(2) = (fPSeed->GetPosition())(2); + + // This is the container (3D distance) for the correction to be computed with different algorithm + DR3 tCorrection ; tCorrection.SetValue(0.,0.,0.); + DR3 tCorTemp ; + + //=============== + //--- for PIXEL planes + // + if( fPlane->GetAnalysisMode() >= 2 ) { // if pixel mode + + // Cut on the charge or on the charge/noise (See above) + // Cut on # pixels in hit added, JB 2009/08/30 + + if( fSNneighbour >= fCut->GetNeighbourPulseHeightToNoise() + && fCut->GetStripsInClusterMin() <= fStripsInClusterFound + && fCut->GetStripsInClusterMax() >= fStripsInClusterFound + ){ + valid = kTRUE; + }else{ + valid = kFALSE; + } + + //RDM050809 for M25 begin +// Float_t cut1[2]; +// Float_t cut2[2]; +// if(fPlane->GetPlaneNumber()==1) {cut1[0]=0. ;cut1[1]=-2100.;cut2[0]=0.;cut2[1]=-2250.;} +// else if(fPlane->GetPlaneNumber()==2){cut1[0]=2000.;cut1[1]=0. ;cut2[0]=0.;cut2[1]=-2350.;} +// else if(fPlane->GetPlaneNumber()==3){cut1[0]= 450.;cut1[1]=-1800.;cut2[0]=0.;cut2[1]=-2350;} +// else if(fPlane->GetPlaneNumber()==4){cut1[0]=1700.;cut1[1]= -500.;cut2[0]=0.;cut2[1]=-2250;} + +// //for M24 +// if(fPlane->GetPlaneNumber()==1) {cut1[0]=1000.;cut1[1]=-1600.;cut2[0]=1800.;cut2[1]=-2250.;} +// else if(fPlane->GetPlaneNumber()==2){cut1[0]=2200.;cut1[1]=-600. ;cut2[0]=1800.;cut2[1]=-2350.;} +// else if(fPlane->GetPlaneNumber()==3){cut1[0]=1000.;cut1[1]=-1500.;cut2[0]=1800.;cut2[1]=-2350;} +// else if(fPlane->GetPlaneNumber()==4){cut1[0]=2000.;cut1[1]=-1000.;cut2[0]=2000.;cut2[1]=-2250;}*/ + +// if((fPSeed->GetPosition()(0)>cut1[0] || fPSeed->GetPosition()(0)GetPosition()(1)>cut2[0] || fPSeed->GetPosition()(1)GetPlaneNumber()<1 ) valid=kFALSE; + //RDM050809 for M25 end //in case you want to use this cut, put <5 instead of <1 in the last "if" line + + // now compute position correction wrt seed position depending on the required algorithm + if( valid) + { + + if(fDebugHit>2) printf(" DHit:Analyse_2_cgo hit is valid!\n"); + + //================== + //Center of gravity with all the neighbours + // pay attention that pixels are ordered geometricaly from one corner to the other in the fStripDistanceU/V arrays + + tCorrection.SetValue( 0., 0., 0.); + Float_t tClusterPulseSum = 0.; + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + // Computation without the fStripDistance array, MG 2010/06/28 + aNeighbour = aListOfPixels->at( tPixelIndexList[ iStripIndex]); + tCorTemp.SetValue( aNeighbour->GetPosition()(0)*aNeighbour->GetPulseHeight(), + aNeighbour->GetPosition()(1)*aNeighbour->GetPulseHeight(), + 0); + tCorrection += tCorTemp; + tClusterPulseSum += aNeighbour->GetPulseHeight(); + + // "Old" computation with the fStripDistance array + /* + tCorTemp.SetValue( ((fPSeed->GetPosition())(0)-fStripDistanceU[iStripIndex])*fStripPulseHeight[iStripIndex], + ((fPSeed->GetPosition())(1)-fStripDistanceV[iStripIndex])*fStripPulseHeight[iStripIndex], + 0); + tCorrection += tCorTemp; + tClusterPulseSum += fStripPulseHeight[iStripIndex]; + */ + //printf("DHit::Analyse_2_cgo plane %d, hit %2d, strip %2d, corr(%.2f, %.2f)=dist(%.2f, %.2f)*%.0f/%.0f\n", fPlane->GetPlaneNumber(), fHitNumber, iStripIndex, tCorrection(0), tCorrection(1), fStripDistanceU[iStripIndex], fStripDistanceV[iStripIndex], fStripPulseHeight[iStripIndex], tClusterPulseSum); + } + *fPositionHitCG = tCorrection/tClusterPulseSum; + fIfMonteCarlo = fPSeed->IfMonteCarlo(); + if(fIfMonteCarlo==1) _monteCarloInfo = fPSeed->GetMonteCarloInfo(); + + //================== + //Center of gravity restricted to a 3x3 cluster + + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster33PulseSum = 0.; + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + if( fabs(fStripDistanceU[iStripIndex])<=fPSeed->GetSize()(0) + && fabs(fStripDistanceV[iStripIndex])<=fPSeed->GetSize()(1) + ) { // check neighbours is at most at 1 pitch from seed + // Computation without the fStripDistance array, MG 2010/06/28 + aNeighbour = aListOfPixels->at( tPixelIndexList[ iStripIndex]); + tCorTemp.SetValue( aNeighbour->GetPosition()(0)*aNeighbour->GetPulseHeight(), + aNeighbour->GetPosition()(1)*aNeighbour->GetPulseHeight(), + 0); + tCorrection += tCorTemp; + tClusterPulseSum += aNeighbour->GetPulseHeight(); + + // "Old" computation with the fStripDistance array + /* + tCorTemp.SetValue( ((fPSeed->GetPosition())(0)-fStripDistanceU[iStripIndex])*fStripPulseHeight[iStripIndex], + ((fPSeed->GetPosition())(1)-fStripDistanceV[iStripIndex])*fStripPulseHeight[iStripIndex], + 0); + tCorrection += tCorTemp; + tClusterPulseSum += fStripPulseHeight[iStripIndex]; + */ + //printf("DHit::Analyse_2_cgo plane %d, hit %2d, strip %2d, corr(%.2f, %.2f)=dist(%.2f, %.2f)*%.0f/%.0f\n", fPlane->GetPlaneNumber(), fHitNumber, iStripIndex, tCorrection(0), tCorrection(1), fStripDistanceU[iStripIndex], fStripDistanceV[iStripIndex], fStripPulseHeight[iStripIndex], tCluster33PulseSum); + } + } + *fPositionHitCG33 = tCorrection/tCluster33PulseSum; + + + //================== + //Center of gravity restricted 2x2 neighbours with the highest charge, JB Nov 2007 + // 2x2 includes the seed + + // The index of the neighbours with the highest charges are ordered in fStripIndexArray + + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster22PulseSum = 0.; + Int_t tOrderedIndex; + for( Int_t iStripIndex=0; iStripIndex < TMath::Min( 4, fStripsInClusterFound); iStripIndex++ ) { // limit changed for sparsified data, JB 2009/09/01 + tOrderedIndex = fStripIndexArray[iStripIndex]; + tCorTemp.SetValue( (fPSeed->GetPosition()(0)-fStripDistanceU[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + (fPSeed->GetPosition()(1)-fStripDistanceV[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + 0); + tCorrection += tCorTemp; + tCluster22PulseSum += fStripPulseHeight[tOrderedIndex]; + } + *fPositionHitCG22 = tCorrection/tCluster22PulseSum; + + + //================== + //Eta algorithm 3x3 + // correct the 3x3 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + if ( tDigital ){ // check info file was there and Eta is available + if(fDebugHit>1 && (fPositionAlgorithm==2 || fPositionAlgorithm==22)) printf(" DHit.cxx:Analyse_2_cgo Digital or CoG response only set for plane %d (forgot about etaXXX.root file?)\n",fPlane->GetPlaneNumber()); + } + else { + + TH1 *tEtaIntU = fPlane->GetEtaIntU(); + TH1 *tEtaIntV = fPlane->GetEtaIntV(); + Int_t iBinU = tEtaIntU->FindBin( (*fPositionHitCG33-*fPositionHit)(0) ); + Int_t iBinV = tEtaIntV->FindBin( (*fPositionHitCG33-*fPositionHit)(1) ); + Double_t corrU=0., corrV=0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU->GetNbinsX() ) corrU = tEtaIntU->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV->GetNbinsX() ) corrV = tEtaIntV->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + if( fDebugHit>1) printf(" Eta correction/digital is (%.1f, %.1f)\n", corrU, corrV); + *fPositionHitEta = *fPositionHit + tCorrection; + + //================== + //Eta algorithm 2x2 + // correct the 2x2 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + tEtaIntU = fPlane->GetEtaIntU2(); + tEtaIntV = fPlane->GetEtaIntV2(); + iBinU = tEtaIntU->FindBin( (*fPositionHitCG22-*fPositionHit)(0) ); + iBinV = tEtaIntV->FindBin( (*fPositionHitCG22-*fPositionHit)(1) ); + corrU = corrV = 0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU->GetNbinsX() ) corrU = tEtaIntU->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV->GetNbinsX() ) corrV = tEtaIntV->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + + *fPositionHitEta22 = *fPositionHit + tCorrection; + + } // end if tDigital + + //================== + //Analog head-tail algorithm + // Algorithm used for large incident angle when seed contains little info on position + // Relies on the extreme pixels on the left and right + // tCorrection.SetValue( (fStripDistanceU[iLeft]+fStripDistanceU[iRight])/2., , 0.); + // *fPositionhitAHT = *fPositionHit - tCorrection; + + //================== + // Now choose which position is stored + if( fPositionAlgorithm==0 ) { // keep Seed position + } + else if( fPositionAlgorithm==1 ) { // Center of Gravity + *fPositionHit = *fPositionHitCG; + } + else if( fPositionAlgorithm==11 ) { // Center of gravity on 3x3 + *fPositionHit = *fPositionHitCG33; + } + else if( fPositionAlgorithm==12 ) { // Center of gravity on 2x2 + *fPositionHit = *fPositionHitCG22; + } + else if( fPositionAlgorithm==2 ) { // Eta corrected from CoG 3x3 + *fPositionHit = *fPositionHitEta; + } + else if( fPositionAlgorithm==22 ) { // Eta corrected from CoG 2x2 + *fPositionHit = *fPositionHitEta22; + } + else { + printf("-*-*- WARNING: algorithm %d for position unknown, taking digital position\n", fPositionAlgorithm); + } + if(fDebugHit>1) printf(" DHit.cxx:Analyse_2_cgo pos algo %d requested, seed[%d-%d]=(%.1f, %.1f), CG(%.1f, %.1f), CG33(%.1f, %.1f), eta(%.1f, %.1f), eta22(%.1f, %.1f)\n", fPositionAlgorithm, fPSeed->GetPixelLine(), fPSeed->GetPixelColumn(), fSeedU, fSeedV, (*fPositionHitCG)(0), (*fPositionHitCG)(1), (*fPositionHitCG33)(0), (*fPositionHitCG33)(1), (*fPositionHitEta)(0), (*fPositionHitEta)(1), (*fPositionHitEta22)(0), (*fPositionHitEta22)(1)); + + } //end if valid + + } // end if PIXEL mode + + + // Release the neighbouring Pixels associated to the seed if the pixel is finally not selected + // only the tested seed (Index=0) is not released + // JB 2009/05/10 + if( !valid ) { + if(fDebugHit>1) printf(" DHit.cxx:Analyse_2_cgo hit NOT selected, releasing %d pixels\n", fStripsInClusterFound-1); + for (Int_t iNeigh = 1; iNeigh < fStripsInClusterFound; iNeigh++){ // loop over associated pixels + if(fDebugHit>2) printf(" DHit.cxx:Analyse_2_cgo releasing pixel %d at index %d\n", iNeigh, fStripIndexArray[iNeigh]); + aListOfPixels->at(fStripIndexArray[iNeigh])->SetFound(kFALSE); + } // end loop over associated pixels + } // end if !valid + + else if(fDebugHit>1) { + printf(" hit selected with %d pixels\n", fStripsInClusterFound); + } + + return valid; +} + +//______________________________________________________________________________ +// + +Bool_t DHit::Analyse_Iterative( Int_t aPixelIndexInList, std::vector *aListOfPixels, bool &IsBigCluster, int MaxClusterSize) +{ + + // Valid for sparse data acquisition + // + // For analog readout use the same algorithm in which construct a hit (or cluster) from a seed pixel and the list of all fired pixels: + // 1) try to associate all neighbouring strips that pass selection cut + // 2) check the build hit passes all selections + // 3) order the array fStripIndexArray of neighbours by decreasing pulseheight + // 4) compute cluster charge, noise and position + // For digital readout implement a dynamic clustering algorithm + // + // Return a boolean: kTRUE if hit is selected, kFalse otherwise + // + // Constructed from the original Analyse( Int_t aPixelIndexInList, std::vector *aListOfPixels ) by AP, 2014 July 01 + // Modified: JB 2015/05/26 to introduce timestamps and TimeLimit + // + + fFound = kFALSE; // JB 2009/05/22 + fPSeed = aListOfPixels->at(aPixelIndexInList); + + DPixel *aNeighbour; + DPixel *aPixel=NULL; + Bool_t pixelTwice = kFALSE; // test if a pixel is present twice in the neighbour list + Bool_t valid = kFALSE; // default return value + Bool_t tDigital = fPlane->GetStripResponseSetting(); + Int_t tStripIndex; + Int_t tStripsInClusterPossible = 0; // remove a warning + //Int_t tPixelIndexList[500]; + + Int_t tTimeLimit = fPlane->GetTimeLimit(); // 2015/05/26 + + fPositionHitCG->Zero(); // clear the position + fPositionHitEta->Zero(); + fPositionHitEta22->Zero(); // JB 2010/12/8 + fPositionHit->Zero(); + fClusterSignalToNoise = 0.0; + + fSeedU = fPSeed->GetPosition()(0); + fSeedV = fPSeed->GetPosition()(1); + fIndexSeed = fPSeed->GetPixelIndex(); + + Int_t seedRow = fPSeed->GetPixelLine(); + Int_t seedCol = fPSeed->GetPixelColumn(); + Int_t iSeed = 0; + + // here, the neighbourhood of strips is assumed to be ordered, + // at index 0 is the seed, to higher indices + // the neighbourstrips are further away from the seed. + + Float_t tClusterAreaNoise = 0.; + fClusterAreaPulseSum = 0.; // area means the cluster except the seed + fClusterPulseSum = fPSeed->GetPulseHeight(); + fClusterNoiseAverage = (fPSeed->GetNoise())*(fPSeed->GetNoise()); // => so it's only a seed strip in the beginning + fStripsInClusterFound = 1; + fPSeed->SetFound(kTRUE); + + if (fStripsInClusterDemanded >0) { // exact number demanded + tStripsInClusterPossible = fStripsInClusterDemanded; + } + else if (fStripsInClusterDemanded == 0) { // number from config file, JB 2009/08/21 + tStripsInClusterPossible = fCut->GetStripsInClusterArea(); //(Int_t)pow( fClusterLimit->Length()/(fPSeed->GetSize())(0)*2+1, 2), JB 2013/08/29 to match really a rectangle + } + else { // JB 2009/08/21 + printf("DHit::Analyse_dynamic WARNING limit on the # pixels in cluster %d is UNKNOWN !!\n", fStripsInClusterDemanded ); + return false; + } + + tPixelIndexList[0] = aPixelIndexInList; + fStripIndexArray[0] = 0; // place seed in position 0 of neighbour + fStripIndex[0] = fPSeed->GetPixelIndex(); // store seed index, JB 2009/05/12 + fStripPulseHeight[0] = fPSeed->GetPulseHeight(); // store seed pulseheight + fStripNoise[0] = fPSeed->GetNoise(); // store seed noise //YV 27/11/09 + fSNseed = fPSeed->GetPulseHeightToNoise(); // JB 2013/11/08 + fSeedPulseHeight = fPSeed->GetPulseHeight(); // Note that seed might change + fSeedNoise = fPSeed->GetNoise(); + fStripDistanceU[0] = 0.; // distance seed to seed = 0. + fStripDistanceV[0] = 0.; // distance seed to seed = 0. + fStoNover2 = 0; // MB/12/11/2010 + + //=============== + // associate neighbouring pixels to seed one + //=============== + if(fDebugHit>1) printf(" DHit:Analyse seed pixel index %d (%d in list, r%d, c%d) (q=%f) with possibly %d neighbours\n", + fIndexSeed, + aPixelIndexInList, + fPSeed->GetPixelLine(), + fPSeed->GetPixelColumn(), + fPSeed->GetPulseHeight(), + tStripsInClusterPossible); + + + //if( fPlane->GetAnalysisMode() != 3) { // if analog readout + if( fPlane->GetAnalysisMode() < 2) { // if analog strip readout + tStripIndex = 1; // start with the first neighbour, in the geometric ordered neighbourhood, avoid 0 because it is the seed itself! + for (Int_t iPix = 0; iPix < (Int_t)aListOfPixels->size(); iPix++){ // loop over hit pixels + + aNeighbour = aListOfPixels->at(iPix); + // Test if the pixel can be associated to the seed + // inside the geometrical cluster limits + // and also in the time limit using the timestamp (which are all 0 if unavailable). + // JB+SS 2013/06/23 + // Geometrical limit test changed from a single 2D distance test + // to two 1D distance test. + // to JB 2013/08/29 to match really a rectangle + if ( !aNeighbour->Found() + //&& fPSeed->Distance( *aNeighbour) < fClusterLimit->Length() + && fabs(fPSeed->DistanceU(aNeighbour->GetPosition())) <= (*fClusterLimit)(0) + && fabs(fPSeed->DistanceV(aNeighbour->GetPosition())) <= (*fClusterLimit)(1) + //&& fPSeed->GetTimestamp() == aNeighbour->GetTimestamp() + && abs(fPSeed->GetTimestamp()-aNeighbour->GetTimestamp())<=tTimeLimit + ) { // if neighbour pixel within limits + + // Additional test to avoid counting the same pixel twice + // JB 2011/11/07 + pixelTwice = kFALSE; + for ( Int_t jPix=0; jPixat( tPixelIndexList[ jPix] ); + pixelTwice &= aNeighbour->GetPixelIndex() == aPixel->GetPixelIndex(); + } // end loop on currently found pixels + + if( !pixelTwice ) { // if pixel is not counted twice + fClusterAreaPulseSum += aNeighbour->GetPulseHeight(); + tClusterAreaNoise +=(aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterNoiseAverage += (aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterPulseSum += aNeighbour->GetPulseHeight(); + tPixelIndexList[tStripIndex] = iPix; // store the index in the original list of pixels + fStripIndexArray[tStripIndex] = tStripIndex; // put neighbour index in array (not index of full pixel list) + fStripIndex[tStripIndex] = aNeighbour->GetPixelIndex(); // this is the index in the matrix, JB 2009/05/12 + fStripPulseHeight[tStripIndex] = aNeighbour->GetPulseHeight(); + fStripNoise[tStripIndex] = aNeighbour->GetNoise(); //YV 27/11/09 + fStripDistanceU[tStripIndex] = fPSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[tStripIndex] = fPSeed->DistanceV(aNeighbour->GetPosition()); + aNeighbour->SetFound(kTRUE); + + if( fDebugHit>1) printf(" neighbour %d at index %d (r%d, c%d) with pulse %.1f and distance %.1f(u=%.1f, v=%.1f) (<%.1f(u=%.1f, v=%.1f)) and timestamp %d / seedTimestamp %d within %d slot found!\n", + tStripIndex, + aNeighbour->GetPixelIndex(), + aNeighbour->GetPixelLine(), + aNeighbour->GetPixelColumn(), + aNeighbour->GetPulseHeight(), + fPSeed->Distance( *aNeighbour), + fPSeed->DistanceU(aNeighbour->GetPosition()), + fPSeed->DistanceV(aNeighbour->GetPosition()), + fClusterLimit->Length(), + (*fClusterLimit)(0), + (*fClusterLimit)(1), + aNeighbour->GetTimestamp(), + fPSeed->GetTimestamp(), + tTimeLimit); + tStripIndex++; // increment the strip index counter + fStripsInClusterFound++; + } // end if pixel is not counted twice + + } // end if neighbour pixel within limits + + } // end loop over hit pixels + } // end if analog strip readout + else { //if pixel analog or binary readout + + //Doing a different cultering for binary readout using a iterative algorithm (most likely not optimal) + std::vector _TheClusterPixelsList; + _TheClusterPixelsList.clear(); + _TheClusterPixelsList.push_back(aPixelIndexInList); + + if(fDebugHit>1) { + cout << endl; + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Seed pixel = " << aPixelIndexInList << " at (col,lin) = (" << seedCol << "," << seedRow << ")" + << ", and time-stamp = " << fPSeed->GetTimestamp() << ". Initial cluster size = " << _TheClusterPixelsList.size() << endl; + cout << endl; + } + + //SON cut for pixels in case of analog output + float SON_cut = 3.0; + + //Define a region of interest (ROI) to look for pixels to add to the seed pixel + int delta_row_ROI = 70; + int delta_col_ROI = 70; + std::vector _ROIlist; + _ROIlist.clear(); + for(Int_t iPix = 0; iPix < (Int_t)aListOfPixels->size(); iPix++){ // loop over hit pixels + if(aPixelIndexInList == iPix) continue; + aNeighbour = aListOfPixels->at(iPix); + if(aNeighbour->Found()) continue; + if(abs(fPSeed->GetTimestamp() - aNeighbour->GetTimestamp()) > tTimeLimit) continue; + int testRow = aNeighbour->GetPixelLine(); + int testCol = aNeighbour->GetPixelColumn(); + + //Only consider pixels with a minimum S/N in case of analog output sensors + if(fPlane->GetAnalysisMode() == 2 && aNeighbour->GetPulseHeightToNoise() < SON_cut) continue; + + //Only conside pixels in ROI region w.r.t seed pixel + if(not( (abs(seedRow - testRow) < delta_row_ROI) && (abs(seedCol - testCol) < delta_col_ROI))) continue; + + _ROIlist.push_back(iPix); + } //end of loop over hit pixels + + if(fDebugHit>1) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Added " << _ROIlist.size() << " pixel to the ROI list." + << endl; + cout << endl; + } + + //Start iterations to include pixels neighbours to already included pixels in cluster + //Stop when no more neighbours are found + int iteration_counter = 0; + std::vector _FiredPixelsList; + do { + _FiredPixelsList.clear(); + + //Check for pixels neighbour to already included pixels + for(Int_t iPix = 0; iPix < int(_ROIlist.size()); iPix++) { // being loop over ROI pixels + aNeighbour = aListOfPixels->at(_ROIlist[iPix]); + if(aNeighbour->Found()) continue; + if(abs(fPSeed->GetTimestamp() - aNeighbour->GetTimestamp()) > tTimeLimit) continue; + + int testRow = aNeighbour->GetPixelLine(); + int testCol = aNeighbour->GetPixelColumn(); + + //Now check if test pixel is neighbour to any pixel already included in cluster + for(int iPixClus=0; iPixClus < int(_TheClusterPixelsList.size()); iPixClus++) { // begin loop over pixel already included to cluster + if(_ROIlist[iPix] == _TheClusterPixelsList[iPixClus]) continue; + aPixel = aListOfPixels->at(_TheClusterPixelsList[iPixClus]); + + int clusRow = aPixel->GetPixelLine(); + int clusCol = aPixel->GetPixelColumn(); + + int deltaRow = abs(clusRow - testRow); + int deltaCol = abs(clusCol - testCol); + if((deltaRow == 1 && deltaCol == 0) || //pixel to the right/left + (deltaRow == 0 && deltaCol == 1) || //pixel at the top/bottom + (deltaRow == 1 && deltaCol == 1) //pixel at diagonal + ) { + + //Check if this pixel has been already added to the list of fired pixels + bool IsNotAlreadyIn = true; + for(int iNewPix=0; iNewPix < int(_FiredPixelsList.size()); iNewPix++) { + if(_ROIlist[iPix] == _FiredPixelsList[iNewPix]) { + IsNotAlreadyIn = false; + break; + } + } + if(IsNotAlreadyIn) _FiredPixelsList.push_back(_ROIlist[iPix]); + } + } // end loop over pixel already included to cluster + } //end loop over ROI pixels + + //Now add the found pixels to the cluster and remove them from the ROI list + if(fDebugHit>1) cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Found " << _FiredPixelsList.size() << " new pixels around seed pixel at iteration " << iteration_counter+1 << "!!!" << endl; + for(int iNewPix=0; iNewPix < int(_FiredPixelsList.size()); iNewPix++) { //begin loop over new cluster pixels + _TheClusterPixelsList.push_back(_FiredPixelsList[iNewPix]); + + if(fDebugHit>1) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Adding pixel " << _FiredPixelsList[iNewPix] << " at (col,lin) = (" << aListOfPixels->at(_FiredPixelsList[iNewPix])->GetPixelColumn() << "," + << aListOfPixels->at(_FiredPixelsList[iNewPix])->GetPixelLine() + << "), time-stamp = " << aListOfPixels->at(_FiredPixelsList[iNewPix])->GetTimestamp() << " (" << tTimeLimit << ")" << endl; + } + + for(Int_t iPix = 0; iPix < int(_ROIlist.size()); iPix++) { // being loop over ROI pixels + if(_FiredPixelsList[iNewPix] == _ROIlist[iPix]) { + _ROIlist.erase(_ROIlist.begin() + iPix); + break; + } + } //end loop over ROI pixels + + } //end loop over new cluster pixels + if(fDebugHit>1 && int(_FiredPixelsList.size()) > 0) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Cluster size increased to " << _TheClusterPixelsList.size() << " at iteration " << iteration_counter+1 << endl; + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". ROI list size reduced to " << _ROIlist.size() << " at iteration " << iteration_counter+1 << endl; + } + if(fDebugHit>1) cout << endl; + + iteration_counter++; + } + while(int(_FiredPixelsList.size()) > 0); + _FiredPixelsList.clear(); + _ROIlist.clear(); + + if(fDebugHit>1) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Final cluster size is " << _TheClusterPixelsList.size() << " after " << iteration_counter << " iterations!" << endl; + cout << endl; + } + + //Excluding repeated pixel. Only keeping the ones with the lowest time-stamp: + std::vector _TheClusterPixelsList_NotRepeated; + _TheClusterPixelsList_NotRepeated.clear(); + std::vector _TheClusterPixelsList_Repeated; + _TheClusterPixelsList_Repeated.clear(); + std::vector _TheClusterPixelsList_All; + _TheClusterPixelsList_All.clear(); + DPixel *aNeighbour_tmp; + for(int iPixClus1=0; iPixClus1 < int(_TheClusterPixelsList.size()); iPixClus1++) { + _TheClusterPixelsList_All.push_back(_TheClusterPixelsList[iPixClus1]); + aNeighbour = aListOfPixels->at(_TheClusterPixelsList[iPixClus1]); + Int_t theRow = aNeighbour->GetPixelLine(); + Int_t theCol = aNeighbour->GetPixelColumn(); + int TS1 = aNeighbour->GetTimestamp(); + + //Only include in the list the pixels which are not repeated + bool IsNotRepeated = true; + for(int iPixClus2=0; iPixClus2 < int(_TheClusterPixelsList_NotRepeated.size()); iPixClus2++) { + aNeighbour_tmp = aListOfPixels->at(_TheClusterPixelsList_NotRepeated[iPixClus2]); + Int_t theRow2 = aNeighbour_tmp->GetPixelLine(); + Int_t theCol2 = aNeighbour_tmp->GetPixelColumn(); + int TS2 = aNeighbour_tmp->GetTimestamp(); + + if(theRow == theRow2 && theCol == theCol2) { + if(fDebugHit>1) { + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Pixel " << iPixClus1+1 + << " in list at (col,lin,TS) = (" << theCol << "," << theRow << "," << TS1 << ") is repated, the other pixel is at (col,lin,TS) = (" + << theCol2 << "," << theRow2 << "," << TS2 << ")" + << endl; + } + //Repeated pixel + IsNotRepeated = false; + //Take the pixel with the earliest time-stamp + if(TS2 > TS1) _TheClusterPixelsList_NotRepeated[iPixClus2] = _TheClusterPixelsList[iPixClus1]; + break; + } + } + //If the pixel is not already in list inclue it + if(IsNotRepeated) _TheClusterPixelsList_NotRepeated.push_back(_TheClusterPixelsList[iPixClus1]); + } + + //Fill list with the removed pixes + for(int iPixClus1=0; iPixClus1 < int(_TheClusterPixelsList.size()); iPixClus1++) { + bool IsRepeated = true; + for(int iPixClus2=0; iPixClus2 < int(_TheClusterPixelsList_NotRepeated.size()); iPixClus2++) { + if(_TheClusterPixelsList[iPixClus1] == _TheClusterPixelsList_NotRepeated[iPixClus2]) IsRepeated = false; + } + if(IsRepeated) _TheClusterPixelsList_Repeated.push_back(_TheClusterPixelsList[iPixClus1]); + } + //Declare all the pixels in the repeated list as found + for(int iPix=0;iPixat(_TheClusterPixelsList_Repeated[iPix]); + aNeighbour->SetFound(kTRUE); + } + _TheClusterPixelsList_Repeated.clear(); + + if(_TheClusterPixelsList.size() != _TheClusterPixelsList_NotRepeated.size() + && fDebugHit>1 + ) { + cout << endl; + cout << "DHit:: Plane " << fPlane->GetPlaneNumber() << ". Cluster size previous to removing repeated pixels: " << _TheClusterPixelsList.size() + << ". Cluster size after removing repeated pixels: " << _TheClusterPixelsList_NotRepeated.size() + << ". Removed " << _TheClusterPixelsList.size() - _TheClusterPixelsList_NotRepeated.size() << " repated pixels!!!" + << endl; + cout << endl; + } + + //Now replace the ClusterPixelList by the one with the repeated pixels removed + _TheClusterPixelsList.clear(); + for(int iPixClus=0; iPixClus < int(_TheClusterPixelsList_NotRepeated.size()); iPixClus++) _TheClusterPixelsList.push_back(_TheClusterPixelsList_NotRepeated[iPixClus]); + _TheClusterPixelsList_NotRepeated.clear(); + + //Calculate the position of the center of gravity: + double COG_U = 0.0; + double COG_V = 0.0; + double TotH = 0.0; + for(int iPixClus=0; iPixClus < int(_TheClusterPixelsList.size()); iPixClus++) { + aNeighbour = aListOfPixels->at(_TheClusterPixelsList[iPixClus]); + double height = aNeighbour->GetPulseHeight(); + double PixelU = aNeighbour->GetPosition()(0); + double PixelV = aNeighbour->GetPosition()(1); + + COG_U += PixelU*height; + COG_V += PixelV*height; + TotH += height; + } + COG_U /= TotH; + COG_V /= TotH; + + //Order the pixels depending of analog or digital output + for(int iii=2;iii<=int(_TheClusterPixelsList.size());iii++) { + for(int jjj=0;jjj<=int(_TheClusterPixelsList.size())-iii;jjj++) { + + if(fPlane->GetAnalysisMode() == 2) { + //In case of analog output arrange the pixels according to charge, + //from highest (seed pixels) to lowest + + double charge_jjj = aListOfPixels->at(_TheClusterPixelsList[jjj])->GetPulseHeight(); + double charge_jjjp1 = aListOfPixels->at(_TheClusterPixelsList[jjj])->GetPulseHeight(); + if(charge_jjj < charge_jjjp1) { + int aux_idx = _TheClusterPixelsList[jjj]; + _TheClusterPixelsList[jjj] = _TheClusterPixelsList[jjj+1]; + _TheClusterPixelsList[jjj+1] = aux_idx; + } + + } + else if(fPlane->GetAnalysisMode() == 3) { + //In case of digital output arrange the pixels according to their distance to the + //center of gravitiy, from closest (seed pixels) to farest + + double PixelU,PixelV; + + aNeighbour = aListOfPixels->at(_TheClusterPixelsList[jjj]); + PixelU = aNeighbour->GetPosition()(0); + PixelV = aNeighbour->GetPosition()(1); + double dist_jjj = sqrt(pow(COG_U - PixelU,2) + pow(COG_V - PixelV,2)); + + aNeighbour = aListOfPixels->at(_TheClusterPixelsList[jjj+1]); + PixelU = aNeighbour->GetPosition()(0); + PixelV = aNeighbour->GetPosition()(1); + double dist_jjjp1 = sqrt(pow(COG_U - PixelU,2) + pow(COG_V - PixelV,2)); + + if(dist_jjj > dist_jjjp1) { + int aux_idx = _TheClusterPixelsList[jjj]; + _TheClusterPixelsList[jjj] = _TheClusterPixelsList[jjj+1]; + _TheClusterPixelsList[jjj+1] = aux_idx; + } + } + + } + } + + //Hard-coded limit in the number of pixel in a cluster + //This is a way to identify cluster due to low-momentum heavy ions from fragmentation + //This should avoid crash of the code when such an event happends. This happends mainly + //for high fluxes (high trigger rates > 20kHz). + //int TheNpixelsLimit = 100; + int TheNpixelsLimit = MaxClusterSize; + if(int(_TheClusterPixelsList.size()) >= TheNpixelsLimit) { + IsBigCluster = true; + cout << endl; + double TheCol,TheLin; + fPlane->ComputeStripPosition_UVToColRow(COG_U,COG_V,TheCol,TheLin); + cout << " DHit: Analyse method found too many pixels in cluster, N-pixels = " << _TheClusterPixelsList.size() << " (Limit is set to config file value MaxNStrips " << TheNpixelsLimit + << "), for plane " << fPlane->GetPlaneNumber() << ". Seed pixel location is (col,lin) = (" << TheCol << "," << TheLin << ")" << endl; + cout << " DHit: It is likely a cluster of low-momentum heavy ion from fragmentation. Excluding pixels from further analysis" << endl; + + for(int iPix=0;iPixat(_TheClusterPixelsList_All[iPix]); + if( fDebugHit>1) { + cout << " DHit:: idx = " << _TheClusterPixelsList_All[iPix] << ", (col,lin) = (" + << aNeighbour->GetPixelColumn() << "," << aNeighbour->GetPixelLine() << ")" + << endl; + } + aNeighbour->SetFound(kTRUE); + } + _TheClusterPixelsList.clear(); + _TheClusterPixelsList_All.clear(); + + return false; + } + _TheClusterPixelsList_All.clear(); + + tClusterAreaNoise = 0.0; + fClusterAreaPulseSum = 0.0; + fClusterPulseSum = 0.0; + fClusterNoiseAverage = 0.0; + fStripsInClusterFound = int(_TheClusterPixelsList.size()); + + //Fill up the tables with the quantities of the cluster + for(int iPix=0;iPixat(_TheClusterPixelsList[iPix]); + if(iPix == 0) { + fPSeed = aNeighbour; + fSeedU = fPSeed->GetPosition()(0); + fSeedV = fPSeed->GetPosition()(1); + fIndexSeed = fPSeed->GetPixelIndex(); + + seedRow = fPSeed->GetPixelLine(); + seedCol = fPSeed->GetPixelColumn(); + fPSeed->SetFound(kTRUE); + + tPixelIndexList[0] = _TheClusterPixelsList[0]; + fStripIndexArray[0] = 0; // place seed in position 0 of neighbour + fStripIndex[0] = fPSeed->GetPixelIndex(); // store seed index, JB 2009/05/12 + fStripPulseHeight[0] = fPSeed->GetPulseHeight(); // store seed pulseheight + fStripNoise[0] = fPSeed->GetNoise(); // store seed noise //YV 27/11/09 + fSNseed = fPSeed->GetPulseHeightToNoise(); // JB 2013/11/08 + fSeedPulseHeight = fPSeed->GetPulseHeight(); // Note that seed might change + fSeedNoise = fPSeed->GetNoise(); + fStripDistanceU[0] = 0.; // distance seed to seed = 0. + fStripDistanceV[0] = 0.; // distance seed to seed = 0. + fStoNover2 = 0; // MB/12/11/2010 + } + else { + fClusterAreaPulseSum += aNeighbour->GetPulseHeight(); + tClusterAreaNoise +=(aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterNoiseAverage += (aNeighbour->GetNoise())*(aNeighbour->GetNoise()); + fClusterPulseSum += aNeighbour->GetPulseHeight(); + tPixelIndexList[iPix] = _TheClusterPixelsList[iPix]; // store the index in the original list of pixels + fStripIndexArray[iPix] = iPix; // put neighbour index in array (not index of full pixel list) + fStripIndex[iPix] = aNeighbour->GetPixelIndex(); // this is the index in the matrix, JB 2009/05/12 + fStripPulseHeight[iPix] = aNeighbour->GetPulseHeight(); + fStripNoise[iPix] = aNeighbour->GetNoise(); //YV 27/11/09 + fStripDistanceU[iPix] = fPSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[iPix] = fPSeed->DistanceV(aNeighbour->GetPosition()); + aNeighbour->SetFound(kTRUE); + + if( fDebugHit>1) printf(" neighbour %d at index %d (r%d, c%d) with pulse %.1f and distance %.1f(u=%.1f, v=%.1f) (<%.1f(u=%.1f, v=%.1f)) found!\n", + iPix, + aNeighbour->GetPixelIndex(), + aNeighbour->GetPixelLine(), + aNeighbour->GetPixelColumn(), + aNeighbour->GetPulseHeight(), + fPSeed->Distance( *aNeighbour), + fPSeed->DistanceU(aNeighbour->GetPosition()), + fPSeed->DistanceV(aNeighbour->GetPosition()), + fClusterLimit->Length(), + (*fClusterLimit)(0), + (*fClusterLimit)(1)); + } + } + _TheClusterPixelsList.clear(); + + } //end if pixel analog or binary readout + + + if(fDebugHit>2) printf(" DHit:Analyse found %d valid neighbours\n", fStripsInClusterFound); + + + //============= + // order pixels + //============= + Int_t *nOfneighbours = new Int_t[fStripsInClusterFound]; + + // For analog readout + // re-order pixels from the highest charge to the lowest + if( fPlane->GetAnalysisMode() == 2 ) { // if analog readout + + DGlobalTools aTool; // JB 2011/07/18 + aTool.OrderIndexDes(&fStripIndexArray[0], &fStripPulseHeight[0], fStripsInClusterFound); + if( fDebugHit>2) { // display result of pixel ordering, JB 2009/05/12 + cout << " DHit:Analyse ordered list of " << fStripsInClusterFound << " pixels in candidate hit" << endl; + for( Int_t iPix=0; iPixGetAnalysisMode() == 3 ) { // if binary readout + // For binary readout, update the seed information + + // swap previous info at index 0 with the one at index iSeed + // so that all arrays have seed info at index 0 + Int_t iTemp; + Float_t temp; + iTemp = tPixelIndexList[iSeed]; + tPixelIndexList[iSeed] = tPixelIndexList[0]; + tPixelIndexList[0] = iTemp; + iTemp = fStripIndexArray[iSeed]; + fStripIndexArray[iSeed] = fStripIndexArray[0]; + fStripIndexArray[0] = iTemp; + iTemp = fStripIndex[iSeed]; + fStripIndex[iSeed] = fStripIndex[0]; + fStripIndex[0] = iTemp; + temp = fStripPulseHeight[iSeed]; + fStripPulseHeight[iSeed] = fStripPulseHeight[0]; + fStripPulseHeight[0] = temp; + + // need to update some variables + // to take into account the new seed definition + fPSeed = aListOfPixels->at( tPixelIndexList[ 0] ); + fSeedU = fPSeed->GetPosition()(0); + fSeedV = fPSeed->GetPosition()(1); + fIndexSeed = fPSeed->GetPixelIndex(); + for( Int_t iPix=1; iPixat( tPixelIndexList[ iPix]); + fStripDistanceU[iPix] = fPSeed->DistanceU(aNeighbour->GetPosition()); + fStripDistanceV[iPix] = fPSeed->DistanceV(aNeighbour->GetPosition()); + } + + if( fDebugHit>2 ) { + printf(" DHit:Analyse seed is now pixel %d in list, index %d, with %d direct neighbours\n", tPixelIndexList[ 0], fIndexSeed, nOfneighbours[ iSeed]); + } + + } // end if binary readout + + else { + printf("DHit::Analyse_dynamic WARNING analysis mode %d UNKNOWN !!\n", fPlane->GetAnalysisMode() ); + return false; + } + + delete[] nOfneighbours; // remove memory leaks, BH 2013/08/21 + + //============== + // additional properties + //============== + // the number of strips in the cluster and the cluster charge sum are now known + // Depending wether the noise is calculated or not, + // the SN ratio is a real ratio or simply the charge + // JB 2010/10/05 and 2010/10/15 to separately compute Cluster and Area values + + tClusterAreaNoise = sqrt(tClusterAreaNoise); + + if (fClusterNoiseAverage > 0.5) { + fClusterSignalToNoise = fClusterPulseSum / sqrt(fClusterNoiseAverage); + } + else { + fClusterSignalToNoise = fClusterPulseSum; + } + if (tClusterAreaNoise > 0.5) { + fSNneighbour = fClusterAreaPulseSum / tClusterAreaNoise; + } + else { + fSNneighbour = fClusterAreaPulseSum; + } + + // Number of pixels with 2*pitch of the seed with S/N>2. + // MB/12/11/2010 + if( fPlane->GetAnalysisMode() <= 2 ) { + for( Int_t iPix=0; iPixat(iPix); + if ( fPSeed->Distance( *aNeighbour) <= 2*(*fStripPitch)(0) && fPSeed->GetPulseHeightToNoise() >= 2 ){ + fStoNover2++; + } + if(fDebugHit>1) cout<<" DHit:Analyse StoNover2 = "<Distance( *aNeighbour) = "<Distance( *aNeighbour)<<" fPSeed->GetFound() = "<< fPSeed->Found()<GetTimestamp(); // JB 2015/05/25 + + if(fDebugHit>2) printf(" DHit:Analyse potential hit has : PulseSum=%f, areaPulseSum=%f, noise=%f, areaNoise=%f, clusterSignalToNoise=%f, areaSignalToNoise=%f cut %f, # pixels=%d within? [%d, %d], stover2=%d, time=%d\n", fClusterPulseSum, fClusterAreaPulseSum, fClusterNoiseAverage, tClusterAreaNoise, fClusterSignalToNoise, fSNneighbour, fCut->GetNeighbourPulseHeightToNoise(), fStripsInClusterFound, fCut->GetStripsInClusterMin(), fCut->GetStripsInClusterMax(), fStoNover2, fTimestamp); + + + //=============== + // Compute hit position + //=============== + + // start to calculate the exact hit position, which is in first order the seed strip position + (*fPositionHit)(0) = (fPSeed->GetPosition())(0); + (*fPositionHit)(1) = (fPSeed->GetPosition())(1); + (*fPositionHit)(2) = (fPSeed->GetPosition())(2); + + // This is the container (3D distance) for the correction to be computed with different algorithm + DR3 tCorrection ; tCorrection.SetValue(0.,0.,0.); + DR3 tCorTemp ; + + //=============== + //--- for PIXEL planes + // + if( fPlane->GetAnalysisMode() >= 2 ) { // if pixel mode + + // Cut on the charge or on the charge/noise (See above) + // Cut on # pixels in hit added, JB 2009/08/30 + + if( fPlane->GetAnalysisMode() != 3) { //if analog readout + if( fSNneighbour >= fCut->GetNeighbourPulseHeightToNoise() + && fCut->GetStripsInClusterMin() <= fStripsInClusterFound + && fStripsInClusterFound <= fCut->GetStripsInClusterMax() + //&& fStoNover2 >=4 // MB 2010/11/12 + ){ + valid = kTRUE; + }else{ + valid = kFALSE; + } + } + else { //if digital readout + if( fSNneighbour >= fCut->GetNeighbourPulseHeightToNoise() + && fCut->GetStripsInClusterMin() <= fStripsInClusterFound + ){ + valid = kTRUE; + }else{ + valid = kFALSE; + } + } + + // now compute position correction wrt seed position depending on the required algorithm + if( valid) { + + if(fDebugHit>2) printf(" DHit:Analyse hit is valid!\n"); + + //================== + //Center of gravity with all the neighbours + // pay attention that pixels are ordered geometricaly from one corner to the other in the fStripDistanceU/V arrays + + tCorrection.SetValue( 0., 0., 0.); + Float_t tClusterPulseSum = 0.; + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + // Computation without the fStripDistance array, MG 2010/06/28 + aNeighbour = aListOfPixels->at( tPixelIndexList[ iStripIndex]); + tCorTemp.SetValue( aNeighbour->GetPosition()(0)*aNeighbour->GetPulseHeight(), + aNeighbour->GetPosition()(1)*aNeighbour->GetPulseHeight(), + 0); + tCorrection += tCorTemp; + tClusterPulseSum += aNeighbour->GetPulseHeight(); + } + *fPositionHitCG = tCorrection/tClusterPulseSum; + fIfMonteCarlo = fPSeed->IfMonteCarlo(); + if(fIfMonteCarlo==1) _monteCarloInfo = fPSeed->GetMonteCarloInfo(); + + //================== + //Center of gravity restricted to a 3x3 cluster + + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster33PulseSum = 0.; + for( Int_t iStripIndex=0; iStripIndex < fStripsInClusterFound; iStripIndex++ ) { + if( fabs(fStripDistanceU[iStripIndex])<=fPSeed->GetSize()(0) + && fabs(fStripDistanceV[iStripIndex])<=fPSeed->GetSize()(1) + ) { // check neighbours is at most at 1 pitch from seed + // Computation without the fStripDistance array, MG 2010/06/28 + aNeighbour = aListOfPixels->at( tPixelIndexList[ iStripIndex]); + tCorTemp.SetValue( aNeighbour->GetPosition()(0)*aNeighbour->GetPulseHeight(), + aNeighbour->GetPosition()(1)*aNeighbour->GetPulseHeight(), + 0); + tCorrection += tCorTemp; + tClusterPulseSum += aNeighbour->GetPulseHeight(); + } + } + *fPositionHitCG33 = tCorrection/tCluster33PulseSum; + + + //================== + //Center of gravity restricted 2x2 neighbours with the highest charge, JB Nov 2007 + // 2x2 includes the seed + + // The index of the neighbours with the highest charges are ordered in fStripIndexArray + + tCorrection.SetValue( 0., 0., 0.); + Float_t tCluster22PulseSum = 0.; + Int_t tOrderedIndex; + for( Int_t iStripIndex=0; iStripIndex < TMath::Min( 4, fStripsInClusterFound); iStripIndex++ ) { // limit changed for sparsified data, JB 2009/09/01 + tOrderedIndex = fStripIndexArray[iStripIndex]; + tCorTemp.SetValue( (fPSeed->GetPosition()(0)-fStripDistanceU[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + (fPSeed->GetPosition()(1)-fStripDistanceV[tOrderedIndex])*fStripPulseHeight[tOrderedIndex], + 0); + tCorrection += tCorTemp; + tCluster22PulseSum += fStripPulseHeight[tOrderedIndex]; + } + *fPositionHitCG22 = tCorrection/tCluster22PulseSum; + + + //================== + //Eta algorithm 3x3 + // correct the 3x3 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + if ( tDigital ){ // check info file was there and Eta is available + if(fDebugHit>1 && (fPositionAlgorithm==2 || fPositionAlgorithm==22)) printf(" DHit.cxx:Analyse Digital or CoG response only set for plane %d (forgot about etaXXX.root file?)\n",fPlane->GetPlaneNumber()); + } + else { + + TH1 *tEtaIntU = fPlane->GetEtaIntU(); + TH1 *tEtaIntV = fPlane->GetEtaIntV(); + Int_t iBinU = tEtaIntU->FindBin( (*fPositionHitCG33-*fPositionHit)(0) ); + Int_t iBinV = tEtaIntV->FindBin( (*fPositionHitCG33-*fPositionHit)(1) ); + Double_t corrU=0., corrV=0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU->GetNbinsX() ) corrU = tEtaIntU->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV->GetNbinsX() ) corrV = tEtaIntV->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + if( fDebugHit>1) printf(" Eta correction/digital is (%.1f, %.1f)\n", corrU, corrV); + *fPositionHitEta = *fPositionHit + tCorrection; + + //================== + //Eta algorithm 2x2 + // correct the 2x2 center of gravity (tCorrection) using the integral histogram of the charge density + // the eta position is the Y value of the bin with X value = tCorrection + // if the tCorrection from CoG is out of the X axis range, do not correct + + tEtaIntU = fPlane->GetEtaIntU2(); + tEtaIntV = fPlane->GetEtaIntV2(); + iBinU = tEtaIntU->FindBin( (*fPositionHitCG22-*fPositionHit)(0) ); + iBinV = tEtaIntV->FindBin( (*fPositionHitCG22-*fPositionHit)(1) ); + corrU = corrV = 0.; + + // correct wrt CoG if possible + if( 1<=iBinU && iBinU<=tEtaIntU->GetNbinsX() ) corrU = tEtaIntU->GetBinContent( iBinU); + if( 1<=iBinV && iBinV<=tEtaIntV->GetNbinsX() ) corrV = tEtaIntV->GetBinContent( iBinV); + tCorrection.SetValue( corrU, corrV, 0.); + + *fPositionHitEta22 = *fPositionHit + tCorrection; + + } // end if tDigital + + //================== + //Analog head-tail algorithm + // Algorithm used for large incident angle when seed contains little info on position + // Relies on the extreme pixels on the left and right + // tCorrection.SetValue( (fStripDistanceU[iLeft]+fStripDistanceU[iRight])/2., , 0.); + // *fPositionhitAHT = *fPositionHit - tCorrection; + + //================== + // Now choose which position is stored + if( fPositionAlgorithm==0 ) { // keep Seed position + } + else if( fPositionAlgorithm==1 ) { // Center of Gravity + *fPositionHit = *fPositionHitCG; + } + else if( fPositionAlgorithm==11 ) { // Center of gravity on 3x3 + *fPositionHit = *fPositionHitCG33; + } + else if( fPositionAlgorithm==12 ) { // Center of gravity on 2x2 + *fPositionHit = *fPositionHitCG22; + } + else if( fPositionAlgorithm==2 ) { // Eta corrected from CoG 3x3 + *fPositionHit = *fPositionHitEta; + } + else if( fPositionAlgorithm==22 ) { // Eta corrected from CoG 2x2 + *fPositionHit = *fPositionHitEta22; + } + else { + printf("-*-*- WARNING: algorithm %d for position unknown, taking digital position\n", fPositionAlgorithm); + } + if(fDebugHit>1) printf(" DHit.cxx:Analyse pos algo %d requested, seed[%d-%d]=(%.1f, %.1f), CG(%.1f, %.1f), CG33(%.1f, %.1f), eta(%.1f, %.1f), eta22(%.1f, %.1f)\n", fPositionAlgorithm, fPSeed->GetPixelLine(), fPSeed->GetPixelColumn(), fSeedU, fSeedV, (*fPositionHitCG)(0), (*fPositionHitCG)(1), (*fPositionHitCG33)(0), (*fPositionHitCG33)(1), (*fPositionHitEta)(0), (*fPositionHitEta)(1), (*fPositionHitEta22)(0), (*fPositionHitEta22)(1)); + + } //end if valid + + } // end if PIXEL mode + + + // Release the neighbouring Pixels associated to the seed if the pixel is finally not selected + // only the tested seed (Index=0) is not released + // JB 2009/05/10 + if( !valid ) { + if(fDebugHit>1) printf(" DHit.cxx:Analyse hit NOT selected, releasing %d pixels\n", fStripsInClusterFound-1); + for (Int_t iNeigh = 1; iNeigh < fStripsInClusterFound; iNeigh++){ // loop over associated pixels + if(fDebugHit>2) printf(" DHit.cxx:Analyse releasing pixel %d at index %d\n", iNeigh, fStripIndexArray[iNeigh]); + aListOfPixels->at(fStripIndexArray[iNeigh])->SetFound(kFALSE); + } // end loop over associated pixels + } // end if !valid + + else if(fDebugHit>1) { + printf(" hit selected with %d pixels\n", fStripsInClusterFound); + } + + return valid; +} + +//______________________________________________________________________________ +// + +DStrip* DHit::GetMinor(Int_t aSk) +{ + // GetMinor(0) is fSeed, GetMinor(1) is strip with lower pulseheight + // than fSeed + + if (aSk < fSeed->GetNeighbourCount() ) { + return fSeed->GetNeighbour(fStripIndexArray[aSk]); + } + else { + printf("DHit, Request to non existing minor strip %d because only %d neighbours, returning seed strip\n", aSk, fSeed->GetNeighbourCount()); + return fSeed; + } +} +//______________________________________________________________________________ +// +DR3 DHit::GetMonteCarloPosition() +{ + if(_monteCarloInfo.size()>=3 && fIfMonteCarlo==1) return DR3(_monteCarloInfo[0], _monteCarloInfo[1], _monteCarloInfo[2]); + else { + std::cout<<"Monte Carlo Position Disable ! --> MC Position Set to (0,0,0)"<0) { + fPositionHit->SetValue(aPosition(0),aPosition(1),aPosition(2)); + fPositionHitCG->SetValue(aPosition(0),aPosition(1),aPosition(2)); + fPositionHitEta->SetValue(aPosition(0),aPosition(1),aPosition(2)); + fPositionHitCG33->SetValue(aPosition(0),aPosition(1),aPosition(2)); + fPositionHitCG22->SetValue(aPosition(0),aPosition(1),aPosition(2)); + fPositionHitEta22->SetValue(aPosition(0),aPosition(1),aPosition(2)); + fResolutionHit->SetValue(aResolution(0),aResolution(1),aResolution(2)); + } + + return; +} +//______________________________________________________________________________ +// +Int_t DHit::Compare( const TObject * obj) const { // QL 04/06/2016 + // QL 04/06/2016 + // to enable Sort method in a TList + // Sorted by comparing zPosition of the plane center + + DPlane *objPlane = ((DHit*)obj)->GetPlane(); + return fPlane->Compare( objPlane); +} +//______________________________________________________________________________ +// +void DHit::DoMCA(void) +{ + //AP 2017/05/09 + //This function performs the Main component analysis of the cluster + + float meanU = 0.0; + float meanV = 0.0; + float meanU2 = 0.0; + float meanV2 = 0.0; + float meanUV = 0.0; + float TotCharge = 0.0; + //cout << " N pixels in hit = " << GetStripsInCluster() << endl; + for(int ipixInHit=0; ipixInHit < GetStripsInCluster(); ipixInHit++) { + + double PixelU, PixelV, height; + if(fPlane->GetReadout() > 100) { + std::vector *aList = GetPlane()->GetListOfPixels(); + PixelU = aList->at(GetIndexInOriginalList(ipixInHit))->GetPosition()(0); + PixelV = aList->at(GetIndexInOriginalList(ipixInHit))->GetPosition()(1); + height = aList->at(GetIndexInOriginalList(ipixInHit))->GetPulseHeight(); + } + else { + int idex_pixel = GetIndex(ipixInHit); + int col = idex_pixel%fPlane->GetStripsNu(); + int row = idex_pixel/fPlane->GetStripsNu(); + + double w; + fPlane->ComputeStripPosition(col,row, PixelU, PixelV, w); + height = GetPulseHeight(ipixInHit); + } + //height = TMath::Abs(height); + if(height < 0.0) height = 0.0; + + meanU += PixelU*height; + meanU2 += pow(PixelU,2)*height; + meanV += PixelV*height; + meanV2 += pow(PixelV,2)*height; + meanUV += PixelU*PixelV*height; + TotCharge += height; + } + + if(TotCharge <= 1.0e-3) return; + + meanU /= TotCharge; + meanU2 /= TotCharge; + meanV /= TotCharge; + meanV2 /= TotCharge; + meanUV /= TotCharge; + + meanU2 -= pow(meanU,2); + meanV2 -= pow(meanV,2); + meanUV -= meanU*meanV; + + int Nphi = 50; + double Rphi[2]; + Rphi[0] = 0.0; + Rphi[1] = TMath::Pi(); + fNormMaxStd = -1.0e+20; + for(int iphi=0;iphiGetStripsNu(); + fColMax = -1; + fRowMin = 2*fPlane->GetStripsNv(); + fRowMax = -1; + + for(int ipix=0;ipix < GetStripsInCluster();ipix++) { + int col,row; + if(fPlane->GetReadout() > 100) { + std::vector *aList = fPlane->GetListOfPixels(); + col = aList->at(GetIndexInOriginalList(ipix))->GetPixelColumn(); + row = aList->at(GetIndexInOriginalList(ipix))->GetPixelLine(); + } + else { + int idex_pixel = GetIndex(ipix); + col = idex_pixel%fPlane->GetStripsNu(); + row = idex_pixel/fPlane->GetStripsNu(); + } + + if(fColMin > col) fColMin = col; + if(fColMax < col) fColMax = col; + if(fRowMin > row) fRowMin = row; + if(fRowMax < row) fRowMax = row; + } + + return; + +} +//______________________________________________________________________________ +// +void DHit::Print(const Option_t*) const +{ + fPlane->Print(); +} + +//______________________________________________________________________________ +// diff --git a/src/DLadder.cxx b/src/DLadder.cxx new file mode 100755 index 0000000..46080cc --- /dev/null +++ b/src/DLadder.cxx @@ -0,0 +1,852 @@ +#include "DLadder.h" +#include "DSetup.h" +#include "DSession.h" +#include "DAcq.h" +#include "DTracker.h" +#include "DHit.h" +//#include "DHitMonteCarlo.h" +#include "DPlane.h" +#include "DLine.h" +#include "DTrack.h" +#include "TStyle.h" +#include "TProfile.h" +#include "TVector3.h" +#include "TRotation.h" + +// Created b y LC +// Last Modified: BH 2013/08/20, warning corrections from clang +// Last Modified: JB 2014/02/17, DLadder, UpdateConfig, PlaneToLadder +// Last Modified: LC 2014/12/05, UpdateAlignment() + AlignLadder +// Last Modified: LC 2014/12/08, MonteCarlo Plots, UpdateAlignment(DR3) +// Last Modified: LC 2014/12/08, UpdateAlignment() (For ladder : Plume, Simple, Salat) +// Last Modified: LC 2014/12/08, MakeMiniVectors(), MakeTrack() +// Last Modified: LC 2014/12/18, Big code cleaning. Now custom by default. +// Last Modified: LC 2014/12/20, New MakeMiniVector() method. +// Last Modified: LC 2014/12/20, Now we use MiniVector Objects. + +///////////////////////////////////////////////////////////// +// // +// Class that handles a group of planes (or sensors). +// +// The Ladder class supersedes only the positions/tilts +// of its associated planes. +// +// OUTDATED : There are some predefined ladder types: +// - Simple : ? +// - Plume : 6 MIMOSA-26 sensors in a raw, +// with same orientation +// - Salat : 4 MIMOSA-28 sensors arranged in a specific way +// see ... +// +// For predefined types, the inter +// +// You may define your own geometry with the "Custom" type +// +// UPTODATE : "Custom" / "custom" by default. (2014/12/18) +// UPTODATE : Using DprecAlign mecanism. +// Local transformations are removed. +// +// The class was created by Loic Cousin. +// // +// // +///////////////////////////////////////////////////////////// + + + +//______________________________________________________________________________ +// +DLadder::DLadder() +{ + fDebugLadder = 0; +} + +//______________________________________________________________________________ +// +DLadder::DLadder( DTracker& aTracker, TString ladderName, Int_t aLadderID, Int_t aStatus, Double_t sensorLengthX, Double_t sensorSeparator, Double_t distanceFromFoam, Double_t rotationX, Double_t rotationY, Double_t rotationZ ) +{ + + // + // + // LC 2013-2014 + // Modified: JB 2014/01/10, introduced "Custom" type + // Modified: LC 2014/12/xx, Use custom type as default. + + + fTracker = &aTracker; + fAcq = fTracker->GetAcq(); // set pointer to Data Acquisition + fc = fTracker->GetSetup(); // set pointer to Configuration + fSession = fc->GetSession(); // set pointer to Session + fDebugLadder = fc->GetDebug(); + + ladderID = aLadderID; + Status = aStatus; + ladderType = ladderName; + + separatorLengthU = sensorSeparator; + + fIfAssociated = 0; + + //-+-+-+ Position of the Ladder + + // initial tilt about the axis perpendicular to the plane (w-axis) + fTilt = DR3(fc->GetLadderPar(ladderID-1).Tilt); + if (fDebugLadder) {printf(" DLadder %2d, Intitial Tilt around z, y, x axis [rad] : ",ladderID); fTilt.Print();} + + // initial position in xyz coordinates + fPosition = DR3(fc->GetLadderPar(ladderID-1).Position); + if (fDebugLadder) {printf(" DLadder %2d, Initial Position(in xyz) [um]: ", ladderID); fPosition.Print();} + + // Initial alignment parameters + Int_t DPrecAlignMethod = fc->GetTrackerPar().DPrecAlignMethod; // LC 2015/01/31 + fPrecAlign = new DPrecAlign(DPrecAlignMethod); // LC 2015/01/31 + + fPrecAlign->SetTranslation( fPosition ); // BEWARE, translation to be set first, always! + fPrecAlign->SetRotations( fTilt ); // because SetRot method compute the plane + if (fDebugLadder) fPrecAlign->PrintAll(); + + + std::cout<<"//*******************************************************//"<GetLadderPar(ladderID-1).Planes; iplane++) { // loop on planes associated to ladder + + planeRelativePosition[iplane](0) = fc->GetLadderPar(ladderID-1).PlaneShift[iplane-1](0); + planeRelativePosition[iplane](1) = fc->GetLadderPar(ladderID-1).PlaneShift[iplane-1](1); + planeRelativePosition[iplane](2) = fc->GetLadderPar(ladderID-1).PlaneShift[iplane-1](2); + + planeRelativeRotation[iplane](2) = fc->GetLadderPar(ladderID-1).PlaneTilt[iplane-1](0); + planeRelativeRotation[iplane](1) = fc->GetLadderPar(ladderID-1).PlaneTilt[iplane-1](1); + planeRelativeRotation[iplane](0) = fc->GetLadderPar(ladderID-1).PlaneTilt[iplane-1](2); + + planeRelativePrecAlign[iplane] = new DPrecAlign(DPrecAlignMethod); // LC 2015/01/31 + + planeRelativePrecAlign[iplane]->SetTranslation( planeRelativePosition[iplane]); + planeRelativePrecAlign[iplane]->SetRotations( planeRelativeRotation[iplane]); + + } // end loop on planes + + } // end if Custom type + + TString hDU_Name = "fhDX" + TString(ladderID); + fhDU = new TH1F(hDU_Name,"Residu in X",500,-100.,+100.); + + TString hDV_Name = "fhDY" + TString(ladderID); + fhDV = new TH1F(hDV_Name,"Residu in Y",500,-100.,+100.); + + TString hDW_Name = "fhDZ" + TString(ladderID); + fhDW = new TH1F(hDW_Name,"Residu in Z",1000,-100.,+100.); + + TString hDU_U_Name = "fhDX_X" + TString(ladderID); + fhDU_U = new TH2F(hDU_U_Name,"Residu in X vs X",500,-10000.,+10000.,200,-1000.,1000.); + + TString hDV_V_Name = "fhDY_Y" + TString(ladderID); + fhDV_V = new TH2F(hDV_V_Name,"Residu in Y vs Y",500,-5000.,+5000.,200,-1000.,1000.); + + TString hDU_V_Name = "fhDX_Y" + TString(ladderID); + fhDU_V = new TH2F(hDU_V_Name,"Residu in X vs Y",500,-5000.,+5000.,200,-1000.,1000.); + + TString hDV_U_Name = "fhDY_X" + TString(ladderID); + fhDV_U = new TH2F(hDV_U_Name,"Residu in Y vs X",500,-10000.,+10000.,200,-1000.,1000.); + + TString hDW_U_Name = "fhDZ_X" + TString(ladderID); + fhDW_U = new TH2F(hDW_U_Name,"Residu in Z vs X",500,-10000.,+10000.,200,-1000.,1000.); + + TString hDW_V_Name = "fhDZ_Y" + TString(ladderID); + fhDW_V = new TH2F(hDW_V_Name,"Residu in Z vs Y",500,-10000.,+10000.,200,-1000.,1000.); + + // TString hDU_W_Name = "fhDX_Z" + TString(ladderID); + // fhDU_W = new TH2F(hDU_W_Name,"Residu in X vs Z",500,-10000.,+10000.,200,-1000.,1000.); + + // TString hDV_W_Name = "fhDY_Z" + TString(ladderID); + // fhDV_W = new TH2F(hDV_W_Name,"Residu in Y vs Z",500,-10000.,+10000.,200,-1000.,1000.); + + // TString hDW_W_Name = "fhDZ_Z" + TString(ladderID); + // fhDW_W = new TH2F(hDW_W_Name,"Residu in Z vs Z",500,-10000.,+10000.,200,-1000.,1000.); + + TString hSlopeX_Name = "fhSlopeX" + TString(ladderID); + fhSlopeX = new TH1F(hSlopeX_Name,"SlopeX",2000,-1.,+1.); + + TString hSlopeY_Name = "fhSlopeY" + TString(ladderID); + fhSlopeY = new TH1F(hSlopeY_Name,"SlopeY",2000,-1.,+1.); + + TString hDiffSlopeX_Name = "fhDiffSlopeX" + TString(ladderID); + fhDiffSlopeX = new TH1F(hDiffSlopeX_Name,"Error Slope X",200,-1.,+1.); + + TString hResMC_U_Name = "fResMC_U" + TString(ladderID); + fResMC_U = new TH1F(hResMC_U_Name,"Residu MC in U",4000,-100.,+100.); + + TString hResMC_V_Name = "fResMC_V" + TString(ladderID); + fResMC_V = new TH1F(hResMC_V_Name,"Residu MC in V",4000,-100.,+100.); + + TString hResMC_W_Name = "fResMC_W" + TString(ladderID); + fResMC_W = new TH1F(hResMC_W_Name,"Residu MC in W",4000,-100.,+100.); + +} + +DLadder::~DLadder() +{ + delete fhDU; + delete fhDV; + delete fhDU_U; + delete fhDV_V; + delete fhDU_V; + delete fhDV_U; + delete fhDW_U; + delete fhDW_V; + // delete fhDU_W; + // delete fhDV_W; + // delete fhDW_W; + delete fhSlopeX; + delete fhSlopeY; + delete fhDiffSlopeX; + delete myProfileX; + delete myProfileY; + delete fResMC_U; + delete fResMC_V; + delete fResMC_W; + + delete fPrecAlign; +} + + +//______________________________________________________________________________ +// +void DLadder::UpdateAlignment() +{ + + // Update the positions (tilts and translations) of all planes within the ladder. + // + // LC + // Modified: JB 2014/02/17 Use ConvoluteAlignment for Custom case + // Modified: LC 2014/12/05 Custom Case + remove old code (new code for PLUME ladders arrive soon ...) + // Modified: LC End of December 2014 : Cleaning code + Custom by default + + if (fDebugLadder) { + printf(" DLadder %2d, updating alignment for %d planes.\n",ladderID,GetNumberOfPlanes()); + } + + fTilt(0) = (Double_t)fPrecAlign->GetRotations()[2]; + fTilt(1) = (Double_t)fPrecAlign->GetRotations()[1]; + fTilt(2) = (Double_t)fPrecAlign->GetRotations()[0]; + + fPosition(0) = (Double_t)fPrecAlign->GetTranslation()[0]; + fPosition(1) = (Double_t)fPrecAlign->GetTranslation()[1]; + fPosition(2) = (Double_t)fPrecAlign->GetTranslation()[2]; + + if(ladderType=="Custom" || ladderType=="custom") { // for Custom case, JB 2014/02/17 + + Int_t j = GetFirstPlane(); + for(int i=1 ; i<=GetNumberOfPlanes() ; ++i) { + // Set the alignment relative to the ladder + planeList[j]->GetPrecAlignment()->CopyAlignment( planeRelativePrecAlign[i] ); + + if( fDebugLadder ) { + cout << " DLadder::UpdateAlignement: Plane alignement before convolution" << endl; + planeList[i]->GetPrecAlignment()->PrintAll(); + } + + // Convolute the relative alignment with the ladder alignment + planeList[j]->GetPrecAlignment()->ConvoluteAlignment( fPrecAlign ); + //planeList[j]->GetPrecAlignment()->PrintRotationMatrix(); + //planeList[j]->GetPrecAlignment()->PrintTorMatrix(); + //planeList[j]->GetPrecAlignment()->PrintRotTimeInv(); + + planeList[j]->UpdatePositions(); + ++j; + + } // end for + } // end if custom + else std::cout<<" No Custom ladder found."<SetValue( (Double_t*)(planeRelativePrecAlign[aPlaneNumber]->GetRotations()) ); + aShift->SetValue( (Double_t*)(planeRelativePrecAlign[aPlaneNumber]->GetTranslation()) ); + + } + + printf( " Relative position of plane %d (absolute #=%d) wrt ladder %d:\n", aPlaneNumber, planeList[aPlaneNumber]->GetPlaneNumber(), ladderID); + printf( " Tilt: /z=%.2f, /y=%.2f, /x=%.2f\n", (*aTilt)(0), (*aTilt)(1), (*aTilt)(2)); + printf( " Shift: z=%.2f, y=%.2f, x=%.2f\n", (*aShift)(0), (*aShift)(1), (*aShift)(2)); + +} + +//______________________________________________________________________________ +// +DR3 DLadder::PlaneToLadder(DR3& aPlaneCoordinate, Int_t aPlaneNumber){ + + // converts a point given in the Plane coordinate frame UVW + // to the ladder coordinate frame, using the relative alignment. + // + // JB 2014/02/17 + + return planeRelativePrecAlign[aPlaneNumber]->TransformHitToTracker( aPlaneCoordinate); + +} + + +//______________________________________________________________________________ +// +void DLadder::AddPlane(DPlane* aPlane, Int_t planeID) +{ + std::cout<<"//*******************************************************//"<GetPlaneNumber()<<" //"<GetPlaneNumber()] = aPlane; + + //planeRotation[planeID] = DR3( aPlane->GetPrecAlignment()->GetRotations()[2], + // aPlane->GetPrecAlignment()->GetRotations()[1], + // aPlane->GetPrecAlignment()->GetRotations()[0] ); + + std::cout<<"// Translations : X = "<GetPrecAlignment()->GetTranslation()[0] + <<" Y = "<GetPrecAlignment()->GetTranslation()[1]<<" Z = " + <GetPrecAlignment()->GetTranslation()[2]<<" //"< MakeMiniVectors(). + // LC 2014/12/19 : Make all MVs per event and save them in _miniVectors container. + // LC 2014/12/19 : New class MiniVector. Mini-vectors are now saved in DLadder (See : _miniVectors) + // LC 2015/03/07 : Fill MonteCarlo MiniVector objects. + + ResetMiniVectors(); + + DPlane* myPlaneLeft = NULL; + + for( Int_t planeNumber=GetFirstPlane() ; planeNumber<(GetFirstPlane()+GetNumberOfPlanes()/2) ; ++planeNumber ) { + + Double_t distance = 0; + + myPlaneLeft = planeList[planeNumber]; + DPrecAlign* myPrecAlignLeft = myPlaneLeft->GetPrecAlignment(); + + if( myPlaneLeft->GetHitsN()==0 ) continue; + + for(Int_t iHitLeft=1 ; iHitLeft<=myPlaneLeft->GetHitsN() ; ++iHitLeft) { + + DHit* myMiniVectorHitLeft = myPlaneLeft->GetHit(iHitLeft); + + DR3 positionLeft = myPrecAlignLeft->TransformHitToTracker( DR3(myMiniVectorHitLeft->GetPositionUhitCG(), myMiniVectorHitLeft->GetPositionVhitCG(), 0. /*myMiniVectorHitLeft->GetPositionWhitCG()*/) ); + //myPrecAlignLeft->PrintAll(); + //positionLeft.Print(); + //myMiniVectorHitLeft->GetMonteCarloPosition().Print(); + //DR3(myMiniVectorHitLeft->GetPositionUhitCG(), myMiniVectorHitLeft->GetPositionVhitCG(), 0.).Print(); + //positionLeft.Print(); + + std::map rightPositions; + std::map > mapHitsRight; + + for(Int_t i=(GetFirstPlane()+GetNumberOfPlanes()/2) ; i<(GetFirstPlane()+GetNumberOfPlanes()) ; ++i) { + + DPlane* myPlaneRight = planeList[i]; + + if( myPlaneRight->GetHitsN()==0 ) continue; + + for( Int_t iHitRight=1 ; iHitRight<=myPlaneRight->GetHitsN() ; ++iHitRight) { + + DPrecAlign* myPrecAlignRight = myPlaneRight->GetPrecAlignment(); + + DHit* myHitRight = myPlaneRight->GetHit(iHitRight); + + DR3 positionRight = myPrecAlignRight->TransformHitToTracker( DR3(myHitRight->GetPositionUhitCG(), myHitRight->GetPositionVhitCG(), 0./*myHitRight->GetPositionWhitCG()*/) ); + //DR3(myHitRight->GetPositionUhitCG(), myHitRight->GetPositionVhitCG(), 0./*myHitRight->GetPositionWhitCG()*/).Print(); + + // Compute mini-vector length + distance = sqrt( (positionRight(2)-positionLeft(2))*(positionRight(2)-positionLeft(2)) + (positionRight(1)-positionLeft(1))*(positionRight(1)-positionLeft(1)) + (positionRight(0)-positionLeft(0))*(positionRight(0)-positionLeft(0)) ); + + // Filling in a map to order per distance (first element = closest) + std::pair paireHitRight(myHitRight,i); + mapHitsRight[distance] = paireHitRight; + rightPositions[distance] = positionRight; + } // end for hits right + + } // end loop on right planes + + DR3 positionRight(0.,0.,0.); + DHit* myMiniVectorHitRight=NULL; + Int_t planeRightIndex; + + DR3 planeFrameLeftPosition(0.,0.,0.); + DR3 planeFrameRightPosition(0.,0.,0.); + + DR3 trackerFrameLeftPositionMC(0., 0., 0.); + DR3 trackerFrameRightPositionMC(0., 0., 0.); + DR3 planeFrameLeftPositionMC(0., 0., 0.); + DR3 planeFrameRightPositionMC(0., 0., 0.); + + if(mapHitsRight.size()!=0) { + myMiniVectorHitRight = mapHitsRight.begin()->second.first; + positionRight = rightPositions.begin()->second; + planeRightIndex = mapHitsRight.begin()->second.second; + myMiniVectorHitRight = mapHitsRight.begin()->second.first; + + planeFrameLeftPosition = DR3(myMiniVectorHitLeft->GetPositionUhitCG(), myMiniVectorHitLeft->GetPositionVhitCG(), 0. ); + planeFrameRightPosition = DR3(myMiniVectorHitRight->GetPositionUhitCG(), myMiniVectorHitRight->GetPositionVhitCG(), 0. ); + + if( myMiniVectorHitRight->IfMonteCarlo() == 1 && myMiniVectorHitLeft->IfMonteCarlo() == 1 ) { + trackerFrameLeftPositionMC = myMiniVectorHitLeft->GetMonteCarloPosition(); + trackerFrameRightPositionMC = myMiniVectorHitRight->GetMonteCarloPosition(); + planeFrameLeftPositionMC = planeList[planeNumber]->GetPrecAlignment()->TransformHitToPlane(trackerFrameLeftPositionMC); + planeFrameRightPositionMC = planeList[planeRightIndex]->GetPrecAlignment()->TransformHitToPlane(trackerFrameRightPositionMC); + + } + + } + + if(positionRight(2) != positionLeft(2) && mapHitsRight.size()!=0 ) { + + DR3 center(0.,0.,0.); + + center(0) = ( positionRight(0)+positionLeft(0) )/2.; + center(1) = ( positionRight(1)+positionLeft(1) )/2.; + center(2) = ( positionRight(2)+positionLeft(2) )/2.; + + Int_t pixelCut = 3; + + Int_t colLeft = planeList[planeNumber]->GetStripsNu(); + Int_t rowLeft = planeList[planeNumber]->GetStripsNv(); + DR3 pitchLeft = planeList[planeNumber]->GetStripPitch(); + + Int_t colRight = planeList[planeRightIndex]->GetStripsNu(); + Int_t rowRight = planeList[planeRightIndex]->GetStripsNv(); + DR3 pitchRight = planeList[planeRightIndex]->GetStripPitch(); + + Double_t limitLeftU = colLeft*pitchLeft(0)/2. - pixelCut*pitchLeft(0); + Double_t limitLeftV = rowLeft*pitchLeft(1)/2. - pixelCut*pitchLeft(1); + + Double_t limitRightU = colRight*pitchRight(0)/2. - pixelCut*pitchRight(0); + Double_t limitRightV = rowRight*pitchRight(1)/2. - pixelCut*pitchRight(1); + + DR3 direction = ComputeDirection(positionLeft, positionRight); + DR3 directionMC = ComputeDirection(trackerFrameLeftPositionMC, trackerFrameRightPositionMC); + DR3 centerMC = (trackerFrameLeftPositionMC+trackerFrameRightPositionMC)/2.; + + centerMC.Print(); + /* + positionLeft.Print(); + positionRight.Print(); + */ + + // Cut for keep cluster of 5*5 + if( TMath::Abs(planeFrameLeftPosition(0))<=limitLeftU && TMath::Abs(planeFrameRightPosition(0))<=limitRightU && TMath::Abs(planeFrameLeftPosition(1))<=limitLeftV && TMath::Abs(planeFrameRightPosition(1))<=limitRightV ) { + + MiniVector* myNewMiniVector = new MiniVector(fPrecAlign, positionLeft, positionRight, planeList[planeNumber]->GetPrecAlignment(), planeList[planeRightIndex]->GetPrecAlignment(), center, direction, planeFrameLeftPosition, planeFrameRightPosition); + + if( myMiniVectorHitRight->IfMonteCarlo() == 1 && myMiniVectorHitLeft->IfMonteCarlo() == 1 ) { + myNewMiniVector->SetMonteCarloMiniVector( trackerFrameLeftPositionMC, trackerFrameRightPositionMC, centerMC, directionMC, planeFrameLeftPositionMC, planeFrameRightPositionMC ); + } + + AddMiniVector(myNewMiniVector); + } + + //std::cout<<" Number of reconstructed mini-vectors = "<& DataTemp, const Int_t ladderNumber, const Int_t planeNumber ) +{ + + // LC 2013/01/09 : New method to fit with Minuit. + // This method add data before the fit with Minuit. + // Modified: LC 2014/12/05 : Custom ladders + clean old code + // In DPlane we define : + /* + myData[0] --> GetHit(k)->GetPositionUhitCG() + myData[1] --> GetHit(k)->GetPositionVhitCG() + myData[2] --> aTrack->GetLinearFit().GetOrigin()(0) + myData[3] --> aTrack->GetLinearFit().GetOrigin()(1) + myData[4] --> aTrack->GetLinearFit().GetOrigin()(2) + myData[5] --> aTrack->GetLinearFit().GetSlopeZ()(0) + myData[6] --> aTrack->GetLinearFit().GetSlopeZ()(1) + myData[7] --> tDistanceU + myData[8] --> tDistanceV + myData[9] --> tDist2D + */ + + Int_t size = DataTemp.size(); + Int_t longueur = 15; + for(Int_t i=0; iGetPrecAlignment(); + + planeDPrecAlign->NewData(DataTemp[i*longueur+0], DataTemp[i*longueur+1], + DataTemp[i*longueur+13], DataTemp[i*longueur+14], + DataTemp[i*longueur+2], DataTemp[i*longueur+3], DataTemp[i*longueur+4], DataTemp[i*longueur+5], DataTemp[i*longueur+6]); + + } +} + + +//______________________________________________________________________________ +// +/* +void DLadder::FillResidus( std::vector& Data, const Int_t planeNumber, DR3& dxdydz ) +{ + fhDU->Fill(Data[7]); // residu DU. 10 -> CoG U 2x2 // 7 -> DU CoG + fhDV->Fill(Data[8]); // residu DV. 11 -> CoG V 2x2 // 8 -> DV CoG + fhDW->Fill(Data[12]); // 12 -> DW CoG + + fhDU_U->Fill(Data[0],Data[7]); // DU vs U + fhDV_V->Fill(Data[1],Data[8]); // DV vs V + + fhDU_V->Fill(Data[0],Data[8]); // DU vs V + fhDV_U->Fill(Data[1],Data[7]); // DU vs U + + fhSlopeX->Fill(Data[5]); // SlopeX + fhSlopeY->Fill(Data[6]); // SlopeY + + Double_t angleMC = 2.0; + Double_t angle = 180./TMath::Pi()*TMath::ATan( TMath::Sqrt(dxdydz(0)*dxdydz(0)+dxdydz(1)*dxdydz(1)) / dxdydz(2) ); + fhDiffSlopeX->Fill( (angle-angleMC)/angleMC ); + +} +*/ +//______________________________________________________________________________ +// +void DLadder::FillResidus(std::vector& Data, const Int_t planeNumber) +{ + fhDU->Fill(Data[10]); // residu DX. 10 -> CoG U 2x2 // 7 -> DU CoG + fhDV->Fill(Data[11]); // residu DY. 11 -> CoG V 2x2 // 8 -> DV CoG + fhDW->Fill(Data[12]); // 12 -> DZ CoG + + fhDU_U->Fill(Data[7],Data[10]); // DX vs X + fhDV_V->Fill(Data[8],Data[11]); // DY vs Y + + fhDU_V->Fill(Data[8],Data[10]); // DX vs Y + fhDV_U->Fill(Data[7],Data[11]); // DY vs X + + fhDW_U->Fill(Data[7],Data[12]); // DZ vs X + fhDW_V->Fill(Data[8],Data[12]); // DZ vs Y + + // fhDW_W->Fill(Data[9],Data[12]); // DZ vs Z + // fhDU_W->Fill(Data[9],Data[10]); // DX vs Z + // fhDV_W->Fill(Data[9],Data[11]); // DY vs Z + + // fhSlopeX->Fill(Data[5]); // SlopeX + // fhSlopeY->Fill(Data[6]); // SlopeY + + //Double_t angleMC = 10.0; + // fhDiffSlopeX->Fill( 0. ); + +} + +void DLadder::FillResidusMC(std::vector& Res, const Int_t planeNumber) +{ + fResMC_U->Fill(Res[0]); // Residus MC in U. + fResMC_V->Fill(Res[1]); // Residus MC in V. + fResMC_W->Fill(Res[2]); // Residus MC in W. +} + +//______________________________________________________________________________ +// +void DLadder::PrepareDisplay() +{ + TString name = "Residus ladder "; + name += ladderID; + TString canvasName = "Canvas"; + canvasName += ladderID; + + fCanvas = new TCanvas(canvasName, name, 800, 600); + fCanvas->Divide(3,4); +/* + TString nameMC = "Residus MC ladder "; + nameMC += ladderID; + TString canvasNameMC = "CanvasMC"; + canvasNameMC += ladderID; + + fCanvasMC = new TCanvas(canvasNameMC, nameMC, 800, 600); + fCanvasMC->Divide(1,3); +*/ +} + +//______________________________________________________________________________ +// +void DLadder::Display(Int_t runNumber) +{ + std::cout<<"Display"<GetEntries()>0) { + fCanvas->cd(1); + fhDU->Draw(); + fhDU->Fit("gaus"); + gStyle->SetOptFit(111); + fhDU->SaveAs(fileNameResDU); + //fhDU->SaveAs(fileNameResDU); + fCanvas->cd(4); + fhDU_U->SetMarkerColor(kRed); + fhDU_U->Draw(); + + fCanvas->cd(7); + fhDU_V->SetMarkerColor(kGreen); + fhDU_V->Draw(); + + // fCanvas->cd(10); + // fhDU_W->SetMarkerColor(kBlue); + // fhDU_W->Draw(); + } + + if ( fhDV && fhDV->GetEntries()>0) { + fCanvas->cd(2); + fhDV->Draw(); + fhDV->Fit("gaus"); + gStyle->SetOptFit(111); + fhDV->SaveAs(fileNameResDV); + //fhDV->SaveAs(fileNameResDV); + fCanvas->cd(5); + fhDV_U->SetMarkerColor(kRed); + fhDV_U->Draw(); + + fCanvas->cd(8); + fhDV_V->SetMarkerColor(kGreen); + fhDV_V->Draw(); + + // fCanvas->cd(11); + // fhDV_W->SetMarkerColor(kBlue); + // fhDV_W->Draw(); + } + + if ( fhDW && fhDW->GetEntries()>0) { + fCanvas->cd(3); + fhDW->Draw(); + fhDW->Fit("gaus"); + gStyle->SetOptFit(111); + fhDW->SaveAs(fileNameResDW); + + fCanvas->cd(6); + fhDW_U->SetMarkerColor(kRed); + fhDW_U->Draw(); + + fCanvas->cd(9); + fhDW_V->SetMarkerColor(kGreen); + fhDW_V->Draw(); + + // fCanvas->cd(12); + // fhDW_W->SetMarkerColor(kBlue); + // fhDW_W->Draw(); + } + // if( fhSlopeX && fhSlopeX->GetEntries()>0 ) { + // fCanvas->cd(8); + // fhSlopeX->Draw(); + // } + + // if( fhSlopeY && fhSlopeY->GetEntries()>0 ) { + // fCanvas->cd(9); + // fhSlopeY->Draw(); + // } + + // if( fhSlopeX && fhSlopeX->GetEntries()>0 ) { + // fCanvas->cd(10); + // gPad->SetLogy(); + // fhDiffSlopeX->Draw(); + // fhDiffSlopeX->SaveAs(fileNameDiffSlope); + // } + + if( fhDV && fhDV->GetEntries()>0 ) { + fCanvas->cd(10); + myProfileX = fhDV_V->ProfileX("myProfileX", -5000, 5000); + myProfileX->Draw(); + fCanvas->cd(11); + myProfileY = fhDV_U->ProfileX("myProfileY"); + myProfileY->Draw(); + } +/* + TString fileNameResMC_DU = "residuMC_DU_Ladder_"; + fileNameResMC_DU += ladderID; + fileNameResMC_DU += "_"; + fileNameResMC_DU += runNumber; + fileNameResMC_DU += ".root"; + + TString fileNameResMC_DV = "residuMC_DV_Ladder_"; + fileNameResMC_DV += ladderID; + fileNameResMC_DV += "_"; + fileNameResMC_DV += runNumber; + fileNameResMC_DV += ".root"; + + TString fileNameResMC_DW = "residuMC_DW_Ladder_"; + fileNameResMC_DW += ladderID; + fileNameResMC_DW += "_"; + fileNameResMC_DW += runNumber; + fileNameResMC_DW += ".root"; + + if( fResMC_U && fResMC_U->GetEntries()>0 ) { + fCanvasMC->cd(1); + fResMC_U->Draw(); + fResMC_U->Fit("gaus"); + gStyle->SetOptFit(111); + fResMC_U->SaveAs(fileNameResMC_DU); + + } + + if( fResMC_V && fResMC_V->GetEntries()>0 ) { + fCanvasMC->cd(2); + fResMC_V->Draw(); + fResMC_V->Fit("gaus"); + gStyle->SetOptFit(111); + fResMC_V->SaveAs(fileNameResMC_DV); + } + + if( fResMC_W && fResMC_W->GetEntries()>0 ) { + fCanvasMC->cd(3); + fResMC_W->Draw(); + fResMC_W->Fit("gaus"); + gStyle->SetOptFit(111); + fResMC_W->SaveAs(fileNameResMC_DW); + } +*/ +} + +//______________________________________________________________________________ +// +void DLadder::AddMiniVector(MiniVector* myNewMiniVector) +{ + + _miniVectors.push_back(myNewMiniVector); + +} + +//______________________________________________________________________________ +// +void DLadder::RemoveLastMiniVector() +{ + + std::vector::iterator iter = _miniVectors.end(); + delete *iter; + _miniVectors.pop_back(); + +} + +//______________________________________________________________________________ +// +void DLadder::ResetMiniVectors() +{ + std::vector::iterator iter = _miniVectors.begin(); + for( ; iter!=_miniVectors.end() ; ++iter ) delete *iter; + _miniVectors.clear(); +} + +//______________________________________________________________________________ +// +void DLadder::ResetAssociatedMiniVectors() +{ + std::vector::iterator iter = _associatedMiniVectors.begin(); + for( ; iter!=_associatedMiniVectors.end() ; ++iter ) delete *iter; + _associatedMiniVectors.clear(); +} + +//______________________________________________________________________________ +// +void DLadder::ResetMiniVectorsList(std::vector listOfDelete ) +{ + std::vector::iterator it = listOfDelete.begin(); + for( ; it!=listOfDelete.end() ; ++it) { + delete _associatedMiniVectors[*it]; + _associatedMiniVectors.erase(_associatedMiniVectors.begin()+*it); + } +} + +//______________________________________________________________________________ +// +void DLadder::AddAssociatedMiniVector(MiniVector* myAssociatedMV) +{ + MiniVector* associatedMiniVector = new MiniVector(); + *associatedMiniVector = *myAssociatedMV; + _associatedMiniVectors.push_back(associatedMiniVector); +} diff --git a/src/DLine.cxx b/src/DLine.cxx new file mode 100755 index 0000000..3b12b01 --- /dev/null +++ b/src/DLine.cxx @@ -0,0 +1,157 @@ +// @(#)maf/dtools:$Name: $:$Id: DLine.cxx,v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Dirk Meier 98/01/09 + + ////////////////////////////////////////////////////////////////////////////////////////////// + // // + // Class Description of DLine // + // // + // a Line object is defined by its // + // origin = (x_0,y_0,z_0), // + // direction = (dx,dy,dz), // + // and length. // + // Points on the line at r_i are given as a function // + // of the parameter beta. beta has no dimension. // + // r_i(beta) = origin_i + beta * direction_i // + // If one wants the pair (x,y) as a function of z along (0,0,dz) then beta = z/dz // + // and r_1(beta) = x_0 + z * dx/dz // + // r_2(beta) = y_0 + z * dy/dz // + // r_3(beta) = z_0 + z * 1 // + // In case one needs pair (x,y,z) as a function of l along (dx,dy,dz) then beta' = l/dl // + // and r_1(beta') = x_0 + l * dx/dl // + // r_2(beta') = y_0 + l * dy/dl // + // r_3(beta') = z_0 + l * dz/dl // + // with the relation beta^2 = beta'^2 * (1-x^2/l^2-y^2/l^2) / (1-dx^2/dl^2-dy^2/dl^2) // + // // + ////////////////////////////////////////////////////////////////////////////////////////////// + + +//*-- Modified : +//*-- Copyright: RD42 +//*-- Author : Dirk Meier 98/01/09 +//*KEEP,CopyRight. + +// Last Modified: JB 2011/07/25 destructor + +/************************************************************************ + * Copyright(c) 1997, DiamondTracking, RD42@cern.ch + ***********************************************************************/ +//*KEND. + +//*KEEP,DLine. +#include "DLine.h" +//*KEEP,DR3. +#include "DR3.h" +//*KEND. + +ClassImp(DLine) // Description of a Line + +//______________________________________________________________________________ +// + +DLine::DLine(){ + fOrigin = new DR3(); + fDirection = new DR3(); + fSlope = new DR3(); + fLength = 0.0; +} + +//______________________________________________________________________________ +// + +DLine::DLine(DR3 &aOrigin, DR3 &aDirection, Float_t aLength){ + fOrigin = new DR3(aOrigin); + fDirection = new DR3(aDirection); + fSlope = new DR3(); + fLength = aLength; +} + +//______________________________________________________________________________ +// + +DLine::~DLine(){ + + // delete instruction modified to avoid crash, JB 2011/07/25 + delete fOrigin; + delete fDirection; + delete fSlope; +} + +//______________________________________________________________________________ +// + +void DLine::SetValue(const DR3& aOrigin, + const DR3& aDirection, + const DR3& aSlope, + const Float_t aLength){ + *fOrigin = aOrigin; + *fDirection = aDirection; + *fSlope = aSlope; + fLength = aLength; +} + +//______________________________________________________________________________ +// + +void DLine::Zero(){ + fOrigin->Zero(); + fDirection->Zero(); + fSlope->Zero(); + fLength = 0; +} + +//______________________________________________________________________________ +// + +DR3 DLine::GetPoint(Float_t beta){ + DR3 result; + result = (*fDirection) * beta; + return result += *fOrigin; +} + +//______________________________________________________________________________ +// + +DR3 DLine::GetIntersectZ(Float_t aZvalue){ + Float_t tDz; + DR3 tZero; + tDz = GetDirection()(2); + if (tDz != 0.) + return GetPoint(aZvalue/tDz); + else + return tZero; +} + +//______________________________________________________________________________ +// + +Float_t DLine::Distance(DR3 &p){ + // distance d = sqrt(n_k n_k) between point p_k and line G + // with G is set of r_k : r_k = a_k x + b_k ; for all x element R and k = 1..3 + // ... now n_i pops out : + // n_i = (1_ik - a_i a_k / a^2) (p_k - b_k) ; 1_ik is kronecker's thing + // ... which delivers distance d: (note a,b,c,p are 3-Vectors) + // d = sqrt(c^2 - 2 (a*c)^2 / a^2 + (a*c)^2) with c = p - b, + // * is the scalar vector product + // and wire it in: + + DR3 c; + Float_t d; + + c.SetDifference(p, *fOrigin); + d = c.InnerProduct(*fDirection); + + return sqrt(c.InnerProduct(c) - + 2 * d * d / fDirection->InnerProduct(*fDirection) + + d * d); +} + + + + + + + + + + + diff --git a/src/DMiniVector.cxx b/src/DMiniVector.cxx new file mode 100755 index 0000000..3d2054e --- /dev/null +++ b/src/DMiniVector.cxx @@ -0,0 +1,586 @@ +// Author : L. Cousin 2014/12/19 +// Save, recompute and project mini-vectors + +#include +#include "DMiniVector.h" + +//______________________________________________________________________________ +// +MiniVector::MiniVector(DPrecAlign* ladderDPrecAlign, DR3& hitLeftPosition, DR3& hitRightPosition, DPrecAlign* alignPlaneLeft, DPrecAlign* alignPlaneRight, DR3& centerPosition, DR3& direction, DR3 planeFrameLeft, DR3 planeFrameRight ) +{ + // LC 2014/12/19. + // Compute the MiniVector in Ladder frame. + _ladderDPrecAlign = ladderDPrecAlign; + _planesDPrecAlign.first = alignPlaneLeft; + _planesDPrecAlign.second = alignPlaneRight; + + // from tracker frame to plane/ladder frame. + DR3 leftPos = alignPlaneLeft->TransformHitToPlane(hitLeftPosition); + DR3 rightPos = alignPlaneRight->TransformHitToPlane(hitRightPosition); + + //DR3 centerPos2 = (hitLeftPosition+hitRightPosition)/2.; + DR3 centerPos = _ladderDPrecAlign->TransformHitToPlane(centerPosition); + + _planeFrameLeft = planeFrameLeft; + _planeFrameRight = planeFrameRight; + +/* + centerPosition.Print(); + centerPos2.Print(); + DR3 centerLadder = (leftPos+rightPos)/2.; + centerLadder.Print(); + centerPos.Print(); +*/ + + for(Int_t i=0; i<3 ; ++i) { + + _hitLeftPosition.push_back( leftPos(i) ); + _hitRightPosition.push_back( rightPos(i) ); + _miniVectorCenterPosition.push_back( centerPos(i) ); + _miniVectorDirection.push_back( 0. ); + _miniVectorOrigin.push_back( 0. ); + } + + GetMiniVectorDirection(); + + //std::cout<<" diff direction 0 = "<<_miniVectorDirection[0] - direction(0)<TransformHitToTracker( hitLeftLadderFrame ); + + return hitLeftTrackerFrame; +} + +//______________________________________________________________________________ +// +DR3 MiniVector::GetHitRightTrackerPosition() +{ + // Recompute the hit position wrt the ladder alignment parameters. + DR3 hitRightLadderFrame = DR3( _hitRightPosition[0], _hitRightPosition[1], _hitRightPosition[2] ); + DR3 hitRightTrackerFrame = (_planesDPrecAlign.second)->TransformHitToTracker( hitRightLadderFrame ); + + return hitRightTrackerFrame; +} + +//______________________________________________________________________________ +// +DR3 MiniVector::GetMiniVectorTrackerCenter() +{ + // Recompute the hit position wrt the ladder alignment parameters. + + DR3 leftTracker = GetHitLeftTrackerPosition(); + DR3 rightTracker = GetHitRightTrackerPosition(); + DR3 centerTracker = (rightTracker + leftTracker)/2.; + + +// std::cout<<"cnterTracker/DPrecAlign Left/ DPrecAlignRight"<PrintAll(); + (_planesDPrecAlign.first)->PrintTorMatrix(); + (_planesDPrecAlign.second)->PrintAll(); + (_planesDPrecAlign.second)->PrintTorMatrix(); +*/ + DR3 centerLadderFrame = DR3( _miniVectorCenterPosition[0], _miniVectorCenterPosition[1], _miniVectorCenterPosition[2] ); + DR3 centerTrackerFrame = _ladderDPrecAlign->TransformHitToTracker( centerLadderFrame ); +/* + std::cout<<"cnterTracker = "<GetCoeffs(); + + //_coeffABC.Print(); + + Double_t t=-(_coeffABC(0)*tx+_coeffABC(1)*ty+tz+_coeffABC(2))/(_coeffABC(0)*tdx+_coeffABC(1)*tdy+1.); + + Double_t _x = tx+t*tdx; + Double_t _y = ty+t*tdy; + Double_t _z = tz+t*1.; + + return DR3(_x, _y, _z); +} + +//______________________________________________________________________________ +// +DR3 MiniVector::CalculateMiniVectorIntersectionLadder(DPrecAlign* myDPrecAlign) +{ + // LC 2014/12/20 Similar to Calcultate Intersection but for MiniVector objects + + DR3 Direction = GetMiniVectorDirection(); + DR3 Origin = GetMiniVectorOrigin(); // GetMiniVectorTrackerCenter(); + + //std::cout<<"origin and direction"<GetCoeffs(); + + Double_t t=-(_coeffABC(0)*tx+_coeffABC(1)*ty+tz+_coeffABC(2))/(_coeffABC(0)*tdx+_coeffABC(1)*tdy+1.); + + Double_t _x = tx+t*tdx; + Double_t _y = ty+t*tdy; + Double_t _z = tz+t*1.; + +/* + std::cout<<"pos tracker"<TransformHitToPlane( DR3(_x, _y, _z) ); + +} + +//______________________________________________________________________________ +// +DR3 MiniVector::GetHitLeftPlanePositionMC() +{ + return DR3( _hitLeftPositionMC[0], _hitLeftPositionMC[1], _hitLeftPositionMC[2] ); +} + +//______________________________________________________________________________ +// +DR3 MiniVector::GetHitRightPlanePositionMC() +{ + return DR3( _hitRightPositionMC[0], _hitRightPositionMC[1], _hitRightPositionMC[2] ); +} + +//______________________________________________________________________________ +// +DR3 MiniVector::GetMiniVectorLadderCenterMC() +{ + return DR3( _miniVectorCenterPositionMC[0], _miniVectorCenterPositionMC[1], _miniVectorCenterPositionMC[2] ); +} + +//______________________________________________________________________________ +// +DR3 MiniVector::GetHitLeftTrackerPositionMC() +{ + // Recompute the hit position wrt the ladder alignment parameters. + + DR3 hitLeftLadderFrameMC = DR3( _hitLeftPositionMC[0], _hitLeftPositionMC[1], _hitLeftPositionMC[2] ); + DR3 hitLeftTrackerFrameMC = (_planesDPrecAlign.first)->TransformHitToTracker( hitLeftLadderFrameMC ); + + return hitLeftTrackerFrameMC; +} + +//______________________________________________________________________________ +// +DR3 MiniVector::GetHitRightTrackerPositionMC() +{ + // Recompute the hit position wrt the ladder alignment parameters. + DR3 hitRightLadderFrameMC = DR3( _hitRightPositionMC[0], _hitRightPositionMC[1], _hitRightPositionMC[2] ); + DR3 hitRightTrackerFrameMC = (_planesDPrecAlign.second)->TransformHitToTracker( hitRightLadderFrameMC ); + + return hitRightTrackerFrameMC; +} + +//______________________________________________________________________________ +// +DR3 MiniVector::GetMiniVectorTrackerCenterMC() +{ + // Recompute the hit position wrt the ladder alignment parameters. + + DR3 leftTrackerMC = GetHitLeftTrackerPositionMC(); + DR3 rightTrackerMC = GetHitRightTrackerPositionMC(); + DR3 centerTrackerMC = (rightTrackerMC + leftTrackerMC)/2.; + + +// std::cout<<"cnterTracker/DPrecAlign Left/ DPrecAlignRight"<PrintAll(); + (_planesDPrecAlign.first)->PrintTorMatrix(); + (_planesDPrecAlign.second)->PrintAll(); + (_planesDPrecAlign.second)->PrintTorMatrix(); +*/ + DR3 centerLadderFrameMC = DR3( _miniVectorCenterPositionMC[0], _miniVectorCenterPositionMC[1], _miniVectorCenterPositionMC[2] ); + DR3 centerTrackerFrameMC = _ladderDPrecAlign->TransformHitToTracker( centerLadderFrameMC ); +/* + std::cout<<"cnterTracker = "<GetCoeffs(); + + //_coeffABC.Print(); + + Double_t t=-(_coeffABC(0)*tx+_coeffABC(1)*ty+tz+_coeffABC(2))/(_coeffABC(0)*tdx+_coeffABC(1)*tdy+1.); + + Double_t _x = tx+t*tdx; + Double_t _y = ty+t*tdy; + Double_t _z = tz+t*1.; + + return DR3(_x, _y, _z); +} + +//______________________________________________________________________________ +// +DR3 MiniVector::CalculateMiniVectorIntersectionLadderMC(DPrecAlign* myDPrecAlign) +{ + // LC 2014/12/20 Similar to Calcultate Intersection but for MiniVector objects + + DR3 DirectionMC = GetMiniVectorDirectionMC(); + DR3 OriginMC = GetMiniVectorOriginMC(); // GetMiniVectorTrackerCenter(); + + //std::cout<<"origin and direction"<GetCoeffs(); + + Double_t t=-(_coeffABC(0)*tx+_coeffABC(1)*ty+tz+_coeffABC(2))/(_coeffABC(0)*tdx+_coeffABC(1)*tdy+1.); + + Double_t _x = tx+t*tdx; + Double_t _y = ty+t*tdy; + Double_t _z = tz+t*1.; + +/* + std::cout<<"pos tracker"<TransformHitToPlane( DR3(_x, _y, _z) ); + +} diff --git a/src/DModule.cxx b/src/DModule.cxx new file mode 100644 index 0000000..aed87b4 --- /dev/null +++ b/src/DModule.cxx @@ -0,0 +1,124 @@ +// @(#)maf/dtools:$Name: $:$Id: DModule.cxx,v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Dirk Meier 98/03/22 + + + //////////////////////////////////////////////////////////////////////////////// + // // + // Class Description of DModule // + // // + // + DModule, may be used in future (>980322) to replace parts of DAcqModule // + // // + //////////////////////////////////////////////////////////////////////////////// + + +//*-- Modified : +//*-- Copyright: RD42 +//*-- Author : Dirk Meier 980322 +//*KEEP,CopyRight. +/************************************************************************ + * Copyright(c) 1997, RD42@CERN, DiamondTracking. + ***********************************************************************/ +//*KEND. + +#include "Riostream.h" + +// DT classes +//*KEEP,DModule. +#include "DModule.h" + +//*KEND. + +ClassImp(DModule) // Description of DModule + +//______________________________________________________________________________ +// +DModule::DModule() +{ + // DModule default constructor +} + +//______________________________________________________________________________ +// +DModule::~DModule() +{ + // DModule default destructor +} + +//______________________________________________________________________________ +// +DModule::DModule(Int_t aValuesN) +{ + fIsConnected = kFALSE; + fValuesN = aValuesN; + + fData = new TArrayF(fValuesN); //Float_t[fValuesN]; +} + +//______________________________________________________________________________ +// +void DModule::SetCodeTable(const Char_t *aLocation, + Int_t aCodingValuesN, + Int_t aCodingBitsN, + Int_t aSplitInputsN, + Int_t aSplitInput) +{ + fLocation = new TArrayC(aCodingValuesN); // first create it with new operator + fLocation->Adopt(aCodingValuesN, aLocation); // then adopt the *Char_t + fCodingValuesN = aCodingValuesN; + fSplitInputsN = aSplitInputsN; + fSplitInput = aSplitInput; + fCodingBitsN = aCodingBitsN; + fIsConnected = kTRUE; +} + +//______________________________________________________________________________ +// +void DModule::Update() +{ + Int_t pp; + if(fIsConnected) + for(Int_t tINP = 1; tINP <= fSplitInputsN; tINP++) + for(Int_t k = 1; k <= fCodingValuesN; k++) { + pp = ( (k-1) * fSplitInputsN + tINP-1 ) * fCodingBitsN/8; + // fData[k-1] = theValue(fLocation->GetArray() + pp, fCodingBitsN/8); + fData->AddAt(theValue(fLocation->GetArray() + pp, fCodingBitsN/8), k-1); + } + else + printf(" DModule, not connected \n"); +} + +//______________________________________________________________________________ +// +void DModule::PrintDataToTerm() +{ + if(fIsConnected) + printf(" DModule, is connected, printing not implemented yet\n"); + else + printf(" DModule, not connected \n"); +} + +//______________________________________________________________________________ +// +Int_t DModule::theValue(const Char_t* aBufferPoint, Int_t width) +{ + + // Converts the contens of buffer to a value + // e.g. *aBufferPoint = (0A 14 FA 3C ... ), + // and width = 2 gives value = 2580 + + Int_t v = 0; + Int_t pot = 1; + for (Int_t k = 1; k <= width; k++){ + v = v + pot * (0x00FF & aBufferPoint[width - k]); + pot = 0x100 * pot; + } + return v; +} + + + + + + + + diff --git a/src/DMonteCarlo.cxx b/src/DMonteCarlo.cxx new file mode 100755 index 0000000..ab6417d --- /dev/null +++ b/src/DMonteCarlo.cxx @@ -0,0 +1,48 @@ +// Author : LC, 2012/10/18 + + //////////////////////////////////////////////////////////// + // Class Description of DMonteCarlo // + // // + // // + //////////////////////////////////////////////////////////// + + +#include "DMonteCarlo.h" +#include "DR3.h" + +ClassImp(DMonteCarlo) // Description of Single Detector DMonteCarlo +//______________________________________________________________________________ +// +DMonteCarlo::DMonteCarlo() +{ + // DMonteCarlo default constructor +} + +//______________________________________________________________________________ +// + +DMonteCarlo::~DMonteCarlo() +{ + // DMonteCarlo default destructor + +} + +//______________________________________________________________________________ +// +DMonteCarlo::DMonteCarlo( Int_t aPlaneNumber, Double_t aMC_X, Double_t aMC_Y, Double_t aMC_Z, Double_t aValue) +{ + // constructor of a MonteCarlo point with his parameter + + fDebugMonteCarlo = 0; + + fPlaneNumber = aPlaneNumber; + fMonteCarloX = aMC_X; + fMonteCarloY = aMC_Y; + fMonteCarloZ = aMC_Z; + fRawValue = aValue; + + fFound = kFALSE; + + if(fDebugMonteCarlo>1) printf("DMonteCarlo : Plane %d with value %f built\n", fPlaneNumber, fRawValue); + +} diff --git a/src/DParticle.cxx b/src/DParticle.cxx new file mode 100755 index 0000000..875f17a --- /dev/null +++ b/src/DParticle.cxx @@ -0,0 +1,50 @@ +// @(#)maf/dtools:$Name: $:$Id: DParticle.cxx,v.1 2005/10/02 18:03:46 sha Exp $ +// Author : Dirk Meier 98/02/19 + + ///////////////////////////////////////////////////////////// + // // + // Class Description of Particle // + // // + // // + ///////////////////////////////////////////////////////////// + +//*-- Modified : +//*-- Copyright: RD42 +//*-- Author : Dirk Meier 98/02/19 +//*KEEP,CopyRight. +/************************************************************************ + * Copyright(c) 1998, RD42@CERN, DiamondTracking. + ***********************************************************************/ +//*KEND. + +//*KEEP,DParticle. +#include "DParticle.h" + +//*KEEP,DR3. +#include "DR3.h" + +//*KEND. + +ClassImp(DParticle) // Description of a Particle + +//______________________________________________________________________________ +// +DParticle::DParticle() +{ + fMomentum = new DR3(); + fPosition = new DR3(); +} + +//______________________________________________________________________________ +// +DParticle::~DParticle() +{ +} + +//______________________________________________________________________________ +// +void DParticle::Vacuum(){ + fMomentum->Zero(); + fPosition->Zero(); + fCharge = 0.; +} diff --git a/src/DPixel.cxx b/src/DPixel.cxx new file mode 100644 index 0000000..77f3455 --- /dev/null +++ b/src/DPixel.cxx @@ -0,0 +1,210 @@ +// @(#)maf/dtools:$Name: $:$Id:DPixel.cxx v.3 2005/10/02 18:03:46 sha Exp $ +// Author : JB, 2008/10/28 +// Modified: RDM 060809 +// Modified: JB 2009/08/17 +// Modified: JB 2010/10/05 signal over noise management +// Modified: JB 2013/06/23 Consructors timestamp info added +// Modified: LC laste 2014 or early 2015 MonteCarlo info management +// Modified: JB 2015/03/25 Constructors with DAQ index +// Modified: AP 2016/04/15 Constructors with Sim-hit index turning on this pixel + + //////////////////////////////////////////////////////////// + // Class Description of DPixel // + // // + // // + //////////////////////////////////////////////////////////// + +#include "DPixel.h" +#include "DR3.h" + +ClassImp(DPixel) // Description of Single Detector DPixel +//______________________________________________________________________________ +// +DPixel::DPixel() +{ + // DPixel default constructor +} + +//______________________________________________________________________________ +// + +DPixel::~DPixel() +{ + // DPixel default destructor + _monteCarloInfo.clear(); +} + +//______________________________________________________________________________ +// +DPixel::DPixel(Int_t aPlaneNumber, const Int_t aPixelIndex, Double_t aValue, Int_t aTime) +{ + // Constructor of a Pixel with index identification. + // + // Note that the index is understood as a DAQ or a physical index: + // - DAQ index = channel nb from DAQ board (BoardReader), + // - physical index = related to (col,row) position with + // col = index%(#pixelsInRow), row = index/(#pixelsInRow) + // + // Last modified: JB, 2009/05/03 + // Last modified: JB, 2013/06/23 timestamp info added + // Last modified: JB, 2015/03/25 DAQ index added + // Last modified: AP, 2016/04/15 Added HitIdx variable to retrive the MC sim-hit turning on this pixel + + fDebugPixel = 0; + + fPlaneNumber = aPlaneNumber; + fPixelIndex = aPixelIndex; + fDAQIndex = aPixelIndex; + fRawValue = aValue; + fTimestamp = aTime; + + fPixelLine = 0; // init, TBD later + fPixelColumn = 0; // init, TBD later + fPosition.SetValue(0, 0, 0); + fSize.SetValue(0, 0, 0); + + fPedestal = 0.; + fCommonMode = 0.; + fNoise = 1.e-5; + fPulseHeight = fRawValue; // To be modified later when pedestal is known, JB 2009/05/03 + fFound = kFALSE; + fIfMonteCarlo = 0; + fMCHitIdx = -1; + + if(fDebugPixel>1) printf("DPixel: pixel %d from plane %d with value %f built\n", fPixelIndex, fPlaneNumber, fRawValue); + +} +//______________________________________________________________________________ +// +DPixel::DPixel(Int_t aPlaneNumber, Int_t aLine, Int_t aColumn, Double_t aValue, Int_t aTime) +{ + // constructor of a Pixel with column and line + // + // Last modified: JB, 2009/08/17 + // Last modified: JB, 2013/06/23 timestamp info added + // Last modified: JB, 2015/03/25 DAQ index added + + fDebugPixel = 0; + + fPlaneNumber = aPlaneNumber; + fPixelLine = aLine; + fPixelColumn = aColumn; + fRawValue = aValue; + fTimestamp = aTime; + + fPixelIndex = -1; // TBD later + fDAQIndex = -1; // TBD later + fPosition.SetValue(0, 0, 0); + fSize.SetValue(0, 0, 0); + + fPedestal = 0.; + fCommonMode = 0.; + fNoise = 1.e-5; + fPulseHeight = fRawValue; // To be modified later when pedestal is known, JB 2009/05/03 + fFound = kFALSE; + fIfMonteCarlo = 0; + + if(fDebugPixel>1) printf("DPixel: pixel %d from plane %d with value %f built\n", fPixelIndex, fPlaneNumber, fRawValue); + +} +//______________________________________________________________________________ + +Double_t DPixel::GetPulseHeightToNoise(){ + + // Note that the method returns the pulseheight if there is no noise available + // + // Modified: JB 2010/10/05 + + if (fNoise > 0.5) { + return fPulseHeight / fNoise; + } + else { + return fPulseHeight; + } +} +//______________________________________________________________________________ +// +Double_t DPixel::Distance(DPixel &aPixel) +{ + return Distance(aPixel.GetPosition()); +} + +//______________________________________________________________________________ +// +Double_t DPixel::Distance(const DR3& aPosition) +{ + DR3 result(fPosition); + result -= aPosition; + return result.Length(); +} + +//______________________________________________________________________________ +// +Double_t DPixel::DistanceU(DPixel &aPixel) +{ + return DistanceU(aPixel.GetPosition()); +} + +//______________________________________________________________________________ +// +Double_t DPixel::DistanceU(const DR3& aPosition) +{ + DR3 result(fPosition); + result -= aPosition; + return result(0); +} + +//______________________________________________________________________________ +// +Double_t DPixel::DistanceV(DPixel &aPixel) +{ + return DistanceV(aPixel.GetPosition()); +} + +//______________________________________________________________________________ +// +Double_t DPixel::DistanceV(const DR3& aPosition) +{ + DR3 result(fPosition); + result -= aPosition; + return result(1); +} + +//______________________________________________________________________________ +// +void DPixel::SetMonteCarlo( Double_t aMC_X, Double_t aMC_Y, Double_t aMC_Z, Int_t row, Int_t column) +{ + if(fDebugPixel) std::cout<<"Setting MonteCarlo parameters"<=3 ) { return DR3( _monteCarloInfo[0], _monteCarloInfo[1], _monteCarloInfo[2] ); } + else { + std::cout<<"Monte Carlo Informations Disable --> To enable these option set HitMonteCarlo: 1 in the config file."<SetSize( (*fSize)) by aPixel->SetSize( (*fPitch)) +// Last Modified: VR, 2014/07/12 add the DHit::Analyse_2_cgo method when fHitFinder == 2) +// Last Modified: AP, 2014/07 find_hits() +// Last Modified: VR, 2014/08/28 add mecanism to keep untracked hits from last event +// Last Modified: LC, 2014/12/05 AlignData : clean old code. +// Last Modified: LC, 2014/12/15 MonteCarlo Infos now in DPixel and DHit :: See DPixel : std::vector _monteCarloInfo. +// Last Modified: AP, 2015/03/09 Adding hit spation resolution information in AlignData +// Last Modified: AB, 2015/03/31 ComputeStripPosition +// Last Modified: JB, 2015/05/26 DPlane to hadle timelimit +// Last Modified: AP, 2015/06/08 Added bool parameter (UseAllHits) to AlignPrec, to decide if doing alignment with all hits or with the closest one. +// Last Modified: JB, 2016/07/20 DPlane, analyse_basics for better management of fNoiseRun option +// Last Modified: JB, 2016/08/17 Updates for multiframe mode +// Last Modified: JB, 2016/08/19 DPlane, allow fNoiserun option for mode 232 +// Last Modified: JB, 2016/10/17 DPlane::DPlane +// Last Modified: JB, 2018/05/04 DPlane::Update +// Last Modified: JB, 2018/07/04 Dplane, Update, SetPixelGainFromHisto for pixel gain map usage +// Last Modified: JB, 2010/11/25 Update + +///////////////////////////////////////////////////////////// +// Class Description of DPlane // +// // +// + finds pedestal // +// + calculates pulseheight // +// + corrects for common mode (shift) // +// + calculates single noise // +// // +///////////////////////////////////////////////////////////// + + +#include "Riostream.h" +#include +#include "DPlane.h" +#include "DSetup.h" +#include "DSession.h" +#include "DAcq.h" +//#include "DAcqModule.h" +//#include "DInp.h" +#include "DTracker.h" +#include "DStrip.h" +#include "DHit.h" +//#include "DHitMonteCarlo.h" +#include "DTrack.h" +#include "DLine.h" +#include "DCut.h" +#include "DPrecAlign.h" +#include "DAlign.h" +#include "DR3.h" +#include "DGlobalTools.h" +#include +#include "TMimosa24_25Map.h" //RDM120509 + +#include + +ClassImp(DPlane) // Description of DPlane + +//______________________________________________________________________________ +// + +DPlane::DPlane() +{ + + fDebugPlane=0; + + rand = new TRandom(182984); + +} + +//______________________________________________________________________________ +// + +DPlane::DPlane(DTracker& aTracker, const Int_t aPlaneNumber, const Int_t aLadderNumber) +{ + // Main constructor of the DPLane class. + // + // Last Modified: JB 2009/08/21 + // Last Modified: JB 2009/09/01, skip DStrip list construction for sparsified data + // Last Modified: JB 2011/07/07 to localize path names + // Last Modified: JB 2012/11/21 include Mapping for strip position computation + // Last Modified: LC 2013/Sping introducing the ladder that this plane may belong to + // Last Modified: JB 2013/07/17 new control parameters (HitFinder, IfDigitize) + // Last Modified: JB 2013/08/15 new parameter fAcqChannelOffset + // Last Modified: JB 2014/04/21 get deformation parameters + // Last Modified: VR 2014/07/12 replace aPixel->SetSize( (*fSize)) by aPixel->SetSize( (*fPitch)) + // Last Modified: JB 2015/05/26 handle time limit + // Last Modified: JB 2015/10/31 pass deformation parameters to DPrecAlign + // Last Modified: JB 2016/10/17 cope with Plane with no DAQ modules (simple material) + // Last Modified: JB 2018/07/04 load pixel gain histo from file if required + + cout << endl << " -*-*- DPlane " << aPlaneNumber << " User Constructor -*-*- " << endl; + + fTracker = &aTracker; + fAcq = fTracker->GetAcq(); // set pointer to Data Acquisition + fc = fTracker->GetSetup(); // set pointer to Configuration + fSession = fc->GetSession(); // set pointer to Session, JB 2011/07/21 + fDebugPlane = fc->GetDebug(); + Int_t st,ch; + + //Get MC information from fAcq + //1st check that the data being readout is MC + MCInfoHolder = NULL; + if(fAcq->GetIfMCBoardReader()) MCInfoHolder = fAcq->GetMCInfoHolder(); + + fLadderNumber = aLadderNumber; // LC 2013/Spring + fPlaneNumber = aPlaneNumber; // 1... planes + fPlaneName = fc->GetPlanePar(fPlaneNumber).Name; + fStatus = fc->GetPlanePar(fPlaneNumber).Status; + fAnalysisMode = fc->GetPlanePar(fPlaneNumber).AnalysisMode; + fReadout = fc->GetPlanePar(fPlaneNumber).Readout; + fMimosaType = fc->GetPlanePar(fPlaneNumber).MimosaType; //RDM210509 + fMapping = fc->GetPlanePar(fPlaneNumber).Mapping; // JB 2012/11/21 + fPlanePurpose = fc->GetPlanePar(fPlaneNumber).Purpose; //YV 08/02/2010 + fHitFinder = fc->GetPlanePar(fPlaneNumber).HitFinder; // JB 2013/07/17 + + + rand = new TRandom(fc->GetAnalysisPar().MCSeed + 3*fPlaneNumber); + + fInitialCounter = 0; // used to check initialization + + fPlaneThickness = fc->GetPlanePar(fPlaneNumber).PlaneThickness;//QL 2016/06/07 + fPlaneMaterial = fc->GetPlanePar(fPlaneNumber).PlaneMaterial;//QL 2016/06/07 + sigma_thetaMS = fTool.scatteringAngle(fSession->GetSetup()->GetTrackerPar().BeamType.Data(), + TMath::Abs(fSession->GetSetup()->GetTrackerPar().BeamMomentum), + fSession->GetSetup()->GetPlanePar(aPlaneNumber).PlaneMaterial.Data(), + fSession->GetSetup()->GetPlanePar(aPlaneNumber).PlaneThickness, + false); + + cout << "Plane " << fPlaneName << " for " << fc->GetPlanePar(fPlaneNumber).Purpose; + if (fStatus == 0) { cout << " (fixed ref and tracking seed) "; } // new status, JB 2011/03/14 + else if (fStatus == 1) { cout << " (fixed ref) "; } + else if (fStatus == 2) { cout << " (variable ref) "; } + else if (fStatus == 3) { cout << " (DUT) "; } + if (fAnalysisMode == 0) { cout << " NOT ANALYZED"; } + else if (fAnalysisMode == 1){ cout << " is a STRIP plane"; } + else if (fAnalysisMode >= 2){ cout << " is a PIXEL plane"; } + if( fLadderNumber > 0 ) { cout << " associated to LADDER " << fLadderNumber; } + cout << endl; + cout << " Hit finder algorith is "<< fHitFinder; + if( fHitFinder > 0 ) { cout << " (Dynamic clustering for digital readout)"; } + else { cout << " (Search area from seed)"; } + cout << endl; + + // Indeed, a plane can use up to 4 inputs of a module, + // JB, 2009/05/07 + fAcqInputsN = fc->GetPlanePar(fPlaneNumber).Inputs; + fChannelsN = 0; + fAcqModuleTypeNumber = 0; + for( Int_t iInp=0; iInpGetPlanePar(fPlaneNumber).ModuleType[iInp]; + fAcqModuleNumber = fc->GetPlanePar(fPlaneNumber).ModuleNumber[iInp]; + fAcqInputNumber = fc->GetPlanePar(fPlaneNumber).InputNumber[iInp]; + fAcqChannelNumber = fc->GetPlanePar(fPlaneNumber).ChannelNumber[iInp]; + fAcqChannelOffset = fc->GetPlanePar(fPlaneNumber).ChannelOffset[iInp]; // JB 2013/08/15 + fChannelsN += fc->GetPlanePar(fPlaneNumber).Channels[iInp]; + fAcqModuleChannels = fc->GetPlanePar(fPlaneNumber).Channels[iInp]; // print the #channels from the plane config, not from the module one, JB 2009/05/25 + if (fDebugPlane) { + cout << " fAcqInputsN=" << fAcqInputsN << endl; + cout << " fAcqModuleTypeNumber=" << fAcqModuleTypeNumber << endl; + cout << " fAcqModuleNumber " << fAcqModuleNumber << endl; + cout << " fAcqInputNumber " << fAcqInputNumber << endl; + cout << " fAcqChannelNumber " << fAcqChannelNumber << endl; + cout << " fAcqChannelOffset " << fAcqChannelOffset << endl; + cout << " fAcqModuleChannels " << fAcqModuleChannels << endl; + cout << " fChannelsN " << fChannelsN << endl; + } + } + + // Some acquisition modules use a Timestamp, + // in which case, a time limit to associate to pixel in a hit is required + // otherwise this limit is set to 0. + // JB 2015/05/26 + fTimeLimit = fc->GetPlanePar(fPlaneNumber).TimeLimit; + if( fAcqInputsN!=0 && fAcqModuleTypeNumber!=0 && fAcq->GetUsageTimestamp( fAcqModuleTypeNumber, fAcqModuleNumber) ) { + if( fTimeLimit < 0 ) { // <0 if never set, complain + cout << "WARNING: plane " << fPlaneNumber << " uses timestamp but no individual time limit set, trying tracker limit: " << fc->GetTrackerPar().TimeLimit << endl; + fTimeLimit = fc->GetTrackerPar().TimeLimit; + if( fTimeLimit < 0 ) { + cout << endl << "ERROR, plane " << fPlaneNumber << " uses timestamp but no time limit is provided in config file !!!" << endl << endl; + return; + } + } + else { + if (fDebugPlane) cout << " this plane uses a time limit at = " << fTimeLimit << " to constraint pixel timestamps in the same hit." << endl; + } + } + else { + fTimeLimit = 0; + if (fDebugPlane) cout << " this plane don't use timestamp." << endl; + } + + fStripsNu = (Int_t) fc->GetPlanePar(fPlaneNumber).Strips(0); + fStripsNv = (Int_t) fc->GetPlanePar(fPlaneNumber).Strips(1); + fStripsN = fStripsNu*fStripsNv; + if (fDebugPlane) cout << " fStrips " << fStripsN << endl; + + if( fStripsN != fChannelsN ) { + printf("\nWARNING #strips(uxv) %d IS NOT #channels %d...do you know what you are doing ?\n", fStripsN, fChannelsN); + } + + fCut = new DCut(*this); + if( fAcqModuleTypeNumber!=0 )fPulseRangeMaximum = pow(2.,fc->GetModulePar(fAcqModuleTypeNumber).SigBits[fAcqInputNumber]); // ???, JB, 2008/10/13 + + + //-+-+-+ Potential digitization emulation of this plane + // IfDigitize = 0 for no emulation + // IfDigitize = 1 to emulate a simple discriminator (1 threshold) + // IfDigitize > 1 to emulate an ADC with n bits sucha as 2^n = IfDigitize thresholds + // JB 2013/07/17, mimicking the MAF ADC emulation + + fIfDigitize = fc->GetPlanePar(fPlaneNumber).IfDigitize; + if( fIfDigitize>0 ) { // if Digitization emulation required + cout << " Emulating digitization over " << fIfDigitize << " threshold(s):"; + + fDigitizeThresholds = new Int_t[fIfDigitize]; + for (Int_t ithre=0; ithreGetPlanePar(fPlaneNumber).DigitizeThresholds[ithre]; + cout << " " << fDigitizeThresholds[ithre]; + } + cout << endl; + + } // end if Digitization emulation required + + + //-+-+-+ Geometry of the plane + + fPitch = new DR3(fc->GetPlanePar(fPlaneNumber).Pitch); + //fSize = new DR3(fc->GetPlanePar(fPlaneNumber).Size); + fSize = new DR3( fStripsNu*(*fPitch)(0), fStripsNv*(*fPitch)(1), (*fPitch)(2)); + fGeometry = new TBRIK(fPlaneName,"DT","void",(*fSize)(0),(*fSize)(1),(*fSize)(2)); + + // Taking into account deformation or not + // JB 2014/04/21 + fIfDeformation = fc->GetPlanePar(fPlaneNumber).IfDeformed; + fUDeformationCoef[0] = (*fSize)(0)/2; + fVDeformationCoef[0] = (*fSize)(1)/2; + for ( int i=1; i<8; i++) { + fUDeformationCoef[i] = fc->GetPlanePar(fPlaneNumber).CoeffLegendreU[i-1]; + fVDeformationCoef[i] = fc->GetPlanePar(fPlaneNumber).CoeffLegendreV[i-1]; + } + if (fDebugPlane) { + if (fIfDeformation) { + printf(" DPlane %2d, surface deformation applied with coeeficients:\n", fPlaneNumber); + printf(" along U:"); + for ( int i=0; i<8; i++) { + printf(" %.3f", fUDeformationCoef[i]); + } + printf("\n"); + printf(" along V:"); + for ( int i=0; i<8; i++) { + printf(" %.3f", fVDeformationCoef[i]); + } + printf("\n"); + } + else { + printf(" DPlane %2d, no surface deformation applied\n", fPlaneNumber); + } + } + + + //-+-+-+ Position of the plane + + // initial tilt about the axis perpendicular to the plane (w-axis) + fTilt = new DR3(fc->GetPlanePar(fPlaneNumber).Tilt); + if (fDebugPlane) {printf(" DPlane %2d, Intitial Tilt around z, y, x axis [rad] : ",fPlaneNumber); fTilt->Print();} + + // initial position in xyz coordinates + fPosition = new DR3(fc->GetPlanePar(fPlaneNumber).Position); + if (fDebugPlane) {printf(" Initial Position(in xyz) [um]: "); fPosition->Print();} + + // Initial alignment parameters + Int_t DPrecAlignMethod = fc->GetTrackerPar().DPrecAlignMethod; // LC 2015/01/31 + fPrecAlign = new DPrecAlign(DPrecAlignMethod); // LC 2015/01/31 + fPrecAlign->SetTranslation( *fPosition); // BEWARE, translation to be set first, always! + fPrecAlign->SetRotations( *fTilt); // because SetRot method compute the plane + // Passing deformation coeff to DPrecAlign object + if (fIfDeformation) { + fPrecAlign->SetDeformation( fUDeformationCoef, fVDeformationCoef); + } + if (fDebugPlane) fPrecAlign->PrintAll(); + + // Additional alignment parameters + // Rotation around W axis + // Translations along U and V + fTiltW = fc->GetPlanePar(fPlaneNumber).AlignmentTilt; + fPositionU = fc->GetPlanePar(fPlaneNumber).AlignmentU; + fPositionV = fc->GetPlanePar(fPlaneNumber).AlignmentV; + if (fDebugPlane) {printf(" TiltW [rad]: %f\n",fTiltW);} + if (fDebugPlane) {printf(" PositionU [um]: %f\n",fPositionU);} + if (fDebugPlane) {printf(" PositionV [um]: %f\n",fPositionV);} + + // Convolute the UVW alignment with global one (in XYZ) + // so far, the new rotation angles are not updated, just the matrices (2010/11/25) + fPrecAlign->ConvoluteUVWAlignment( fPositionU, fPositionV, fTiltW); + fTilt->SetValue( (Float_t)fPrecAlign->GetRotations()[0], (Float_t)fPrecAlign->GetRotations()[1], (Float_t)fPrecAlign->GetRotations()[2] ); + fPosition->SetValue( (Float_t)fPrecAlign->GetTranslation()[0], (Float_t)fPrecAlign->GetTranslation()[1], (Float_t)fPrecAlign->GetTranslation()[2]); + if (fDebugPlane) fPrecAlign->PrintAll(); + + if (fDebugPlane) { printf(" Final Tilt [rad]: "); fTilt->Print();} + if (fDebugPlane) { printf(" Final Position [um]: "); fPosition->Print();} + + fPlaneNode = new TNode(fPlaneName,fPlaneName,fPlaneName,(*fPosition)(0),(*fPosition)(1),(*fPosition)(2)); + + + //-+-+-+ event count necessary for initialization + + fInitialPedestal = fc->GetPlanePar(fPlaneNumber).InitialPedestal; // note this is never used + fInitialNoise = fc->GetPlanePar(fPlaneNumber).InitialNoise; + + if (fDebugPlane) printf(" DPlane %d : InitPed= %d, InitNoise=%d\n", fPlaneNumber, fInitialPedestal, fInitialNoise); + + + //-+-+-+ If a noise run has been specified + // YV 21/10/09 for S/N ratio and pedestal subtraction + // If analysis mode corresponds to real binary output data, + // force fNoiseRun to 0, JB 2014/01/08 + // Moved up here because needed in Strip creation if fNoiseRun>0 + + if( fAnalysisMode==3 && !fIfDigitize ) { // if real binary output + fNoiseRun = 0; + } + else { // otherwise + fNoiseRun = fc->GetRunPar().NoiseRun; + } + + Char_t NoiseFileDataPath[350]; + Char_t histoName[400]; + // sprintf(NoiseFileDataPath,"%s/Noise_run%d.root",fSession->GetResultDirName().Data(), fNoiseRun); + sprintf(NoiseFileDataPath,"Results/%d/Noise_run%d.root",fNoiseRun, fNoiseRun); // changed JB 2014/01/07 + sprintf(NoiseFileDataPath,"%s", fTool.LocalizeDirName( NoiseFileDataPath)); // JB 2011/07/07 + if( fDebugPlane) printf("name of noise file = %s \n",NoiseFileDataPath); + if( fNoiseRun > 0 /*&& fReadout != 126*/ && fReadout!= 0 ) { // test if noise run provided, JB 2010/04/27 + // Exclusion of real binary output sensors not needed anymore, JB 2014/01/07 + fNoiseFile = new TFile(NoiseFileDataPath,"read"); + sprintf( histoName, "hnoisepl%d", fPlaneNumber); + fHNoise = (TH2F*)fNoiseFile->Get(histoName); + sprintf( histoName, "hPedestalpl%d", fPlaneNumber); + fHPedestal = (TH2F*)fNoiseFile->Get(histoName); + if( fHPedestal!=nullptr && fHNoise!=nullptr ) { + printf(" Dplane %d, noise map extracted properly from %s\n", fPlaneNumber, NoiseFileDataPath); + } + //fHPedestal->Draw("colz"); + } + else { + fNoiseFile = 0; + fHNoise = 0; + fHPedestal = 0; + } + + //-+-+-+ If a pixel gain map has been specified + // If analysis mode corresponds to real binary output data, + // force fPixelGainRun to 0 + // JB 2018/07/01 + + if( fAnalysisMode==3 && !fIfDigitize ) { // if real binary output + fPixelGainRun = 0; + } + else { // otherwise + fPixelGainRun = fc->GetRunPar().PixelGainRun; + } + + Char_t gainFileDataPath[350]; + sprintf(gainFileDataPath,"Results/%d/PixelGain_run%d.root",fPixelGainRun, fPixelGainRun); + sprintf(gainFileDataPath,"%s", fTool.LocalizeDirName( gainFileDataPath)); // JB 2011/07/07 + if( fDebugPlane) printf("name of pixelgain file = %s \n",gainFileDataPath); + if( fPixelGainRun > 0 && fReadout!= 0 ) { + fGainFile = new TFile(gainFileDataPath,"read"); + sprintf( histoName, "hpixelgainpl%d", fPlaneNumber); + fHPixelGain = (TH2F*)fGainFile->Get(histoName); + if( fHPixelGain!=nullptr ) { + printf(" Dplane %d, pixel gain map extracted properly from %s\n", fPlaneNumber, gainFileDataPath); + } + } + else { + fGainFile = 0; + fHPixelGain = 0; + } + + + //======= + if( fReadout!=0 && ( fReadout < 100 || fReadout == 232 ) ) { // Useless part for sparsified data and unread plane, JB 2010/11/25, 2011/02/09, 2013/06/23 + //======= + + //-+-+-+ create arrays for computing pedestal, noise, pulsheight, etc. + + fRegions = fc->GetPlanePar(fPlaneNumber).CommonRegions; + + fChannel = new Long_t[fChannelsN]; // index array of channels + fChannelGood = new Long_t[fChannelsN]; // array of good channels + fStripIndices = new Long_t[fStripsN]; // index array of strips + + fCommonShift = new Float_t[fRegions]; + fCommonChannels = new Long_t[fRegions]; + + for(Int_t region = 0; region < fRegions; region++) { + fCommonShift[region] = 0.; + fCommonChannels[region] = 0; + } + // mark all channels as good: + + for (ch = 1; ch <=fChannelsN; ch++) { + fChannelGood[ch] = 1; + } + + for (ch = 0; ch < fChannelsN; ch++){ + fChannel[ch] = ch+1; + } + + //-+-+-+ Building strips + // NOTE THAT STRIP COUNTING STARTS AT 0 + // the assigned position there does not take into account the plane alignement, + // i.e. position (0,0) is the center of the plane. + // i.e. position (-fStripsNu/2,-fStripsNv/2) is the left bottom of the plane. + // checked by JB 2008/10/17 + + if (fDebugPlane) printf(" DPlane: Constructing DStrips: %dx%d = %d\n", fStripsNu, fStripsNv, fStripsN); + + fStripList = new DStrip*[fStripsN]; + + DR3 tPosition(0,0,0); + DR3 tSize(0,0,0); + Double_t u,v,w; + u=v=w=0; + + for (Int_t stv = 0; stv < fStripsNv; stv++) { // lpop on rows + for (Int_t stu = 0; stu < fStripsNu; stu++) { // loop on columns + st = stv*fStripsNu + stu; + if (fDebugPlane && st<0) { + printf("WARNING Strip number < 0 !! st=%d for stu=%d stv=%d\n",st,stu,stv); + } + //if( st<128) cout << "Creating strip " << st << endl; + ComputeStripPosition( stu, stv, u, v, w); // new function introduced, JB 2012/11/21 + // u = ((2*stu - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*stv - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + //if( fAnalysisMode >= 2 && 200GetPlanePar(fPlaneNumber).StripSize(0) << " " << fc->GetPlanePar(fPlaneNumber).StripSize(1) << " " << fc->GetPlanePar(fPlaneNumber).StripSize(2) << endl; + fStripList[st] = new DStrip(*this, st, tPosition, (*fPitch)); + + // If a noise run has been specified, set the pedestal and noise + // JB 2014/01/07 + if( fNoiseRun && fHNoise!=NULL && fHPedestal!=NULL ) { + GetStrip(st)->SetPedestal( fHPedestal->GetBinContent( stu+1, stv+1)); + GetStrip(st)->SetNoise( fHNoise->GetBinContent( stu+1, stv+1)); + if( fDebugPlane>3) printf("DPlane: strip %d (col=%d, row=%d), ped=%.1f, noise=%.1f\n", st, stu, stv, fHPedestal->GetBinContent( stu+1, stv+1), fHNoise->GetBinContent( stu+1, stv+1)); + } + + } // lpop on columns + } // lpop on rows + + FindNeighbours(); + + //======= + } // end useless for sparsified data + //======= + + + //-+-+-+ Hit list + + fHitMax = fc->GetTrackerPar().HitsInPlaneMaximum; + fKeepUnTrackedHitsBetw2evts = fc->GetTrackerPar().KeepUnTrackedHitsBetw2evts; // VR 2014.08.28 + fHitsUnTrackedLastEventN = 0; // VR 2014.08.28 + DR3 aZero; + + + + //------------------------ + // If asked, prepare for Keep UnTrackedHits Betwen 2 events // VR 2014.08.28 + //------------------------ + if(fKeepUnTrackedHitsBetw2evts == 0) + { + fHit = new DHit*[fHitMax]; + + for (Int_t ht = 0; ht < fHitMax; ht++) + { + fHit[ht] = new DHit(aZero, *this, ht+1); + } + } + else + { + printf("Keeping untracked hits from an event to the next one in enabled \n"); + + fHit = new DHit*[2*fHitMax]; + + for (Int_t ht = 0; ht < 2*fHitMax; ht++) + { + fHit[ht] = new DHit(aZero, *this, ht+1); + } + + fHitUnTrackedLastEvent = new DHit*[fHitMax]; + for (Int_t ht = 0; ht < fHitMax; ht++) + { + fHitUnTrackedLastEvent[ht] = new DHit(aZero, *this, ht+1); + } + } + + //-+-+-+ Alignement object + + fAlign = new DAlign( fPlaneNumber, fDebugPlane); + fAlign->SetEvents( fc->GetTrackerPar().EventsForAlignmentFit ); // JB 2009/05/25 + + + //-+-+-+ connect this plane to its raw data array -+-+-+-// + + //fRawData = fAcq->GetRawData( fAcqModuleTypeNumber, fAcqModuleNumber, fAcqInputNumber); + fListOfPixels = fAcq->GetListOfPixels( fPlaneNumber); // JB, 2009/05/03 + //if(fIfHitMonteCarlo==1) fListOfMonteCarlo = fAcq->GetListOfMonteCarlo( fPlaneNumber); // LC 2012/10/19 + if (fDebugPlane) printf(" RawData array associated at %d-%d-%d\n", fAcqModuleTypeNumber, fAcqModuleNumber, fAcqInputNumber); + + + //-+-+-+ connect to histos or tables for eta distribution -+-+-+-// + // method to connect 2D-eta added, JB Sept 2007 + + //TFile *tWeightFile = fSession->GetWeightFile(); + + fChargeFractionDensityList = new TObjArray(10*10); + fChargeFractionDistributionList = new TObjArray(10*10); + Char_t tChargeFractionDataName[100]; + TH1F *tH1 = 0; + + fEtaIntU = 0; + fEtaIntV = 0; + fEtaIntU2 = 0; + fEtaIntV2 = 0; + fDigitalStripResponse = kFALSE; + + TString WeightFile = fSession->GetResultDirName(); + WeightFile += "eta"; + WeightFile += long(fSession->GetRunNumber()); + WeightFile += ".root"; + fTool.LocalizeDirName( &WeightFile); + FileStat_t Fstat; + TFile *tWeightFile = NULL; + if(gSystem->GetPathInfo(WeightFile.Data(),Fstat) == 0) { + tWeightFile = new TFile(WeightFile.Data(),"READ"); + if( tWeightFile == NULL) { + fDigitalStripResponse = kTRUE; + if( fc->GetPlanePar(fPlaneNumber).HitPositionAlgorithm == 2 ) { // if eta algorithm required + cout << "WARNING from DPlane::DPlane(), " << "file " << WeightFile.Data() << " Doesn't exits!!" << endl; + } //end if eta algorithm required + } + else if( tWeightFile->IsZombie() || !(tWeightFile->GetNkeys()) ) { + fDigitalStripResponse = kTRUE; + if( fc->GetPlanePar(fPlaneNumber).HitPositionAlgorithm == 2 ) { // if eta algorithm required + if( tWeightFile->IsZombie()) cout << "WARNING from DPlane::DPlane(), " << "file " << WeightFile.Data() << " is Zombie!!!" << endl; + else if(!(tWeightFile->GetNkeys()) ) cout << "WARNING from DPlane::DPlane(), " << "file " << WeightFile.Data() << " has no keys!!!" << endl; + } //end if eta algorithm required + } + } + else { + fDigitalStripResponse = kTRUE; + if( fc->GetPlanePar(fPlaneNumber).HitPositionAlgorithm == 2 ) { // if eta algorithm required + cout << "WARNING from DPlane::DPlane(), " << "file " << WeightFile.Data() << " Doesn't exits!!" << endl; + } //end if eta algorithm required + } + + if (!fDigitalStripResponse && fAnalysisMode == 1){ // STRIPS + // use only 2-strip clusters + // now the loop over strips with decending pulseheights, start with seed, which has highest signal + + for(Int_t tSk = 0; tSk < 2; tSk++) { // loop over strips with highest pulseheights + sprintf(tChargeFractionDataName,"HEtaDenPk%d",fPlaneNumber); + tH1 = (TH1F*)tWeightFile->Get(tChargeFractionDataName); + if (tH1==0) { + fDigitalStripResponse = kTRUE; + if (fDebugPlane) cout << " No charge fraction hist!\n"; + } + tH1->SetDirectory(0); + fChargeFractionDensityList->AddAt( tH1, tSk); + } + } + else if (!fDigitalStripResponse && fAnalysisMode >= 2){ // PIXELS + sprintf(tChargeFractionDataName,"HEtaIntUPk%d",fPlaneNumber); + fEtaIntU = (TH1F*)tWeightFile->Get(tChargeFractionDataName); + sprintf(tChargeFractionDataName,"HEtaIntVPk%d",fPlaneNumber); + fEtaIntV = (TH1F*)tWeightFile->Get(tChargeFractionDataName); + sprintf(tChargeFractionDataName,"HEtaInt2UPk%d",fPlaneNumber); + fEtaIntU2 = (TH1F*)tWeightFile->Get(tChargeFractionDataName); + sprintf(tChargeFractionDataName,"HEtaInt2VPk%d",fPlaneNumber); + fEtaIntV2 = (TH1F*)tWeightFile->Get(tChargeFractionDataName); + if (fEtaIntU==0 || fEtaIntV==0 || fEtaIntU2==0 || fEtaIntV2==0) { + fDigitalStripResponse = kTRUE; + if (fDebugPlane) cout << " No hist with charge density in 2D for eta algo!\n"; + } + fEtaIntU->SetDirectory(0); + fEtaIntV->SetDirectory(0); + fEtaIntU2->SetDirectory(0); + fEtaIntV2->SetDirectory(0); + } + + // issue a warning if Eta algo required and no Eta file available + if ( fDigitalStripResponse && fc->GetPlanePar(fPlaneNumber).HitPositionAlgorithm==2 ) { + if(gSystem->GetPathInfo(WeightFile.Data(),Fstat) != 0) { + printf("\nWARNING from DPlane::DPlane(), file %s does not exist (access %d)\n", + WeightFile.Data(), + gSystem->AccessPathName(WeightFile.Data())); + } + else { + printf("\nWARNING from DPlane::DPlane(), file %s does exist (access %d), but either it is empty (zombie %d, keys %d), either it does not contain the proper histos, using CoG for position method only\n", + WeightFile.Data(), + gSystem->AccessPathName(WeightFile.Data()), + tWeightFile->IsZombie(), + tWeightFile->GetNkeys()); + } + + printf(" you have to make a new one (use gTAF->MakeEta())!\n\n"); + } + + if(gSystem->GetPathInfo(WeightFile.Data(),Fstat) == 0) { + tWeightFile->Close(); + delete tWeightFile; + } + + + if (tH1) {tH1 = 0;} + + + //__________________________________________________________________________________________ + + + + cout << " -*-*- DPlane " << aPlaneNumber << " User Constructor DONE -*-*- " << endl; + +} + + + +//______________________________________________________________________________ +// + + +DPlane::~DPlane(){ + delete [] fStripList; + delete fListOfPixels; + delete [] fHit; + delete [] fHitUnTrackedLastEvent; + delete fCut; + delete fGeometry; + delete fPlaneNode; + delete fPlaneNodeName; + delete fChargeFractionDensityList; + delete fChargeFractionDistributionList; + delete fEtaIntU; + delete fEtaIntV; + delete fEtaIntU2; + delete fEtaIntV2; + delete fNoiseFile; //YV 27/11/09 + +} + +//______________________________________________________________________________ +// + +void DPlane::SetDebug(Int_t aDebug) +{ + // Initialize or update the debug level + // update also the level for hits, align objects + // JB 2009/05/12 + // Modified JB 2015/10/31 to update DPrecAlign + + fDebugPlane = aDebug; + + fAlign->SetDebug( aDebug); // JB 2010/12/14 + + if( fPrecAlign!=NULL ) fPrecAlign->SetDebug( aDebug); // JB 2015/10/31 + + for (Int_t ht = 0; ht < fHitMax; ht++) { + fHit[ht]->SetDebug( aDebug); + } + + cout << "DPlane " << fPlaneNumber << " debug updated to " << fDebugPlane << endl; + +} + +//______________________________________________________________________________ +// + +TH1F* DPlane::GetChargeFractionDensity(Int_t tStripIndex) { + return (TH1F*)fChargeFractionDensityList->At(tStripIndex); +} + +//______________________________________________________________________________ +// + +TH1F* DPlane::GetChargeFractionDistribution(Int_t tStripIndex) { + return (TH1F*)fChargeFractionDistributionList->At(tStripIndex); +} + +//______________________________________________________________________________ +// + +void DPlane::ShowAlignment(){ + + // Display the current alignement (offsets and tilt) of the plane + // JB 2009/05/18 + // Modified JB 2011/04/05 + + printf("Position of plane %d:\n", fPlaneNumber); + printf(" Alignment U=%.1f um, V=%.1f, tiltW=%.3f [deg]\n", fPositionU, fPositionV, fTiltW*TMath::RadToDeg()); + fPrecAlign->PrintAll(); + +} +//______________________________________________________________________________ +// + +Bool_t DPlane::Align(DTrack *aTrack, Bool_t ifFit, bool UseAllHits){ + + // Compute the alignment parameters + // + // Loop on the hits in the plane to find the one nearest to the track within a given bound. + // Submit this hit to the DAlign object which will return alignement parameters + // and update the bound to associate track and hit, + // once enough hits have been accumulated (limit from config file). + // Do it for both direction U, V if PIXELS, only in U for STRIPS. + // + // Return true if a fit was performed (enough hits), false otherwise. + // + // Modified by JB to allow 2D plane alignment, 2007 August + // Modified to select best hit in 2D, JB 2009/05/09 + // Modified to allow no fit ifFit argumnet), JB 2009/08/23 + // Modified to update the global alignement with the DPrecAlign class, JB 2010/11/25 + // Modified to take properly into account the alignment corrections, JB 2011/04/05 + // Modified to have as output wether the fit was done or not, JB 2011/07/25 + // Modified AP 2015/06/10: added bool parameter (UseAllHits) to decide if doing alignment with all hits (UseAllHits = true), + // or the closest one (UseAllHits = false). Default value is false. + + Bool_t fitDone = kFALSE; + + Float_t tDistanceU = 0, tDistanceV=0., tDist2D=0.; + Float_t tMinDistanceU = 0, tMinDistanceV = 0, tMinDistance2D = 0; + DR3 tTrackPos; // the Track Position in uvw coordinates + //DR3 *tHitPos; // the Hit Position in uvw coordinates, JB 2009/05/09 + + // find the hit nearest to the track + + tTrackPos = Intersection( aTrack); // trackPosition in uvw frame with new class, JB 2010/11/25 + if( fDebugPlane>1 ) printf(" DPLane::Align plane %d Having track at position in plane: (XY)=(%f,%f), (UV)=(%f,%f)\n", fPlaneNumber, fPrecAlign->GetTrackPosition()(0), fPrecAlign->GetTrackPosition()(1), tTrackPos(0), tTrackPos(1)); + + // take hit - track position in uvd Plane frame, the order/sign matters!! + + if(GetHitsN() > 0) { + if(UseAllHits) { + for (Int_t k=1; k<= GetHitsN(); k++) { // loop on hits + //tHitPos = GetHit(k)->GetPosition(); + tDistanceU = GetHit(k)->GetPositionUhit() - tTrackPos(0); // strips and pixels + + //if(fIfDeformation){ //BB + // Double_t tPositionHitU = GetHit(k)->GetPositionUhit();//BB + // Double_t tPositionTrackU = tTrackPos(0);//BB + //} + + if(fAnalysisMode>=2 ) { // PIXELS only + tDistanceV = GetHit(k)->GetPositionVhit() - tTrackPos(1); + tDist2D = sqrt( tDistanceU*tDistanceU + tDistanceV*tDistanceV ); + + tMinDistance2D = tDist2D; + tMinDistanceU = tDistanceU; + tMinDistanceV = tDistanceV; + } + else { // STRIPS + if (fabs(tDistanceU) <= fabs(tMinDistanceU)) { + tMinDistanceU = tDistanceU; + } + } + + if( fDebugPlane ) printf(" DPLane::Align plane %d Accumulating with distance (u=%f,v=%f) 2d=%f\n", fPlaneNumber, tMinDistanceU, tMinDistanceV, tMinDistance2D); + + // Only store the distances if no fit recquired, JB 2009/05/13 + if( ifFit==kFALSE ) { + if(fAnalysisMode>=2 ) { // PIXELS only + if( fabs(tMinDistanceU)GetBounding() && fabs(tMinDistanceU)GetBounding() ) + fAlign->Store2D( tTrackPos, tMinDistanceU, tMinDistanceV); + } + else { // STRIPS + fAlign->StoreU( tTrackPos, tMinDistanceU); + } + if(k == GetHitsN()) return fitDone; + } + + //------------------------------------------ + // Below do the accumulation and fitting if ready + + //if( 1000=2 ) { // PIXELS only + fAlign->Accumulate2D(tTrackPos, tMinDistanceU, tMinDistanceV); // this line replace the two followings, JB 2009/05/09 + } + else { // strips + fAlign->AccumulateU(tTrackPos, tMinDistanceU); + } + + } + } + else { + tMinDistanceU = 1000000.; // init + tMinDistanceV = 1000000.; + tMinDistance2D = 1000000.; + for (Int_t k=1; k<= GetHitsN(); k++) { // loop on hits + //tHitPos = GetHit(k)->GetPosition(); + tDistanceU = GetHit(k)->GetPositionUhit() - tTrackPos(0); // strips and pixels + + if(fAnalysisMode>=2 ) { // PIXELS only + tDistanceV = GetHit(k)->GetPositionVhit() - tTrackPos(1); + tDist2D = sqrt( tDistanceU*tDistanceU + tDistanceV*tDistanceV ); + if( fabs(tDist2D) <= fabs(tMinDistance2D)) { + tMinDistance2D = tDist2D; + tMinDistanceU = tDistanceU; + tMinDistanceV = tDistanceV; + } + } + else { // STRIPS + if (fabs(tDistanceU) <= fabs(tMinDistanceU)) { + tMinDistanceU = tDistanceU; + } + } + + if( fDebugPlane>1 ) printf(" DPLane::Align plane %d Trying hit %d and distance (u=%f,v=%f) 2d=%f\n", fPlaneNumber, k, tDistanceU, tDistanceV, tDist2D); + } // end loop on hits + + if( fDebugPlane ) printf(" DPLane::Align plane %d Accumulating with distance (u=%f,v=%f) 2d=%f\n", fPlaneNumber, tMinDistanceU, tMinDistanceV, tMinDistance2D); + + // Only store the distances if no fit recquired, JB 2009/05/13 + if( ifFit==kFALSE ) { + if(fAnalysisMode>=2 ) { // PIXELS only + if( fabs(tMinDistanceU)GetBounding() && fabs(tMinDistanceU)GetBounding() ) + fAlign->Store2D( tTrackPos, tMinDistanceU, tMinDistanceV); + } + else { // STRIPS + fAlign->StoreU( tTrackPos, tMinDistanceU); + } + return fitDone; + } + + //------------------------------------------ + // Below do the accumulation and fitting if ready + + //if( 1000=2 ) { // PIXELS only + fAlign->Accumulate2D(tTrackPos, tMinDistanceU, tMinDistanceV); // this line replace the two followings, JB 2009/05/09 + //fAlign->AccumulateV(tTrackPos, tMinDistanceV); + //fAlign->AccumulateU(tTrackPos, tMinDistanceU); + } + else { // strips + fAlign->AccumulateU(tTrackPos, tMinDistanceU); + } + //} // end if given area + //------------------------------------------ + } // end else of if(UseAllHits) + } // enf if there is some hits + + if ( ifFit==kTRUE && ( // JB 2009/08/23 + (fAnalysisMode==1 && fAlign->EnoughU() == kTRUE) // strips + ||(fAnalysisMode>=2 && fAlign->EnoughU() == kTRUE && fAlign->EnoughV() == kTRUE) // pixels + ||(fAnalysisMode>=2 && fAlign->Enough2D() == kTRUE) // pixels, JB 2009/05/13 + ) ) { + fitDone = kTRUE; + + Int_t eventN = fSession->GetCurrentEventNumber(); + Int_t counts = fAlign->GetCounts(); + printf(" ---------------------------------------------------------- \n"); + printf(" Interactive Alignment of plane %d %s (swap %.2f deg): Event %d kept %d with bound %.1f um\n",fPlaneNumber, fPlaneName, GetTilt()(2)*180./M_PI, eventN, counts, fAlign->GetBounding()); + printf(" ---------------------------------------------------------- \n"); + cout << " Current position" << endl; + ShowAlignment(); + + // printout computed corrections for this iteration + fAlign->ShowCorrection(); + + // Compute the new position taking into account alignment params + // offset are now added, to match sign changed in DPrecAlign, JB 2011/07/25 + fPrecAlign->ConvoluteUVWAlignment( +fAlign->GetOffsetU(), +fAlign->GetOffsetV(), +fAlign->GetTiltW()); + fTilt->SetValue( (Float_t)fPrecAlign->GetRotations()[0], (Float_t)fPrecAlign->GetRotations()[1], (Float_t)fPrecAlign->GetRotations()[2] ); + fPosition->SetValue( (Float_t)fPrecAlign->GetTranslation()[0], (Float_t)fPrecAlign->GetTranslation()[1], (Float_t)fPrecAlign->GetTranslation()[2]); + + // Reset alignment params + fTiltW = 0.; + fPositionU = 0.; + fPositionV = 0.; + + cout << " New position" << endl; + ShowAlignment(); + + // re-init align counters for next iteration + fAlign->Modified(); + + } // end if enough events + + return fitDone; + +} + + +//______________________________________________________________________________ +// + +Bool_t DPlane::AlignAllHits(DTrack *aTrack, Bool_t ifFit){ + + // Compute the alignment parameters, + // !!! COPY OF ALIGN method above, but all hits considered for each track !! + // + // Created JB, 2014/05/14 + + Bool_t fitDone = kFALSE; + + Float_t tDistanceU, tDistanceV=0., tDist2D=0.; + DR3 tTrackPos; // the Track Position in uvw coordinates + //DR3 *tHitPos; // the Hit Position in uvw coordinates, JB 2009/05/09 + + // find the hit nearest to the track + + tTrackPos = Intersection( aTrack); // trackPosition in uvw frame with new class, JB 2010/11/25 + if( fDebugPlane>1 ) printf(" DPLane::Align plane %d Having track at position in plane: (XY)=(%f,%f), (UV)=(%f,%f)\n", fPlaneNumber, fPrecAlign->GetTrackPosition()(0), fPrecAlign->GetTrackPosition()(1), tTrackPos(0), tTrackPos(1)); + + // take hit - track position in uvd Plane frame, the order/sign matters!! + + if (GetHitsN() > 0) { + + for (Int_t k=1; k<= GetHitsN(); k++) { // loop on hits + + //tHitPos = GetHit(k)->GetPosition(); + tDistanceU = GetHit(k)->GetPositionUhit() - tTrackPos(0); // strips and pixels + + if(fAnalysisMode>=2 ) { // PIXELS only + tDistanceV = GetHit(k)->GetPositionVhit() - tTrackPos(1); + tDist2D = sqrt( tDistanceU*tDistanceU + tDistanceV*tDistanceV ); + } + + if( fDebugPlane ) printf(" DPLane::Align plane %d Trying hit %d and distance (u=%f,v=%f) 2d=%f\n", fPlaneNumber, k, tDistanceU, tDistanceV, tDist2D); + + // Only store the distances if no fit recquired, JB 2009/05/13 + if( ifFit==kFALSE ) { + if(fAnalysisMode>=2 ) { // PIXELS only + if( fabs(tDistanceU)GetBounding() && fabs(tDistanceU)GetBounding() ) + fAlign->Store2D( tTrackPos, tDistanceU, tDistanceV); + } + else { // STRIPS + fAlign->StoreU( tTrackPos, tDistanceU); + } + return fitDone; + } + + //------------------------------------------ + // Below do the accumulation and fitting if ready + + //if( 1000=2 ) { // PIXELS only + fAlign->Accumulate2D(tTrackPos, tDistanceU, tDistanceV); // this line replace the two followings, JB 2009/05/09 + //fAlign->AccumulateV(tTrackPos, tDistanceV); + //fAlign->AccumulateU(tTrackPos, tDistanceU); + } + else { // strips + fAlign->AccumulateU(tTrackPos, tDistanceU); + } + //} // end if given area + //------------------------------------------ + + } // end loop on hits + + } // enf if there is some hits + + if ( ifFit==kTRUE && ( // JB 2009/08/23 + (fAnalysisMode==1 && fAlign->EnoughU() == kTRUE) // strips + ||(fAnalysisMode>=2 && fAlign->EnoughU() == kTRUE && fAlign->EnoughV() == kTRUE) // pixels + ||(fAnalysisMode>=2 && fAlign->Enough2D() == kTRUE) // pixels, JB 2009/05/13 + ) ) { + fitDone = kTRUE; + + Int_t eventN = fSession->GetCurrentEventNumber(); + Int_t counts = fAlign->GetCounts(); + printf(" ---------------------------------------------------------- \n"); + printf(" Interactive Alignment of plane %d %s (swap %.2f deg): Event %d kept %d with bound %.1f um\n",fPlaneNumber, fPlaneName, GetTilt()(2)*180./M_PI, eventN, counts, fAlign->GetBounding()); + printf(" ---------------------------------------------------------- \n"); + cout << " Current position" << endl; + ShowAlignment(); + + // printout computed corrections for this iteration + fAlign->ShowCorrection(); + + // Compute the new position taking into account alignment params + // offset are now added, to match sign changed in DPrecAlign, JB 2011/07/25 + fPrecAlign->ConvoluteUVWAlignment( +fAlign->GetOffsetU(), +fAlign->GetOffsetV(), +fAlign->GetTiltW()); + fTilt->SetValue( (Float_t)fPrecAlign->GetRotations()[0], (Float_t)fPrecAlign->GetRotations()[1], (Float_t)fPrecAlign->GetRotations()[2] ); + fPosition->SetValue( (Float_t)fPrecAlign->GetTranslation()[0], (Float_t)fPrecAlign->GetTranslation()[1], (Float_t)fPrecAlign->GetTranslation()[2]); + + // Reset alignment params + fTiltW = 0.; + fPositionU = 0.; + fPositionV = 0.; + + cout << " New position" << endl; + ShowAlignment(); + + // re-init align counters for next iteration + fAlign->Modified(); + + } // end if enough events + + return fitDone; + +} + + +//______________________________________________________________________________ +// + +void DPlane::UpdatePositions() +{ + + // Update the rotation and translation vectors according to the values + // stored in the DPrecAlign object associated with this plane. + // + // LC + + fTilt->SetValue( (Float_t)fPrecAlign->GetRotations()[0], (Float_t)fPrecAlign->GetRotations()[1], (Float_t)fPrecAlign->GetRotations()[2] ); + fPosition->SetValue( (Float_t)fPrecAlign->GetTranslation()[0], (Float_t)fPrecAlign->GetTranslation()[1], (Float_t)fPrecAlign->GetTranslation()[2]); + +} + +//______________________________________________________________________________ +// + +void DPlane::AlignPrec(DTrack *aTrack, + const Float_t tiniBound, + bool UseAllHits){ + + /* + LC 2012/09/06 : New method to fit with Minuit. + This methos add data before the fit with Minuit. + AP 2015/06/08 : added bool parameter (UseAllHits) to decide if doing alignement with all hits or with the one closest to the track + - If UseAllHits = true => Use all hits within a distance tiniBound to the track + - If UseAllHits = false => Use the closest hits within a distance tiniBound to the track + */ + + Float_t tDistanceU=0., tDistanceV=0., tDist2D=0.; + + DR3 tTrackPos; // the Track Position in uvw coordinates. + //DR3 *tHitPos; // the Hit Position in uvw coordinates. + + tTrackPos = Intersection( aTrack); // trackPosition in uvw frame with new class, JB 2010/11/25 + + if( fDebugPlane>1 ) printf(" DPLane::Align plane %d Having track at position in plane: (XY)=(%f,%f), (UV)=(%f,%f)\n", fPlaneNumber, fPrecAlign->GetTrackPosition()(0), fPrecAlign->GetTrackPosition()(1), tTrackPos(0), tTrackPos(1)); + + Float_t tDist2Dmin = 1.0e+20; + Int_t idx_closestHit = -999; + for (Int_t k=1 ; k<= GetHitsN() ; k++) { + + tDistanceU = GetHit(k)->GetPositionUhit() - tTrackPos(0); + tDistanceV = GetHit(k)->GetPositionVhit() - tTrackPos(1); + tDist2D = sqrt( tDistanceU*tDistanceU + tDistanceV*tDistanceV ); + + if(!UseAllHits) { + // Looking for the hit cloest to the track + if(tDist2Dmin > tDist2D) { + tDist2Dmin = tDist2D; + idx_closestHit = k; + } + } + else { + if (fAnalysisMode>=2 && tDist2D < tiniBound ) { // tDist2D < tiniBound. + fPrecAlign->NewData( GetHit(k)->GetPositionUhit(), GetHit(k)->GetPositionVhit(), + GetHit(k)->GetResolutionUhit(), GetHit(k)->GetResolutionVhit(), + aTrack->GetLinearFit().GetOrigin()(0), aTrack->GetLinearFit().GetOrigin()(1), aTrack->GetLinearFit().GetOrigin()(2), + aTrack->GetLinearFit().GetSlopeZ()(0), aTrack->GetLinearFit().GetSlopeZ()(1) ); + + if( fDebugPlane>1 ) printf(" DPLane::Align Event %i plane %d Accumulating data with parameters : (Hu,Hv)=(%f,%f), (Tx,Ty,Tz,Tdx,Tdy)=(%f,%f,%f,%f,%f)\n", fAcq->GetEventNumber(), fPlaneNumber, GetHit(k)->GetPositionUhit(), GetHit(k)->GetPositionVhit(), aTrack->GetLinearFit().GetOrigin()(0), aTrack->GetLinearFit().GetOrigin()(1), aTrack->GetLinearFit().GetOrigin()(2), aTrack->GetLinearFit().GetSlopeZ()(0), aTrack->GetLinearFit().GetSlopeZ()(1) ); + + fAlign->Store2D( tTrackPos, tDistanceU, tDistanceV); // To fill the graphs after the fit. + + } // end if. + } //end of else + + } // end for. + + if(!UseAllHits && idx_closestHit >= 1) { + tDistanceU = GetHit(idx_closestHit)->GetPositionUhit() - tTrackPos(0); + tDistanceV = GetHit(idx_closestHit)->GetPositionVhit() - tTrackPos(1); + tDist2D = sqrt( tDistanceU*tDistanceU + tDistanceV*tDistanceV ); + + if (fAnalysisMode>=2 && tDist2D < tiniBound ) { // tDist2Dmin < tiniBound. + fPrecAlign->NewData( GetHit(idx_closestHit)->GetPositionUhit(), GetHit(idx_closestHit)->GetPositionVhit(), + GetHit(idx_closestHit)->GetResolutionUhit(), GetHit(idx_closestHit)->GetResolutionVhit(), + aTrack->GetLinearFit().GetOrigin()(0), aTrack->GetLinearFit().GetOrigin()(1), aTrack->GetLinearFit().GetOrigin()(2), + aTrack->GetLinearFit().GetSlopeZ()(0), aTrack->GetLinearFit().GetSlopeZ()(1) ); + + if( fDebugPlane>1 ) printf(" DPLane::Align Event %i plane %d Accumulating data with parameters : (Hu,Hv)=(%f,%f), (Tx,Ty,Tz,Tdx,Tdy)=(%f,%f,%f,%f,%f)\n", fAcq->GetEventNumber(), fPlaneNumber, GetHit(idx_closestHit)->GetPositionUhit(), GetHit(idx_closestHit)->GetPositionVhit(), aTrack->GetLinearFit().GetOrigin()(0), aTrack->GetLinearFit().GetOrigin()(1), aTrack->GetLinearFit().GetOrigin()(2), aTrack->GetLinearFit().GetSlopeZ()(0), aTrack->GetLinearFit().GetSlopeZ()(1) ); + + fAlign->Store2D( tTrackPos, tDistanceU, tDistanceV); // To fill the graphs after the fit. + + } // end if. + } //end if (UseAllHits) + +} + +void DPlane::AlignData(DTrack *aTrack, const Double_t tiniBound, std::vector& myData) +{ + + + // Modified: LC 2014/12/05 : clean old code. + Double_t tDistanceU=0., tDistanceV=0., tDist2D=0.; + //Double_t tDistanceW=0.; + + DR3 tTrackPos; // the Track Position in uvw coordinates. + + myData.clear(); + + tTrackPos = Intersection( aTrack); // trackPosition in uvw frame with new class, JB 2010/11/25 + DR3 trackInTrackerFrame = fPrecAlign->TransformHitToTracker(tTrackPos); + + for (Int_t k=1 ; k<= GetHitsN() ; k++) { + + tDistanceU = GetHit(k)->GetPositionUhitCG() - tTrackPos(0); + tDistanceV = GetHit(k)->GetPositionVhitCG() - tTrackPos(1); + double resolutionU = GetHit(k)->GetResolutionUhit(); + double resolutionV = GetHit(k)->GetResolutionVhit(); + + DR3 hitInTrackerFrame = fPrecAlign->TransformHitToTracker( DR3(GetHit(k)->GetPositionUhitCG(), GetHit(k)->GetPositionVhitCG(), 0.) ); + + Double_t trackerFrameDistanceX = hitInTrackerFrame(0) - trackInTrackerFrame(0); + Double_t trackerFrameDistanceY = hitInTrackerFrame(1) - trackInTrackerFrame(1); + Double_t trackerFrameDistanceZ = hitInTrackerFrame(2) - trackInTrackerFrame(2); + + tDist2D = sqrt( tDistanceU*tDistanceU + tDistanceV*tDistanceV ); + + if (fAnalysisMode>=2 && tDist2D < tiniBound ) { + + myData.push_back( GetHit(k)->GetPositionUhitCG() ); // 0 + myData.push_back( GetHit(k)->GetPositionVhitCG() ); // 1 + myData.push_back( aTrack->GetLinearFit().GetOrigin()(0) ); // 2 + myData.push_back( aTrack->GetLinearFit().GetOrigin()(1) ); // 3 + myData.push_back( aTrack->GetLinearFit().GetOrigin()(2) ); // 4 + myData.push_back( aTrack->GetLinearFit().GetSlopeZ()(0) ); // 5 + myData.push_back( aTrack->GetLinearFit().GetSlopeZ()(1) ); // 6 + myData.push_back( hitInTrackerFrame(0) ); // 7 + myData.push_back( hitInTrackerFrame(1) ); // 8 + myData.push_back( hitInTrackerFrame(2) ); // 9 + + /* + myData.push_back( GetHit(k)->GetPositionUhitCG() - tTrackPos(0) ); //tDistanceU // 7 + myData.push_back( GetHit(k)->GetPositionVhitCG() - tTrackPos(1) ); //tDistanceV // 8 + myData.push_back( tDist2D ); // 9 + */ + /* + myData.push_back( GetHit(k)->GetPositionUhitCG22() - tTrackPos(0) ); // 10 + myData.push_back( GetHit(k)->GetPositionVhitCG22() - tTrackPos(1) ); // 11 + myData.push_back( GetHit(k)->GetPositionWhitCG() - tTrackPos(2) ); // 12 + */ + myData.push_back( trackerFrameDistanceX ); // 10 + myData.push_back( trackerFrameDistanceY ); // 11 + myData.push_back( trackerFrameDistanceZ ); // 12 + + myData.push_back( resolutionU ); // 13 + myData.push_back( resolutionV ); // 14 + + } + } + +} +//______________________________________________________________________________ +// + +void DPlane::AlignPrecUpdateConfig() +{ + + /* + LC 2012/09/06 : To Update the config file with fit parameters. + */ + + std::cout<<" AlignPrecUpdateConfig() "<PrintAll(); + + fTilt->SetValue( (Float_t)fPrecAlign->GetRotations()[0], (Float_t)fPrecAlign->GetRotations()[1], (Float_t)fPrecAlign->GetRotations()[2] ); + fPosition->SetValue( (Float_t)fPrecAlign->GetTranslation()[0], (Float_t)fPrecAlign->GetTranslation()[1], (Float_t)fPrecAlign->GetTranslation()[2]); + +} + +//______________________________________________________________________________ +// + +Float_t DPlane::GetCommonModeRegion(Int_t aRegion) const { + if (aRegion <= fRegions && aRegion > 0) + return fCommonShift[aRegion-1]; + else + return 0.; +} + +//______________________________________________________________________________ +// + +DStrip* DPlane::NearestStrip(DR3& aPosition){ + + DStrip *guess; + + Float_t tDistance, tMinimum; + Int_t tK = 0; + DR3 tPosition(0,0,0); // explicit zero + tPosition = aPosition; + guess = GetStrip(tK); + tDistance = guess->DistanceU(tPosition); + tMinimum = fabs(tDistance); + // this is a very time consuming loop! + for(Int_t k = 1; k < fStripsN; k++){ + guess = GetStrip(k); + tDistance = guess->DistanceU(tPosition); + if ( fabs(tDistance) < tMinimum ) { + tMinimum = fabs(tDistance); + tK = k; + } + } + + return GetStrip(tK); +} + +//______________________________________________________________________________ +// + +Float_t DPlane::GetPulseRangeMaximum(){ + return fPulseRangeMaximum; +} + +//______________________________________________________________________________ +// + +Float_t DPlane::GetPulseHeightToNoise(Int_t aSk){ + return GetStrip(aSk)->GetPulseHeightToNoise(); +} + + +//______________________________________________________________________________ +// + +Float_t DPlane::GetCommonMode(Int_t aSk) { + return GetStrip(aSk)->GetCommonMode(); +} + +//______________________________________________________________________________ +// + +Float_t DPlane::GetRawValue(Int_t aSk) { + return GetStrip(aSk)->GetRawValue(); +} + + + +Float_t DPlane::GetRawFrame1Value(Int_t aSk) { + return GetStrip(aSk)->GetRawFrame1Value(); +} + +// + +Float_t DPlane::GetRawFrame2Value(Int_t aSk) { + return GetStrip(aSk)->GetRawFrame2Value(); +} + +//______________________________________________________________________________ +// + +Float_t DPlane::GetPedestal(Int_t aSk) { + return GetStrip(aSk)->GetPedestal(); +} + +//______________________________________________________________________________ +// + +Float_t DPlane::GetPulseHeight(Int_t aSk) { + return GetStrip(aSk)->GetPulseHeight(); +} + +//______________________________________________________________________________ +// + +Float_t DPlane::GetNoise(Int_t aSk) { + return GetStrip(aSk)->GetNoise(); +} + +//______________________________________________________________________________ +// + +void DPlane::SetCDSvariance(Float_t aVar){ + fCDSvariance= aVar; +} + +//______________________________________________________________________________ +// + +DPixel* DPlane::GetPixelFromList(Int_t aSk) +{ + + DPixel* aPixel = NULL; + if(aSk+1 > (int)(fListOfPixels->size())) return aPixel; + else return fListOfPixels->at(aSk); + +} +//_________________________________________________________ +// +DHit* DPlane::GetPrincipalHit() { + // Modified: JB 2012/08/27 to return NULL if no hits + if( fHitsN > 0 ) return fHit[0]; + else return NULL; +} +//______________________________________________________________________________ +// + +Bool_t DPlane::Update(){ + + // Calculate or update pedestal, pulseheights, noise, common mode shift on channels + // then search for hits in plane + // + // Returns kFALSE if data are OK, kTRUE otherwise + // + // Pay attention that the old frawdata is now untrustable, use systematically GetStrip(st)->GetRawValue() + // + // Readout: (usually the number of the MIMOSA sensor) + // is used tp re-arrange raw data if needed + // 0 = don't read + // 1-99 = planes with non zero-supressed data + // 100- = planes with zero-supressed data + // + // Last Modified, JB 2009/05/12 + // Last Modified, JB 2009/05/25 + // Last Modified, RDM 2009/05/26 + // Last Modified, JB 2009/08/17 for MIMOSA26 - PXI reading + // Last Modified, JB 2010/09/20 added flag planeReady to indicate no problem even if no analysis + // Last Modified, MB 2010/11/10 method to take into account pedestal corrected + // Last Modified, SS 2012/08/10 for readout 32 (MIMOSA 32) + // Last Modified, JB 2012/11/21 use method ComputeStripPosition + // Last Modified, JB 2013/06/23 first MultiFrame Readout mode 232 for MIMOSA 32 + // Last Modified: VR 2014/07/12 replace aPixel->SetSize( (*fSize)) by aPixel->SetSize( (*fPitch)) + // Last Modified, JB 2016/07/20 better management of fNoiseRun option + // Last Modified, JB 2016/08/17 signed value in multiframe mode + // Last Modified, JB 2016/08/19 allow NoieRun option for readmode 232 + // Last Modified, JB 2018/05/04 new readout==3 mode for polarity inversion + // Last Modified, JB 2010/11/25 implemented mimosatype=61 (MonolithicImager) + + Bool_t goForAnalysis = kTRUE ; + Bool_t planeReady = kTRUE ; // JB 2010/09/20 + fKillNoise=kFALSE; + fHitsN = 0; // necessary otherwise DSession::FillTree may screw up, JB 2007 June + + + DPixel *aPixel; + Int_t st=0, colPhys=0, linPhys=0, stPhys=0; + DR3 tPosition(0,0,0); + DR3 tSize(0,0,0); + Double_t u=0,v=0,w=0; + Float_t aRawvalue, aNoise, aPedestal; + + if(fDebugPlane) printf(" DPLane::Update Updating plane %d with readout %d status=%d analysisMode=%d mimosaType=%d noiseRun=%d\n", fPlaneNumber, fReadout, fStatus, fAnalysisMode, fMimosaType, fNoiseRun); + + + //====================== + // Skip if readout is 0 + if( fReadout==0 ) { + if( fDebugPlane) printf(" DPlane::Update skipping plane %d because readout=%d\n", fPlaneNumber, fReadout); + return !planeReady; + } + + //====================== + // Readout 1 + // - without zero suppression + // - no need to re-order channel numbering wrt strip numbering + // - no CDS required or CDS already performed in BoardReader class + // - further analysis done with DStrip object + // - does not allow to take into account external noise or gain file + // Checked JB 2012/08/21 + else if ( fReadout==1 ){ + fPixelsN = fListOfPixels->size(); // update number of hit pixels + if( fDebugPlane>1 ) printf(" DPlane::Update: Plane %d has %d pixels\n", fPlaneNumber, fPixelsN); + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + aPixel->SetPixelLine( st / fStripsNu); + aPixel->SetPixelColumn( st % fStripsNu); + + if( fMimosaType==60 && 60600<=fSession->GetRunNumber() && fSession->GetRunNumber()<60641) { // row 0-3 -> 4-7 and 4-7 -> 0-3 + aPixel->SetPixelLine( (st/fStripsNu+4)%8 ); + st = ((st/fStripsNu+4)%8)*fStripsNu + st%fStripsNu; + } + + GetStrip(st)->SetPixelIndex( tci); + GetStrip(st)->SetRawValue( aPixel->GetRawValue() ); + //GetStrip(st)->SetRawValue(fRawData[st]); // old way + + if ((fMimosaType==33 && tci<27) + ) { + aPixel->SetRawValue(0.); + aPixel->SetPulseHeight(0.); + GetStrip(st)->SetRawValue( 0.); + } + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d, at (line,col)=(%d,%d) and raw value %.1f or %.1f\n", tci, st, st / fStripsNu, st & fStripsNu, aPixel->GetRawValue(), GetStrip(st)->GetRawValue()); + + } + } //end readout==1 + + //====================== + // Readout 2 + // - without zero suppression + // - re-ordering of the channel numbering wrt strip numbering + // - no CDS required or CDS already performed in BoardReader class + // - allows to take into account external noise or gain file + // - further analysis done with DPixel or DStrip objects + // JB 2013/08/14 + else if ( fReadout==2 ){ + fPixelsN = fListOfPixels->size(); // update number of hit pixels + if( fDebugPlane>1 ) printf(" DPlane::Update: Plane %d has %d pixels\n", fPlaneNumber, fPixelsN); + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + if( fMimosaType==61 ) { + int input = st/32768; // input nb + int stinput = st%32768; // index in input + int pseudocol = stinput%128; + int adc = 3-(pseudocol%4); + int group = pseudocol/4; + linPhys = stinput / 128; + colPhys = input*128 + group + adc*32; + // printf( " st=%6d, inp=%d, pseudoc=%3d, a=%d, g=%d\n", st, input, pseudocol, adc, group); + } + else { + linPhys = st / fStripsNu; + colPhys = st % fStripsNu; + } + + stPhys = colPhys + linPhys*fStripsNu; + if( fDebugPlane>2 && stPhys>fStripsN-1) printf(" Pb1 with st %d, (line,col)=(%d,%d), physIndex %d, value %f\n", st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + ComputeStripPosition( colPhys, linPhys, u, v, w); + tPosition.SetValue(u,v,w); // + + // update the pixel + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + + if(180000 <= fSession->GetRunNumber() && fSession->GetRunNumber() <= 180500 && linPhys==0 && (colPhys==2 || colPhys==3) ) { + aPixel->SetRawValue(1.0e-6); + aPixel->SetPulseHeight(1.0e-6); + } + + if ( fPixelGainRun ) { + SetPixelGainFromHisto( colPhys, linPhys, aPixel); + } + + if( fNoiseRun) { + SetPedandNoiseFromHisto( colPhys, linPhys, aPixel); + } + + // update the strip + GetStrip(stPhys)->SetPixelIndex( tci); + GetStrip(stPhys)->SetRawValue( aPixel->GetRawValue() ); + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d) channel=%d and rawvalue %f\n", tci, st, linPhys, colPhys, stPhys, aPixel->GetRawValue()); + + } + } //end readout==2 + + //====================== + // Readout 3 + // - same as Readout==1 BUT REVERESE POLARITY + // JB, MK 2018/05/04 + else if ( fReadout==3 ){ + fPixelsN = fListOfPixels->size(); // update number of hit pixels + if( fDebugPlane>1 ) printf(" DPlane::Update: Plane %d has %d pixels\n", fPlaneNumber, fPixelsN); + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + aPixel->SetPixelLine( st / fStripsNu); + aPixel->SetPixelColumn( st % fStripsNu); + + // reverse polarity here + aPixel->SetRawValue( -aPixel->GetRawValue()); + + GetStrip(st)->SetPixelIndex( tci); + GetStrip(st)->SetRawValue( aPixel->GetRawValue() ); + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d, at (line,col)=(%d,%d) and raw value %.1f or %.1f\n", tci, st, st / fStripsNu, st & fStripsNu, aPixel->GetRawValue(), GetStrip(st)->GetRawValue()); + + } + } //end readout==3 + + //====================== + // Readout 102 + // - with zero suppression + // - re-ordering of the channel numbering wrt strip numbering + // - no CDS required or CDS already performed in BoardReader class + // - allows to take into account external noise file + // - further analysis done with DPixel object + // JB 2013/08/18 + else if ( fReadout==102 ){ + + if(fMimosaType == 225) { + //Subtracting the fist 8 columns from the pixel list. Only applies to Mi22THR + //temporal list with hit pixels excluding hot-pixels + std::vector Temp_list; + Temp_list.clear(); + for(int iPix=0;iPixsize());iPix++) { + aPixel = fListOfPixels->at(iPix); + if(aPixel->GetPixelIndex() % fStripsNu >= 8) Temp_list.push_back(aPixel); + else delete aPixel; + } + fListOfPixels->clear(); + for(int iPix=0;iPixpush_back(Temp_list[iPix]); + } + Temp_list.clear(); + } + + fPixelsN = fListOfPixels->size(); // update number of hit pixels + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + linPhys = st / fStripsNu; + colPhys = st % fStripsNu; + stPhys = colPhys + linPhys*fStripsNu; + //if( fDebugPlane>2 && stPhys>fStripsN-1) printf(" Pb1 with st %d, (line,col)=(%d,%d), physIndex %d, value %f\n", st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + ComputeStripPosition( colPhys, linPhys, u, v, w); + tPosition.SetValue(u,v,w); // + + if(fMimosaType == 226 && !(124<=linPhys && linPhys <= 248) ) { + aPixel->SetRawValue(0); + aPixel->SetPulseHeight(0); + if( colPhys>63 ) { + colPhys -= 64; + } else { + colPhys += 64; + } + } + + // update the pixel + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPixelIndex( stPhys); // JB 2014/08/26 + aPixel->SetPosition( tPosition); + + //if(fMimosaType == 225) { + //if(colPhys >= 0 && colPhys <= 7) { + // aPixel->SetRawValue(-1.0); + // aPixel->SetPulseHeight(1.0); + //} + //} + + + + if( fNoiseRun) { + SetPedandNoiseFromHisto( colPhys, linPhys, aPixel); + //aPixel->SetPixelIndex(aPixel->GetPixelLine()*fStripsNu + aPixel->GetPixelColumn()); + } + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d) channel=%d, position (%.1f, %.1f, %.1f), size (%.1f, %.1f, %.1f) raw value %.1f pulse height %.1f S/N %.2f ped=%.1f noise=%.1f\n", tci, st, linPhys, colPhys, stPhys, u, v, w, (*fPitch)(0), (*fPitch)(1), (*fPitch)(2), aPixel->GetRawValue(), aPixel->GetPulseHeight(), aPixel->GetPulseHeightToNoise(), aPixel->GetPedestal(), aPixel->GetNoise()); + } // end loop over hit pixels + + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + //cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in event " << fAcq->GetEventNumber() << endl; + } + } //end readout==102 + + + //====================== + // Readout without zero suppression BUT recquiring re-ordering + // of channels wrt strips + // Readout adapted to Mimosa 5 + else if ( fReadout==5 ){ + // the plane data corresponds to 2 inputs of the daq module + // so basically st = 512*... + // we inverse all the channel indexes for the second half or input + // (that is complementing the column number to 511) + // this is due to the readout of scheme of sub-matrices + // which is symetric wrt the center of the chip + Int_t nPix = 512; // actual number of pixels of submatrix + fPixelsN = fListOfPixels->size(); // update number of hit pixels + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + + if( st >= 3*nPix*nPix ) { // submatrix A3 + linPhys = nPix-1 - st/nPix; // flip line 511->0 & 0->511 + colPhys = st % nPix + fStripsNu-nPix; // shift by nPix if fStripsNu=2xnPix + } + else if( st >= 2*nPix*nPix ) { // submatrix A2 + linPhys = nPix-1 -st/nPix + fStripsNv-nPix; // flip line 511->0 & 0->511 and shift by nPix if fStripsNv=2xnPix + colPhys = st % nPix + fStripsNu-nPix; // shift by nPix if fStripsNu=2xnPix + } + else if( st >= nPix*nPix ) { // submatrix A1 + linPhys = nPix-1 - st/nPix + fStripsNv-nPix; // flip line 511->0 & 0->511 and shift by nPix if fStripsNv=2xnPix + colPhys = st % nPix; + } + else { // submatrix A0 + linPhys = nPix-1 - st/nPix; // flip line 511->0 & 0->511 + colPhys = st % nPix; + } + stPhys = colPhys + linPhys*fStripsNu; + if( fDebugPlane>2 && stPhys>fStripsN-1) printf(" Pb1 with st %d, (line,col)=(%d,%d), physIndex %d, value %f\n", st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + + ComputeStripPosition( colPhys, linPhys, u, v, w); // JB 2012/11/21 + // u = ((2*colPhys - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).aPitch(0))/2 ; + // v = ((2*linPhys - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + tPosition.SetValue(u,v,w); // + + // update the pixel + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + + // update the strip + GetStrip(stPhys)->SetPixelIndex( tci); + GetStrip(stPhys)->SetRawValue( aPixel->GetPulseHeight()); + //GetStrip(stPhys)->UpdateSignal(); // done at call for analyze_basic, JB 2011/04/15 + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d) channel=%d, value %f\n", tci, st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + } // end loop over hit pixels + + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in real event " << fAcq->GetEventNumber() << endl; + } + + } //end if Readout==5 + + + //====================== + // Readout with zero-suppression using a list of hit pixels + // MIMOSA5 type indexes, i.e. 4 submatrices from equal size + else if ( fReadout==105 ){ + + fPixelsN = fListOfPixels->size(); // update number of hit pixels + Int_t nPix = 512; // size of one submatrix + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + // special treatment for November 2009 PLUME test + if(fSession->GetRunNumber()/100==205 && fPlaneNumber==6 ) { // NCS 07/11/09 + //cout << "fPlaneNumber=" << fPlaneNumber << endl ; + st = st +1; + } + // compute line and column index from the index + // test order modified, JB 2009/05/25 + if( st >= 3*nPix*nPix ) { // submatrix A3 + linPhys = nPix-1 - st/nPix; // flip line 511->0 & 0->511 + colPhys = st % nPix + fStripsNu-nPix; // shift by nPix if fStripsNu=2xnPix + } + else if( st >= 2*nPix*nPix ) { // submatrix A2 + linPhys = nPix-1 -st/nPix + fStripsNv-nPix; // flip line 511->0 & 0->511 and shift by nPix if fStripsNv=2xnPix + colPhys = st % nPix + fStripsNu-nPix; // shift by nPix if fStripsNu=2xnPix + } + else if( st >= nPix*nPix ) { // submatrix A1 + linPhys = nPix-1 - st/nPix + fStripsNv-nPix; // flip line 511->0 & 0->511 and shift by nPix if fStripsNv=2xnPix + colPhys = st % nPix; + } + else { // submatrix A0 + linPhys = nPix-1 - st/nPix; // flip line 511->0 & 0->511 + colPhys = st % nPix; + } + ComputeStripPosition( colPhys, linPhys, u, v, w); // JB 2012/11/21 + // u = ((2*colPhys - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*linPhys - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + tPosition.SetValue(u,v,w); // + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + if( fNoiseRun) { + SetPedandNoiseFromHisto( colPhys, linPhys, aPixel); + aPixel->SetPixelIndex(aPixel->GetPixelLine()*fStripsNu + aPixel->GetPixelColumn()); // added MB/10/11/2010 + if( TMath::Abs(aPixel->GetPedestal()) == 1023 ) { + aPixel->SetPulseHeight( 0.); + } + } + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d), position (%.1f, %.1f, %.1f), size (%.1f, %.1f, %.1f) raw value %.1f pulse height %.1f S/N %.2f ped=%.1f noise=%.1f\n", tci, st, linPhys, colPhys, u, v, w, (*fPitch)(0), (*fPitch)(1), (*fPitch)(2), aPixel->GetRawValue(), aPixel->GetPulseHeight(), aPixel->GetPulseHeightToNoise(), aPixel->GetPedestal(), aPixel->GetNoise()); + } // end loop over hit pixels + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + //cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in event " << fAcq->GetEventNumber() << endl; + } + } //end readout==105 + + + //====================== + // Readout without zero suppression BUT recquiring re-ordering + // of channels wrt strips + // Readout adapted to Mimosa 18 + else if ( fReadout==18 ){ + // the plane data corresponds to 2 inputs of the daq module + // so basically st = 256*... + // we inverse all the channel indexes for the second half or input + // (that is complementing the column number to 255) + // this is due to the readout of scheme of sub-matrices + // which is symetric wrt the center of the chip + Int_t nPix = 256; // actual number of pixels of submatrix + fPixelsN = fListOfPixels->size(); // update number of hit pixels + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + + if( st >= 3*nPix*nPix ) { // submatrix A3 + linPhys = st / nPix - 3*nPix; // shift from 768->1023 to 0->256 + colPhys = (nPix-1) - st % nPix + nPix; // flip from 0->255 to 255->0 and shift by 256 + } + else if( st >= 2*nPix*nPix ) { // submatrix A2 + linPhys = (4*nPix-1) - st / nPix; // flip from 512->767 to 511->256 + colPhys = (nPix-1) - st % nPix + nPix; // flip from 0->255 to 255->0 and shift by 256 + } + else if( st >= nPix*nPix ) { // submatrix A1 + linPhys = 3*nPix - (st / nPix)-1; // flip from 256->511 to 511->256 + colPhys = st % nPix; + } + else { // submatrix A0 + linPhys = st / nPix; + colPhys = st % nPix; + } + stPhys = colPhys + linPhys*fStripsNu; + if( fDebugPlane>2 && stPhys>fStripsN-1) printf(" Pb1 with st %d, (line,col)=(%d,%d), physIndex %d, value %f\n", st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + + ComputeStripPosition( colPhys, linPhys, u, v, w); // JB 2012/11/21 + // u = ((2*colPhys - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*linPhys - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + tPosition.SetValue(u,v,w); // + + // update the pixel + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + + if(180000 <= fSession->GetRunNumber() && fSession->GetRunNumber() <= 180500 && linPhys==0 && (colPhys==2 || colPhys==3) ) { + aPixel->SetRawValue(1.0e-6); + aPixel->SetPulseHeight(1.0e-6); + } + + // update the strip + GetStrip(stPhys)->SetPixelIndex( tci); + GetStrip(stPhys)->SetRawValue( aPixel->GetPulseHeight()); // put minus sign if needed here + //GetStrip(stPhys)->UpdateSignal(); // done at call for analyze_basic, JB 2011/04/15 + + if( fDebugPlane>4 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d) channel=%d, value %f\n", tci, st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + } // end loop over hit pixels + + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in real event " << fAcq->GetEventNumber() << endl; + } + + } //end if Readout==18 + + + //====================== + // Readout with zero-suppression using a list of hit pixels + // MIMOSA18 type indexes, i.e. 4 submatrices from equal size + else if ( fReadout==118 ){ + + fPixelsN = fListOfPixels->size(); // update number of hit pixels + Int_t nPix = 256; // size of one submatrix, JB 2009/05/25 + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + // special treatment for November 2009 PLUME test + if(fSession->GetRunNumber()/100==205 && fPlaneNumber==6 ) { // NCS 07/11/09 + //cout << "fPlaneNumber=" << fPlaneNumber << endl ; + st = st +1; + } + // compute line and column index from the index + // test order modified, JB 2009/05/25 + if( st >= 4*nPix*nPix ) { // submatrix imaginary ! + cout << "WARNING DPlane: M-18 readout 118: pixel index crazy = " << st << endl; + } + else if( st >= 3*nPix*nPix ) { // submatrix A3 + linPhys = st / nPix - 3*nPix; // shift from 768->1023 to 0->256 + colPhys = (nPix-1) - st % nPix + nPix; // flip from 0->255 to 255->0 and shift by 256 + } + else if( st >= 2*nPix*nPix ) { // submatrix A2 + linPhys = (4*nPix-1) - st / nPix; // flip from 512->767 to 511->256 + colPhys = (nPix-1) - st % nPix + nPix; // flip from 0->255 to 255->0 and shift by 256 + } + else if( st >= nPix*nPix ) { // submatrix A1 + linPhys = 3*nPix - (st / nPix)-1; // flip from 256->511 to 511->256 + colPhys = st % nPix; + } + else { // submatrix A0 + linPhys = st / nPix; + colPhys = st % nPix; + } + + // Specific since Oct 2011 + if( 0<=colPhys && colPhys<28 ) { + colPhys +=228; + } + else if( 28<=colPhys && colPhys<256 ) { + colPhys -=28; + } + else if( 256<=colPhys && colPhys<512-28 ) { + colPhys +=28; + } + else if( 512-28<=colPhys && colPhys<512 ) { + colPhys -=228; + } + + + ComputeStripPosition( colPhys, linPhys, u, v, w); // JB 2012/11/21 + // u = ((2*colPhys - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*linPhys - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + tPosition.SetValue(u,v,w); // + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPixelIndex( aPixel->GetPixelLine()*fStripsNu + aPixel->GetPixelColumn()); // JB 2014/08/26 + aPixel->SetPosition( tPosition); + + if(180000 <= fSession->GetRunNumber() && fSession->GetRunNumber() <= 180500 && linPhys==0 && (colPhys==2 || colPhys==3) ) { + aPixel->SetRawValue(1.0e-6); + aPixel->SetPulseHeight(1.0e-6); + } + + if( fNoiseRun) { + SetPedandNoiseFromHisto( colPhys, linPhys, aPixel); + //aPixel->SetPixelIndex(aPixel->GetPixelLine()*fStripsNu + aPixel->GetPixelColumn()); + if( TMath::Abs(aPixel->GetPedestal()) == 1023 ) { + aPixel->SetPulseHeight( 0.); + } + } + + // Specific for LNF beam test May 2014 + // useless since June 2014 + // if( colPhys==367 && linPhys<257 && fSession->GetRunNumber()<100) { + // aPixel->SetPulseHeight( 0.); + // } + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d), position (%f, %f, %f), value %f\n", tci, st, linPhys, colPhys, u, v, w, aPixel->GetPulseHeight()); + // if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d), position (%f, %f, %f), size (%f, %f, %f) value %f\n", tci, st, linPhys, colPhys, u, v, w, (*fPitch)(0), (*fPitch)(1), (*fPitch)(2), aPixel->GetPulseHeight()); + } // end loop over hit pixels + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + //cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in event " << fAcq->GetEventNumber() << endl; + } + } //end readout==118 + + + //====================== + // Readout using a list of hit pixels + // MIMOSA20 type indexes, i.e. 5 submatrices 320 ligns * 66 columns + // with the 2 first pixels out of 66 being markers and not used + // NCS 27/09/09 + else if ( fReadout==20 ) + { + fPixelsN = fListOfPixels->size(); // update number of hit pixels + Int_t nPixPerBloc = 66; // size of one submatrix, in Nb of Columns NCS 27/09/09 + Int_t nPixPerLign = 330; // size of one submatrix in Nb of columns, includes the 10 marker pixels + Int_t bloc=0 ; // to know in which submatrix we are (between 0 and 4) + Int_t colInsideBloc=0; // Column Number inside the submatrix + Int_t indexBloc=0; // Starting index of the submatrix + Int_t NbOfMarkers =0; + + if(fDebugPlane>8) cout << "DPlane::Update, readout = "<< fReadout <<", fPixelsN=" << fPixelsN << endl ; + for (Int_t tci = 0; tci < fPixelsN; tci++) // loop over hit pixels + { + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); // TNT pixel index NCS 01/10/09 + // ----- Organisation of indexes in physical Lines and columns ---- // + if(st<105600) // pixel TNT numbering ie with the markers submatrix A1 + { + // Determination of the lign in the matrix + linPhys=st/nPixPerLign; // entire part of the division + // For chip in vertical position Height 640 width 320 + //++colPhys=st/nPixPerLign; // entire part of the division + // Determination of the submatrix number (between 0 and 4) = rest of the division by 5 gives the number of the submatrix + bloc=st%5; + // Determination of the column number inside a submatrix + colInsideBloc=(st-linPhys*nPixPerLign-bloc)/5 - 2 ; // shift of 2 because of the markers + // For chip in vertical position Height 640 width 320 + //++colInsideBloc=(st-colPhys*nPixPerLign-bloc)/5 - 2 ; //=> LineInsideBloc en fait puisque vertical + if(colInsideBloc<0)// a negative colInsideBloc indicates a marker + { + cout << "fPixelsN =" << fPixelsN << "** tci marker=" << tci << "** st=" << st << endl ; + //tci++ ; + NbOfMarkers ++; + //if(tci105599)// pixel TNT numbering, submatrix A0 + { + // Determination of the lign in the matrix + //linPhys=st/nPixPerLign; // entire part of the division + // For chip in vertical position Height 640 width 320 + colPhys=(st-105600)/nPixPerLign; // entire part of the division + // Determination of the submatrix number (between 0 and 4) = rest of the division by 5 gives the number of the submatrix + bloc=(st-105600)%5; + // Determination of the column number inside a submatrix + //colInsideBloc=(st-105600-linPhys*nPixPerLign-bloc)/5 - 2 ; // shift of 2 because of the markers + // For chip in vertical position Height 640 width 320 + colInsideBloc=(st-105600-colPhys*nPixPerLign-bloc)/5 - 2 ; + if(colInsideBloc<0)// a negative colInsideBloc indicates a marker + { + cout << "fPixelsN =" << fPixelsN << "** tci marker=" << tci << "** st=" << st << endl ; + //tci++; + NbOfMarkers ++; + //if(tciSetRawValue( aPixel->GetPulseHeight())=" << aPixel->GetPulseHeight()<< endl ; + //GetStrip(stPhys)->UpdateSignal(); // done at call for analyze_basic, JB 2011/04/15 // Remark : NCS 05/10/09 update only for signals + + + } // end loop over hit pixels + if( fPixelsN==0 ) + { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in event " << fAcq->GetEventNumber() << endl; + } + + + } //end readout==20, fin NCS 27/09/09 Mimosa20 readout + + //====================== + // Readout with zero-suppression using a list of hit pixels + // MIMOSA20 type indexes + else if ( fReadout==120 ) + { + //if(fPlaneNumber==1 || fPlaneNumber==3) + //cout << "M20 DPlane.cxx st=" << st << " fPlaneNumber=" << fPlaneNumber <<", evtnumber = " << fSession->GetCurrentEventNumber()<< endl; + fPixelsN = fListOfPixels->size(); // update number of hit pixels + Int_t nPixPerBloc = 66; // size of one submatrix, in Nb of Columns NCS 27/09/09 + Int_t nPixPerLign = 330; // size of one submatrix in Nb of columns, includes the 10 marker pixels + Int_t bloc=0 ; // to know in which submatrix we are (between 0 and 4) + Int_t colInsideBloc=0; // Column Number inside the submatrix + Int_t indexBloc=0; // Starting index of the submatrix + Int_t NbOfMarkers =0; + + if(fDebugPlane>8) cout << "DPlane::Update, readout = "<< fReadout <<", fPixelsN=" << fPixelsN << endl ; + for (Int_t tci = 0; tci < fPixelsN; tci++) // loop over hit pixels + { + + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); // TNT pixel index NCS 01/10/09 + //cout << endl << "M20 st=" << st << " fPlaneNumber=" << fPlaneNumber <<", evtnumber = " << fSession->GetCurrentEventNumber()<< endl; + + //if(st<11){ cout << "st<11=" << st << endl ; getchar();} + //cout << " st = " << st << endl ; + //cout << "aPixel->GetPulseHeight()=" << aPixel->GetPulseHeight()<< endl ; + //if(fSession->GetPlaneNumber()==0){h1->Fill(st);h5->Fill(aPixel->GetPulseHeight());} + //if(aPixel->GetPulseHeight()>3300) {cout << "st=" << st << " GetPulseHeight=" << aPixel->GetPulseHeight()<< endl ;} + //if(st==65012){ cout << "marker!"<< endl ; getchar();} + + // ----- Organisation of indexes in physical Lines and columns ---- // + if(st<105600) // pixel TNT numbering ie with the markers submatrix A1 + { + //cout << "NCS DPlane.cxx st<105600 : st=" << st << endl ; + // Determination of the lign in the matrix + //linPhys=st/nPixPerLign; // entire part of the division + // For chip in vertical position Height 640 width 320 + colPhys=st/nPixPerLign; // entire part of the division + //cout << "colPhys=st/330=" << colPhys << endl ; + // Determination of the submatrix number (between 0 and 4) = rest of the division by 5 gives the number of the submatrix + bloc=st%5; + //cout << "bloc=st%5=" << bloc << endl ; + + // Determination of the column number inside a submatrix + //colInsideBloc=(st-linPhys*nPixPerLign-bloc)/5 - 2 ; // shift of 2 because of the 2 markers of each bloc + // For chip in vertical position Height 640 width 320 + colInsideBloc=(st-colPhys*nPixPerLign-bloc)/5 - 2 ; //=> LineInsideBloc en fait puisque vertical + //cout << "colInsideBloc=(st-colPhys*330-bloc)/5 - 2 =" << colInsideBloc<< endl ; + if(colInsideBloc<0)// a negative colInsideBloc indicates a marker + { + //if(st!=0){cout << "fPixelsN =" << fPixelsN << "** tci marker=" << tci << "** st=" << st << endl ;getchar();} + //if(st==65012 ||st==79861 ){ cout << "marker!"<< endl ; return 0;} + //tci++ ; + NbOfMarkers ++; + //if(tci=0) + { + // Shift index with respect to the beginning of the global matrix + indexBloc= bloc*(nPixPerBloc-2); + //cout << "indexBloc= bloc*(nPixPerBloc-2)=" << indexBloc <GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*linPhys - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + u=-u;// NCS 101209 OK for PLUME VERTICAL + v=-v; // NCS 101209 OK for PLUME VERTICAL + //temp=u; // NCS 101209 for PLUME HORIZONTAL + //u=v; + //v=temp; + + //cout << "tci=" << tci << " colPhys=" << colPhys << " u=" << u << endl ; + //cout << "linPhys=" << linPhys << " v=" << v << endl ; + //cout << "(u,v)=("<< u <<","<< v<<")" << " (line,col)=(" << linPhys << "," << colPhys <<")" << endl ; + + //if(TMath::Abs(u)<3000 && v > (-7500) && v < (-500) ) + { + tPosition.SetValue(u,v,w); // + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + } + //else{cout << "je suis sur la matrice du haut "<< endl ;} + //****************************************************************************** + } + + } + else if(st>105599)// pixel TNT numbering, submatrix A0 + { + //cout << "NCS DPlane.cxx st>105599 : st=" << st << endl ; + // Determination of the lign in the matrix + //linPhys=(st-105600)/nPixPerLign; // entire part of the division + // For chip in vertical position Height 640 width 320 + //cout << "NCS DPlane.cxx st=+3200 : st=" << st << endl ; + colPhys=(st-105600)/nPixPerLign; // entire part of the division + //cout << "colPhys=(st-105600)/330=" << colPhys << endl ; + + // Determination of the submatrix number (between 0 and 4) = rest of the division by 5 gives the number of the submatrix + bloc=(st-105600)%5; + //cout << "bloc=(st-105600)%5=" << bloc <=0) + { + // Shift index with respect to the beginning of the global matrix + indexBloc= (bloc+5)*(nPixPerBloc-2); // adding matrix A1 columns (5 blocs) + //cout << "indexBloc= (bloc+5)*(nPixPerBloc-2)=" << indexBloc << endl ; + + // Column number inside the general matrix + //colPhys = indexBloc+colInsideBloc; + // For chip in vertical position Height 640 width 320 + linPhys = indexBloc+colInsideBloc; + //cout << "linPhys = indexBloc+colInsideBloc=" << linPhys << endl ; + //****************************************************************************** + ComputeStripPosition( colPhys, linPhys, u, v, w); // JB 2012/11/21 + // u = ((2*colPhys - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*linPhys - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + u=-u;// NCS 101209 OK for PLUME VERTICAL + v=-v;// NCS 101209 OK for PLUME VERTICAL + //temp=u; // NCS 101209 for PLUME HORIZONTAL + //u=v; + //v=temp; + + //cout << "tci=" << tci << " colPhys=" << colPhys << " u=" << u << endl ; + //cout << "linPhys=" << linPhys << " v=" << v << endl ; + //cout << "(u,v)=("<< u <<","<< v<<")" << " (line,col)=(" << linPhys << "," << colPhys <<")" << endl ; + + + //if(TMath::Abs(u)<3000 && v > (-7500) && v < (-500) ) + { + tPosition.SetValue(u,v,w); // + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + } + //else{cout << "je suis sur la matrice du haut "<< endl ;} + //****************************************************************************** + } + } // end pixel TNT numbering > 105600 (after shift), matrix A0 + + if( fDebugPlane>8 ) printf("DPlane::Update() pixel %d with index %d updated at (line,col)=(%d,%d), position (%f, %f, %f), size (%f, %f, %f) value %f\n", tci, st, linPhys, colPhys, u, v, w, (*fPitch)(0), (*fPitch)(1), (*fPitch)(2), aPixel->GetPulseHeight()); + + } // end loop over hit pixels + if( fPixelsN==0 ) + { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in event " << fAcq->GetEventNumber() << endl; + } + } //end readout==120, fin NCS 30/10/09 Mimosa20 readout + + + //====================== + // Readout : + // - without zero suppression + // - recquiring re-ordering of channels wrt strips + // - with binary output + // Readout adapted to Mimosa 22 digital part + // JB 2013/08/14 + else if ( fReadout==22 ){ + // the plane data corresponds to 2 inputs of the daq module + // so basically st = 256*... + // we inverse all the channel indexes for the second half or input + // (that is complementing the column number to 255) + // this is due to the readout of scheme of sub-matrices + // which is symetric wrt the center of the chip + fPixelsN = fListOfPixels->size(); // update number of hit pixels + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + if(fMimosaType != 225) { + linPhys = st / fStripsNu; + colPhys = st % fStripsNu; + } + else { + linPhys = st / fStripsNu; + if((st / (fStripsNu/2)) % 2) colPhys = 2*(st % (fStripsNu/2)) + 1; + else colPhys = 2*(st % (fStripsNu/2)); + } + stPhys = colPhys + linPhys*fStripsNu; + if( fDebugPlane>2 && stPhys>fStripsN-1) printf(" Pb1 with st %d, (line,col)=(%d,%d), physIndex %d, value %f\n", st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + ComputeStripPosition( colPhys, linPhys, u, v, w); // JB 2012/11/21 + tPosition.SetValue(u,v,w); // + + // update the pixel + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + + // update the strip + GetStrip(stPhys)->SetPixelIndex( tci); // JB 2013/08/20 + GetStrip(stPhys)->SetRawValue( aPixel->GetPulseHeight()); + //GetStrip(stPhys)->UpdateSignal(); // done at call for analyze_basic, JB 2011/04/15 + + // Trick to consider only one part of MIMOSA 22 + if ( + (22700<=fSession->GetRunNumber() && fSession->GetRunNumber()<22800 && colPhys>=320) // 22AHR: S1-S10 col<320, S11-S16 col>=320 + || + (22800<=fSession->GetRunNumber() && fSession->GetRunNumber()<22900 && colPhys>96) // 22AHR: S1-S4 col:96/192/256 + ) { + aPixel->SetRawValue(0); + aPixel->SetPulseHeight(0); + GetStrip(stPhys)->SetRawValue(0); + } + + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d) channel=%d, value %f\n", tci, st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + } // end loop over hit pixels + + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in real event " << fAcq->GetEventNumber() << endl; + } + + } //end if Readout==22 + + + //====================== + // Readout without zero-suppression BUT recquiring re-ordering + // MIMOSA25 type indexes + // RDM 210509, JB 2009/05/25 + else if ( fReadout==25 ){ + + TMimosa24_25Map *Mi=0; + switch (fMimosaType) { + case 20: + Mi = new TMimosa24_25Map("Mi25B_20um"); //20um pitch + break; + case 30: + Mi = new TMimosa24_25Map("Mi25B_30um"); //30um pitch + break; + case 40: + Mi = new TMimosa24_25Map("Mi25B_40um"); //40um pitch + break; + default: + cout << "MimosaType " << fMimosaType << " unknown for Mimosa25" << endl; + Fatal("DPlane:Update", "==> CHANGE CONFIG FILE, I AM STOPPING! <=="); + }; + fPixelsN = fListOfPixels->size(); // update number of hit pixels + Int_t nPix = TMath::Max( fStripsNu/2, fStripsNv*2); // size of submatrix is the smallest + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + // compute line and column index from the index + switch (fMimosaType) { + case 20: + linPhys = Mi->get_submatrix(st / nPix,st % nPix)*32+Mi->get_row(st / nPix,st % nPix); + break; + case 30: + if (Mi->get_submatrix(st / nPix,st % nPix)==0) + linPhys = Mi->get_row(st / nPix,st % nPix); + else if (Mi->get_submatrix(st / nPix,st % nPix)==1) + linPhys = 21 + Mi->get_row(st / nPix,st % nPix); + else if (Mi->get_submatrix(st / nPix,st % nPix)==2) + linPhys = 43 + Mi->get_row(st / nPix,st % nPix); + break; + case 40: + linPhys = Mi->get_submatrix(st / nPix,st % nPix)*16+Mi->get_row(st / nPix,st % nPix); + break; + }; + + colPhys = Mi->get_column(st / nPix,st % nPix); + // physical index + stPhys = colPhys + linPhys*fStripsNu; + + aPixel->SetPixelLine( linPhys); // YV, 2009/06/05 + aPixel->SetPixelColumn( colPhys); // YV, 2009/06/05 + + // update the strip + GetStrip(stPhys)->SetPixelIndex( tci); + GetStrip(stPhys)->SetRawValue( aPixel->GetPulseHeight()); + //GetStrip(stPhys)->UpdateSignal(); // done at call for analyze_basic, JB 2011/04/15 + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d) channel=%d, value %f\n", tci, st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + } // end loop over hit pixels + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in real event " << fAcq->GetEventNumber() << endl; + } + delete Mi; //RDM290509 + } //end readout==25 + + + //====================== + // Readout with zero-suppression using a list of hit pixels + // RDM 210509 largely modified!!! + // MIMOSA25 type indexes + else if ( fReadout==125 ){ + + TMimosa24_25Map *Mi=0; + switch (fMimosaType) { + case 20: + Mi = new TMimosa24_25Map("Mi25A_20um"); //20um pitch + break; + case 30: + Mi = new TMimosa24_25Map("Mi25A_30um"); //30um pitch + break; + case 40: + Mi = new TMimosa24_25Map("Mi25A_40um"); //40um pitch + break; + default: + cout << "MimosaType " << fMimosaType << " unknown for Mimosa25" << endl; + Fatal("DPlane:Update", "==> CHANGE CONFIG FILE, I AM STOPPING! <=="); + }; + fPixelsN = fListOfPixels->size(); // update number of hit pixels + Int_t nPix = TMath::Max( fStripsNu/2, fStripsNv*2); // size of submatrix is the smallest + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + // compute line and column index from the index + switch (fMimosaType) { + case 20: + linPhys = Mi->get_submatrix(st / nPix,st % nPix)*32+Mi->get_row(st / nPix,st % nPix); + break; + case 30: + if (Mi->get_submatrix(st / nPix,st % nPix)==0) + linPhys = Mi->get_row(st / nPix,st % nPix); + else if (Mi->get_submatrix(st / nPix,st % nPix)==1) + linPhys = 21 + Mi->get_row(st / nPix,st % nPix); + else if (Mi->get_submatrix(st / nPix,st % nPix)==2) + linPhys = 43 + Mi->get_row(st / nPix,st % nPix); + break; + case 40: + linPhys = Mi->get_submatrix(st / nPix,st % nPix)*16+Mi->get_row(st / nPix,st % nPix); + break; + }; + + colPhys = Mi->get_column(st / nPix,st % nPix); + ComputeStripPosition( colPhys, linPhys, u, v, w); // JB 2012/11/21 + // u = ((2*colPhys - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*linPhys - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + tPosition.SetValue(u,v,w); // + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + + aPixel->SetPixelIndex(colPhys + linPhys*16); //RDM060809 + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d), position (%f, %f, %f), size (%f, %f, %f) value %f\n", tci, st, linPhys, colPhys, u, v, w, (*fPitch)(0), (*fPitch)(1), (*fPitch)(2), aPixel->GetPulseHeight()); + } // end loop over hit pixels + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + if( fDebugPlane>2 ) cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in real event " << fAcq->GetEventNumber() << endl; //RDM310509 add if debug + } + delete Mi; //RDM290509 + } //end readout==125 + + + //====================== + // Readout without zero suppression BUT recquiring re-ordering + // of channels wrt strips + // RDM 210509, then JB 2009/05/25, YV 27/11/09 + // MIMOSA24 type indexes + + else if ( fReadout==24 ){ + + TMimosa24_25Map *Mi; + Mi = new TMimosa24_25Map("Mi24"); + fPixelsN = fListOfPixels->size(); // update number of hit pixels + Int_t nPix = 4096 ; //YV 09/06/09 + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + + // compute line and column index from the index + switch(Mi->get_submatrix(st / nPix,st % nPix)) { + case 0:// OK ? + linPhys = 62 - Mi->get_row(st / nPix,st % nPix); + colPhys = Mi->get_column(st / nPix,st % nPix); + break; + case 1: // OK + linPhys = 31 - Mi->get_row(st / nPix,st % nPix); + colPhys = Mi->get_column(st / nPix,st % nPix); + break; + case 2: // OK + linPhys = 64 + Mi->get_row(st / nPix,st % nPix); + colPhys = Mi->get_column(st / nPix,st % nPix); + break; + case 3: // OK + linPhys = 95 + Mi->get_row(st / nPix,st % nPix); + colPhys = Mi->get_column(st / nPix,st % nPix); + break; + case 4: // OK + linPhys = 64 + Mi->get_row(st / nPix,st % nPix); + colPhys = 127 - Mi->get_column(st / nPix,st % nPix); + break; + case 5: // OK + linPhys = 95 + Mi->get_row(st / nPix,st % nPix); + colPhys = 127 - Mi->get_column(st / nPix,st % nPix); + break; + case 6: // OK + linPhys = 30 - Mi->get_row(st / nPix,st % nPix); + //colPhys = 31 - Mi->get_column(st / nPix,st % nPix); + colPhys = 127 - Mi->get_column(st / nPix,st % nPix); //YV 11/10/09 + break; + case 7: // OK + linPhys = 15 - Mi->get_row(st / nPix,st % nPix); + //colPhys = 31 - Mi->get_column(st / nPix,st % nPix); + colPhys = 127 - Mi->get_column(st / nPix,st % nPix); //YV 11/10/09 + break; + default: // OK + linPhys = -1111; + colPhys = -1111; + break; + }; + + //commented out 30/06/09 + //linPhys = Mi->get_submatrix(st / nPix,st % nPix)*32+Mi->get_row(st / nPix,st % nPix); + //colPhys = Mi->get_column(st / nPix,st % nPix); + + //phys. index + stPhys = colPhys + linPhys*fStripsNu; + aPixel->SetPixelLine( linPhys); // YV, 2009/06/02 + aPixel->SetPixelColumn( colPhys); // YV, 2009/06/02 + + // update the strip + GetStrip(stPhys)->SetPixelIndex( tci); + GetStrip(stPhys)->SetRawValue( aPixel->GetPulseHeight()); + //GetStrip(stPhys)->UpdateSignal(); // done at call for analyze_basic, JB 2011/04/15 + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d) channel=%d, value %f\n", tci, st, linPhys, colPhys, stPhys, aPixel->GetPulseHeight()); + } // end loop over hit pixels + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + } + delete Mi; //RDM290509 + + } //end readout==24 + + + //====================== + // Readout with zero-suppression using a list of hit pixels + // RDM 210509 + // RDM 220509 + // YV 27/11/09 + // MIMOSA24 type indexes + + else if ( fReadout==124 ){ + + TMimosa24_25Map *Mi; + Mi = new TMimosa24_25Map("Mi24"); + fPixelsN = fListOfPixels->size(); // update number of hit pixels + Int_t nPix = 4096; + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + + //readout M24 as 1 plane + + switch(Mi->get_submatrix(st / nPix,st % nPix)) { + case 0:// OK ? + linPhys = 62 - Mi->get_row(st / nPix,st % nPix); + colPhys = Mi->get_column(st / nPix,st % nPix); + break; + case 1: // OK + linPhys = 31 - Mi->get_row(st / nPix,st % nPix); + colPhys = Mi->get_column(st / nPix,st % nPix); + break; + case 2: // OK + linPhys = 64 + Mi->get_row(st / nPix,st % nPix); + colPhys = Mi->get_column(st / nPix,st % nPix); + break; + case 3: // OK + linPhys = 95 + Mi->get_row(st / nPix,st % nPix); + colPhys = Mi->get_column(st / nPix,st % nPix); + break; + case 4: // OK + linPhys = 64 + Mi->get_row(st / nPix,st % nPix); + colPhys = 127 - Mi->get_column(st / nPix,st % nPix); + break; + case 5: // OK + linPhys = 95 + Mi->get_row(st / nPix,st % nPix); + colPhys = 127 - Mi->get_column(st / nPix,st % nPix); + break; + case 6: // OK + linPhys = 30 - Mi->get_row(st / nPix,st % nPix); + //colPhys = 31 - Mi->get_column(st / nPix,st % nPix); + colPhys = 127 - Mi->get_column(st / nPix,st % nPix); //YV 11/10/09 + break; + case 7: // OK + linPhys = 15 - Mi->get_row(st / nPix,st % nPix); + //colPhys = 31 - Mi->get_column(st / nPix,st % nPix); + colPhys = 127 - Mi->get_column(st / nPix,st % nPix); //YV 11/10/09 + break; + default: // OK + //printf("pixel index = %d, row = %d, column = %d, submatrix = %d \n", st, Mi->get_row(st / nPix,st % nPix), Mi->get_column(st / nPix,st % nPix), Mi->get_submatrix(st / nPix,st % nPix)); //YV 23/09/09 + linPhys = -1111; + colPhys = -1111; + break; + }; + + + ComputeStripPosition( colPhys, linPhys, u, v, w); // JB 2012/11/21 + // u = ((2*colPhys - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*linPhys - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + tPosition.SetValue(u,v,w); + aPixel->SetSize( (*fPitch)); + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPosition( tPosition); + + //YV 21/10/09 + + TH2F *h2 = fHNoise; + aNoise = h2->GetBinContent(st%64,64-(st/64)); //1st channel + //aNoise = h2->GetBinContent(st%64,(st-4096)/64); //2nd channel + //aNoise = h2->GetBinContent(st%64,(st-8192)/64); //3rd channel + //aNoise = h2->GetBinContent((st%64)+1,(st-12288)/64+32); //4rth channel + aPixel->SetNoise(aNoise); + //printf("pixel %d, noise = %f\n",st,aNoise); + + TH2F *h3 = fHPedestal; + //aPedestal = h3->GetBinContent((st%64)+1,(st/64)); //channel 1 + //aPedestal = h3->GetBinContent((st%64)+1,(st-4096)/64); //channel 2 + //aPedestal = h3->GetBinContent((st%64)+1,(st-8192)/64); //channel 3 + aPedestal = h3->GetBinContent((st%64)+1,(st-12288)/64+32); //channel 4 + aPixel->SetPedestal(aPedestal); + Float_t newRawValue = aPixel->GetPulseHeight() - aPedestal; + aPixel->SetPulseHeight(newRawValue); + //printf("pixel: %d, new raw value=%f \n",st,aPixel->GetPulseHeight()); + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d updated at (line,col)=(%d,%d) channel=%d and rawvalue (pix)%f (strip)%f\n", tci, st, linPhys, colPhys, stPhys, aPixel->GetRawValue(), GetStrip(stPhys)->GetRawValue()); + + } // end loop over hit pixels + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + } + delete Mi; //RDM290509 + + } //end readout==124 + + + //====================== + // Readout with binary zero-suppression using a list of hit pixels + // JB 2009/08/17 + // MIMOSA26 && MIMOSA28 && FSBB + else if ( fReadout==126 ){ + + fPixelsN = fListOfPixels->size(); // update number of hit pixels + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + aPixel->SetPixelIndex(aPixel->GetPixelLine()*fStripsNu + aPixel->GetPixelColumn()); + ComputeStripPosition( aPixel->GetPixelColumn(), aPixel->GetPixelLine(), u, v, w); // JB 2012/11/21 + // u = ((2*aPixel->GetPixelColumn() - fStripsNu + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(0))/2 ; + // v = ((2*aPixel->GetPixelLine() - fStripsNv + 1 ) * fc->GetPlanePar(fPlaneNumber).Pitch(1))/2 ; + // w = fc->GetPlanePar(fPlaneNumber).Pitch(2); + tPosition.SetValue(u,v,w); // + aPixel->SetSize( (*fPitch)); + aPixel->SetPosition( tPosition); + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d at (line,col)=(%d,%d), position (%f, %f, %f), size (%f, %f, %f) value %f\n", tci, aPixel->GetPixelIndex(), aPixel->GetPixelLine(), aPixel->GetPixelColumn(), u, v, w, (*fPitch)(0), (*fPitch)(1), (*fPitch)(2), aPixel->GetPulseHeight()); + } // end loop over hit pixels + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + } + + } //end readout==126 + + + //====================== + // Readout without zero suppression for Mimosa 32A + else if ( fReadout==32 ){ + fPixelsN = fListOfPixels->size(); // update number of hit pixels + + // if( fPixelsN!=fChannelsN ) { + // cout <<"WARNING Plane " << fPlaneNumber << " has " << fPixelsN << " hit pixels which is different from the exepected " << fChannelsN << "channels in non-sparsified mode." << endl; + // } + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + + linPhys = st / fStripsNu ; + colPhys = st % fStripsNu ; + //SS 2012.08.10 - Solution for the wrong line order + // for run taken with PXIe (>328xx) + if( fSession->GetRunNumber()>=32800 ) { + if (colPhys==0) colPhys=63; + else colPhys--; + //JB 2012/08/18 - swapping of real column groups 8-11 with 12-15 + // note that real columns are lines in our config + // ONLY FOR RUN 32824 + if( fSession->GetRunNumber()==32824 ) { + if( 8<=linPhys && linPhys<=11) linPhys += 4; + else if( 12<=linPhys && linPhys<=15) linPhys -= 4; + } + } + + // update the pixel + stPhys = colPhys + linPhys*fStripsNu; + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPixelIndex( stPhys); + + // update the strip, + // take into account that after noise initialization + // we consider only absolute value of frame1-frame2. + GetStrip(stPhys)->SetPixelIndex( tci); + if(fInitialCounter <= fInitialNoise) { + GetStrip(stPhys)->SetRawValue( aPixel->GetRawValue() ); + } + else { + GetStrip(stPhys)->SetRawValue( fabs(aPixel->GetRawValue()) ); + } + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d, physical index %d at (line,col)=(%d,%d) and raw value %.1f or %.1f\n", tci, st, stPhys, linPhys, colPhys, aPixel->GetRawValue(), GetStrip(stPhys)->GetRawValue()); + + + if ( fIfDigitize && fInitialCounter > fInitialNoise ) { // if some digitization is required and after initialization + // further update the pixel + ComputeStripPosition( colPhys, linPhys, u, v, w); + tPosition.SetValue(u,v,w); // + aPixel->SetSize( (*fPitch) ); + aPixel->SetPosition( tPosition); + + aRawvalue = fabs(aPixel->GetRawValue()); + aPedestal = GetStrip(stPhys)->GetPedestal(); + aNoise = GetStrip(stPhys)->GetNoise(); + aPixel->SetNoise( aNoise); + aPixel->SetPedestal( aPedestal); + //aRawvalue = Digitize( aRawvalue - aPedestal ); + //aPixel->SetRawValue( aRawvalue ); + aPixel->SetPulseHeight( aRawvalue - aPedestal ); + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d, physical index %d at (line,col)=(%d,%d) and raw value %.1f, pulse height %.1f\n", tci, st, stPhys, linPhys, colPhys, aPixel->GetRawValue(), aPixel->GetPulseHeight()); + + } // end some digitization is required + + } // end loop over hit pixels + + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in real event " << fAcq->GetEventNumber() << endl; + } + + } //end if Readout==32 + + //====================== + // Readout with zero suppression for Mimosa 32A + else if ( fReadout==132 ){ + fPixelsN = fListOfPixels->size(); // update number of hit pixels + + // if( fPixelsN!=fChannelsN ) { + // cout <<"WARNING Plane " << fPlaneNumber << " has " << fPixelsN << " hit pixels which is different from the exepected " << fChannelsN << "channels in non-sparsified mode." << endl; + // } + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + + linPhys = st / fStripsNu ; + colPhys = st % fStripsNu ; + //SS 2012.08.10 - Solution for the wrong line order + // for run taken with PXIe (>328xx) + if( fSession->GetRunNumber()>=32800 ) { + if (colPhys==0) colPhys=63; + else colPhys--; + //JB 2012/08/18 - swapping of real column groups 8-11 with 12-15 + // note that real columns are lines in our config + // ONLY FOR RUN 32824 + if( fSession->GetRunNumber()==32824 ) { + if( 8<=linPhys && linPhys<=11) linPhys += 4; + else if( 12<=linPhys && linPhys<=15) linPhys -= 4; + } + } + + stPhys = colPhys + linPhys*fStripsNu; + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + aPixel->SetPixelIndex( stPhys); + ComputeStripPosition( colPhys, linPhys, u, v, w); + tPosition.SetValue(u,v,w); // + aPixel->SetSize( (*fPitch)); + aPixel->SetPosition( tPosition); + + if( fNoiseRun) { + SetPedandNoiseFromHisto( colPhys, linPhys, aPixel); + aPixel->SetPixelIndex(aPixel->GetPixelLine()*fStripsNu + aPixel->GetPixelColumn()); + } + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d, physical index %d at (line,col)=(%d,%d) and raw value %.1f\n", tci, st, stPhys, linPhys, colPhys, aPixel->GetRawValue()); + } // end loop over hit pixels + + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in real event " << fAcq->GetEventNumber() << endl; + } + + } //end if Readout==132 + + //====================== + // Readout without zero suppression AND multiframe for Mimosa 32 + else if ( fReadout==232 ){ + fPixelsN = fListOfPixels->size(); // update number of hit pixels + if( fDebugPlane>3 ) Printf( "Update:: %d hits to update\n", fPixelsN); + + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = aPixel->GetPixelIndex(); + + linPhys = st / fStripsNu ; + colPhys = st % fStripsNu ; + //SS 2012.08.10 - Solution for the wrong line order + // for run taken with PXIe (>328xx) + if( fSession->GetRunNumber()>=32800 && fSession->GetRunNumber() < 33000) { + if (colPhys==0) colPhys=63; + else colPhys--; + //JB 2012/08/18 - swapping of real column groups 8-11 with 12-15 + // note that real columns are lines in our config + // ONLY FOR RUN 32824 + if( fSession->GetRunNumber()==32824 ) { + if( 8<=linPhys && linPhys<=11) linPhys += 4; + else if( 12<=linPhys && linPhys<=15) linPhys -= 4; + } + } + stPhys = colPhys + linPhys*fStripsNu; + aPixel->SetPixelLine( linPhys); + aPixel->SetPixelColumn( colPhys); + ComputeStripPosition( colPhys, linPhys, u, v, w); + tPosition.SetValue(u,v,w); + aPixel->SetPosition( tPosition); + aPixel->SetSize( (*fPitch)); + + if( fDebugPlane>3 ) printf("DPlane:Update pixel %d with index %d, physical index %d at (line,col)=(%d,%d), raw value %.1f\n", tci, st, stPhys, linPhys, colPhys, aPixel->GetRawValue()); + + // update the corresponding strip and pixel, + // Note that after noise initialization + // we consider the signed value of frame1-frame2 to properly observe pixel behavior + // Case for external noise computation (fNoiseRun==kTrue) added. + // JB 2016/08/17 + GetStrip(stPhys)->SetPixelIndex( tci); + if( fNoiseRun) { + SetPedandNoiseFromHisto( colPhys, linPhys, aPixel); + GetStrip(stPhys)->SetRawValue( aPixel->GetRawValue() ); + } + else { + if(fInitialCounter <= fInitialNoise ) { + //GetStrip(stPhys)->SetRawValue( aPixel->GetRawValue() ); + if( Int_t(aPixel->GetRawValue()) != 0 ) GetStrip(stPhys)->SetRawValue( aPixel->GetRawValue() ); + aPixel->SetPulseHeight( aPixel->GetRawValue() ); + } + else { + aRawvalue = aPixel->GetRawValue(); + aPedestal = GetStrip(stPhys)->GetPedestal(); + aNoise = GetStrip(stPhys)->GetNoise(); + GetStrip(stPhys)->SetRawValue( aRawvalue ); + aPixel->SetNoise( aNoise); + aPixel->SetPedestal( aPedestal); + aPixel->SetPulseHeight( aRawvalue - aPedestal); + //if( aRawvalue>200 ) printf(" pixel %d index %d at (line,col)=(%d,%d), timestamp %d, raw value %.1f, pedestal %.1f, noise %.1f, pulseheight %.1f\n", tci, st, stPhys, linPhys, aPixel->GetTimestamp(), GetStrip(stPhys)->GetRawValue(), aPixel->GetPedestal(), aPixel->GetNoise(), aPixel->GetPulseHeight()); + } + } + + if( fDebugPlane>3 ) printf(" pixel %d raw value %.1f, pedestal %.1f, noise %.1f, pulseheight %.1f\n", tci, GetStrip(stPhys)->GetRawValue(), aPixel->GetPedestal(), aPixel->GetNoise(), aPixel->GetPulseHeight()); + } // end loop over hit pixels + + if( fPixelsN==0 ) { + goForAnalysis = kFALSE; + cout <<"WARNING Plane " << fPlaneNumber << " has no hit pixels, no more analysis for it in real event " << fAcq->GetEventNumber() << endl; + } + + } //end if Readout==232 + + + //====================== + // ANY OTHER READOUT issue a warning + else { + planeReady = kFALSE; + printf( "WARNING, DPlane:Update readout %d unknown, no analysis !\n", fReadout); + } + + + //====================== + // Call the analysis now + //====================== + + if (goForAnalysis) { + + //============== + // compute pedestal, noise and common noise shift + // or update the strip values + // exclude zero-suppressed data (readout>100), JB 2009/05/25 + // exclude noise computed from previous run, JB 2014/01/07 + // include multi-frame readout (232) only for init step, JB 2013/ + // modified condition fInitialCounterGetStatus() != 0 && fAnalysisMode>0) { + + //============== + // Digitize the matrix if required + if( fIfDigitize>0 ) { + DigitizeMatrix(); + } + + //============== + // potentially update pedestal, noise + // or update the strip values + // only for not zero-suppressed data, JB 2011/04/15 + // if( fReadout<100 && fAnalysisMode<=1 ) { + // UpdatePedestalAndNoise(); + // } // end if readout<100 + + //============== + // look for hits + find_hits(); + if (fDebugPlane) cout << " Plane " << fPlaneNumber << " : " << fHitsN << " new hits found" << endl; + + } + + } // end if goForAnalysis + else { + if (fDebugPlane) cout << "Plane " << fPlaneNumber << ": can't analyse or no data " << endl ; + } + + if ( !planeReady && fDebugPlane) cout << "Plane " << fPlaneNumber << ": bad raw data " << endl ; + + if(fAcq->GetIfMCBoardReader()) { // AP, 2016/07/27. Do some operations only in the case of reading MC-data + //Now, if some hits where not digitized, then generate hits with the MC information + CheckNonDigitizedMCHits(); + + //Do hit truth matching and get the particle generating this hit + MCHitsTruthMatching(); + } // end if reading MC-data + + return !planeReady; // JB 2010/09/20 + +} +//______________________________________________________________________________ +// +DStrip* DPlane::GetStrip(Int_t aSk) +{ + // Modified by JB, to start at 0 up to fStripsN-1, 2008/10/17 + + if( aSk >= 0 && aSk < fStripsN ) { + return fStripList[aSk]; + } + else { + //printf("WARNING DPlane::GetStrip() request to non-existing strip %d, investigate!\n Returning strip 0.\n", aSk); + return fStripList[0]; + } +} + +//______________________________________________________________________________ +// + +void DPlane::ComputeStripPosition(Int_t col, Int_t lin, Double_t &u, Double_t &v, Double_t &w) +{ + + fTool.ComputeStripPosition( fMapping, col, lin, u, v, w, fStripsNu, fStripsNv, (*fPitch)(0), (*fPitch)(1), (*fPitch)(2)); + + /* + // Compute the 3D position of the strip at column "col" and line "lin", + // set the values in the "u, v, w" variables. + // The strip position depends on the mapping, look below. + // + // JB 2012/11/21 + // Modified CLM 2012/11/24 correction for P31 of M32ter + // Modified AB 2015/03/31 new case 7 adapted to M22thrb6,7 + + switch (fMapping) { + + // When pixels are organized *on an orthogonal grid + case 1: + default: + u = ((2*col - fStripsNu + 1 ) * (*fPitch)(0))/2 ; + //printf( " u = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", col, fStripsNu, (*fPitch)(0), (2*col - fStripsNu + 1 ), (*fPitch)(0)/2, u); + v = ((2*lin - fStripsNv + 1 ) * (*fPitch)(1))/2 ; + //printf( " v = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", lin, fStripsNv, (*fPitch)(1), (2*lin - fStripsNv + 1 ), (*fPitch)(1)/2, v); + break; + + // When pixels are staggered from one column to the other + case 2: + u = ((2*col - fStripsNu + 1 ) * (*fPitch)(0))/2 ; + // v = ((2*lin + 1./2. - lin%2 - fStripsNv + 1 ) * (*fPitch)(1))/2 ; + // v = ((2*lin - 1./2. + lin%2 - fStripsNv + 1 ) * (*fPitch)(1))/2 ; //clm + //printf( " u = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", col, fStripsNu, (*fPitch)(0), (2*col - fStripsNu + 1 ), (*fPitch)(0)/2, u); + + if ( col%2 == 0 ) v = (((lin - fStripsNv/2.0 + 1./2. ) * (*fPitch)(1))) + 0.30 * (*fPitch)(1); //clm 2012.11.24 + else v = (((lin - fStripsNv/2.0 + 1./2. ) * (*fPitch)(1))) - 0.19 * (*fPitch)(1); //clm 2012.11.24 + //printf( " v = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", lin, fStripsNv, (*fPitch)(1), (2*lin - fStripsNv + 1 ), (*fPitch)(1)/2, v); + break; + case 3: + //Clm Mapping For M32 L8_2 + if ( lin==7 && col == 10) u = ((2*col - fStripsNu + 1 ) * (*fPitch)(0))/2 ; + else u = -9999; //((2*col+2 - fStripsNu + 1 ) * (*fPitch)(0))/2 ; + v = ((2*lin - fStripsNv + 1 ) * (*fPitch)(1))/2 ; + break; + // MonteCarlo Simulation. // LC 2014/01/10. + case 4: + u = ((2.*col - fStripsNu + 2. ) * (*fPitch)(0))/2. ; // LC 2015/02/17 : +2 commented + //printf( " u = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", col, fStripsNu, (*fPitch)(0), (2*col - fStripsNu + 1 ), (*fPitch)(0)/2, u); + v = ((2.*lin - fStripsNv + 2. ) * (*fPitch)(1))/2. ; // LC 2015/02/17 : +2 commented + //printf( " v = (2x%d-%d+1) * %f/2 = %d*%f = %f\n", lin, fStripsNv, (*fPitch)(1), (2*lin - fStripsNv + 1 ), (*fPitch)(1)/2, v); + break; + case 5: + { + u = (2*col + 1 - fStripsNu) * (*fPitch)(0)/2.0; + double fraction = 0.25; + //double fraction = 0.75; + if ( col%2 == 0 ) v = 0.5*(fStripsNv - 2*lin - 2*(fraction )) * (*fPitch)(1); + else v = 0.5*(fStripsNv - 2*lin - 2*(1 - fraction)) * (*fPitch)(1); + break; + } + case 7: //M22-THRB7 and B6 -> set the matrix type and Mapping accordingly in the config file ! + u = ((2*col - fStripsNu + 1 ) * (*fPitch)(0))/2 ; + if ( col%2 == 0 ) v = (((lin - fStripsNv/2.0 + 1./2. ) * (*fPitch)(1))) - 0.50 * (*fPitch)(1); //correct +0.5 + else v = (((lin - fStripsNv/2.0 + 1./2. ) * (*fPitch)(1))) - 0.00 * (*fPitch)(1); //correct -0.5 + //cout<<" DPlane::ComputeStripPosition "< N(%d,%d), pitch(%.1f,%.1f), (%d, %d): %.1f, %.1f\n", fStripsNu, fStripsNv, (*fPitch)(0), (*fPitch)(1), col, lin, u, v); + + */ + + return; + +} + +//______________________________________________________________________________ +// +void DPlane::ComputeStripPosition_UVToColRow( Double_t u, Double_t v, double &col, double &lin) +{ + + fTool.ComputeStripPosition_UVToColRow( fMapping, u, v, col, lin, fStripsNu, fStripsNv, (*fPitch)(0), (*fPitch)(1)); + + /* + // Compute the 2D position of a strip in the variables u and v to the set of variables column and line + // The strip position depends on the mapping, look below. + // AP 2014/06/26 + // Modified AB 2015/03/31 new case 7 adapted to M22thrb6,7 + + //cout << (*fPitch)(0) << " " << (*fPitch)(1) << endl; + + switch (fMapping) { + // When pixels are organized on an orthogonal grid + case 1: + default: + col = (u/(*fPitch)(0)) + ((fStripsNu - 1)/2.); + lin = (v/(*fPitch)(1)) + ((fStripsNv - 1)/2.); + break; + // When pixels are staggered from one column to the other + case 2: + col = (u/(*fPitch)(0)) + ((fStripsNu - 1)/2.); + if(int(col)%2 == 0) lin = (v/(*fPitch)(1)) + ((fStripsNv - 1)/2.) - 0.30; + else lin = (v/(*fPitch)(1)) + ((fStripsNv - 1)/2.) + 0.19; + break; + case 3: + //Clm Mapping For M32 L8_2 + col = (u/(*fPitch)(0)) + ((fStripsNu - 1)/2.); + lin = (v/(*fPitch)(1)) + ((fStripsNv - 1)/2.); + break; + // MonteCarlo Simulation. // LC 2014/01/10. + case 4: + col = (u/(*fPitch)(0)) + ((fStripsNu)/2.); // LC 2015/02/17 : -2 commented + lin = (v/(*fPitch)(1)) + ((fStripsNv)/2.); // LC 2015/02/17 : -2 commented + break; + + case 5: + { + col = (u/(*fPitch)(0)) + ((fStripsNu - 1)/2.); + + double fraction = 0.25; + //double fraction = 0.75; + + int IntCol = int(col); + double delta = col - IntCol; + if(delta >= 0.5) IntCol++; + + if(IntCol%2 == 0) lin = ((fStripsNv - 2*(fraction ))/2.0) - (v/(*fPitch)(1)); + else lin = ((fStripsNv - 2*(1 - fraction))/2.0) - (v/(*fPitch)(1)); + + //cout << "(u,v) = (" << u << "," << v << ")" << endl; + //cout << "col = " << col << endl; + //cout << "IntCol = " << IntCol << endl; + //cout << "delta = " << delta << endl; + //cout << "IntCol = " << IntCol << endl; + //cout << "lin = " << lin << endl; + + break; + } + case 7://M22-THRB7 and B6 -> set the matrix type and Mapping accordingly in the config file ! + col = (u/(*fPitch)(0)) + ((fStripsNu - 1)/2.); + if(int(col)%2 == 0) lin = (v/(*fPitch)(1)) + ((fStripsNv - 1)/2.) + 0.50; //correct -0.5 + else lin = (v/(*fPitch)(1)) + ((fStripsNv - 1)/2.) + 0.0; //correct +0.5 + //cout<<" DPlane::ComputeStripPosition_UVToColRow "<Introduce(*fStripList[st]); // Introduce itself + + diffU = rc = 0; + while ( !rc && abs(diffU)Introduce(*fStripList[stTest]); + } + diffU++; + + } + + diffU = -1; + rc = 0; + while ( !rc && abs(diffU)Introduce(*fStripList[stTest]); + } + diffU--; + } + } + } + // Method for pixels + // bug fixed for neighbourLines/Columns -> Limit(1,0)/Pitch(1,0), AB 2012/10/22 + else if (fAnalysisMode >= 2){ + + // only for debug messages + Int_t minSt=200, maxSt=260; + + Int_t tNeighbourLines = (Int_t) (fc->GetPlanePar(fPlaneNumber).ClusterLimit(1)/fc->GetPlanePar(fPlaneNumber).Pitch(1)); + Int_t tNeighbourColumns = (Int_t) (fc->GetPlanePar(fPlaneNumber).ClusterLimit(0)/fc->GetPlanePar(fPlaneNumber).Pitch(0)); + if (fDebugPlane) cout << "FindNeighbours: tNeighbourLines =" << tNeighbourLines << " of " << (*fPitch)(0) << " um and tNeighbourColumns=" << tNeighbourColumns << " of " << (*fPitch)(1) << " um." << endl; + for (Int_t sta = 0; sta < fStripsN; sta++) { // loop on all strips + Int_t iLine = sta/fStripsNu; // Line of this pixel + Int_t iCol = sta%fStripsNu; // Colomn of this pixel + if (fDebugPlane>3 && minStGetStripIndex() << " ( " << iCol << ", " << iLine << ") introducing: "; + fStripList[sta]->Introduce(*fStripList[sta]); + for(Int_t il=iLine-tNeighbourLines; il3 && minSt=0 && ic>=0 && il2 && minStGetStripIndex() << endl; + fStripList[sta]->Introduce(*fStripList[il*fStripsNu+ic]); + // so pixel can have a maximum number of neighbours + //but can have less as well if it is near the edge + } + } + } + if (fDebugPlane>3 && minStGetRawValue(); + aPedestal = fHPedestal->GetBinContent( col+1, row+1); + aNoise = fHNoise->GetBinContent( col+1, row+1); + if (fDebugPlane>3) printf("SetPedandNoiseFromHisto:pixel c=%d, r=%d updated with raw=%.1f, ped=%.1f, noise=%.1f\n", col+1, row+1, aRawvalue, aPedestal, aNoise); + aPixel->SetNoise( aNoise); + aPixel->SetPedestal( aPedestal); + aPixel->SetPulseHeight( aRawvalue - aPedestal); + +} + +//______________________________________________________________________________ +// + +void DPlane::SetPixelGainFromHisto( Int_t col, Int_t row, DPixel *aPixel) { + + // Set the pixel gain from a previous computation + // This computation is valid if the following variables are true: + // fPixelGainRun, fHPixelGain + // + // JB 2018/08/01 + + if( !fPixelGainRun || fHPixelGain==NULL ) return; + + Float_t aRawvalue = aPixel->GetRawValue() / fHPixelGain->GetBinContent( col+1, row+1); + aPixel->SetRawValue( aRawvalue); + if (fDebugPlane>3) printf("SetPixelGainFromHisto:pixel c=%d, r=%d updated with raw=%.1f/%.1f=%.1f\n", col+1, row+1, aPixel->GetRawValue(), fHPixelGain->GetBinContent( col+1, row+1), aRawvalue); + +} + +//______________________________________________________________________________ +// + +void DPlane::analyze_basics(){ + + // Depending on the initializing status, change the strip related values + // before init: accumulate data, + // at init : compute initial values for pedestal and noise + // after init : update the noise + // Operations before and after init are only performed for fired strips. + // + // JB, 2008/10/13 + // Last Modified, JB 2010/09/20 allow computation only for fired strips (=pixels) + // Last Modified, JB 2011/04/15 allow update only for fired strips (=pixels) + // Last Modified, JB 2016/07/20 better management of fNoiseRun option + + Int_t region, st; + DPixel *aPixel; + DStrip *aStrip; + + //================ + // for first events just accumulate pedestals and their squares + if(fInitialCounter <= fInitialNoise && !fNoiseRun) { + fInitialCounter++; + if(fDebugPlane) printf("DPlane::analyze_basics called for plane %d accumulating data with event %d where %d are required for init\n", fPlaneNumber, fInitialCounter, fInitialNoise); + + // Loop only on fired pixels, JB 2010/09/20 + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = fStripsNu*aPixel->GetPixelLine() + aPixel->GetPixelColumn(); + aStrip = GetStrip(st); + if( fDebugPlane>2) printf("analyze_basics: pix=%d, st=%d, rawdata=%.1f (pixVal %.1f)\n", tci, st, aStrip->GetRawValue(), aPixel->GetPulseHeight()); + aStrip->SumValue(); + aStrip->SumSquareValue(); + aStrip->UpdateSignal(); // added JB 2012/08/17, rawData=pulseheight since ped and CMS are still 0 for now + } + } + + + //================ + // When init is over calculate pedestal and noise + if (fInitialCounter == fInitialNoise && !fNoiseRun) { + + if(fDebugPlane) printf("DPlane::analyze_basics called for plane %d InitNoiseAndPedestal : fInitialCounter = %d\n", fPlaneNumber, fInitialCounter ); + + for(st = 0; st < fStripsN; st++) { + aStrip = GetStrip(st); + aStrip->InitNoiseAndPedestal(); + aStrip->UpdateSignal(); // added JB 2012/08/17 + aStrip->SetFound( kFALSE); // JB 2012/08/20 + if(fDebugPlane && (st<=5 || (fStripsN-st)<5)) printf("DPlane::analyse_basics Pl %d st %d ped=%f noise=%f\n", fPlaneNumber, st, aStrip->GetPedestal(), aStrip->GetNoise()); + } + cout << "-- Plane " << fPlaneNumber << " Pedestals and Noises initialized at event " << fInitialCounter << " --" << endl; + } + + + //================ + // For all events after the init step + else if (fInitialCounter >= fInitialNoise) { + + // calculate common mode shift + //CalculateCommonMode(); // Do not work yet, JB 2020/09/20 + + // Loop only on fired pixels, JB 2011/04/15 + for (Int_t tci = 0; tci < fPixelsN; tci++) { // loop over hit pixels + aPixel = fListOfPixels->at(tci); + st = fStripsNu*aPixel->GetPixelLine() + aPixel->GetPixelColumn(); + aStrip = GetStrip(st); + region = (Int_t)((1.*(st-1))/fStripsN * fRegions); + aStrip->SetCommonMode(fCommonShift[region]); + //aStrip->Update(); + aStrip->UpdateSignal(); + aStrip->SetFound( kFALSE); // JB 2012/08/20 + // The two following lines are required because the pixel list + // is used to find hits, JB 2012/08/17 + // Additional possibility for digitization emulation, JB 2013/08/29 + // if( !fIfDigitize ) { + aPixel->SetPulseHeight( aStrip->GetPulseHeight() ); + aPixel->SetNoise( aStrip->GetNoise() ); + // } + // else { + // Int_t aValue = Digitize( aStrip->GetPulseHeight() ); + // aPixel->SetRawValue( aValue ); + // aPixel->SetPulseHeight( aValue ); + // } + + if(fDebugPlane>3 /*&& st<=5*/) printf("DPlane::analyse_basics Pl %d st %d raw=%.1f ped=%.1f noise=%.1f cms=%.1f pulse=%.1f snr=%.1f and pixel pulse=%.1f snr=%.1f\n", fPlaneNumber, st, aStrip->GetRawValue(), aStrip->GetPedestal(), aStrip->GetNoise(), aStrip->GetCommonMode(), aStrip->GetPulseHeight(), aStrip->GetPulseHeightToNoise(), aPixel->GetPulseHeight(), aPixel->GetPulseHeightToNoise()); + } + + } +} + +void DPlane::UpdatePedestalAndNoise(){ + for(Int_t st = 0; st < fStripsN; st++) { + // -- if strip (pixel) doesn't belong to a cluster, update ped and noise + if(!(GetStrip(st)->Found())){ + GetStrip(st)->UpdatePedestalAndNoise(); + if(fDebugPlane && st<=5) printf("DPlane::UpdatePedestalAndNoise Pl %d st %d ped=%f noise=%f\n", fPlaneNumber, st, GetStrip(st)->GetPedestal(), GetStrip(st)->GetNoise()); + } + } +} + +void DPlane::CalculateCommonMode() { + + // -+-+- Calculate the common signal shift on several channels in the detector + // in order to exclude channels with hit do the following + // split detector in different regions + // calculate shift for each region, exclude bad channels + // (given by strip map) choose the smallest shift + + Int_t region, st; + Float_t r, tNoiseCut; + + Int_t fReadout; + fReadout=fc->GetPlanePar(fPlaneNumber).Readout; + + for (region = 0; region < fRegions; region++) { // loop over regions + fCommonShift[region] = 0.0; // reset the comon shift + fCommonChannels[region] = 0; // and the channel counter + } + + for (st = 0; st < fStripsN; st++) { + region = (Int_t)((1.*st)/fStripsN * fRegions); + if (fChannelGood[st] == 1) { // limit on good channels i.e. exclude bad + // exclude hits from calculation + tNoiseCut = fc->GetAnalysisPar().CmsNoiseCut * GetStrip(st)->GetNoise(); + if (fabs( r =GetStrip(st)->GetRawValue()-GetStrip(st)->GetPedestal() )< tNoiseCut){ + fCommonShift[region]+=r; + fCommonChannels[region]++; + } + } + } + + if( fReadout==10 || fReadout==12 || fReadout==13){ // exclude some readout mode + fCommonShift[region] = 0.0; + } + else { // for all other readout + + for (region = 0; region < fRegions; region++) { // loop over regions + if (fCommonChannels[region] > 0){ + fCommonShift[region] /= fCommonChannels[region]; // calculate shift for each regions + } + else { + fCommonShift[region] = 0.0; // do not shift, if no channel good + + //if(fPlaneNumber>2){ // don't see why we should keep this, historical, JB, 2007, June + printf(" DPlane, Plane %d, CommonMode Error in Region %d (# channels selected=%ld), investigate !!!\n",fPlaneNumber,region+1,fCommonChannels[region]); + //} + + } + + if(fDebugPlane>1) printf("DPLane::CalculateCommonMode pl %d, region %d, channels used %ld, cms %f\n", fPlaneNumber, region, fCommonChannels[region], fCommonShift[region]); + } //end loop on regions + + } + +} + +//______________________________________________________________________________ +// + +Float_t DPlane::minimum(const Float_t* d, const Int_t N){ + Float_t m; + + m = fabs(d[N-1]); + for (Int_t k = 0; k < N-1; k++) + m = (m < fabs(d[k])) ? m : fabs(d[k]); + printf("in Dlane:minimum: m=%f",m); + + return m; +} + +//______________________________________________________________________________ +// + +Int_t DPlane::extremumIndex(const Float_t* d, + const Int_t N){ + Int_t ext; + ext = N-1; + + for (Int_t k = 0; k < N-1; k++) + ext = (fabs(d[ext]) > fabs(d[k])) ? ext : k; + return ext; +} + +//______________________________________________________________________________ +// +Bool_t DPlane::CheckSaturation(){ + + //Quality check to eliminate "dead" events: when both frames saturate, CDS is zero flat. + // We exclude such events. + // But the procedure can be useless if we apply first "cleaning" by KillNoise + // + // This is the only place where we can still use the fRawData[] array + // because we don't care about the ordering of channels here, JB 2009/05/25 + + Bool_t QC = kFALSE; + Double_t RawDataMean=0; + Double_t RawDataVar=0; + Double_t RawData2=0; + for(Int_t i=0; i3 && i<5) { + printf("DPLane::CheckSaturation rawData[%d]=%d\n", i, fRawData[i]); + } + } + RawDataMean /= fChannelsN/2; + RawData2 /= fChannelsN/2; + RawDataVar=RawData2-RawDataMean*RawDataMean; + fCDSvariance = RawDataVar; + //---abm8 mimosa 8 digital case: don't check saturation: + Int_t fReadout; + fReadout=fc->GetPlanePar(fPlaneNumber).Readout; + if (fDebugPlane>2) { + printf("DPLane::CheckSaturation for readout %d", fReadout); + printf(" mean=%f, squareMean=%f, var=%f, CDSvar=%f\n", RawDataMean, RawData2, RawDataVar, fCDSvariance); + } + //----ADC + if((fReadout!=10)&&(fReadout!=12)&&(fReadout!=13)){ //mimosa 8 digital , + if(RawDataMean == 0. || RawDataVar < 0.1){ + cout << "Dead (saturated) event # " << fAcq->GetEventNumber() << "; Plane "<< fPlaneNumber << endl; + QC=kTRUE; + } + } + //----ADC + + return QC; +} + +//______________________________________________________________________________at( +// + +Int_t DPlane::Digitize( Float_t aValue ){ + + // Digitize an analogue value according to the thresholds provided. + // Number of thresholds (i.e. digital values) is given by fIfDigitize + // and threshold by array fDigitizeThresholds. + // PAY ATTENTION, those thresholds are not ADC-bit limits, + // rather the limits inbetween the fIfDigitize possible values. + // The maximum digital value returned is fIfDigitize. + // + // Examples: with fIfDigitize =2 and fDigitizeThresholds[2]={ 100, 150} + // value 53.5 -> 0 + // value 104.9 -> 1 + // value 208.3 -> 2 + // + // JB 2013/08/29 + + if ( fIfDigitize==0 ) { + Warning("Digitize", "There is no thresholds settings to digitize --> returning 0"); + return 0; + } + + Int_t digital_signal=0; + Int_t iThreshold=0; + + while( aValue>=fDigitizeThresholds[iThreshold] && iThresholdsize()); + + std::vector temporaryList; // pointer to temporary list of hit pixel + DPixel *aPixel; + Int_t digitalValue; + + // Generate list of fired pixels after digitization + for (Int_t tci = 0; tci < (Int_t)fListOfPixels->size(); tci++) { // loop over pixels + aPixel = fListOfPixels->at(tci); + digitalValue = Digitize( aPixel->GetPulseHeight() ); + if ( digitalValue>0 ) { + aPixel->SetRawValue( digitalValue ); + aPixel->SetPulseHeight( digitalValue ); + temporaryList.push_back( aPixel); + if( fDebugPlane>3 ) printf("DPlane:DigitizeMatrix pixel %d with index %d, has been digitized to raw value %.1f and pulse height %.1f, -> temporary pixel list has %d elements\n", tci, aPixel->GetPixelIndex(), aPixel->GetRawValue(), aPixel->GetPulseHeight(), (Int_t)temporaryList.size()); + } + else { // if pixel not selected, delete the object (otherwise not deleted) + delete aPixel; + } + } // end over pixels + + // Replace original list with new list containing only fired pixels (sparsification) + fListOfPixels->clear(); + // for (Int_t tci = 0; tci < (Int_t)temporaryList.size(); tci++) { // loop over pixels + // aPixel = temporaryList.at(tci); + // fListOfPixels->push_back( aPixel ); + // } + fListOfPixels->insert( fListOfPixels->begin(), temporaryList.begin(), temporaryList.end()); + fPixelsN = (Int_t)fListOfPixels->size(); + + if( fDebugPlane ) printf("DPlane:DigitizeMatrix After digitization, plane %d has now %d fired pixels.\n", fPlaneNumber, (Int_t)fListOfPixels->size()); + + temporaryList.clear(); +} + +//______________________________________________________________________________at( +// + +void DPlane::find_hits(){ + + // -+-+- Searches hits in plane + // then submit the analysis + // + // Orders the strips or pixels by either pulseheight or pulseheight ratio, + // the method may differ depending on the type of plane (Strip or Pixel) + // and the readout type, + // then try to see if each strips may be used as a seed to make a hit + // + // Last modified JB 2009/05/12 + // Last modified JB 2009/08/21 deal with binary hit finding (AnalysisMode==3) + // Last modified JB 2010/10/06 call to DPixel::GetPulseHeightToNoise for cut + // Last modified JB 2012/08/18 management of non-sparsified clustering with DStrip objects + // Last modified AP 2014/07 addition of hit finder option + + if( fDebugPlane>1 ) printf("DPlane: finding hits in plane %d with readout=%d analysis=%d over %d pixels\n", fPlaneNumber, fReadout, fAnalysisMode, fPixelsN); + + fHitsN = 0; + + std::vector SeedPixelsList; + SeedPixelsList.clear(); + + if(fHitFinder == 1 && GetAnalysisMode() == 2) { + // Here there is a new algorithm for cluster reconstruction with pixelated sensor with analogue readout + // The first step is to find the local maxima on the pixel map (seed pixels) + // Only select those seed pixels passing the selection requirements: passing the threshold on seed-charge or seed S/N + // Then perform the analysis to add pixels to this seed (clustering) as usual. + + //Get the list of time-stamps in this event + std::vector ListOfTS; + ListOfTS.clear(); + for (Int_t tci = 0; tci < fPixelsN; tci++){ + int ts = fListOfPixels->at(tci)->GetTimestamp(); + bool IsNotIn = true; + for(int itstmp=0;itstmp ts_jjjp1) { + int ts_aux = ListOfTS[jjj]; + ListOfTS[jjj] = ListOfTS[jjj+1]; + ListOfTS[jjj+1] = ts_aux; + } + } + } + + //Initialize variables to find the local maxima in the pixel matrix + int IdxInList_ColRow[ListOfTS.size()][fStripsNu][fStripsNv]; + float Value_ColRow[ListOfTS.size()][fStripsNu][fStripsNv]; + //float SON_ColRow[ListOfTS.size()][fStripsNu][fStripsNv]; + for(int its = 0; its < int(ListOfTS.size()); its++) { // begin time-stamp loop + for(int icol = 0; icol < fStripsNu; icol++) { // begin column loop + for(int irow = 0; irow < fStripsNv; irow++) { // begin row loop + IdxInList_ColRow[its][icol][irow] = -1; + Value_ColRow[its][icol][irow] = -1.0e+10; + //SON_ColRow[its][icol][irow] = -1.0e+10; + } // end row loop + } // end column loop + } // end time-stamp loop + + //Fill variables separated in time-stamp + for (Int_t tci = 0; tci < fPixelsN; tci++) { // being loop over pixels + int ts = fListOfPixels->at(tci)->GetTimestamp(); + int col = fListOfPixels->at(tci)->GetPixelColumn(); + int row = fListOfPixels->at(tci)->GetPixelLine(); + float val = fListOfPixels->at(tci)->GetPulseHeight(); + //float sOn = fListOfPixels->at(tci)->GetPulseHeightToNoise(); + //cout << "col = " << col << ", row = " << row << ", tci = " << tci << ", index = " << col + row*GetStripsNu() << endl; + + for(int its=0;its3) { + for(int its = 0; its < int(ListOfTS.size()); its++) { + for(int icol = 0; icol < fStripsNu; icol++) { + for(int irow = 0; irow < fStripsNv; irow++) { + if(IdxInList_ColRow[its][icol][irow] == -1) cout << "DPlane::WARNING: (col,row,ts) = (" << icol << "," << irow << "," << ListOfTS[its] << ") has index = -1" << endl; + } + } + } + } + + //Now find the local maxima + for(int its = 0; its < int(ListOfTS.size()); its++) { // begin time-stamp loop + + for(int icol=0;icol fStripsNu-1) continue; + for(int j=0;j<3;j++) { + int row_test = irow + j - 1; + if(row_test < 0 || row_test > fStripsNv-1) continue; + + if(icol == col_test && irow == row_test) continue; + + if(Value_ColRow[its][icol][irow] < Value_ColRow[its][col_test][row_test]) { + IsLocalMax = false; + break; + } + + } + if(!IsLocalMax) break; + } + if(!IsLocalMax) continue; + + //Now check if local maxima pixel passes additional selection requirements + if(fListOfPixels->at(IdxInList_ColRow[its][icol][irow])->GetPulseHeightToNoise() > fCut->GetSeedPulseHeightToNoise() && + fListOfPixels->at(IdxInList_ColRow[its][icol][irow])->GetNoise() < fCut->GetMaximalNoise() && + fListOfPixels->at(IdxInList_ColRow[its][icol][irow])->GetNoise() > 0.0) { + + //If local maximum passes additional requirements put it on list for further analysis + SeedPixelsList.push_back(IdxInList_ColRow[its][icol][irow]); + } + + } // end row loop + } // end column loop + } // end time-stamp loop + + ListOfTS.clear(); + + //Order possible seed pixels by charge from highest to lowest + for(int iii=2;iii<=int(SeedPixelsList.size());iii++) { + for(int jjj=0;jjj<=int(SeedPixelsList.size())-iii;jjj++) { + double charge_jjj = fListOfPixels->at(SeedPixelsList[jjj])->GetPulseHeight(); + double charge_jjjp1 = fListOfPixels->at(SeedPixelsList[jjj+1])->GetPulseHeight(); + if(charge_jjj < charge_jjjp1) { + int aux_idx = SeedPixelsList[jjj]; + SeedPixelsList[jjj] = SeedPixelsList[jjj+1]; + SeedPixelsList[jjj+1] = aux_idx; + } + } + } + + if(fDebugPlane > 1) { + for(int iii=0;iiiat(SeedPixelsList[iii])->GetPixelColumn(); + row = fListOfPixels->at(SeedPixelsList[iii])->GetPixelLine(); + + cout << "Found local maximum at (col,row) = (" << col << "," << row << ")" + << ", index = " << SeedPixelsList[iii] + << ", charge = " << fListOfPixels->at(SeedPixelsList[iii])->GetPulseHeight() + << ", S/N = " << fListOfPixels->at(SeedPixelsList[iii])->GetPulseHeightToNoise() + << endl; + } + } + + + + } // end of condition HitFinder == 1 and AnalysisMode == 2 + else { + //If sensor is not analogue output or HitFinder algorithm is not 1 then put in list to check all the pixels + for (Int_t tci = 0; tci < fPixelsN; tci++) SeedPixelsList.push_back(tci); + } + + Bool_t *tested = new Bool_t[fPixelsN]; + for (Int_t tci = 0; tci < fPixelsN; tci++) tested[tci] = kFALSE; + + int potential_seed_counter = 0; + + Bool_t hitOK = kTRUE; // true while hits are found + while ( hitOK == kTRUE && fHitsN < fHitMax ) { // Main loop to find hits + + Int_t seed = -1; // seed undefined by default + hitOK = kFALSE; // set false by default for this search + + //for (Int_t tci = 0; tci < fPixelsN; tci++){ // loop over hit pixels + if(fHitFinder == 1 && GetAnalysisMode() == 2 && potential_seed_counter < (int)(SeedPixelsList.size())) { + if(!fListOfPixels->at(SeedPixelsList[potential_seed_counter])->Found()) seed = SeedPixelsList[potential_seed_counter]; + + if(seed < 0) hitOK = kTRUE; + + if(fDebugPlane > 1) { + int col,row; + col = fListOfPixels->at(SeedPixelsList[potential_seed_counter])->GetPixelColumn(); + row = fListOfPixels->at(SeedPixelsList[potential_seed_counter])->GetPixelLine(); + + cout << endl; + cout << "DPlane::hind_hits(): test seed pixel with index " << SeedPixelsList[potential_seed_counter] << " (col,row) = (" << col << "," << row << "), has index " << seed << " for further analysis!" << endl; + cout << endl; + } + + potential_seed_counter++; + } + else { + for(Int_t iseed = 0; iseed < int(SeedPixelsList.size()); iseed++){ // loop over hit pixels + Int_t tci = SeedPixelsList[iseed]; + //================ + // This loop on strips (tci), sort them in decreasing "significance", + // in order to find hits also with decreasing significance. + // This significance may be the PulseHeightToNoise ratio or the Pulseheight + // of the strip. + // Seed is the index of the current most significant strip. + // For one loop on all strips, the next most significant strip is checked to built a hit. + //================ + + if (fListOfPixels->at(tci)->Found() == kFALSE && + tested[tci] == kFALSE && + fListOfPixels->at(tci)->GetPulseHeightToNoise() > fCut->GetSeedPulseHeightToNoise() && + fListOfPixels->at(tci)->GetNoise()GetMaximalNoise() ) { // test if already found and not tested as seed (JB 2010/10/25) + + // Algo for STRIP detector + // fAnalysisMode = 0,1 + // condition on STRIP only modified by JB, 2007, June + // Remember that tci is the current strip index and seed the current most significant strip + // Treat specific cases first, then the general one + if ( fAnalysisMode<2 ){ + if( seed < 0 ) { + seed = tci; + } + else { + seed = ( + fabs(fListOfPixels->at(seed)->GetPulseHeight()) + > fabs(fListOfPixels->at(tci)->GetPulseHeight()) + ) ? seed : tci; + } + } //end if fAnalysisMode<2 + + // Algo for PIXEL detectors with analogue data + // fAnalysisMode == 2 + // condition on PIXEL modified by JB, 2007, June + // condition on tested pixel added by JB 2010/10/25 + else if ( fAnalysisMode==2 ){ + if( fDebugPlane>3 && + fListOfPixels->at(tci)->GetPulseHeightToNoise() > 0) printf("DPlane: finding (analysisMode %d) hits try pixel %d with PulseHeightToNoise %.1f PulseHeight %.1f (already found? %d or tested? %d), for now seed is %d\n", fAnalysisMode, tci, fListOfPixels->at(tci)->GetPulseHeightToNoise(), fListOfPixels->at(tci)->GetPulseHeight(), fListOfPixels->at(tci)->Found(), tested[tci], seed); + if( seed < 0 ) { + seed = tci; + } + else { + seed = ( + fabs(fListOfPixels->at(tci)->GetPulseHeight()) + > fabs(fListOfPixels->at(seed)->GetPulseHeight()) + ) ? tci : seed; + } + } //end if fAnalysisMode==2 + + // Algo for PIXEL detectors with binary data + // fAnalysisMode == 3 + // All pusleheight is 1 so all pixels are seed candidates + // JB 2009/08/21 + else if ( fAnalysisMode==3 ){ + if( fDebugPlane>3) printf("DPlane(%d): finding hits (current index %d) try pixel %d with Pulseheight %f\n", fPlaneNumber, fHitsN, tci, fListOfPixels->at(tci)->GetPulseHeight()); + + seed = tci; + break; + + } //end if fAnalysisMode==3 + + // for other fAnalysisMode, algo unknown ! + // condition modified by JB, 2007, June + else { + printf("DPlane::Find_hits WARNING analysis mode %d UNKNOWN !!\n", fAnalysisMode); + } //end test on fAnalysisMode + + } // end test if already found + + } //end loop over strips + } + + + if( seed > -1 ) { // if a seed is defined + + + if( fDebugPlane>1 ) printf("DPlane(%d): finding hits (current index %d) found potential seed pixel %d with pulse %.3f and SN %.3f ( %f), already found=%d\n", fPlaneNumber, fHitsN, seed, fListOfPixels->at(seed)->GetPulseHeight(), fListOfPixels->at(seed)->GetPulseHeightToNoise(), fCut->GetSeedPulseHeightToNoise(), tested[seed]); + + fListOfPixels->at(seed)->SetFound(kTRUE); // mark the strip as found + tested[seed] = kTRUE; // mark the strip as already tested for seed + + if ( fListOfPixels->at(seed)->GetPulseHeightToNoise() > fCut->GetSeedPulseHeightToNoise() ) { // pixel class knows by itself when to return PH or PH/Noise, JB 2010/10/05 + + Int_t stPhys = fListOfPixels->at(seed)->GetPixelColumn()+fListOfPixels->at(seed)->GetPixelLine()*fStripsNu; + + // for non zero-suppressed read-out + if( fReadout<100 && !fIfDigitize ) { // new condition to exclude digital-emulated data which, JB 2013/08/29 + //cout << " using analyse dstrip " << endl ; + if(fHitFinder == 0) { + //Reseach region clustering algorith + hitOK = fHit[fHitsN]->Analyse( GetStrip( stPhys)); + } + else if(fHitFinder == 1) { + //Iterative clustering algorithm + bool IsBigCluster = false; + int MaxClusterSize = fc->GetPlanePar(fPlaneNumber).MaxNStrips; + hitOK = fHit[fHitsN]->Analyse_Iterative( GetStrip( stPhys),IsBigCluster,MaxClusterSize); + if(IsBigCluster) cout << " DPlane::find_hits: Found the big cluster at Evt " << fSession->GetCurrentEventNumber()-1 << endl << endl; + } + else { + //Reseach region clustering algorith as default: + hitOK = fHit[fHitsN]->Analyse( GetStrip( stPhys)); + } + } + // for zero-suppressed read-out + // hit finder option added, 2014/07 AP + else { + if(fHitFinder == 0) { + //Reseach region clustering algorith + hitOK = fHit[fHitsN]->Analyse( seed, fListOfPixels); + } + else if(fHitFinder == 1) { + //Iterative clustering algorithm + bool IsBigCluster = false; + int MaxClusterSize = fc->GetPlanePar(fPlaneNumber).MaxNStrips; + hitOK = fHit[fHitsN]->Analyse_Iterative( seed, fListOfPixels,IsBigCluster,MaxClusterSize); + if(IsBigCluster) cout << " DPlane::find_hits:: Found the big cluster at Evt " << fSession->GetCurrentEventNumber()-1 << endl << endl; + } + else if(fHitFinder == 2){ + // Compare the distance from real center of gravity to the pixel position with a search radius to associate this pixel + hitOK = fHit[fHitsN]->Analyse_2_cgo( seed, fListOfPixels); + } + else { + //Reseach region clustering algorith as default: + hitOK = fHit[fHitsN]->Analyse( seed, fListOfPixels); + } + + //Setting hit resolution. Only for digitized output + double u,v,col,lin; + u = fHit[fHitsN]->GetPositionUhit(); + v = fHit[fHitsN]->GetPositionVhit(); + ComputeStripPosition_UVToColRow(u,v,col,lin); + + TVector2 HitResolution(0.0,0.0); + GetHitResolution(col,lin,fHit[fHitsN]->GetStripsInCluster(),HitResolution); + fHit[fHitsN]->SetResolutionUVhit(HitResolution.X(),HitResolution.Y()); + } + + + if ( hitOK == kTRUE ) { + // If non-sparsified readout, it is required to mark the object + // DPixel to found from their corresponding DStrip object. + // Note that we set all pixels even if seed shall have been set found + // already. But seed may have changed... + // This is not required otherwise because method Analyze with DPixel + // does it already. + if( fReadout<100 && !fIfDigitize ) { // new condition to exclude digital-emulated data which, JB 2013/08/29 + if( fDebugPlane>1 ) printf("DPlane: Set found status to the %d strips of hit %d.\n", fHit[fHitsN]->GetStripsInCluster(), fHitsN ); + if(fHitFinder != 1) { + for( Int_t iStrip=0; iStripGetStripsInCluster(); iStrip++ ) { + fListOfPixels->at( fHit[fHitsN]->GetMinor(iStrip)->GetPixelIndex() )->SetFound(kTRUE); + if( fDebugPlane>3 ) printf(" neighbour %d, strip %d (pixel %d) found status set to %d.\n", + iStrip, + fHit[fHitsN]->GetMinor(iStrip)->GetStripIndex(), + fHit[fHitsN]->GetMinor(iStrip)->GetPixelIndex(), + fListOfPixels->at( fHit[fHitsN]->GetMinor(iStrip)->GetPixelIndex() )->Found() + ); + } + } + + } + fHitsN++; + } + else if( (fAnalysisMode==2 || fAnalysisMode==3) && seed1 ) printf(" ==> DPlane(%d)::find_hits %d hits found\n", fPlaneNumber, fHitsN); + + return; + +} +//______________________________________________________________________________ +// +DR3 DPlane::DeformedLocalPoint(DR3& aPlaneCoordinate){ + + // Use the model for the plane deformation + // to change the w coordinate of the given point in the local plane frame. + // Note that only w is changed, (u,v) are unchanged. + // + // JB 2014/04/21 + // ==> call DPrecAlign equivalent since 2015/10/31 + + return fPrecAlign->DeformedLocalPoint( aPlaneCoordinate); + +// DR3 aDeformedPoint = aPlaneCoordinate; +// double unorm = aPlaneCoordinate(0); +// aDeformedPoint += DR3( 0., 0., fTool.CLof7LegendrePol( &unorm, fUDeformationCoef) ); +// double vnorm = aPlaneCoordinate(1); +// aDeformedPoint += DR3( 0., 0., fTool.CLof7LegendrePol( &vnorm, fVDeformationCoef) ); +// if(fDebugPlane) { +// printf("DPlane::DeformedLocalPoint plane %d deformation applied.\n", fPlaneNumber); +// printf(" from: %.1f, %.1f, %1.f to %.1f, %.1f, %1.f\n", aPlaneCoordinate(0), aPlaneCoordinate(1), aPlaneCoordinate(2), aDeformedPoint(0), aDeformedPoint(1), aDeformedPoint(2)); +// } +// +// return aDeformedPoint; +} + + +//______________________________________________________________________________ +// +DR3 DPlane::PlaneToTracker(DR3& aPlaneCoordinate){ + + // converts a point given in the Plane coordinate sytem (f-system) UVW + // to the tracker coordinate system (e-system) XYZ. + // + // JB 2010/11/25 + // Modified: JB 2014/04/21 for potential deformation + // => cancelled, since taken care of DPrecAlign since 2015/10/31 + + return fPrecAlign->TransformHitToTracker( aPlaneCoordinate); + + // Not useful anymore since taken care into DPrecAlign directly + // // Take into account deformation if required + // DR3 aPoint = aPlaneCoordinate; + // if( fIfDeformation ) { + // DR3 aPoint = DeformedLocalPoint( aPlaneCoordinate); + // if (fDebugPlane) { + // printf("DPlane::PlaneToTracker plane %d deformation applied.\n", fPlaneNumber); + // printf(" from: %.1f, %.1f, %1.f to %.1f, %.1f, %1.f\n", aPlaneCoordinate(0), aPlaneCoordinate(1), aPlaneCoordinate(2), aPoint(0), aPoint(1), aPoint(2)); + // } + // } + // return fPrecAlign->TransformHitToTracker( aPoint); + +} + + +//______________________________________________________________________________ +// +DR3 DPlane::TrackerToPlane(DR3& aTrackerCoordinate){ + + // From a 3D point in the tracker coordinates (e-system) (X,Y,Z), + // compute the same 3D point in the plane coordinates (f-system) (U,V, Z) + // Note that no deformation is taken into account here, + // as if the tracker coordinate is the intersection of a track + // with the plane at normal incidence. + // -> If you need for a general track-plane intersection mechanism, + // use DPlane::Intersection( DTrack *aTrack) + // + // JB 2010/11/25 + + return fPrecAlign->TransformHitToPlane( aTrackerCoordinate); + +} + + +//_____________________________________________________________________________ + +DR3 DPlane::Intersection(DTrack *aTrack) { + + // Return the intersection of a track with this plane in the Plane frame. + // If required, take into account deformation: + // 1) get the intersection of the track with the plane considered flat, + // 2) use intersection(u,v) to get the deformation height from the parametrisation, + // 3) add this height to the intersection(w) = new(w) + // 4) compute new(u,v) from the new(w) and the track slope + // + // Use new DPrecAlign mechanism, JB 2010/11/25 + // Modified: JB 2014/04/21, take into account deformation + // => cancelled, since taken care of DPrecAlign since 2015/10/31 + + DR3 aFlatPoint = fPrecAlign->TransformTrackToPlane( aTrack->GetLinearFit().GetOrigin()(0), aTrack->GetLinearFit().GetOrigin()(1), aTrack->GetLinearFit().GetOrigin()(2), aTrack->GetLinearFit().GetSlopeZ()(0), aTrack->GetLinearFit().GetSlopeZ()(1)); + + return aFlatPoint; + + // the following is now useless since deformation taken care in DPrecAlign + + // Deformation + // if( fIfDeformation ) { + // DR3 aDeformedPoint = DeformedLocalPoint( aFlatPoint); + // DR3 trackSlopeInPlane = fPrecAlign->RotateToPlane( aTrack->GetLinearFit().GetSlopeZ() ); + // if (fDebugPlane) { + // printf("DPlane::Intersection plane %d deformation applied.\n", fPlaneNumber); + // printf(" from: %.1f, %.1f, %1.f to %.1f, %.1f, %1.f\n", aFlatPoint(0), aFlatPoint(1), aFlatPoint(2), aDeformedPoint(0), aDeformedPoint(1), aDeformedPoint(2)); + // } + // Double_t deltaZU = aDeformedPoint(2)/tan(fc->GetPlanePar(fPlaneNumber).Tilt(1)) - aFlatPoint(2); + // Double_t deltaZV = (aDeformedPoint(2) -aFlatPoint(2));///tan(fc->GetPlanePar(fPlaneNumber).Tilt(0)); + // if((fc->GetPlanePar(fPlaneNumber).Tilt(2)*180./M_PI) < 180. && abs(fc->GetPlanePar(fPlaneNumber).Tilt(2)*180./M_PI) > 175. ) { + // aDeformedPoint -= DR3( trackSlopeInPlane(0)*deltaZU, trackSlopeInPlane(1)*deltaZV, 0.); + // } + // else{ + // aDeformedPoint += DR3( trackSlopeInPlane(0)*deltaZU, trackSlopeInPlane(1)*deltaZV, 0.); + // } + // // Double_t deltaZ = aDeformedPoint(2)-aFlatPoint(2); + // //aDeformedPoint += DR3( (trackSlopeInPlane(0))*deltaZ, trackSlopeInPlane(1)*deltaZ, 0.); + // if (fDebugPlane) { + // printf(" then with deltaZ=(%.1f,%.1f) and thetaPlane=%.1f to %.1f, %.1f, %1.f\n", deltaZU, deltaZV, fc->GetPlanePar(fPlaneNumber).Tilt(2)*180./M_PI, aDeformedPoint(0), aDeformedPoint(1), aDeformedPoint(2)); + // } + // return aDeformedPoint; + // } + // + // // No deformation (= flat plane) + // else { + // return aFlatPoint; + // } + +} + + +//______________________________________________________________________________ +// +void DPlane::SetPositionU(Float_t posU) +{ + fPositionU = posU; +} + +void DPlane::SetPositionV(Float_t posV) +{ + fPositionV = posV; +} + +void DPlane::SetPositionZ(Float_t posZ) +{ + (*fPosition)(2) = posZ; +} + +void DPlane::SetTiltW(Float_t tiltW) +{ + fTiltW = tiltW; +} + +void DPlane::ChangePositionByOffset(DR3& offset) +{ + //VR 2014/06/29 + *fPosition+=offset; + fPrecAlign->SetTranslation( *fPosition); +} + +void DPlane::ChangePositionByValue(DR3& newvalue) +{ + //VR 2014/06/29 + *fPosition=newvalue; + fPrecAlign->SetTranslation( *fPosition); +} + +void DPlane::ChangeTiltByOffset(DR3& offset) +{ + //VR 2014/06/29 + *fTilt+=offset; + fPrecAlign->SetRotations( *fTilt); +} + +void DPlane::ChangeTiltByValue(DR3& newvalue) +{ + //VR 2014/06/29 + *fTilt=newvalue; + fPrecAlign->SetRotations( *fTilt); +} + +void DPlane::PrintPosition(void) +{ + //VR 2014/06/29 + cout << " PositionX = " << (*fPosition)(0)/1000 << " ; PositionY = " << (*fPosition)(1)/1000 << " ; PositionZ = " << (*fPosition)(2)/1000 << " [mm]" << endl; +} + +void DPlane::PrintTilt(void) +{ + //VR 2014/06/29 + cout << " TiltX = " << -TMath::RadToDeg()*(*fTilt)(2) << " ; TiltY = " << -TMath::RadToDeg()*(*fTilt)(1) << " ; TiltZ = " << -TMath::RadToDeg()*(*fTilt)(0) << " [°]" << endl; +} + + + +//______________________________________________________________________________ +// +/* + DR3 DPlane::Rotate_PlaneToTracker(DR3& aPlaneCoordinate){ + + // functions deprecated USE NEW DPRECALIGN MECHANISM (JB 2010/11/25) + + // converts a point given in the Plane coordinate sytem (f-system) + // to the tracker coordinate system (e-system). + // For that consider the position of the plane in the e-system + // and the tilting angle(s) in the e-system. + // The transformation rotates u,v,w using the rotation matrix + // which gives a point in the e-system. Later the position of the Plane + // in the e-system can be added. + // result = postion(of Plane in e-system) + rotation(of point given in f-system) + // the rotation matrix rot_ij is defined via the unit vectors e_j for the + // e-system and f_k for the f-system: + // rot_jk = e_j * f_k ; * is inner product between both vectors + // 980110: just implement one angle, rotation around z-axis, + // one can generalize later for three angle rotation with e.g. euler angles + + DR3 rot[3]; + DR3 hp; // position in xyz coordinates + + Float_t c[3]; + Float_t s[3]; + + for(Int_t i=0 ; i<3 ; i++) { + c[i] = cos((*fTilt)(i)) ; + s[i] = sin((*fTilt)(i)) ; + } + + rot[0].SetValue( c[0]*c[2] + s[0]*s[1]*s[2] , + s[0]*c[2] - c[0]*s[1]*s[2] , + c[1]*s[2] ); + + rot[1].SetValue(-s[0]*c[1] , + c[0]*c[1] , + s[1] ); + + rot[2].SetValue(-s[2]*c[0] + s[0]*s[1]*c[2] , + -s[2]*s[0] - c[0]*s[1]*c[2] , + c[1]*c[2] ); + + + rot[0] *= aPlaneCoordinate(0); + rot[1] *= aPlaneCoordinate(1); + rot[2] *= aPlaneCoordinate(2); + + hp = rot[0]; + hp += rot[1]; + hp += rot[2]; + + + return hp; + } + */ +//______________________________________________________________________________ +// +/* + DR3 DPlane::Rotate_TrackerToPlane(DR3& aTrackerCoordinate){ + + // functions deprecated USE NEW DPRECALIGN MECHANISM (JB 2010/11/25) + + // From a 3D point in the tracker coordinates (e-system) (X,Y,Z), + // compute the same 3D point in the plane coordinates (f-system) (U,V, Z) + // WITHOUT OFFSET !!! + // + // irot is the inverted matrix to rot (see above) + + DR3 hp(aTrackerCoordinate); // hit position in Tracker Coordinates (X,Y,Z) + DR3 irot[3]; // this is the rotation matrix + + + Float_t c[3]; + Float_t s[3]; + + for(Int_t i=0 ; i<3 ; i++) { + c[i] = cos((*fTilt)(i)) ; + s[i] = sin((*fTilt)(i)) ; + } + + irot[0].SetValue( c[0]*c[2] + s[0]*s[1]*s[2] , + -s[0]*c[1] , + -s[2]*c[0] + s[0]*s[1]*c[2] ); + + irot[1].SetValue( s[0]*c[2] - c[0]*s[1]*s[2] , + c[0]*c[1] , + -s[2]*s[0] - c[0]*s[1]*c[2] ); + + irot[2].SetValue( c[1]*s[2] , + s[1] , + c[1]*c[2] ); + + irot[0] *= hp(0); + irot[1] *= hp(1); + irot[2] *= hp(2); + + hp = irot[0]; + hp += irot[1]; + hp += irot[2]; + + return hp; + } + */ +//______________________________________________________________________________ +// +void DPlane::AddMCGeneratedHit(DR3 aPosition,DR3 aResolution,Int_t hitMC) +{ + + if(fHitsN == fHitMax) { + cout << endl; + cout << "Number of hits " << fHitsN << " is at maximum " << fHitMax << endl; + cout << "Doing nothing!!!" << endl; + cout << endl; + } + + fHit[fHitsN]->SetHitPosition(aPosition,aResolution); + fHit[fHitsN]->SetMCHitID(hitMC); + fHitsN++; + + return; + +} +//______________________________________________________________________________ +// +Int_t DPlane::Compare( const TObject * obj) const { + // QL 04/06/2016 + // to enable Sort method in a TList + // Sorted by comparing zPosition of the plane center + + if (this == obj) + return 0; + DR3 posThis = *fPosition; + DR3 posObj = ((DPlane*)obj)->GetPosition(); + if (posThis(2) > posObj(2)) + return 1; + else + return -1; +} +//______________________________________________________________________________ +// +void DPlane::Print(const Option_t*) const +{ + printf("Plane %i ", fPlaneNumber); + fPosition->Print(); + +} +//______________________________________________________________________________ +// +void DPlane::GetHitResolution(int col, int lin, int ClusterMult,TVector2 &HitResolution) +{ + + //AP 2016/07/27: Function to find the hit resolution depending on it position in plane + + int MyClusterMult = ClusterMult; + + int idx_reg = GetRegion(col,lin); + //Once the region is found look if there is a multiplicity dependent resolution in the region + if(fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].ResolutionU.size() > 0) { + //Get the cluster multiplicity + if(MyClusterMult > int(fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].ResolutionU.size())) { + //If cluster multiplicity is higher than the multiplicity dependent resolution list, use the las entry to set up the resolutions on U and V + MyClusterMult = fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].ResolutionU.size(); + } + HitResolution.Set(fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].ResolutionU[ClusterMult-1], + fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].ResolutionV[ClusterMult-1]); + } + else if(fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].GlobalPlaneResolutionU != -1) { + //There is defined a global resolution in the region different for U and V + HitResolution.Set(fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].GlobalPlaneResolutionU, + fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].GlobalPlaneResolutionV); + } + else if(fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].GlobalPlaneResolution != -1) { + //There is defined a global resolution in the region the same for U and V + HitResolution.Set(fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].GlobalPlaneResolution, + fc->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].GlobalPlaneResolution); + } + else { + cout << endl; + cout << "ERROR: No resolution defined for region " << idx_reg+1 << " of plane " << fPlaneNumber << ". Check your inputs. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + return; + +} +//______________________________________________________________________________ +// +int DPlane::GetRegion(int col, int lin) +{ + //AP 2016/07/27: Function returns the regions index for position col,lin + int idx_reg = 0; + + for(int ireg=0;iregGetSetup()->GetPlanePar(fPlaneNumber).PlanePerformancesList.size());ireg++) { + //There is a list of regions in which the resolution is defined. + //Get the region in which the hit is in. + //If the (col,lin) is in no region, use the multiplicity dependent resolution of region 0 + if(col >= fSession->GetSetup()->GetPlanePar(fPlaneNumber).PlanePerformancesList[ireg].Region.R_col[0] && + col <= fSession->GetSetup()->GetPlanePar(fPlaneNumber).PlanePerformancesList[ireg].Region.R_col[1] && + lin >= fSession->GetSetup()->GetPlanePar(fPlaneNumber).PlanePerformancesList[ireg].Region.R_lin[0] && + lin <= fSession->GetSetup()->GetPlanePar(fPlaneNumber).PlanePerformancesList[ireg].Region.R_lin[1]) { + idx_reg = ireg; + break; + } + } + + return idx_reg; + +} +//______________________________________________________________________________ +// +int DPlane::GenerateMCMultiplicity(int col, int lin) +{ + //AP 2016/07/27: Function to generate a MC multiplicity based in measurements + + int ClusterMult = -999; + int idx_reg = GetRegion(col,lin); + if(fSession->GetSetup()->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].ResolutionU.size() > 0) { + double prob = rand->Uniform(0.0,1.0); + for(int imult=0;imultGetSetup()->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].MultProbCumul.size());imult++) { + if(prob <= fSession->GetSetup()->GetPlanePar(fPlaneNumber).PlanePerformancesList[idx_reg].MultProbCumul[imult]) ClusterMult = imult+1; + break; + } + } + + return ClusterMult; + +} +//______________________________________________________________________________ +// +void DPlane::MCHitsTruthMatching(void) +{ + + //AP 2016/07/27: Function to perform the truth matching of the reconstructed hits + + for(int ihit=0;ihitDoHitTruthMatching(fHit[ihit],MCHitID,NpixelsMCHitID); + + fHit[ihit]->SetMCHitID(MCHitID); + fHit[ihit]->SetStripsFromMCHitID(NpixelsMCHitID); + } + + return; + +} +//______________________________________________________________________________ +// +void DPlane::CheckNonDigitizedMCHits(void) +{ + //AP 2016/07/27: In case there are non digitized hits in this plane, this function generate a hit by smearing with the plane sigma_sp + + // Loop over all the particles in event + //cout << endl; + //cout << "Plane " << fPlaneNumber << endl; + //cout << "Nparticles = " << MCInfoHolder->GetNSimParticles() << endl; + for(int ipart=0;ipartGetNSimParticles();ipart++) { + int FirstHitIdx = MCInfoHolder->GetASimParticle(ipart).FirstHitIdx; + // Loop over all the hits of this particle + for(int ihit=0;ihitGetASimParticle(ipart).NHits;ihit++) { + //Check that the hit has not being digitized + if(MCInfoHolder->GetASimHit(FirstHitIdx + ihit).Npixels != -1) continue; + + //Check that the hit is on the current plane + if(fPlaneNumber != MCInfoHolder->GetASimHit(FirstHitIdx + ihit).sensorID+1) continue; + + //Get the hit local position + double u = MCInfoHolder->GetASimHit(FirstHitIdx + ihit).PosAveUVmm.X()*1.0e+3; + double v = MCInfoHolder->GetASimHit(FirstHitIdx + ihit).PosAveUVmm.Y()*1.0e+3; + + //Get the closest pixel to this poistion + double col, row; + ComputeStripPosition_UVToColRow(u,v,col,row); + + //Generate a cluster multiplicity from measurement if available + int ClusterMult = GenerateMCMultiplicity(col,row); + + //Get a hit resolution based on its position and multiplicity + TVector2 MyHitResolution(0.0,0.0); + GetHitResolution(col,row,ClusterMult,MyHitResolution); + + //Now will smear the position + double u_rec, v_rec; + u_rec = rand->Gaus(u,MyHitResolution.X()); + v_rec = rand->Gaus(v,MyHitResolution.Y()); + + //Add this hit to the list of hits + DR3 HitPosition(u_rec,v_rec,0.0); + DR3 HitResolution(MyHitResolution.X(),MyHitResolution.Y(),0.0); + AddMCGeneratedHit(HitPosition,HitResolution,FirstHitIdx + ihit); + + //cout << "hit " << ihit+1 << " of particle " << ipart+1 << " of this event was not digitized." + // << " Adding a hit with position (u,v) = (" << HitPosition(0) << "," << HitPosition(1) << ") um, and resolution (" << HitResolution(0) << "," << HitResolution(1) << ") um" + // << endl; + + } + } + //cout << endl; + + return; + +} +//______________________________________________________________________________ +// diff --git a/src/DPrecAlign.cxx b/src/DPrecAlign.cxx new file mode 100644 index 0000000..1243058 --- /dev/null +++ b/src/DPrecAlign.cxx @@ -0,0 +1,1600 @@ +// @(#)maf/dtools:$Name: $:$Id: DPrecAlign.cxx,v.3 2005/10/02 18:03:46 sha Exp $ +// Author : G.Orazi 1/2/2000 +//////////////////////////////////////////////////////////////////////// +// Class Description of DPrecAlign // +// // +// This class stores the precise alignement of a plane. +// 6 parameters are used: 3 for translations and 3 for rotations. +// +// Notations: +// Telescope or tracker frame coordinates = XYZ +// Plane frame coordinates = UVW +// +// Transformations from one from to the other are : +// XYZ = InverseRotation of (UVW) - Translations +// UVW = Rotation of ( XYZ - Translations) +// +// Parameters: +// - translation vector is _fTr[3] (in micrometers) +// these coordinates are given in the tracker frame. +// - rotation angles vector _fTh[3] (in radian) +// rotations around the following axis 0=z 1=y' 2=x". +// // +// Standard usage: +// - First set the alignment parameters with // +// SetTranslation( tx, ty, tz) // +// SetRotations( thz, thx, thy) // +// - Transformation hit coordinates from plane frame // +// to tracker frame with: // +// DR3 hit_x = TransformHitToTracker(DR3 hit_u); // +// - Transformation track coordinated from plane frame // +// to tracker frame with: // +// DR3 track_u = TransformTrackToPlane( Double_t tx, Double_t ty, Double_t tz, Double_t tdx, Double_t tdy); // +// - if the alignment parameters are relative to another alignment (refAlign), +// the absolute alignment (wrt the tracker) can be obtained with +// ConvoluteAlignment( DPRecAlign *refAlign) +// +// For alignment purpose when a minimization is required: +// - Accumulate pairs of matching hit-track with +// NewData(Double_t auh,Double_t avh,Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy) +// // +// // +///////////////////////////////////////////////////////////////////////// +//*-- Modified : LC 2015/01/.. New definition of matrices, Convolute Alignement, calculate planes, decompose rotation --> Method 1 +//*-- Modified : LC 2015/01/.. Previous matrices was the transpose matrices. +//*-- Modified : LC 2015/01/.. New definition return good matrices elements for global alignment. +//*-- Modified : LC 2014/12/05 DecomposeRotations() -> cuts removed (bad tilts with ConvoluteAlignment) +//*-- Modified : JB 2014/02/17 ConvoluteAlignment, CopyAlignment +//*-- Modified : JB 2012/09/05 add method to reset datapoints +//*-- Modified : JB 2012/07/16 bug fix in CalculatePlane +//*-- Modified : JB 2012/05/04 new method to compute plane equation +//*-- Modified : JB 2011/10/27 names _A/B/C replaced by _A/B/Ccoeff +//*-- Modified : JB 2011/07/25 Translation sign changed to match plane correct position +//*-- Modified : JB 2011/04/04 add rotation decomposition & correct rotation convolution +//*-- Modified : JB 2010/11/25 overloaded method Set and new rotation methods +//*-- Modified : JB 2010/09/08 Compute the plane equation properly with the Z translation +//*-- Modified : JB 2010/09/01 to include rotation matrix for Plane->Tracker +//*-- Author : G.Orazi 1/2/2000 +#include "Riostream.h" +#include +//*KEEP,DPrecAlign. +#include "DPrecAlign.h" +#include "DR3.h" +#include "TMath.h" +ClassImp(DataPoints) +ClassImp(DPrecAlign) +//______________________________________________________________________________ +// +DataPoints::~DataPoints() +{ + // DataPoints default destructor +} +//______________________________________________________________________________ +// +DataPoints::DataPoints(Double_t auh,Double_t avh, + Double_t aresU,Double_t aresV, + Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy) +{ + _uh = auh ; + _vh = avh ; + _resU = aresU ; + _resV = aresV ; + _tx = atx ; + _ty = aty ; + _tz = atz ; + _tdx = atdx ; + _tdy = atdy ; +} +//______________________________________________________________________________ +// +void DataPoints::Set(Double_t auh,Double_t avh, + Double_t aresU,Double_t aresV, + Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy) +{ + _uh = auh ; + _vh = avh ; + _resU = aresU ; + _resV = aresV ; + _tx = atx ; + _ty = aty ; + _tz = atz ; + _tdx = atdx; + _tdy = atdy; +} +//______________________________________________________________________________ +// +void DataPoints::PrintData() +{ + printf("DataPoint: hit: u=%f v=%f\n res: resU=%f resV=%f\n track: x=%f y=%f z=%f dx/dz=%f dy/dz=%f\n", + _uh,_vh, + _resU,_resV, + _tx,_ty,_tz,_tdx,_tdy); +} +//______________________________________________________________________________ +// +DR3 DataPoints::GetHitPosition() +{ + DR3 tmp(_uh,_vh,0.0); + return tmp ; +} +//______________________________________________________________________________ +// +DR3 DataPoints::GetHitResolution() +{ + DR3 tmp(_resU,_resV,0.0); + return tmp; +} +//______________________________________________________________________________ +// +DR3 DataPoints::GetTrackOrigin() +{ + DR3 tmp(_tx,_ty,_tz); + return tmp ; +} +//______________________________________________________________________________ +// +DR3 DataPoints::GetTrackDirection() +{ + DR3 tmp(_tdx,_tdy,1.); + return tmp ; +} +//______________________________________________________________________________ +// +DPrecAlign::DPrecAlign(const DPrecAlign &aobj) +{ + + cout << "WARNING: copy constructor of DPrecAlign does nothing !!!" << endl; + +} +//______________________________________________________________________________ +// +DPrecAlign::DPrecAlign( Int_t method ) +{ + SetDebug(0); + if(fDebugDPrecAlign) cout << "DPrecAlign constructor" << endl; + DPrecAlignMethod = method; + _fIfDeformation = 0; + +} + +//______________________________________________________________________________ +// +DPrecAlign::DPrecAlign() +{ + SetDebug(0); + if(fDebugDPrecAlign) cout << "DPrecAlign constructor : BEWARE Method 0 !!!" << endl; + DPrecAlignMethod = 0; + _fIfDeformation = 0; +} + +//______________________________________________________________________________ +// +DPrecAlign::~DPrecAlign() +{ + // DPrecAlign default destructor +} +//______________________________________________________________________________ +// +void DPrecAlign::NewData(Double_t auh,Double_t avh, + Double_t aresU,Double_t aresV, + Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy) +{ + _data.Add( (new DataPoints(auh,avh, + aresU,aresV, + atx,aty,atz,atdx,atdy)) ) ; +} +//______________________________________________________________________________ +// +void DPrecAlign::NewData1(DataPoints* myDataPoint) +{ + _data1.Add( myDataPoint ) ; +} +//______________________________________________________________________________ +// +void DPrecAlign::NewData(DataPoints* myDataPoint) +{ + _data.Add( myDataPoint ) ; +} +//______________________________________________________________________________ +// +void DPrecAlign::RemoveData(DataPoints* myDataPoint) +{ + _data.Remove(myDataPoint); +} +//______________________________________________________________________________ +// +void DPrecAlign::RemoveData1(DataPoints* myDataPoint) +{ + _data1.Remove(myDataPoint); +} +/* +//______________________________________________________________________________ +// +void DPrecAlign::NewMiniVector(DTrack* myMV) +{ + _dataMV.Add( myMV ) ; +} +//______________________________________________________________________________ +// +void DPrecAlign::NewMiniVector1(DTrack* myMV1) +{ + _dataMV1.Add( myMV1 ) ; +} +//______________________________________________________________________________ +// +void DPrecAlign::RemoveMiniVector(DTrack* myMV) +{ + _dataMV.Remove(myMV); +} +//______________________________________________________________________________ +// +void DPrecAlign::RemoveMiniVector1(DTrack* myMV1) +{ + _dataMV1.Remove(myMV1); +} +*/ +//______________________________________________________________________________ +// +void DPrecAlign::ListDataPoints() +{ + cout<< "Listing data..." << endl; + DataPoints *current ; + current = (DataPoints*) _data.First(); + + //DTrack* miniVector; + //miniVector = (DTrack*) _dataMV1.First(); + + while(current) { + current->PrintData() ; + //miniVector->GetHit(1)->GetPositionCG()->Print(); + current=(DataPoints*) _data.After(current) ; + //miniVector = (DTrack*) _dataMV1.After(miniVector); + } +} +//______________________________________________________________________________ +// +Int_t DPrecAlign::DataSize() +{ + return _data.GetSize(); +} +//______________________________________________________________________________ +// +Int_t DPrecAlign::DataSize1() +{ + return _data1.GetSize(); +} +/* +//______________________________________________________________________________ +// +Int_t DPrecAlign::DataSizeMV() +{ + return _dataMV.GetSize(); +} +//______________________________________________________________________________ +// +Int_t DPrecAlign::DataSizeMV1() +{ + return _dataMV1.GetSize(); +} +*/ +//______________________________________________________________________________ +// +void DPrecAlign::SetInitialRotations() +{ + //initialRotations = new Double_t[3]; + for(Int_t i=0; i<3; ++i) _initialRotations[i] = _fTh[i]; +} +//______________________________________________________________________________ +// +void DPrecAlign::SetInitialPosition() +{ + //initialPosition = new Double_t[3]; + for(Int_t i=0; i<3; ++i) _initialPosition[i] = _fTr[i]; +} +//______________________________________________________________________________ +// +void DPrecAlign::SetRotations(Double_t th0,Double_t th1,Double_t th2) +{ + //th0, th1, th2 : Rotation angles around z, y' and x" axis + + // printf("Setting Rotations... %11f %11f %11f\n",th0,th1,th2); + // cout << "th0= " << th0/3.1415*180. << endl; + // cout << "th1= " << th1/3.1415*180. << endl; + // cout << "th2= " << th2/3.1415*180. << endl; + + _fTh[0]= th0 ; + _fTh[1]= th1 ; + _fTh[2]= th2 ; + ComputeRotationMatrix() ; + CalculatePlane(); +} +//______________________________________________________________________________ +// +void DPrecAlign::SetRotations(DR3 tilt) +{ + //tilt[0], tilt[1], tilt[2] should be the rotation angles around the z, y' and x" axis + // JB 2010/11/25 + + SetRotations( tilt(0), tilt(1), tilt(2)); +} +//______________________________________________________________________________ +// +void DPrecAlign::SetTranslation(Double_t t0,Double_t t1,Double_t t2 ) +{ + // Sets a translation + + //printf("translation: \n") ; + //printf("translation: %f %f %f \n",t0, t1, t2) ; + _fTr[0]=t0 ; + _fTr[1]=t1 ; + _fTr[2]=t2 ; + //printf("DPrec::SetTranslation to %f %f %f \n",_fTr[0], _fTr[1], _fTr[2]) ; +} +//______________________________________________________________________________ +// +void DPrecAlign::SetTranslation(DR3 tr) +{ + //tr[0], tr[1], tr[2] should be the translation along the x y z axis + // JB 2010/11/25 + + SetTranslation( tr(0), tr(1), tr(2)); +} +//______________________________________________________________________________ +// +void DPrecAlign::CopyAlignment( DPrecAlign *anAlign) +{ + // Copy the alignment parameters of anAlign, + // and recompute everything. + // + // JB 2014/02/17 + DPrecAlignMethod = anAlign->GetDPrecAlignMethod(); + SetTranslation( anAlign->GetTranslation()[0], anAlign->GetTranslation()[1], anAlign->GetTranslation()[2]); + SetRotations( anAlign->GetRotations()[0], anAlign->GetRotations()[1], anAlign->GetRotations()[2]); +} + +//______________________________________________________________________________ +// +void DPrecAlign::SetDeformation( Double_t *coeffU, Double_t *coeffV) +{ + // Define deformation parameters + // JB 2015/10/31 + + if( coeffU!=NULL) { + _fIfDeformation = 1; + for ( int i=0; i<8; i++) { + _fUDeformationCoef[i] = coeffU[i]; + } + } + + if( coeffV!=NULL) { + _fIfDeformation = 1; + for ( int i=0; i<8; i++) { + _fVDeformationCoef[i] = coeffV[i]; + } + } + + PrintDeformations(); + +} + +//______________________________________________________________________________ +// +void DPrecAlign::ComputeRotationMatrix() +{ + //Compute the rotation matrix from Tracker frame to Plane Frame + // alpha is the rotation around z + // beta is the rotation around y' + // gamma is the rotation around x" + // final matrix is gamma*beta*alpha + // + // This method is called when the rotation angles are set + // with SetRotations( thz, thy, thx). + // + // Matrix element expression assuming: + // ca = cos(alpha), sb=sin(beta), cg/sg=cos/sin(gamma) + // + // ca.cb cb.sa -sb + // ca.sb.sg-sa.sg sa.sb.sg+ca.cg cb.sg + // ca.sb.cg-sa.sg sa.sb.cg-ca.sg cb.cg + + if(DPrecAlignMethod==0) { + + //cout << "computing rotation matrix..." << endl; + Double_t c[3] ; + Double_t s[3] ; + for (Int_t i=0 ; i<3 ; i++){ + c[i]=cos(_fTh[i]); + s[i]=sin(_fTh[i]); + } + // Three rotation matrices: + _alpha[0][0] = c[0]; + _alpha[0][1] = s[0]; + _alpha[0][2] = 0.; + _alpha[1][0] = -s[0]; + _alpha[1][1] = c[0]; + _alpha[1][2] = 0.; + _alpha[2][0] = 0.; + _alpha[2][1] = 0.; + _alpha[2][2] = 1.; + // + _beta[0][0] = c[1]; + _beta[0][1] = 0.; + _beta[0][2] = -s[1]; + _beta[1][0] = 0.; + _beta[1][1] = 1.; + _beta[1][2] = 0.; + _beta[2][0] = s[1]; + _beta[2][1] = 0.; + _beta[2][2] = c[1]; + // + _gamma[0][0] = 1.; + _gamma[0][1] = 0.; + _gamma[0][2] = 0.; + _gamma[1][0] = 0.; + _gamma[1][1] = c[2]; + _gamma[1][2] = s[2]; + _gamma[2][0] = 0.; + _gamma[2][1] = -s[2]; + _gamma[2][2] = c[2]; + // + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _rotmat[i][j] = 0.; + for (Int_t l=0; l<3; l++) { + for (Int_t k=0; k<3; k++) _rotmat[i][j]+=_gamma[i][l]*_beta[l][k]*_alpha[k][j]; + } + } + } + } // end if Method 0 + + if(DPrecAlignMethod==1) { + + Double_t angle_x = +_fTh[2]; // Horaire (-) Anti-Horaire (+) + Double_t angle_y = +_fTh[1]; + Double_t angle_z = +_fTh[0]; + + Double_t A = cos(angle_x); + Double_t B = sin(angle_x); + Double_t C = cos(angle_y); + Double_t D = sin(angle_y); + Double_t E = cos(angle_z); + Double_t F = sin(angle_z); + + Double_t AD = A*D; + Double_t BD = B*D; + + // Rotation X,Y,Z : + _rotmat[0][0] = C*E; + _rotmat[0][1] = BD*E - A*F; + _rotmat[0][2] = AD*E + B*F; + _rotmat[1][0] = C*F; + _rotmat[1][1] = BD*F + A*E; + _rotmat[1][2] = AD*F - B*E; + _rotmat[2][0] = -D; + _rotmat[2][1] = B*C; + _rotmat[2][2] = A*C; + + /* + // Rotation Z,Y,X + _rotmat[0][0] = C*E; + _rotmat[0][1] = -C*F; + _rotmat[0][2] = D; + _rotmat[1][0] = BD*E + A*F; + _rotmat[1][1] = -BD*F + A*E; + _rotmat[1][2] = -B*C; + _rotmat[2][0] = -AD*E + B*F; + _rotmat[2][1] = AD *F + B*E; + _rotmat[2][2] = A*C; + */ + } + + ComputeTorationMatrix(); // JB 2010/09/08 + //PrintRotationMatrix(); +} +//______________________________________________________________________________ +// +void DPrecAlign::ComputeTorationMatrix() +{ + //Compute the rotation matrix from Plane frame to Tracker Frame + // ahpla is the inverse rotation around z + // ateb is the inverse rotation around y + // ammag is the inverse rotation around x + // final matrix is ammag*ateb*ahpla + // + // This method is called when the rotation matrix is computed + // with ComputeRotationMatrix(). + // + // Created: JB 2010/09/03 + if(DPrecAlignMethod==0) { + + // cout << "computing rotation matrix..." << endl; + Double_t c[3] ; + Double_t s[3] ; + for (Int_t i=0 ; i<3 ; i++){ + c[i]=cos(_fTh[i]); + s[i]=sin(_fTh[i]); + } + // Three rotation matrices: + _ahpla[0][0] = c[0]; + _ahpla[0][1] = -s[0]; + _ahpla[0][2] = 0.; + _ahpla[1][0] = s[0]; + _ahpla[1][1] = c[0]; + _ahpla[1][2] = 0.; + _ahpla[2][0] = 0.; + _ahpla[2][1] = 0.; + _ahpla[2][2] = 1.; + // + _ateb[0][0] = c[1]; + _ateb[0][1] = 0.; + _ateb[0][2] = s[1]; + _ateb[1][0] = 0.; + _ateb[1][1] = 1.; + _ateb[1][2] = 0.; + _ateb[2][0] = -s[1]; + _ateb[2][1] = 0.; + _ateb[2][2] = c[1]; + // + _ammag[0][0] = 1.; + _ammag[0][1] = 0.; + _ammag[0][2] = 0.; + _ammag[1][0] = 0.; + _ammag[1][1] = c[2]; + _ammag[1][2] = -s[2]; + _ammag[2][0] = 0.; + _ammag[2][1] = s[2]; + _ammag[2][2] = c[2]; + // + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _tormat[i][j] = 0.; + for (Int_t l=0; l<3; l++) { + for (Int_t k=0; k<3; k++) _tormat[i][j]+=_ahpla[i][l]*_ateb[l][k]*_ammag[k][j]; + } + } + } + } // end if Method 0 + + if(DPrecAlignMethod==1) { + + Double_t angle_x = -_fTh[2]; // (+) Anti-Horaire (-) Horaire + Double_t angle_y = -_fTh[1]; + Double_t angle_z = -_fTh[0]; + + Double_t A = cos(angle_x); + Double_t B = sin(angle_x); + Double_t C = cos(angle_y); + Double_t D = sin(angle_y); + Double_t E = cos(angle_z); + Double_t F = sin(angle_z); + + Double_t AD = A*D; + Double_t BD = B*D; + + // Rotation Z,Y,X + + _tormat[0][0] = C*E; + _tormat[0][1] = -C*F; + _tormat[0][2] = D; + _tormat[1][0] = BD*E + A*F; + _tormat[1][1] = -BD*F + A*E; + _tormat[1][2] = -B*C; + _tormat[2][0] = -AD*E + B*F; + _tormat[2][1] = AD *F + B*E; + _tormat[2][2] = A*C; + + /* + // Rotation X,Y,Z + _tormat[0][0] = C*E; + _tormat[0][1] = BD*E - A*F; + _tormat[0][2] = AD*E + B*F; + _tormat[1][0] = C*F; + _tormat[1][1] = BD*F + A*E; + _tormat[1][2] = AD*F - B*E; + _tormat[2][0] = -D; + _tormat[2][1] = B*C; + _tormat[2][2] = A*C; + */ + } + +} +//______________________________________________________________________________ +// +void DPrecAlign::CalculatePlane() +{ + // A,B and C are parameters of the plane: z+Ax+By+C=0 + // + // This method is called when the rotation angles are set + // with SetRotations( thz, thy, thx), just after the rotation matrix + // has been calculated. + // + // The original method crashed in certain cases and was replaced by a + // more robust computation. +/* + // Original method by G.Orazi + // e0,e1 and e2 are points that determine the plane + // we start with the original plane in the UVW frame, + // then rotate it into the XYZ frame and find the A,B and C params + // of the rotated plane + DR3 e00(0.,0.,0.); + DR3 e10(1.,0.,0.); + DR3 e20(0.,1.,0.); + DR3 e0 = TransformHitToTracker(e00); + DR3 e1 = TransformHitToTracker(e10); + DR3 e2 = TransformHitToTracker(e20); + _Bcoeff=((e2(2)-e1(2))*e0(0)+(e0(2)-e2(2))*e1(0)+(e1(2)-e0(2))*e2(0))/ + ((e0(0)-e1(0))*(e1(1)-e2(1))+(e0(1)-e1(1))*(e2(0)-e1(0))); + _Ccoeff=(_Bcoeff*(e0(1)*e1(0)-e0(0)*e1(1))-e0(0)*e1(2)+e1(0)*e1(2)+e0(2)*e1(0)-e1(2)*e1(0))/(e0(0)-e1(0)); + _Acoeff=(-e0(2)+e1(2)-_Bcoeff*(e0(1)-e1(1)))/(e0(0)-e1(0)); + + printf("DPrec::CalculatePlane e00: %f %f %f\n",e00(0),e00(1),e00(2)); + printf("DPrec::CalculatePlane e0: %f %f %f\n",e0(0),e0(1),e0(2)); + printf("DPrec::CalculatePlane e01: %f %f %f\n",e10(0),e10(1),e10(2)); + printf("DPrec::CalculatePlane e1: %f %f %f\n",e1(0),e1(1),e1(2)); + printf("DPrec::CalculatePlane e02: %f %f %f\n",e20(0),e20(1),e20(2)); + printf("DPrec::CalculatePlane e2: %f %f %f\n",e2(0),e2(1),e2(2)); + printf("DPrec::CalculatePlane: old way plane: z+ %f x + %f y + %f =0\n", _Acoeff,_Bcoeff,_Ccoeff); +*/ + // New method by JB 2012/05/04 + // !!! Correction on 2012/07/16 R[2][x] changed to R[x][2] !!! + // A plane equation in the telescope frame writes like V.X = c + // where V is a row-vector (a, b, 1) and X the column vector (x, y, z). + // The same plane equation in the plane frame writes + // W.U = 0 or w=0 with W=row(0,0,1) and U=column(u,v,w). + // Taking into account that U = R (X-T) where: + // o R is a rotation matrix, + // o T is a shift vector. + // We simply get : W.R(X-T)=0 wich translates into (WR)X=WRT. + // So we can identify the vector WR=V and the scalar WRT=c. + // Finally, replacing the elements, we have : + // c = (RT)[2]/R[2][2] + // a = R[0][2]/R[2][2] + // b = R[1][2]/R[2][2] + // Of course, when R[2][2]=0 the plane cannot be // z. + + if(DPrecAlignMethod==0) { + + DR3 aVect; + DR3 trans(_fTr[0],_fTr[1],_fTr[2]); + aVect = RotateToPlane( trans); + if( _rotmat[2][2] != 0. ) { + _Ccoeff = -aVect(2)/_rotmat[2][2]; + _Acoeff = _rotmat[0][2]/_rotmat[2][2]; + _Bcoeff = _rotmat[1][2]/_rotmat[2][2]; + //std::cout<<"Calculate coefficients"<<_Acoeff<<" "<<_Bcoeff<<" "<<_Ccoeff< parameters set to 0.\n\n"); + _Ccoeff = 0.; + _Acoeff = 0.; + _Bcoeff = 0.; + } + // printf("DPrec::CalculatePlane: plane: z+ %f x + %f y + %f =0\n", _Acoeff,_Bcoeff,_Ccoeff); + } // end if Method 0 + + if(DPrecAlignMethod==1) { + + // New version : + // Rotate (x,y,z) to (u,v,w) : _rotmat + // Last Modified : LC 2015/01/30 Now we use the real definition of the rotation matrix. + + Double_t mat22 = _rotmat[2][2]; + + if( mat22 != 0 ) { + + _Acoeff = _rotmat[2][0] / mat22; + _Bcoeff = _rotmat[2][1] / mat22; + _Ccoeff = -(_rotmat[2][0]/mat22*_fTr[0] + _rotmat[2][1]/mat22*_fTr[1] + _fTr[2]); + } + + else { + + printf( "\n*** WARNING *** can't compute plane equation !\n --> parameters set to 0.\n\n"); + _Ccoeff = 0.; + _Acoeff = 0.; + _Bcoeff = 0.; + } + } // end if Method 1 + +} +//______________________________________________________________________________ +// +void DPrecAlign::CalculateIntersection(DataPoints* aDataPoint) +{ + //If a plane is determined as Ax+By+z+C=0 + // and a line - as x=x0+t*a + // y=y0+t*b + // z=z0+t*c + // then a crossection point is at -t=Ax0+By0+z0+C/(Aa+Bb+c) + // and one can calculate x,y,z of that point + // All computation in telescope frame + // + // Modified JB 2015/10/31 to store track slope + + DR3 TrackOrigin = aDataPoint->GetTrackOrigin(); + DR3 TrackDirection = aDataPoint->GetTrackDirection(); + Double_t tx=TrackOrigin(0); + Double_t ty=TrackOrigin(1); + Double_t tz=TrackOrigin(2); + Double_t tdx=TrackDirection(0); + Double_t tdy=TrackDirection(1); + Double_t t=-(_Acoeff*tx+_Bcoeff*ty+tz+_Ccoeff)/(_Acoeff*tdx+_Bcoeff*tdy+1.); + + //std::cout<<"A= "<<_Acoeff<<" B= "<<_Bcoeff<<" C= "<<_Ccoeff<<" t = "< no deformation in U!\n"); + } + + if ( _fVDeformationCoef!=NULL ) { + printf(" V: "); + for (Int_t i=0 ; i<8 ; i++){ + printf("%.2f ",_fVDeformationCoef[i]); + } + printf("\n"); + } + else { + printf(" -> no deformation in V!\n"); + } + +} + +//______________________________________________________________________________ +// +void DPrecAlign::PrintAll() +{ + // JB 2010/09/08 + // Modified: JB, 2015/10/31 print deformation added + + printf("\n Plane equation (XYZ frame, um): z + %.2f x + %.2f y + %.2f = 0\n", _Acoeff, _Bcoeff, _Ccoeff); + PrintRotationMatrix(); + PrintTranslations(); + if( _fIfDeformation ) PrintDeformations(); + printf("\n"); +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::RotateToPlane(DR3 xxx) +{ + // Rotate a vector from the telescope frame to the plane frame + // Mathematical operation is: uuu = rotMatrix * xxx + // + // Created: JB 2010/11/25 + DR3 uuu(0.0,0.0,0.0) ; + //printf("DPrec::RotateToPlane: xxx= %f %f %f\n",xxx(0),xxx(1),xxx(2)); + + if(DPrecAlignMethod==0) { + + for (Int_t i=0 ; i< 3 ; i++){ + for (Int_t j=0 ; j< 3 ; j++){ + uuu(i)+=_rotmat[j][i]*xxx(j); + } + } + } // end if Method 0 + + if(DPrecAlignMethod==1) { + + for (Int_t i=0 ; i< 3 ; i++){ + for (Int_t j=0 ; j< 3 ; j++){ + uuu(i)+=_rotmat[i][j]*xxx(j); + } + } + } // end if Method 1 + + //printf("DPrec::RotateToPlane: rotated vector= %f %f %f\n",uuu(0),uuu(1),uuu(2)); + return uuu; +} +//______________________________________________________________________________ +// +DR3 DPrecAlign::RotateToTracker( Double_t u, Double_t v, Double_t w) +{ + // Rotate a (U,V,W) vector from the plane frame to the telescope frame + // + // Created: JB 2010/11/25 + DR3 uuu( u, v, w); + DR3 xxx = RotateToTracker( uuu); + return xxx; +} +//______________________________________________________________________________ +// +DR3 DPrecAlign::RotateToTracker(DR3 uuu) +{ + // Rotate a vector from the plane frame to the telescope frame + // + // Created: JB 2010/11/25 + + //printf("DPrec::RotateToTracker: uuu= %f %f %f\n",uuu(0),uuu(1),uuu(2)); + DR3 xxx(0.0,0.0,0.0) ; + + if(DPrecAlignMethod==0) { + + for (Int_t i=0 ; i< 3 ; i++){ + for (Int_t j=0 ; j< 3 ; j++){ + xxx(i)+=_tormat[j][i]*uuu(j); + } + } + } // end if Method 0 + + if(DPrecAlignMethod==1) { + + for (Int_t i=0 ; i< 3 ; i++){ + for (Int_t j=0 ; j< 3 ; j++){ + xxx(i)+=_tormat[i][j]*uuu(j); + } + } + } // End if Method 1 + + //printf("DPrec::RotateToTracker: rotated vector= %f %f %f\n",xxx(0),xxx(1),xxx(2)); + return xxx; +} +//______________________________________________________________________________ +// +DR3 DPrecAlign::TransformHitToTracker(DR3 uuu) +{ + // Boost the given position from the plane frame to the telescope frame + // + // Created: JB 2010/09/03 + // Modified JB 2015/10/31 take deformation into account + + DR3 aPoint = uuu; + + // Take into account deformation if required + if( _fIfDeformation ) { + aPoint = DeformedLocalPoint( uuu); + if (fDebugDPrecAlign) { + printf("DPrecAlign::PlaneToTracker deformation applied.\n"); + printf(" from: %.1f, %.1f, %1.f to %.1f, %.1f, %1.f\n", uuu(0), uuu(1), uuu(2), aPoint(0), aPoint(1), aPoint(2)); + } + } + + DR3 res(0.0,0.0,0.0) ; + DR3 trans(_fTr[0],_fTr[1],_fTr[2]); + res = RotateToTracker( aPoint) + trans; // changed to +, JB 2011/07/25 + //printf("DPrec::Hit2Tracker transformed vector xyz = RotToTracker( uvw[%.1f, %.1f, %.1f] ) + trans[%.1f, %.1f, %.1f] = %f %f %f\n",aPoint(0), aPoint(1), aPoint(2), trans(0), trans(1), trans(2), res(0),res(1),res(2)); + return res; +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::TransformHitToPlane(DR3 xxx) +{ + // Boost the given position from the tracker frame to the plane frame + // Use the mechanism built for track, though there is no need + // to find the track intersection with the plane + // + // Created: JB 2010/11/25 + //printf("DPrec::Hit2Plane xyz= %f %f %f\n",xxx(0),xxx(1),xxx(2)); + SetTrackPosition( xxx); + DR3 res = TransformTrackToPlane(); + //printf("DPrec::Hit2Plane transformed vector uvw= %f %f %f\n",res(0),res(1),res(2)); + return res; +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::TransformTrackToPlane() +{ + // Returns the position where the track crosses the plane + // in the plane frame + // Assumes the position of the track at the plane but in the telescop frame is known + // + // Note the plane is considered as flat with no deformation, + // to take into account deformation, call DPlane::Intersection + + DR3 tmp = GetTrackPosition() ; + DR3 trans(_fTr[0],_fTr[1],_fTr[2]); + DR3 aFlatPoint(0.0,0.0,0.0) ; + aFlatPoint = RotateToPlane( tmp - trans ); // changed to -, JB 2011/07/25 + + //printf("DPrec::Track2PLane transformed vector in uvw = RotToPlane( xyz[%.1f, %.1f, %.1f] - trans[%.1f, %.1f, %.1f] ) = %f %f %f\n",tmp(0), tmp(1), tmp(2), trans(0), trans(1), trans(2), aFlatPoint(0),aFlatPoint(1),aFlatPoint(2)); + //return aFlatPoint; + + // Deformation + if( _fIfDeformation ) { // if deformation + DR3 aDeformedPoint = DeformedLocalPoint( aFlatPoint); + DR3 trackSlope = GetTrackSlope(); + DR3 trackSlopeInPlane = RotateToPlane( trackSlope ); + if (fDebugDPrecAlign) { + printf("DPrecAlign::Intersection deformation applied.\n"); + printf(" from: %.1f, %.1f, %1.f to %.1f, %.1f, %1.f\n", aFlatPoint(0), aFlatPoint(1), aFlatPoint(2), aDeformedPoint(0), aDeformedPoint(1), aDeformedPoint(2)); + } + Double_t deltaZU = aDeformedPoint(2)/tan(_fTh[1]) - aFlatPoint(2); + Double_t deltaZV = aDeformedPoint(2) - aFlatPoint(2); + if((_fTh[2]*180./M_PI) < 180. && abs(_fTh[2]*180./M_PI) > 175. ) { + aDeformedPoint -= DR3( trackSlopeInPlane(0)*deltaZU, trackSlopeInPlane(1)*deltaZV, 0.); + } + else{ + aDeformedPoint += DR3( trackSlopeInPlane(0)*deltaZU, trackSlopeInPlane(1)*deltaZV, 0.); + } + // Double_t deltaZ = aDeformedPoint(2)-aFlatPoint(2); + //aDeformedPoint += DR3( (trackSlopeInPlane(0))*deltaZ, trackSlopeInPlane(1)*deltaZ, 0.); + if (fDebugDPrecAlign) { + printf(" then with deltaZ=(%.1f,%.1f) and thetaPlane=%.1f to %.1f, %.1f, %1.f\n", deltaZU, deltaZV, _fTh[2]*180./M_PI, aDeformedPoint(0), aDeformedPoint(1), aDeformedPoint(2)); + } + return aDeformedPoint; + } // end if deformation + + else { // if no deformation + return aFlatPoint; + } + +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::TransformTrackToPlane( Double_t tx, Double_t ty, Double_t tz, Double_t tdx, Double_t tdy) +{ + // Returns the position where the track crosses the plane + // in the plane frame + // (tx, ty, tz=0) are the coordinate of the track origin in the telescope frame + // (tdx, tdy, tdz=1) are the slope of the track so that, in the telescope frame, + // the track equation is: x=(z-tz)*tdx+tx, y=(z-tz)*tdy+ty, z=(z-tz)*tdz+tz + // + // Created: JB 2010/09/10 + DataPoints aPosition(0,0,0,0,tx,ty,tz,tdx,tdy); // track at origin in the telescope frame + CalculateIntersection(&aPosition); // track at the plane surface in the telescope frame + return TransformTrackToPlane(); // track at the plane surface in the plane frame +} +//______________________________________________________________________________ +// +void DPrecAlign::SetTrackPosition( DR3 xxx) +{ + // Set a "track" position in the XYZ frame + // + // JB 2010/11/25 + _xh = xxx(0); + _yh = xxx(1); + _zh = xxx(2); +} +//______________________________________________________________________________ +// +DR3 DPrecAlign::GetTrackPosition() +{ + // Returns the position where the track crosses the plane + // in the telescope frame + DR3 tmp(_xh,_yh,_zh); + return tmp ; +} +//______________________________________________________________________________ +// +DR3 DPrecAlign::GetTrackSlope() +{ + // Returns the slope of the track + // in the telescope frame + DR3 tmp(_xtd,_ytd,_ztd); + return tmp ; +} +//______________________________________________________________________________ +// +void DPrecAlign::ConvoluteRotation( Double_t tiltW) +{ + // Recompute the rotation angles around z,y',x" + // taking into account an additional rotation around w + // + // First compute the new rotation matrix : R(z,y,x)*R-1(w,0,0) + // Then compute the new toration matrix : R(w,0,0)*R-1(z,y,x) + // Finaly deconvolute the rotation matrix to get the new angles + // + // JB 2010/11/25 + // Modified JB 2011/04/05 matrix product swapped + //printf("DPrecAlign: convoluting rotation with angle (around W) %.5f degrees\n", tiltW*TMath::RadToDeg()); + Double_t temp[3][3]; + // the R-1(w,0,0) matrix + Double_t torw[3][3]; + torw[0][0] = cos( tiltW); + torw[0][1] = -sin( tiltW); // sign changed on 2011/04/04 + torw[0][2] = 0.; + torw[1][0] = sin( tiltW); // sign changed on 2011/04/04 + torw[1][1] = cos( tiltW); + torw[1][2] = 0.; + torw[2][0] = 0.; + torw[2][1] = 0.; + torw[2][2] = 1.; + + // new rotation matrix R-1(w,0,0)*R(z,y,x) + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + temp[i][j] = 0.; + for (Int_t l=0; l<3; l++) temp[i][j] += _rotmat[i][l]*torw[l][j]; + } + } + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _rotmat[i][j] = temp[i][j]; + } + } + // the R(w,0,0) matrix + Double_t rotw[3][3]; + rotw[0][0] = cos( tiltW); + rotw[0][1] = sin( tiltW); // sign changed on 2011/04/04 + rotw[0][2] = 0.; + rotw[1][0] = -sin( tiltW); // sign changed on 2011/04/04 + rotw[1][1] = cos( tiltW); + rotw[1][2] = 0.; + rotw[2][0] = 0.; + rotw[2][1] = 0.; + rotw[2][2] = 1.; + + // new toration matrix R-1(z,y,x)*R(w,0,0) + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + temp[i][j] = 0.; + for (Int_t l=0; l<3; l++) temp[i][j] += rotw[i][l]*_tormat[l][j]; + } + } + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _tormat[i][j] = temp[i][j]; + } + } + // deconvolute the new rotation matrix to get the angles + DecomposeRotations(); +} +//______________________________________________________________________________ +// +void DPrecAlign::ConvoluteRotation( DR3 aTilt) +{ + // Recompute the rotation matrix R and angles around z,y',x" + // taking into account additional rotation angles from aTilt. + // + // Notation: + // o Rin is the initial rotation matrix, + // o Rtilt is the rotation matrix Rtilt from the agnles aTilt, + // o Rout is the final rotation matrix with + // Rout = Rin x Rtilt + // + // JB 2014/02/16 + +} + +//______________________________________________________________________________ +// +void DPrecAlign::ConvoluteUVWAlignment( Double_t shiftU, Double_t shiftV, Double_t tiltW) +{ + // Recompute all the alignment parameters in the XYZ frame + // from an alignment performed in the UVW frame + // (only U,V shifts and W anlge) + // + // First convolute the W alignment angle with the initial rotation matrix + // so far, the new rotation angles are not updated, just the matrices (2010/11/25) + // + // Then convolute the alignment (shift and rotation) with the initial position and rotations + // first rotate the u-shift vector to tracker coordinates + // which then has to be added to the plane center position. + // + // Also update the plane definition + // + // JB 2010/11/25 + DR3 shifts = RotateToTracker( shiftU, shiftV, 0.); // for translations + //printf("DPrecAlign: convoluting translations with shift (U,V) = ( %.2f, %.2f)\n", shiftU, shiftV); + _fTr[0] -= shifts(0); + _fTr[1] -= shifts(1); + _fTr[2] -= shifts(2); + ConvoluteRotation( tiltW ); // for rotation + CalculatePlane(); +} +//______________________________________________________________________________ +// +void DPrecAlign::ConvoluteAlignment( DPrecAlign *refAlignment) +{ + // Consider the current alignment is relative to the given one (refAlignment). + // So change this alignment to be absolute wrt Telescope frame. + // + // Notation: + // o current alignment = shift vector Srel, rotation matrix Rrel, + // o reference alignment = shift vector Sref, rotation matrix Rref, + // o final aboslute alignemnt = shift vector Sabs, rotation matrix Rabs. + // + // Formula are: + // Rabs = Rref x Rrel + // Sabs = invRrel x Srel + Sref + // + // JB 2014/02/16 + + // Get the shift of the reference alignment Rref + DR3 shiftRef( refAlignment->GetTranslation()[0], refAlignment->GetTranslation()[1], refAlignment->GetTranslation()[2] ); + DR3 shiftAbs = refAlignment->RotateToTracker( DR3(_fTr[0], _fTr[1], _fTr[2]) ) + shiftRef; // RotateToTracker(DR3(shiftRef(0), shiftRef(1), 0)); + + SetTranslation( shiftAbs); + + // Get the rotation matrix of the reference alignment Rref + Double_t rotmatRef[3][3]; + + Double_t *temp = refAlignment->GetRotationMatrix(); + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + rotmatRef[i][j] = temp[i*3+j]; + } + } + + + if(DPrecAlignMethod==0) { + + // Compute the new rotation matrix Rabs + Double_t rotmatAbs[3][3]; + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + rotmatAbs[i][j] = 0.; + for (Int_t l=0; l<3; l++) rotmatAbs[i][j] += rotmatRef[i][l]*_rotmat[l][j]; + } + } + + // Store the new rotation matrix + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _rotmat[i][j] = rotmatAbs[i][j]; + } + } + + } + else if(DPrecAlignMethod==1) { + + // Compute the new rotation matrix Rabs + Double_t rotmatAbs[3][3]; + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + rotmatAbs[i][j] = 0.; + for (Int_t l=0; l<3; l++) rotmatAbs[i][j] += _rotmat[i][l]*rotmatRef[l][j]; + } + } + + // Store the new rotation matrix + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _rotmat[i][j] = rotmatAbs[i][j]; + } + } + + } + + // Compute the inverse of the rotation matrix + // using the angles obtained by decomposition of the rotation matrix + DecomposeRotations(); + ComputeTorationMatrix(); + + // Recompute plane equation + CalculatePlane(); + + if(fDebugDPrecAlign) { + cout<<"Convolute Alignment"<GetTorationMatrix(); + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + tormatRef[i][j] = temp[i*3+j]; + } + } + + Double_t rotmatRel[3][3]; + + if(DPrecAlignMethod==0) { + // Compute the new rotation matrix Rrel + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + rotmatRel[i][j] = 0.; + for (Int_t l=0; l<3; l++) rotmatRel[i][j] += tormatRef[i][l]*_rotmat[l][j]; + } + } + } + else if(DPrecAlignMethod==1) { + // Compute the new rotation matrix Rrel + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + rotmatRel[i][j] = 0.; + for (Int_t l=0; l<3; l++) rotmatRel[i][j] += _rotmat[i][l]*tormatRef[l][j]; + } + } + } + + // Store the new rotation matrix + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _rotmat[i][j] = rotmatRel[i][j]; + } + } + + // Compute the inverse of the rotation matrix + // using the angles obtained by decomposition of the rotation matrix + DecomposeRotations(); + ComputeTorationMatrix(); + + + // Get the shift of the reference alignment Rref + DR3 shiftRef( refAlignment->GetTranslation()[0], refAlignment->GetTranslation()[1], refAlignment->GetTranslation()[2] ); + // Compute the relative shift + DR3 shiftDiff( _fTr[0]-shiftRef(0), _fTr[1]-shiftRef(1), _fTr[2]-shiftRef(2) ); + DR3 shiftRel = refAlignment->RotateToPlane( shiftDiff); + SetTranslation( shiftRel); + + // Recompute plane equation + CalculatePlane(); + + //PrintAll(); + +} +//______________________________________________________________________________ +// +void DPrecAlign::DecomposeRotations() +{ + // Decomposes the rotation matrix, that is: + // compute the values of the rotation angle around z, x', y" + // from the values of the rotation matrix + // + // To solve ambiguities, angle values nearest to the known ones are chosen. + // + // Updates the angle values in the _fTh vector, + // [0]=z, [1]=y', [2]=x" + // + // JB 2011/04/04 + // LC : Caution : cuts removed. + + Double_t theta[3]; //0=z, 1=y, 2=x + + // first angle is obtained from + // rotmat[0,2] = - sin(theta[1]) + // but we need to test if this +/- 1 + +// OLD CODE :: (LC 2014/12/05) + Int_t NoGimbalLock = 1; + + if(DPrecAlignMethod==0 && NoGimbalLock==1) + { + // Case where theta[1] = +/- pi/2 means the beam is perpendicular to the sensor!!! + if( TMath::Abs(_rotmat[0][2]) > (1-1e-4) ) { + cout << " Rotation around y is pi/2 and indicates the beam is perpendicular to the sensor!!!" << endl; + for( Short_t i=0; i<3; i++) { + theta[i] = _fTh[i]; + } + } + // Case where theta[1] != +/- pi/2 + else { + if( _rotmat[0][2] < 1.e-4 ) { // theta[1] is 0 or Pi, keep as before + theta[1] = _fTh[1]; + } + else { + theta[1] = asin( - _rotmat[0][2]); + } + //cout << " th(y) = asin(" << _rotmat[0][2] << ") = " << theta[1] << endl; + theta[2] = atan2( _rotmat[1][2]*cos(theta[1]), _rotmat[2][2]*cos(theta[1]) ); + //cout << " th(x) = atan(" << _rotmat[1][2]*cos(theta[1]) << " / " << _rotmat[2][2]*cos(theta[1]) << ") = " << theta[2] << endl; + theta[0] = atan2( _rotmat[0][1]*cos(theta[1]), _rotmat[0][0]*cos(theta[1]) ); + //cout << " th(z) = atan(" << _rotmat[0][1]*cos(theta[1]) << " / " << _rotmat[0][0]*cos(theta[1]) << ") = " << theta[0] << endl; + } + + for( Short_t i=0; i<3; i++) { + _fTh[i] = theta[i]; + } + + } // end if test + + if(DPrecAlignMethod==0 && NoGimbalLock==0) { + //NEW CODE :: (LC 2014/12/05) BEWARE !!!!!!!!!!!!! GIMBAL LOCK !!!!!!!!!!!!!!!! + theta[1] = asin( -_rotmat[0][2]); + theta[2] = atan2( _rotmat[1][2]*cos(theta[1]), _rotmat[2][2]*cos(theta[1]) ); + theta[0] = atan2( _rotmat[0][1]*cos(theta[1]), _rotmat[0][0]*cos(theta[1]) ); + + for( Short_t i=0; i<3; i++) { + _fTh[i] = theta[i]; + } + } + + if(NoGimbalLock==0 && DPrecAlignMethod==1) { + + if( fabs(_rotmat[2][0]) < 1.e-4 ) { // if theta[1] is 0, Pi or -Pi, keep as before + theta[1] = _fTh[1]; // 0., PI, -PI + } + else { + theta[1] = asin( -_rotmat[2][0] ); + } + + Double_t cosY = cos(theta[1]); + + Double_t cosX = _rotmat[2][2] / cosY; + Double_t sinX = +_rotmat[2][1] / cosY; + theta[2] = atan2(sinX, cosX); // Rad + + Double_t cosZ = _rotmat[0][0] / cosY; + Double_t sinZ = +_rotmat[1][0] / cosY; + theta[0] = atan2(sinZ, cosZ); // Rad + + for( Short_t i=0; i<3; i++) { + _fTh[i] = fmod( theta[i], 2.*TMath::Pi() ); + } + + } + + if(NoGimbalLock==1 && DPrecAlignMethod==1) { + + // With rotation in this order : X, Y, Z. + //std::cout<<"_fTh[1] = "<<_fTh[1]< 1 ) { + DPrecAlign::Class()->ReadBuffer(R__b,this,R__v,R__s,R__c); + return; + } + //====process old versions before automatic schema evolution=v1 + if(fDebugDPrecAlign) cout << "Processing old version " << endl; + TObject::Streamer(R__b); + R__b.ReadStaticArray((double*)_ahpla); + R__b.ReadStaticArray((double*)_ateb); + R__b.ReadStaticArray((double*)_ammag); + R__b.ReadStaticArray((double*)_tormat); + R__b.ReadStaticArray((double*)_alpha); + R__b.ReadStaticArray((double*)_beta); + R__b.ReadStaticArray((double*)_gamma); + R__b.ReadStaticArray((double*)_rotmat); + R__b >> _Acoeff; + R__b >> _Bcoeff; + R__b >> _Ccoeff; + R__b.ReadStaticArray((double*)_fTh); + R__b.ReadStaticArray((double*)_fTr); + R__b.ReadInt((int&)_fIfDeformation); + R__b.ReadStaticArray((double*)_fUDeformationCoef); + R__b.ReadStaticArray((double*)_fVDeformationCoef); + _data.Streamer(R__b); + _data1.Streamer(R__b); + //__miniVectors.Streamer(R__b); + //_dataMV.Streamer(R__b); + //_dataMV1.Streamer(R__b); + R__b >> _xh; + R__b >> _yh; + R__b >> _zh; + R__b.ReadStaticArray((double*)_initialRotations); + R__b.ReadStaticArray((double*)_initialPosition); + R__b.CheckByteCount(R__s, R__c, DPrecAlign::IsA()); + //====end of old version + } else { + if(fDebugDPrecAlign) cout << "Buffer is writing " << endl; + DPrecAlign::Class()->WriteBuffer(R__b,this); + } +} diff --git a/src/DPrecAlign.cxx_NEW b/src/DPrecAlign.cxx_NEW new file mode 100755 index 0000000..76d4bb1 --- /dev/null +++ b/src/DPrecAlign.cxx_NEW @@ -0,0 +1,1429 @@ +// @(#)maf/dtools:$Name: $:$Id: DPrecAlign.cxx,v.3 2005/10/02 18:03:46 sha Exp $ +// Author : G.Orazi 1/2/2000 + +//////////////////////////////////////////////////////////////////////// +// Class Description of DPrecAlign // +// // +// This class stores the precise alignement of a plane. +// 6 parameters are used: 3 for translations and 3 for rotations. +// +// Notations: +// Telescope or tracker frame coordinates = XYZ +// Plane frame coordinates = UVW +// +// Transformations from one from to the other are : +// XYZ = InverseRotation of (UVW) - Translations +// UVW = Rotation of ( XYZ - Translations) +// +// Parameters: +// - translation vector is _fTr[3] (in micrometers) +// these coordinates are given in the tracker frame. +// - rotation angles vector _fTh[3] (in radian) +// rotations around the following axis 0=z 1=y' 2=x". +// // +// Standard usage: +// - First set the alignment parameters with // +// SetTranslation( tx, ty, tz) // +// SetRotations( thz, thx, thy) // +// - Transformation hit coordinates from plane frame // +// to tracker frame with: // +// DR3 hit_x = TransformHitToTracker(DR3 hit_u); // +// - Transformation track coordinated from plane frame // +// to tracker frame with: // +// DR3 track_u = TransformTrackToPlane( Double_t tx, Double_t ty, Double_t tz, Double_t tdx, Double_t tdy); // +// - if the alignment parameters are relative to another alignment (refAlign), +// the absolute alignment (wrt the tracker) can be obtained with +// ConvoluteAlignment( DPRecAlign *refAlign) +// +// For alignment purpose when a minimization is required: +// - Accumulate pairs of matching hit-track with +// NewData(Double_t auh,Double_t avh,Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy) +// // +// // +//////////////////////////////////////////////////////////////////////// + +//*-- Modified : LC 2015/01/30 Redifinition of plane equation and deconvoluteRotation with the good matrices. +//*-- Modified : LC 2015/01/30 Redefinition of rotmat and tormat : it was the transposed matrix. +//*-- Modified : LC 2014/12/05 DecomposeRotations() -> cuts removed (bad tilts with ConvoluteAlignment) +//*-- Modified : JB 2014/02/17 ConvoluteAlignment, CopyAlignment +//*-- Modified : JB 2012/09/05 add method to reset datapoints +//*-- Modified : JB 2012/07/16 bug fix in CalculatePlane +//*-- Modified : JB 2012/05/04 new method to compute plane equation +//*-- Modified : JB 2011/10/27 names _A/B/C replaced by _A/B/Ccoeff +//*-- Modified : JB 2011/07/25 Translation sign changed to match plane correct position +//*-- Modified : JB 2011/04/04 add rotation decomposition & correct rotation convolution +//*-- Modified : JB 2010/11/25 overloaded method Set and new rotation methods +//*-- Modified : JB 2010/09/08 Compute the plane equation properly with the Z translation +//*-- Modified : JB 2010/09/01 to include rotation matrix for Plane->Tracker +//*-- Author : G.Orazi 1/2/2000 + +#include "Riostream.h" +#include +//*KEEP,DPrecAlign. +#include "DPrecAlign.h" +#include "DR3.h" +#include "TMath.h" + +ClassImp(DataPoints) +ClassImp(DPrecAlign) + +//______________________________________________________________________________ +// +DataPoints::~DataPoints() +{ + // DataPoints default destructor +} + +//______________________________________________________________________________ +// +DataPoints::DataPoints(Double_t auh,Double_t avh,Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy) +{ + _uh = auh ; + _vh = avh ; + _tx = atx ; + _ty = aty ; + _tz = atz ; + _tdx=atdx ; + _tdy=atdy ; +} + +//______________________________________________________________________________ +// +void DataPoints::Set(Double_t auh,Double_t avh,Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy) +{ + _uh = auh ; + _vh = avh ; + _tx = atx ; + _ty = aty ; + _tz = atz ; + _tdx= atdx; + _tdy= atdy; +} + +//______________________________________________________________________________ +// +void DataPoints::PrintData() +{ + printf("DataPoint: hit: u=%f v=%f\n track: x=%f y=%f z=%f dx/dz=%f dy/dz=%f\n", + _uh,_vh,_tx,_ty,_tz,_tdx,_tdy); +} + + +//______________________________________________________________________________ +// +DR3 DataPoints::GetHitPosition() +{ + DR3 tmp(_uh,_vh,0.0); + return tmp ; +} + + +//______________________________________________________________________________ +// +DR3 DataPoints::GetTrackOrigin() +{ + DR3 tmp(_tx,_ty,_tz); + return tmp ; +} + +//______________________________________________________________________________ +// +DR3 DataPoints::GetTrackDirection() +{ + DR3 tmp(_tdx,_tdy,1.); + return tmp ; +} + +//______________________________________________________________________________ +// +DPrecAlign::DPrecAlign(const DPrecAlign &aobj) +{ + + cout << "WARNING: copy constructor of DPrecAlign does nothing !!!" << endl; + +} + +//______________________________________________________________________________ +// +DPrecAlign::DPrecAlign() +{ + SetDebug(0); + if(fDebugDPrecAlign) cout << "DPrecAlign constructor" << endl; +} + +//______________________________________________________________________________ +// +DPrecAlign::~DPrecAlign() +{ + // DPrecAlign default destructor +} + +//______________________________________________________________________________ +// +void DPrecAlign::NewData(Double_t auh,Double_t avh,Double_t atx,Double_t aty,Double_t atz, Double_t atdx, Double_t atdy) +{ + _data.Add( (new DataPoints(auh,avh,atx,aty,atz,atdx,atdy)) ) ; +} + +//______________________________________________________________________________ +// +void DPrecAlign::NewData1(DataPoints* myDataPoint) +{ + _data1.Add( myDataPoint ) ; +} + +//______________________________________________________________________________ +// +void DPrecAlign::NewData(DataPoints* myDataPoint) +{ + _data.Add( myDataPoint ) ; +} + +//______________________________________________________________________________ +// +void DPrecAlign::RemoveData(DataPoints* myDataPoint) +{ + _data.Remove(myDataPoint); +} + +//______________________________________________________________________________ +// +void DPrecAlign::RemoveData1(DataPoints* myDataPoint) +{ + _data1.Remove(myDataPoint); +} +/* +//______________________________________________________________________________ +// +void DPrecAlign::NewMiniVector(DTrack* myMV) +{ + _dataMV.Add( myMV ) ; +} + +//______________________________________________________________________________ +// +void DPrecAlign::NewMiniVector1(DTrack* myMV1) +{ + _dataMV1.Add( myMV1 ) ; +} + +//______________________________________________________________________________ +// +void DPrecAlign::RemoveMiniVector(DTrack* myMV) +{ + _dataMV.Remove(myMV); +} + +//______________________________________________________________________________ +// +void DPrecAlign::RemoveMiniVector1(DTrack* myMV1) +{ + _dataMV1.Remove(myMV1); +} +*/ +//______________________________________________________________________________ +// +void DPrecAlign::ListDataPoints() +{ + cout<< "Listing data..." << endl; + DataPoints *current ; + current = (DataPoints*) _data.First(); + + //DTrack* miniVector; + //miniVector = (DTrack*) _dataMV1.First(); + + while(current) { + current->PrintData() ; + //miniVector->GetHit(1)->GetPositionCG()->Print(); + current=(DataPoints*) _data.After(current) ; + //miniVector = (DTrack*) _dataMV1.After(miniVector); + } +} + +//______________________________________________________________________________ +// + +Int_t DPrecAlign::DataSize() +{ + return _data.GetSize(); +} + +//______________________________________________________________________________ +// + +Int_t DPrecAlign::DataSize1() +{ + return _data1.GetSize(); +} + +/* +//______________________________________________________________________________ +// +Int_t DPrecAlign::DataSizeMV() +{ + return _dataMV.GetSize(); +} + +//______________________________________________________________________________ +// + +Int_t DPrecAlign::DataSizeMV1() +{ + return _dataMV1.GetSize(); +} +*/ +//______________________________________________________________________________ +// + +void DPrecAlign::SetInitialRotations() +{ + //initialRotations = new Double_t[3]; + for(Int_t i=0; i<3; ++i) _initialRotations[i] = _fTh[i]; +} + +//______________________________________________________________________________ +// + +void DPrecAlign::SetInitialPosition() +{ + //initialPosition = new Double_t[3]; + for(Int_t i=0; i<3; ++i) _initialPosition[i] = _fTr[i]; +} + +//______________________________________________________________________________ +// +void DPrecAlign::SetRotations(Double_t th0,Double_t th1,Double_t th2) +{ + //th0, th1, th2 : Rotation angles around z, y' and x" axis + + // printf("Setting Rotations... %11f %11f %11f\n",th0,th1,th2); + // cout << "th0= " << th0/3.1415*180. << endl; + // cout << "th1= " << th1/3.1415*180. << endl; + // cout << "th2= " << th2/3.1415*180. << endl; + + _fTh[0]= th0 ; + _fTh[1]= th1 ; + _fTh[2]= th2 ; + ComputeRotationMatrix() ; + CalculatePlane(); +} + +//______________________________________________________________________________ +// +void DPrecAlign::SetRotations(DR3 tilt) +{ + //tilt[0], tilt[1], tilt[2] should be the rotation angles around the z, y' and x" axis + // JB 2010/11/25 + + SetRotations( tilt(0), tilt(1), tilt(2)); +} + +//______________________________________________________________________________ +// +void DPrecAlign::SetTranslation(Double_t t0,Double_t t1,Double_t t2 ) +{ + // Sets a translation + + //printf("translation: \n") ; + //printf("translation: %f %f %f \n",t0, t1, t2) ; + + _fTr[0]=t0 ; + _fTr[1]=t1 ; + _fTr[2]=t2 ; + + //printf("DPrec::SetTranslation to %f %f %f \n",_fTr[0], _fTr[1], _fTr[2]) ; +} + + +//______________________________________________________________________________ +// +void DPrecAlign::SetTranslation(DR3 tr) +{ + //tr[0], tr[1], tr[2] should be the translation along the x y z axis + // JB 2010/11/25 + + SetTranslation( tr(0), tr(1), tr(2)); +} + + +//______________________________________________________________________________ +// +void DPrecAlign::CopyAlignment( DPrecAlign *anAlign) +{ + // Copy the alignment parameters of anAlign, + // and recompute everything. + // + // JB 2014/02/17 + + SetTranslation( anAlign->GetTranslation()[0], anAlign->GetTranslation()[1], anAlign->GetTranslation()[2]); + SetRotations( anAlign->GetRotations()[0], anAlign->GetRotations()[1], anAlign->GetRotations()[2]); + +} + + +//______________________________________________________________________________ +// +void DPrecAlign::ComputeRotationMatrix() +{ + //Compute the rotation matrix from Tracker frame to Plane Frame + // alpha is the rotation around z + // beta is the rotation around y' + // gamma is the rotation around x" + // final matrix is gamma*beta*alpha + // + // This method is called when the rotation angles are set + // with SetRotations( thz, thy, thx). + // + // Matrix element expression assuming: + // ca = cos(alpha), sb=sin(beta), cg/sg=cos/sin(gamma) + // + // ca.cb cb.sa -sb + // ca.sb.sg-sa.sg sa.sb.sg+ca.cg cb.sg + // ca.sb.cg-sa.sg sa.sb.cg-ca.sg cb.cg + + + // cout << "computing rotation matrix..." << endl; + // Last Modified : LC 2015/01/30 from transpose matrix to real rotation matrix. +/* + Double_t c[3] ; + Double_t s[3] ; + for (Int_t i=0 ; i<3 ; i++){ + c[i]=TMath::Cos(-_fTh[i]); // signe (-) = sens horaire. + s[i]=TMath::Sin(-_fTh[i]); // signe (+) = sens anti-horaire. + } + + // Three rotation matrices: (Anti-Horaire) + _alpha[0][0] = c[0]; + _alpha[0][1] = +s[0]; + _alpha[0][2] = 0.; + + _alpha[1][0] = -s[0]; + _alpha[1][1] = c[0]; + _alpha[1][2] = 0.; + + _alpha[2][0] = 0.; + _alpha[2][1] = 0.; + _alpha[2][2] = 1.; + // + _beta[0][0] = c[1]; + _beta[0][1] = 0.; + _beta[0][2] = -s[1]; + + _beta[1][0] = 0.; + _beta[1][1] = 1.; + _beta[1][2] = 0.; + + _beta[2][0] = +s[1]; + _beta[2][1] = 0.; + _beta[2][2] = c[1]; + // + _gamma[0][0] = 1.; + _gamma[0][1] = 0.; + _gamma[0][2] = 0.; + + _gamma[1][0] = 0.; + _gamma[1][1] = c[2]; + _gamma[1][2] = +s[2]; + + _gamma[2][0] = 0.; + _gamma[2][1] = -s[2]; + _gamma[2][2] = c[2]; + // + + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _rotmat[i][j] = 0.; + for (Int_t l=0; l<3; l++) { + //for (Int_t k=0; k<3; k++) _rotmat[i][j]+=_gamma[i][l]*_beta[l][k]*_alpha[k][j]; // INVERSE !!!! + for (Int_t k=0; k<3; k++) _rotmat[i][j]+=_alpha[i][l]*_beta[l][k]*_gamma[k][j]; // new version ds ce sens : X,Y,Z + } + } + } +*/ + Double_t angle_x = +_fTh[2]; // Horaire (+) Anti-Horaire (-) + Double_t angle_y = +_fTh[1]; + Double_t angle_z = +_fTh[0]; + + Double_t A = TMath::Cos(angle_x); + Double_t B = TMath::Sin(angle_x); + Double_t C = TMath::Cos(angle_y); + Double_t D = TMath::Sin(angle_y); + Double_t E = TMath::Cos(angle_z); + Double_t F = TMath::Sin(angle_z); + + Double_t AD = A*D; + Double_t BD = B*D; + + // Rotation X,Y,Z : + _rotmat[0][0] = C*E; + _rotmat[0][1] = BD*E - A*F; + _rotmat[0][2] = AD*E + B*F; + _rotmat[1][0] = C*F; + _rotmat[1][1] = BD*F + A*E; + _rotmat[1][2] = AD*F - B*E; + _rotmat[2][0] = -D; + _rotmat[2][1] = B*C; + _rotmat[2][2] = A*C; + +/* + _rotmat[0][0] = C*E; + _rotmat[0][1] = -C*F; + _rotmat[0][2] = D; + _rotmat[1][0] = BD*E + A*F; + _rotmat[1][1] = -BD*F + A*E; + _rotmat[1][2] = -B*C; + _rotmat[2][0] = -AD*E + B*F; + _rotmat[2][1] = AD *F + B*E; + _rotmat[2][2] = A*C; +*/ + ComputeTorationMatrix(); // JB 2010/09/08 + //PrintRotationMatrix(); +} + +//______________________________________________________________________________ +// +void DPrecAlign::ComputeTorationMatrix() +{ + //Compute the rotation matrix from Plane frame to Tracker Frame + // ahpla is the inverse rotation around z + // ateb is the inverse rotation around y + // ammag is the inverse rotation around x + // final matrix is ammag*ateb*ahpla + // + // This method is called when the rotation matrix is computed + // with ComputeRotationMatrix(). + // + // Created: JB 2010/09/03 + + // cout << "computing rotation matrix..." << endl; + +// Last Modified : LC 2015/01/30 from transpose inverse matrix to real inverse matrix. +/* + Double_t c[3] ; + Double_t s[3] ; + for (Int_t i=0 ; i<3 ; i++){ + c[i]=TMath::Cos(_fTh[i]); // signe (-) : sens horaire. + s[i]=TMath::Sin(_fTh[i]); // signe (+) : sens anti-horaire. + } + + // Three rotation matrices : (Anti-Horaire) + _ahpla[0][0] = c[0]; + _ahpla[0][1] = +s[0]; + _ahpla[0][2] = 0.; + + _ahpla[1][0] = -s[0]; + _ahpla[1][1] = c[0]; + _ahpla[1][2] = 0.; + + _ahpla[2][0] = 0.; + _ahpla[2][1] = 0.; + _ahpla[2][2] = 1.; + // + _ateb[0][0] = c[1]; + _ateb[0][1] = 0.; + _ateb[0][2] = -s[1]; + + _ateb[1][0] = 0.; + _ateb[1][1] = 1.; + _ateb[1][2] = 0.; + + _ateb[2][0] = +s[1]; + _ateb[2][1] = 0.; + _ateb[2][2] = c[1]; + // + _ammag[0][0] = 1.; + _ammag[0][1] = 0.; + _ammag[0][2] = 0.; + + _ammag[1][0] = 0.; + _ammag[1][1] = c[2]; + _ammag[1][2] = +s[2]; + + _ammag[2][0] = 0.; + _ammag[2][1] = -s[2]; + _ammag[2][2] = c[2]; + // + + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _tormat[i][j] = 0.; + for (Int_t l=0; l<3; l++) { + for (Int_t k=0; k<3; k++) _tormat[i][j]+=_ammag[i][l]*_ateb[l][k]*_ahpla[k][j]; + //for (Int_t k=0; k<3; k++) _tormat[i][j]+=_ahpla[i][l]*_ateb[l][k]*_ammag[k][j]; // INVERSE !!! New version + } + } + } +*/ + + Double_t angle_x = -_fTh[2]; + Double_t angle_y = -_fTh[1]; + Double_t angle_z = -_fTh[0]; + + Double_t A = TMath::Cos(angle_x); + Double_t B = TMath::Sin(angle_x); + Double_t C = TMath::Cos(angle_y); + Double_t D = TMath::Sin(angle_y); + Double_t E = TMath::Cos(angle_z); + Double_t F = TMath::Sin(angle_z); + + Double_t AD = A*D; + Double_t BD = B*D; + + // Rotation Z,Y,X + _tormat[0][0] = C*E; + _tormat[0][1] = -C*F; + _tormat[0][2] = D; + _tormat[1][0] = BD*E + A*F; + _tormat[1][1] = -BD*F + A*E; + _tormat[1][2] = -B*C; + _tormat[2][0] = -AD*E + B*F; + _tormat[2][1] = AD *F + B*E; + _tormat[2][2] = A*C; + +/* + // Rotation X,Y,Z + _tormat[0][0] = C*E; + _tormat[0][1] = BD*E - A*F; + _tormat[0][2] = AD*E + B*F; + _tormat[1][0] = C*F; + _tormat[1][1] = BD*F + A*E; + _tormat[1][2] = AD*F - B*E; + _tormat[2][0] = -D; + _tormat[2][1] = B*C; + _tormat[2][2] = A*C; +*/ +} + +//______________________________________________________________________________ +// +void DPrecAlign::CalculatePlane() +{ + // A,B and C are parameters of the plane: z+Ax+By+C=0 + // + // This method is called when the rotation angles are set + // with SetRotations( thz, thy, thx), just after the rotation matrix + // has been calculated. + // + // The original method crashed in certain cases and was replaced by a + // more robust computation. + +/* + // Original method by G.Orazi + // e0,e1 and e2 are points that determine the plane + // we start with the original plane in the UVW frame, + // then rotate it into the XYZ frame and find the A,B and C params + // of the rotated plane + DR3 e00(0.,0.,0.); + DR3 e10(1.,0.,0.); + DR3 e20(0.,1.,0.); + DR3 e0 = TransformHitToTracker(e00); + DR3 e1 = TransformHitToTracker(e10); + DR3 e2 = TransformHitToTracker(e20); + _Bcoeff=((e2(2)-e1(2))*e0(0)+(e0(2)-e2(2))*e1(0)+(e1(2)-e0(2))*e2(0))/ + ((e0(0)-e1(0))*(e1(1)-e2(1))+(e0(1)-e1(1))*(e2(0)-e1(0))); + _Ccoeff=(_Bcoeff*(e0(1)*e1(0)-e0(0)*e1(1))-e0(0)*e1(2)+e1(0)*e1(2)+e0(2)*e1(0)-e1(2)*e1(0))/(e0(0)-e1(0)); + _Acoeff=(-e0(2)+e1(2)-_Bcoeff*(e0(1)-e1(1)))/(e0(0)-e1(0)); + + printf("DPrec::CalculatePlane e00: %f %f %f\n",e00(0),e00(1),e00(2)); + printf("DPrec::CalculatePlane e0: %f %f %f\n",e0(0),e0(1),e0(2)); + printf("DPrec::CalculatePlane e01: %f %f %f\n",e10(0),e10(1),e10(2)); + printf("DPrec::CalculatePlane e1: %f %f %f\n",e1(0),e1(1),e1(2)); + printf("DPrec::CalculatePlane e02: %f %f %f\n",e20(0),e20(1),e20(2)); + printf("DPrec::CalculatePlane e2: %f %f %f\n",e2(0),e2(1),e2(2)); + printf("DPrec::CalculatePlane: old way plane: z+ %f x + %f y + %f =0\n", _Acoeff,_Bcoeff,_Ccoeff); +*/ + + + // New method by JB 2012/05/04 + // !!! Correction on 2012/07/16 R[2][x] changed to R[x][2] !!! + // A plane equation in the telescope frame writes like V.X = c + // where V is a row-vector (a, b, 1) and X the column vector (x, y, z). + // The same plane equation in the plane frame writes + // W.U = 0 or w=0 with W=row(0,0,1) and U=column(u,v,w). + // Taking into account that U = R (X-T) where: + // o R is a rotation matrix, + // o T is a shift vector. + // We simply get : W.R(X-T)=0 wich translates into (WR)X=WRT. + // So we can identify the vector WR=V and the scalar WRT=c. + // Finally, replacing the elements, we have : + // c = (RT)[2]/R[2][2] + // a = R[0][2]/R[2][2] + // b = R[1][2]/R[2][2] + // Of course, when R[2][2]=0 the plane cannot be // z. + +/* + DR3 aVect; + DR3 trans(_fTr[0],_fTr[1],_fTr[2]); + aVect = RotateToPlane( trans); + if( _rotmat[2][2] != 0. ) { + _Ccoeff = -aVect(2)/_rotmat[2][2]; + _Acoeff = _rotmat[2][0]/_rotmat[2][2]; + _Bcoeff = _rotmat[2][1]/_rotmat[2][2]; + //std::cout<<"Calculate coefficients"<<_Acoeff<<" "<<_Bcoeff<<" "<<_Ccoeff< parameters set to 0.\n\n"); + _Ccoeff = 0.; + _Acoeff = 0.; + _Bcoeff = 0.; + } +*/ + +// New version : +// Rotate (x,y,z) to (u,v,w) : _tormat +// Last Modified : LC 2015/01/30 Now we use the real definition of the rotation matrix. + + Double_t mat22 = _rotmat[2][2]; +/* + if( mat22 != 0 ) { + + _Acoeff = _rotmat[0][2] / mat22; + _Bcoeff = _rotmat[1][2] / mat22; + _Ccoeff = -(_rotmat[0][2]/mat22*_fTr[0] + _rotmat[1][2]/mat22*_fTr[1] + _fTr[2]); + } +*/ + + if( mat22 != 0 ) { + + _Acoeff = _rotmat[2][0] / mat22; + _Bcoeff = _rotmat[2][1] / mat22; + _Ccoeff = -(_rotmat[2][0]/mat22*_fTr[0] + _rotmat[2][1]/mat22*_fTr[1] + _fTr[2]); + } + + else { + + printf( "\n*** WARNING *** can't compute plane equation !\n --> parameters set to 0.\n\n"); + _Ccoeff = 0.; + _Acoeff = 0.; + _Bcoeff = 0.; + } + +// printf("DPrec::CalculatePlane: plane: z+ %f x + %f y + %f =0\n", _Acoeff,_Bcoeff,_Ccoeff); + +} + +//______________________________________________________________________________ +// +void DPrecAlign::CalculateIntersection(DataPoints* aDataPoint) +{ + //If a plane is determined as Ax+By+z+C=0 + // and a line - as x=x0+t*a + // y=y0+t*b + // z=z0+t*c + // then a crossection point is at -t=Ax0+By0+z0+C/(Aa+Bb+c) + // and one can calculate x,y,z of that point + // All computation in telescope frame + DR3 TrackOrigin = aDataPoint->GetTrackOrigin(); + DR3 TrackDirection = aDataPoint->GetTrackDirection(); + Double_t tx=TrackOrigin(0); + Double_t ty=TrackOrigin(1); + Double_t tz=TrackOrigin(2); + Double_t tdx=TrackDirection(0); + Double_t tdy=TrackDirection(1); + Double_t t=-(_Acoeff*tx+_Bcoeff*ty+tz+_Ccoeff)/(_Acoeff*tdx+_Bcoeff*tdy+1.); + + //std::cout<<"A= "<<_Acoeff<<" B= "<<_Bcoeff<<" C= "<<_Ccoeff<<" t = "< i,j + } + } + //printf("DPrec::RotateToPlane: rotated vector= %f %f %f\n",uuu(0),uuu(1),uuu(2)); + return uuu; +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::RotateToTracker( Double_t u, Double_t v, Double_t w) +{ + // Rotate a (U,V,W) vector from the plane frame to the telescope frame + // + // Created: JB 2010/11/25 + + DR3 uuu( u, v, w); + DR3 xxx = RotateToTracker( uuu); + return xxx; +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::RotateToTracker(DR3 uuu) +{ + // Rotate a vector from the plane frame to the telescope frame + // + // Created: JB 2010/11/25 + // Last Modified : LC 2015/01/30 : Now we use the good invere rotation matrix. + + //printf("DPrec::RotateToTracker: uuu= %f %f %f\n",uuu(0),uuu(1),uuu(2)); + DR3 xxx(0.0,0.0,0.0) ; + for (Int_t i=0 ; i< 3 ; i++){ + for (Int_t j=0 ; j< 3 ; j++){ + xxx(i)+=_tormat[i][j]*uuu(j); // LC 2015/01/30 : j,i --> i,j + } + } + //printf("DPrec::RotateToTracker: rotated vector= %f %f %f\n",xxx(0),xxx(1),xxx(2)); + return xxx; +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::TransformHitToTracker(DR3 uuu) +{ + // Boost the given position from the plane frame to the telescope frame + // + // Created: JB 2010/09/03 + + DR3 res(0.0,0.0,0.0) ; + DR3 trans(_fTr[0],_fTr[1],_fTr[2]); + + res = RotateToTracker( uuu) + trans; // changed to +, JB 2011/07/25 + + //printf("DPrec::Hit2Tracker transformed vector xyz = RotToTracker( uvw[%.1f, %.1f, %.1f] ) + trans[%.1f, %.1f, %.1f] = %f %f %f\n",uuu(0), uuu(1), uuu(2), trans(0), trans(1), trans(2), res(0),res(1),res(2)); + + return res; +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::TransformHitToPlane(DR3 xxx) +{ + // Boost the given position from the tracker frame to the plane frame + // Use the mechanism built for track, though there is no need + // to find the track intersection with the plane + // + // Created: JB 2010/11/25 + + //printf("DPrec::Hit2Plane xyz= %f %f %f\n",xxx(0),xxx(1),xxx(2)); + + SetTrackPosition( xxx); + DR3 res = TransformTrackToPlane(); + + //printf("DPrec::Hit2Plane transformed vector uvw= %f %f %f\n",res(0),res(1),res(2)); + + return res; +} + +//______________________________________________________________________________ +// +DR3 DPrecAlign::TransformTrackToPlane() +{ + // Returns the position where the track crosses the plane + // in the plane frame + // Assumes the position of the track at the plane but in the telescop frame is known + // + // Note the plane is considered as flat with no deformation, + // to take into account deformation, call DPlane::Intersection + + DR3 tmp = GetTrackPosition() ; + DR3 trans(_fTr[0],_fTr[1],_fTr[2]); + DR3 res(0.0,0.0,0.0) ; +/* + std::cout<<"translation : "; + trans.Print(); + std::cout<<" trackpos : "; + tmp.Print(); + std::cout<GetTranslation()[0], refAlignment->GetTranslation()[1], refAlignment->GetTranslation()[2] ); + DR3 shiftAbs = refAlignment->RotateToTracker( DR3(_fTr[0], _fTr[1], _fTr[2]) ) + shiftRef; + + //DR3(_fTr[0], _fTr[1], _fTr[2]).Print(); + //refAlignment->RotateToTracker( DR3(_fTr[0], _fTr[1], _fTr[2]) ).Print(); + + SetTranslation( shiftAbs); + + // Get the rotation matrix of the reference alignment Rref + + Double_t rotmatRef[3][3]; + Double_t *temp = refAlignment->GetRotationMatrix(); + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + rotmatRef[i][j] = temp[i*3+j]; + } + } + + // Compute the new rotation matrix Rabs + Double_t rotmatAbs[3][3]; + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + rotmatAbs[i][j] = 0.; + for (Int_t l=0; l<3; l++) rotmatAbs[i][j] += rotmatRef[i][l]*_rotmat[l][j]; + } + } + + // Store the new rotation matrix + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _rotmat[i][j] = rotmatAbs[i][j]; + } + } + + // Compute the inverse of the rotation matrix + // using the angles obtained by decomposition of the rotation matrix + DecomposeRotations(); + SetRotations( _fTh[0], _fTh[1], _fTh[2] ); + //ComputeTorationMatrix(); + + // Recompute plane equation + //CalculatePlane(); + + //PrintAll(); + + if(fDebugDPrecAlign) { + cout<<"Convolute Alignment"<GetTorationMatrix(); + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + tormatRef[i][j] = temp[i*3+j]; + } + } + + // Compute the new rotation matrix Rrel + Double_t rotmatRel[3][3]; + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + rotmatRel[i][j] = 0.; + for (Int_t l=0; l<3; l++) rotmatRel[i][j] += tormatRef[i][l]*_rotmat[l][j]; + } + } + + // Store the new rotation matrix + for (Int_t i=0; i<3; i++) { + for (Int_t j=0; j<3; j++) { + _rotmat[i][j] = rotmatRel[i][j]; + } + } + + // Compute the inverse of the rotation matrix + // using the angles obtained by decomposition of the rotation matrix + DecomposeRotations(); + ComputeTorationMatrix(); + + + // Get the shift of the reference alignment Rref + DR3 shiftRef( refAlignment->GetTranslation()[0], refAlignment->GetTranslation()[1], refAlignment->GetTranslation()[2] ); + + // Compute the relative shift + DR3 shiftDiff( _fTr[0]-shiftRef(0), _fTr[1]-shiftRef(1), _fTr[2]-shiftRef(2) ); + DR3 shiftRel = refAlignment->RotateToPlane( shiftDiff); + SetTranslation( shiftRel); + + // Recompute plane equation + CalculatePlane(); + + //PrintAll(); + +} + + +//______________________________________________________________________________ +// +void DPrecAlign::DecomposeRotations() +{ + // Decomposes the rotation matrix, that is: + // compute the values of the rotation angle around z, x', y" + // from the values of the rotation matrix + // + // To solve ambiguities, angle values nearest to the known ones are chosen. + // + // Updates the angle values in the _fTh vector, + // [0]=z, [1]=y', [2]=x" + // + // JB 2011/04/04 + + Double_t theta[3]; //0=z, 1=y, 2=x + + // first angle is obtained from + // rotmat[0,2] = - sin(theta[1]) + // but we need to test if this +/- 1 + +// OLD CODE :: (LC 2014/12/05) +/* + // Case where theta[1] = +/- pi/2 means the beam is perpendicular to the sensor!!! + if( TMath::Abs(_rotmat[0][2]) > (1-1e-4) ) { + cout << " Rotation around y is pi/2 and indicates the beam is perpendicular to the sensor!!!" << endl; + for( Short_t i=0; i<3; i++) { + theta[i] = _fTh[i]; + } + } + + // Case where theta[1] != +/- pi/2 + else { + if( _rotmat[0][2] < 1.e-4 ) { // theta[1] is 0 or Pi, keep as before + theta[1] = _fTh[1]; + } + else { + theta[1] = asin( - _rotmat[0][2]); + } + //cout << " th(y) = asin(" << _rotmat[0][2] << ") = " << theta[1] << endl; + theta[2] = atan2( _rotmat[1][2]*cos(theta[1]), _rotmat[2][2]*cos(theta[1]) ); + //cout << " th(x) = atan(" << _rotmat[1][2]*cos(theta[1]) << " / " << _rotmat[2][2]*cos(theta[1]) << ") = " << theta[2] << endl; + theta[0] = atan2( _rotmat[0][1]*cos(theta[1]), _rotmat[0][0]*cos(theta[1]) ); + //cout << " th(z) = atan(" << _rotmat[0][1]*cos(theta[1]) << " / " << _rotmat[0][0]*cos(theta[1]) << ") = " << theta[0] << endl; + } +*/ + +//NEW CODE :: (LC 2014/12/05) + +/* + theta[1] = asin( -_rotmat[0][2]); + theta[2] = atan2( _rotmat[1][2]*cos(theta[1]), _rotmat[2][2]*cos(theta[1]) ); + theta[0] = atan2( _rotmat[0][1]*cos(theta[1]), _rotmat[0][0]*cos(theta[1]) ); +*/ + + // Case where theta[1] = +/- pi/2 means the beam is perpendicular to the sensor!!! +/* + if( TMath::Abs(_rotmat[2][0]) > 0.9999 ) { + cout << " Rotation around y is pi/2 and indicates the beam is perpendicular to the sensor!!!" << endl; + for( Short_t i=0; i<3; i++) { + theta[i] = _fTh[i]; + } + } + + // Case where theta[1] != +/- pi/2 + else { + if( _rotmat[2][0] < 1.e-4 ) { // theta[1] is 0 or Pi, keep as before + theta[1] = _fTh[1]; + } + else { + theta[1] = asin( - _rotmat[2][0]); + } + //cout << " th(y) = asin(" << _rotmat[0][2] << ") = " << theta[1] << endl; + theta[2] = atan2( _rotmat[2][1]*cos(theta[1]), _rotmat[2][2]*cos(theta[1]) ); + //cout << " th(x) = atan(" << _rotmat[1][2]*cos(theta[1]) << " / " << _rotmat[2][2]*cos(theta[1]) << ") = " << theta[2] << endl; + theta[0] = atan2( _rotmat[1][0]*cos(theta[1]), _rotmat[0][0]*cos(theta[1]) ); + //cout << " th(z) = atan(" << _rotmat[0][1]*cos(theta[1]) << " / " << _rotmat[0][0]*cos(theta[1]) << ") = " << theta[0] << endl; + } + + for( Short_t i=0; i<3; i++) { + _fTh[i] = theta[i]; + } + +*/ + +// With rotation in this order : X, Y, Z. +/* + theta[1] = TMath::ASin(+_tormat[2][0]); // (+) --> sens anti-horaire + Double_t cosY = TMath::Cos(theta[1]); + + if( fabs(cosY) > 1e-4 ) { // No GIMBAL LOCK + + Double_t cosX = _rotmat[2][2] / cosY; + Double_t sinX = -_rotmat[2][1] / cosY; // (-) --> sens anti-horaire. + theta[2] = TMath::ATan2(sinX, cosX); // Rad + + Double_t cosZ = _rotmat[0][0] / cosY; + Double_t sinZ = -_rotmat[1][0] / cosY; // (-) --> sens anti-horaire. + theta[0] = TMath::ATan2(sinZ, cosZ); // Rad + + } + else { // GIMBAL LOCK ! + + theta[0] = 0; + + Double_t cosX = _rotmat[1][1]; + Double_t sinX = +_rotmat[1][2]; // (+) --> sens anti-horaire. + theta[2] = TMath::ATan2(sinX, cosX); + } + + for( Short_t i=0; i<3; i++) { + _fTh[i] = fmod(theta[i], 2*TMath::Pi() ); + } +*/ +// Last Modified : 2015/01/30 : Now we compute the sensor tilts with the real rotation matrix. +// With rotation in this order : X, Y, Z. + + theta[1] = TMath::ASin(+_tormat[0][2]); // (-) --> sens anti-horaire. + Double_t cosY = cos(theta[1]); + + if( fabs(cosY) > 1e-4 ) { // No GIMBAL LOCK + + Double_t cosX = _rotmat[2][2] / cosY; + Double_t sinX = -_rotmat[1][2] / cosY; // (+) --> sens anti-horaire. + theta[2] = TMath::ATan2(sinX, cosX); // Rad + + Double_t cosZ = _rotmat[0][0] / cosY; + Double_t sinZ = -_rotmat[0][1] / cosY; // (+) --> sens anti-horaire. + theta[0] = TMath::ATan2(sinZ, cosZ); // Rad + + } + else { // To compose with GIMBAL LOCK :) + + theta[2] = 0; + + Double_t cosZ = _rotmat[1][1]; + Double_t sinZ = -_rotmat[1][0]; // (-) --> sens anti-horaire. + theta[0] = TMath::ATan2(sinZ, cosZ); //rad + } + + for( Short_t i=0; i<3; i++) { + _fTh[i] = fmod(theta[i], 2*TMath::Pi() ); + } + +} + +//______________________________________________________________________________ +// +// JB, for inline compilation +void DPrecAlign::Streamer(TBuffer &R__b) +{ + // Modified: JB 2010/09/03 + + if(fDebugDPrecAlign) cout << "In DPrecAlign::Streamer " << endl; + if ( R__b.IsReading() ) { + if(fDebugDPrecAlign) cout << "Buffer is reading " << endl; + UInt_t R__s, R__c; + Version_t R__v = R__b.ReadVersion(&R__s,&R__c); + if(fDebugDPrecAlign) cout << "Version "<< R__v << endl; + if ( R__v > 1 ) { + DPrecAlign::Class()->ReadBuffer(R__b,this,R__v,R__s,R__c); + return; + } + //====process old versions before automatic schema evolution=v1 + if(fDebugDPrecAlign) cout << "Processing old version " << endl; + TObject::Streamer(R__b); + R__b.ReadStaticArray((double*)_ahpla); + R__b.ReadStaticArray((double*)_ateb); + R__b.ReadStaticArray((double*)_ammag); + R__b.ReadStaticArray((double*)_tormat); + R__b.ReadStaticArray((double*)_alpha); + R__b.ReadStaticArray((double*)_beta); + R__b.ReadStaticArray((double*)_gamma); + R__b.ReadStaticArray((double*)_rotmat); + R__b >> _Acoeff; + R__b >> _Bcoeff; + R__b >> _Ccoeff; + R__b.ReadStaticArray((double*)_fTh); + R__b.ReadStaticArray((double*)_fTr); + _data.Streamer(R__b); + _data1.Streamer(R__b); + //__miniVectors.Streamer(R__b); + //_dataMV.Streamer(R__b); + //_dataMV1.Streamer(R__b); + R__b >> _xh; + R__b >> _yh; + R__b >> _zh; + R__b.ReadStaticArray((double*)_initialRotations); + R__b.ReadStaticArray((double*)_initialPosition); + R__b.CheckByteCount(R__s, R__c, DPrecAlign::IsA()); + //====end of old version + } else { + if(fDebugDPrecAlign) cout << "Buffer is writing " << endl; + DPrecAlign::Class()->WriteBuffer(R__b,this); + } +} diff --git a/src/DR3.cxx b/src/DR3.cxx new file mode 100755 index 0000000..a44bccb --- /dev/null +++ b/src/DR3.cxx @@ -0,0 +1,293 @@ +// @(#)maf/dtools:$Name: $:$Id: DR3.cxx v.2 2005/10/02 18:03:46 sha Exp $ +//*-- Author : Dirk Meier 98/01/09 + + ///////////////////////////////////////////////////////////////////////// + // Class Description of DR3 // + // // + // this is a basic vector class, restricted to 3 dimensional vectors // + // could be replaced later by more general class // + // // + ///////////////////////////////////////////////////////////////////////// + + +//*-- Modified : +// Last Modified: VR 2014/06/29 Add Convert2DoubleArray() and ComputeWithSlopeAndDistance methods and SetValue(const Double_t) + +//*-- Copyright: RD42 + + +//*KEEP,CopyRight. +/************************************************************************ + * Copyright(c) 1997, DiamonTracking + ***********************************************************************/ + +#include "Riostream.h" + +//*KEEP,DR3. +#include "DR3.h" + +//*KEND. + +ClassImp(DR3) // Description of a Vector in 3 dim. space, R^3 + +//______________________________________________________________________________ +// +DR3::DR3() +{ + fCoordinate = new Double_t[3]; +} + +//______________________________________________________________________________ +// +DR3::DR3(const DR3 &aR3) +{ + fCoordinate = new Double_t[3]; + copy(aR3); +} + +//______________________________________________________________________________ +// +DR3::~DR3() +{ + delete [] fCoordinate; +} + +//______________________________________________________________________________ +// + +void DR3::copy(const DR3 &aR3) +{ + fCoordinate[0] = aR3(0); + fCoordinate[1] = aR3(1); + fCoordinate[2] = aR3(2); +} + +//______________________________________________________________________________ +// +DR3::DR3(Double_t aX, Double_t aY, Double_t aZ) +{ + fCoordinate = new Double_t[3]; + fCoordinate[0] = aX; + fCoordinate[1] = aY; + fCoordinate[2] = aZ; +} + +//______________________________________________________________________________ +// +void DR3::Convert2DoubleArray(Double_t *vector3) +{ + vector3[0]=fCoordinate[0]; + vector3[1]=fCoordinate[1]; + vector3[2]=fCoordinate[2]; + +} +//______________________________________________________________________________ +// +void DR3::Print(const Option_t*) const +{ + printf("DR3: %f, %f, %f\n",fCoordinate[0],fCoordinate[1],fCoordinate[2]); + +} + +//______________________________________________________________________________ +// +void DR3::Zero() +{ + fCoordinate[0] = 0.; + fCoordinate[1] = 0.; + fCoordinate[2] = 0.; +} + +//______________________________________________________________________________ +// +Double_t DR3::Length() +{ + return sqrt(fCoordinate[0] * fCoordinate[0] + + fCoordinate[1] * fCoordinate[1] + + fCoordinate[2] * fCoordinate[2]); +} + +//______________________________________________________________________________ +// +void DR3::SetDifference(DR3 &a, DR3 &b) +{ + fCoordinate[0] = a(0) - b(0); + fCoordinate[1] = a(1) - b(1); + fCoordinate[2] = a(2) - b(2); +} + +//______________________________________________________________________________ +// +Double_t DR3::InnerProduct(DR3 &a) +{ + return a(0) * fCoordinate[0] + a(1) * fCoordinate[1] + a(2) * fCoordinate[2]; +} + +//______________________________________________________________________________ +// +void DR3::SetScale(DR3 &a, const Double_t s) +{ + fCoordinate[0] = a(0) * s; + fCoordinate[1] = a(1) * s; + fCoordinate[2] = a(2) * s; +} + +//______________________________________________________________________________ +// +void DR3::SetBias(DR3 &a, const Double_t b) +{ + fCoordinate[0] = a(0) + b; + fCoordinate[1] = a(1) + b; + fCoordinate[2] = a(2) + b; +} + +//______________________________________________________________________________ +// +void DR3::SetValue(Double_t u, Double_t v, Double_t w) +{ + fCoordinate[0] = u; + fCoordinate[1] = v; + fCoordinate[2] = w; +} + +//______________________________________________________________________________ +// +void DR3::SetValue(const Float_t* value) +{ + fCoordinate[0] = value[0]; + fCoordinate[1] = value[1]; + fCoordinate[2] = value[2]; +} + +//______________________________________________________________________________ +// +void DR3::SetValue(const Double_t* value) +{ + //VR 2014/06/29 + fCoordinate[0] = (Double_t)value[0]; + fCoordinate[1] = (Double_t)value[1]; + fCoordinate[2] = (Double_t)value[2]; +} + +//______________________________________________________________________________ +// +void DR3::SetValue(const DR3 &a){ + fCoordinate[0] = a(0); + fCoordinate[1] = a(1); + fCoordinate[2] = a(2); +} + +//______________________________________________________________________________ +// +Double_t& DR3::operator()(Int_t aIndex) +{ + return (Double_t&)((*(const DR3 *)this)(aIndex)); + //return fCoordinate[aIndex]; +} + +//______________________________________________________________________________ +// +Double_t& DR3::operator()(Int_t aIndex) const +{ + return fCoordinate[aIndex]; +} + +//______________________________________________________________________________ +// +DR3& DR3::operator-=(const DR3 &rhs) +{ + fCoordinate[0] -= rhs(0); + fCoordinate[1] -= rhs(1); + fCoordinate[2] -= rhs(2); + return *this; +} + +//______________________________________________________________________________ +// +DR3& DR3::operator+=(const DR3 &rhs) +{ + fCoordinate[0] += rhs(0); + fCoordinate[1] += rhs(1); + fCoordinate[2] += rhs(2); + return *this; +} + +//______________________________________________________________________________ +// +DR3& DR3::operator/=(const Double_t s) +{ + if (s != 0.0) { + fCoordinate[0] /= s; + fCoordinate[1] /= s; + fCoordinate[2] /= s; + } + return *this; +} + +//______________________________________________________________________________ +// +DR3& DR3::operator*=(const Double_t s) +{ + fCoordinate[0] *= s; + fCoordinate[1] *= s; + fCoordinate[2] *= s; + + return *this; +} + +//______________________________________________________________________________ +// +DR3& DR3::operator=(const DR3& rhs) +{ + SetValue(rhs); + return *this; +} + +//______________________________________________________________________________ +// +DR3 DR3::operator*(const Double_t rhs) +{ + DR3 result(*this); + result *= rhs; + return result; +} + +//______________________________________________________________________________ +// +DR3 DR3::operator/(const Double_t rhs) +{ + DR3 result(*this); + result /= rhs; + return result; +} + +//______________________________________________________________________________ +// +DR3 DR3::operator+(const DR3& rhs) +{ + DR3 result(*this); + result += rhs; + return result; +} + +//______________________________________________________________________________ +// +DR3 DR3::operator-(const DR3& rhs) +{ + DR3 result(*this); + result -= rhs; + return result; +} + +//______________________________________________________________________________ +// +DR3 DR3::ComputeWithSlopeAndDistance(const DR3& slope, const Double_t& distance) +{ + // Compute a point position from a start point, a slope, and a distance + DR3 result; + result(0) = (*(const DR3 *)this)(0) + slope(0)*distance; + result(1) = (*(const DR3 *)this)(1) + slope(1)*distance; + result(2) = (*(const DR3 *)this)(2) + slope(2)*distance; + + return result; +} diff --git a/src/DSession.cxx b/src/DSession.cxx new file mode 100644 index 0000000..7435899 --- /dev/null +++ b/src/DSession.cxx @@ -0,0 +1,703 @@ +// @(#)maf/dtools:$Name: $:$Id:DSession.cxx v.1 2005/10/02 18:03:46 sha Exp $ +// Author : ? +// Last Modified: JB 2008/10/13 +// Last Modified: JB 2009/05/22,24,26 +// Last Modified: JB 2009/07/17 +// Last Modified: JB 2009/08/26 FillTree +// Last Modified: JB 2009/09/09 FillTree +// Last Modified: JB 2009/09/14 ResultDir added +// Last Modified: JB 2009/10/02 Finish +// Last Modified: JB 2010/10/13 Finish +// Last Modified: JB 2011/03/14 NextEvent, FillTree +// Last Modified: JB 2011/07/21 FillTree +// Last Modified: SS 2011/11/14 InitSession +// Last Modified: SS 2011/12/14 Finish +// Last Modified: SS 2012/08/10 NextRawEvent +// Last Modified: JB 2013/10/11 Get/SetTrackGeoLimitsForAlign +// Last Modified: JB 2013/06/22 Improved management of EventBuildingBoardMode (InitSession) +// Last Modified: JB 2013/07/14 TrackChi2Limit introducedForAlign +// Last Modified: BH 2013/08/20 Warning corrections from clang +// Last Modified: VR 2014/06/29 Add SetEventsToDo() and GetConfigFile() methods +// Last Modified: VR 2014/06/30 Simplification in InitSession +// Last Modified: VR 2014/07/13 Rename fEventCount by fCurrentEventNumber and add the GoToEvent and GoToNextEvent methods +// Last Modified: JB 2014/08/29 FillTree +// Last Modified: BB 2015/11/18 Modification of FillTree to avoid a Break segmentation +// Last Modified: JB 2021/05/01 Propagate potential sourcePath set via command line + + //////////////////////////////////////////////////////////// + // Class Description of DSession // + // // + // + frame for analysis of raw event data // + // + dumps data on standard output // + // + fills events for storing in .root file // + // // + //////////////////////////////////////////////////////////// + +#include "Riostream.h" +#include "TString.h" +#include "DSession.h" +#include "DTracker.h" +#include "DPlane.h" +#include "DHit.h" +#include "DTrack.h" +//#include "DInp.h" +#include "DStrip.h" +#include "DSetup.h" +#include "DAcq.h" +//#include "DReader.h" +#include "DR3.h" +#include "TBits.h" + +ClassImp(DSession) // DSession + +DSession *DSession::fgInstance = 0; // returns pointer to global object + +//_____________________________________________________________________________ +// +DSession::DSession(Option_t*) +{ + if (fgInstance) Warning("DSession", "object already instantiated"); + else fgInstance = this; + fDebugSession=0; //SS 2011.11.16 Initialization of debug level. It was set to one under certain circumstances + + fTracker = nullptr; // liuqy 2014/11/20: Avoid segment fault caused by "if(pointer) pointer->Method()" without pointer initialization. + fAcq = nullptr; // liuqy 2014/11/20: Avoid segment fault caused by "if(pointer) pointer->Method()" without pointer initialization. + +} + +//_____________________________________________________________________________ +// +DSession::DSession() +{ + + fc = nullptr; + fAcq = nullptr; + fTracker = nullptr; + + cout << endl << " -*-*- DSession Constructor -*-*- " << endl; + fc = new DSetup(*this); // creation and initialization of DSetup + fc->SetDebug( fDebugSession); // JB, 2008/10/13 + cout << " - Reading configuration " << endl; + //----------------------- + fc->ReadConfiguration(); + //----------------------- + fAcq = new DAcq(*fc); // construct "DataAcquisition" object. + fTracker = new DTracker(*fc, *fAcq); // construct the DTracker + + fEventsToDo = 0; + fCurrentEventNumber = 0; + + // JB 2013/06/11 + fTrackLimitsForAlignX[0] = 0.; + fTrackLimitsForAlignX[1] = 0.; + fTrackLimitsForAlignY[0] = 0.; + fTrackLimitsForAlignY[1] = 0.; + fTrackChi2LimitForAlign = 0; // 2013/07/14 + + cout << endl << " - Session now started " << endl; + if (fgInstance) Warning("DSession", "object already instantiated"); + else fgInstance = this; + + cout << endl << " -*-*- DSession Constructor DONE -*-*- " << endl; +} + +//______________________________________________________________________________ +// +DSession::DSession(const Int_t aRunNumber) +{ + cout << endl << " -*-*- DSession Constructor -*-*- " << endl; + + SetRunNumber(aRunNumber); + cout << " done " << endl; + if (fgInstance) Warning("DSession", "object already instantiated"); + else fgInstance = this; + + cout << endl << " -*-*- DSession Constructor DONE -*-*- " << endl; +} + +//______________________________________________________________________________ +// +void DSession::InitSession() +{ + // Initialize any session + // this is the very first method to be called + // + // Modified: JB 2011/07/07 to localize path names + // Modified: SS 2011/11/14 for EventBuildingMode + // Modified: JB 2013/06/22 for EventBuildingBoardMode + // Modified: VR 2014/06/30 simplification of SetConfigPath and SetConfigFileName + + cout << endl << " -+-+- DSession Session Initialization -+-+- " << endl; + + fStatus = 0; // AP, 2015/12/07 + // + + // Get basic information + Char_t textRunNumber[250]; + sprintf(textRunNumber,"%d",fRunNumber); + cout << endl << " - Run Number : " << fRunNumber << endl; + + fc = nullptr; + fc = new DSetup(*this); // creation and initialization of DSetup + if( abs(fDebugSession) < 10 ) { + fc->SetDebug( abs(fDebugSession)); + } + else{ + fc->SetDebug( 0); + } + fc->SetConfigPath(fConfigPath); + fc->SetConfigFileName(fConfigFileName); + fc->SetSourcePath(fRawSourcePath); + + // Read the .cfg file + cout << " - Reading configuration " << endl; + fc->ReadConfiguration(); // read config file with information about setup and DAQ + + // If fEventBuildingMode is positive, it will override the setting taken above by fc->ReadConfiguration(), SS 2011.11.14. + // Also update the EventBuildingBoardMode param, JB 2013/06/22 + if(fEventBuildingMode>=0) { + fc->GetAcqPar().EventBuildingMode=fEventBuildingMode; + for (int imod = 1; imod<=fc->GetAcqPar().ModuleTypes; imod++) { // correcting bug: adding initialisation BH 2013/08/20 + fc->GetModulePar(imod).EventBuildingBoardMode = fEventBuildingMode; + } + } + + // Not needed with new reading, JB 2008/10/13 + //fReader = new DReader(*fc); // construct a Run environment + //fReader->SetRawSourcePath(fRawSourcePath); // + // Read info from header file if any + //cout << "Read header file " << endl; + //fReader->ReadHeaderFile(*fc); + + // Build the run environment from previous info + fAcq = new DAcq(*fc); // construct "DataAcquisition" object. + if( fDebugSession<=0 ) fAcq->SetDebug( fDebugSession); // JB, 2010/11/25 + + fTracker = new DTracker(*fc, *fAcq); // construct the DTracker + if( fDebugSession>=0 ) fTracker->SetDebug( fDebugSession); // JB, 2010/11/25 + + fEventsToDo = 0; + fCurrentEventNumber = 0; + + // Test if the DAQ is able to go to a specif event + fDaqAbleToGoToAspecificEvent = 0; + if (((fc->GetModulePar(1).Type)/10)==5 && (fc->GetAcqPar().ModuleTypes)==1) // If DAQ is PXIeBoardReader with only one module + { + fDaqAbleToGoToAspecificEvent = 1; + std::cout << " DSession, the DAQ is able to give a specific event number !" << std::endl; + } + + + TString fnHead, fnExt; + fnHead = "DSF"; + fnExt = ".root"; + cout << "=====================================" << endl; + fSummaryFileName = fnHead + textRunNumber + fnExt; + fSummaryFilePathAndName = fSummaryFilePath + "/" + fSummaryFileName; + fTool.LocalizeDirName( &fSummaryFilePathAndName); // JB 2011/07/07 + + fSummaryFileTitle = TString("TAF TTree ") + textRunNumber; // JB 2015/03/24 + + printf(" DSession, Paths and Files :\n"); + printf(" Raw Data Source Path is %s\n", fc->GetRunPar().DataPath ); // fRawSourcePath.Data() ); JB 2009/05/12 +// printf(" Data Summary File Path (temporary OUTPUT) %s\n", fSummaryFilePath.Data() ); +// printf(" Data Summary File Name %s\n", fSummaryFileName.Data() ); + printf(" Data Summary File Name is %s\n", fSummaryFilePathAndName.Data() ); +// printf(" Data Summary File Title is %s\n", fSummaryFileTitle.Data() ); + + gSystem->mkdir( fResultDir.Data(), 1); + printf(" Result directory is %s\n", fResultDir.Data()); + + //printf(" Weight file is %s\n", fWeightFileName.Data()); + + cout << endl << " -+-+- DSession Session Initialization DONE -+-+- " << endl; + +} + +//______________________________________________________________________________ +// +void DSession::SetDebug(Int_t aDebug) +{ + // Initialize or update the debugging level + // updates also the level for Acquisition and tracker + // + // Created by JB 2009/05/12 + // Last Modified: JB 2009/05/22 (cope with negative debug level) + + fDebugSession = aDebug; + cout << "DSession debug updated to " << fDebugSession << endl; + + if( aDebug>=0 ) { // for positive level, update only the Tracker + if( fTracker ) { fTracker->SetDebug( aDebug); } + } + if( aDebug<=0 ) { // for negative level, update only the Dacq + if( fAcq ) { fAcq->SetDebug( aDebug); } + } + +} + +//______________________________________________________________________________ +// +void DSession::SetTrackGeoLimitsForAlign(Double_t xmin, Double_t xmax, Double_t ymin, Double_t ymax) { + + // Define geometrical limits of tracks to be considered for alignment. + // Those limits are given in the tracker frame AND FOR Z=0. + // + // JB 2013/06/10 + + fTrackLimitsForAlignX[0] = xmin; + fTrackLimitsForAlignX[1] = xmax; + fTrackLimitsForAlignY[0] = ymin; + fTrackLimitsForAlignY[1] = ymax; + + printf("--> Align procedure is restricted to tracks with (at Z=0):"); + printf(" %.2f < X < %.2f and %.2f < Y < %.2f\n\n", fTrackLimitsForAlignX[0], fTrackLimitsForAlignX[1], fTrackLimitsForAlignY[0], fTrackLimitsForAlignY[1]); + +} + +//______________________________________________________________________________ +// +void DSession::SetTrackChi2LimitForAlign(Double_t aLimit) { + + // Define upper chi2 limit of tracks to be considered for alignment. + // + // JB 2013/07/14 + + fTrackChi2LimitForAlign = aLimit; + + printf("--> Align procedure is restricted to tracks with chi2<=%f.\n", fTrackChi2LimitForAlign); + +} + +//______________________________________________________________________________ +// +void DSession::GetTrackGeoLimitsForAlign(Double_t &xmin, Double_t &xmax, Double_t &ymin, Double_t &ymax) { + + // Store the geometrical limits of tracks to be considered for alignment, + // in the variable references provided. + // Those limits are given in the tracker frame AND FOR Z=0. + // + // JB 2013/06/11 + + xmin = fTrackLimitsForAlignX[0]; + xmax = fTrackLimitsForAlignX[1]; + ymin = fTrackLimitsForAlignY[0]; + ymax = fTrackLimitsForAlignY[1]; + +} + +//______________________________________________________________________________ +// +//void DSession::SetWeightFile( TString aFileName) { +// +// // Open the file containing the paramettrization for the eta function +// // +// // JB 2011/04/12 +// // Modified JB 2011/07/07 to localize path name +// +// fWeightFileName = aFileName; +// fTool.LocalizeDirName( &fWeightFileName); // JB 2011/07/07 +// if( gSystem->AccessPathName(fWeightFileName.Data())) Info("SetWeightFile","%s doesn't exist, it is created.",fWeightFileName.Data()); +// fWeightFile = new TFile(fWeightFileName.Data(), "UPDATE"); // READ->UPDATE, JB 2011/04/12 +// if(fWeightFile->IsZombie()||fWeightFile->GetNkeys()==0){ // QL 2015/11/04, recreate the file if it is a zombie or empty to avoid TAF crash. +// fWeightFile->Close(); +// fWeightFile = new TFile(fWeightFileName.Data(), "RECREATE"); +// } +// +//} +//______________________________________________________________________________ +// + +Bool_t DSession::NextRawEvent( Int_t aTrigger) +{ + + // Generate the reading of the next event, + // optionally corresponding to a given trigger, + // aTrigger=-1 means no specific trigger required. + // + // This methods define the event number known to TAF. + // + // completely changed for new reading, JB 2008/10/13 + // Modified: JB 2011/03/14, to start event number at 0 + // Modified: JB 2012/07/10, request a specific trigger to DAQ + // Modified: SS 2012/08/10, management of DAcq multi-bits output + + TBits* DAcqResult=new TBits(2); + + if (fCurrentEventNumber++ <= fEventsToDo) { + //------------------------ + DAcqResult = fAcq->NextEvent( fCurrentEventNumber-1, aTrigger); // get the next event from DAcq, -1 to start at 0, JB 2011/03/14 + //------------------------ + if( !DAcqResult->TestBitNumber(0) ) { cout << "WARNING: DSession, event " << fCurrentEventNumber << " can't be retrieve!" << endl; } + if( DAcqResult->TestBitNumber(1) ) { cout << "WARNING: DSession, event " << fCurrentEventNumber << " is missing from the list!" << endl; } + + } else { + cout << "WARNING: DSession, enough events " << fCurrentEventNumber << " / " << fEventsToDo << "!"<GetPlanesStatus() ){ // Moved from Loop(), JB 2009/05/26 + SetStatus(fTracker->GetPlanesStatus()) ; + } + + // display current event number with variable frequency + Int_t frequency = 1; // added by JB, April 2008 + if( fDebugSession) { cout << endl << endl; } + else if( fCurrentEventNumber > 100000) frequency = 10000; + else if( fCurrentEventNumber > 10000) frequency = 5000; + else if( fCurrentEventNumber > 1000) frequency = 500; + else if( fCurrentEventNumber > 10) frequency = 50; + if( fCurrentEventNumber/frequency*frequency == fCurrentEventNumber) { + cout << "Event " << fCurrentEventNumber << " over " << fEventsToDo << " "; + fWatch.Print(); // JB, 2008 September, to monitor CPU time + fWatch.Continue(); + } + + return DAcqResult->TestBitNumber(0); // stop only when no more event readable +} + +//______________________________________________________________________________ +// +Int_t DSession::GoToEvent(Int_t anEvent) +{ + // Specific method to ask the DAQ for a given event + // + // Created : VR 2014/07/13, from NextRawEvent( Int_t aTrigger) + if (anEvent<0) + { + cout << "ERROR: DSession::GoToEvent : give a positive event nb value!" << endl; + return -1; + } + + if (fDaqAbleToGoToAspecificEvent) + { + TBits* DAcqResult=new TBits(2); + + DAcqResult = fAcq->NextEvent(anEvent, anEvent); + if( !DAcqResult->TestBitNumber(0)) + { + cout << "WARNING: DSession::GoToEvent : event " << anEvent << " can't be retrieve!" << endl; + return -1; + } + if( DAcqResult->TestBitNumber(1)) + { + cout << "WARNING: DSession::GoToEvent : event " << anEvent << " is missing from the list!" << endl; + return -1; + } + + fCurrentEventNumber = anEvent; + + if (GetStatus()==0 && fTracker->GetPlanesStatus() ) + { + SetStatus(fTracker->GetPlanesStatus()) ; + } + + return fCurrentEventNumber; + } + else + { + cout << "ERROR: DSession::GoToEvent : to use this function, the real event nb must be able to be calculated, not the case!" << endl; + return -1; + } +} + +//______________________________________________________________________________ +// +Int_t DSession::GoToNextEvent(void) +{ + // Specific method to ask the DAQ for a given event + // + // Created : VR 2014/07/13, from NextRawEvent( Int_t aTrigger) + + if (fDaqAbleToGoToAspecificEvent) + { + TBits* DAcqResult=new TBits(2); + + DAcqResult = fAcq->NextEvent(fCurrentEventNumber+1,fCurrentEventNumber+1); + if( !DAcqResult->TestBitNumber(0)) + { + cout << "WARNING: DSession::GoToEvent : event " << fCurrentEventNumber+1<< " can't be retrieve!" << endl; + return -1; + } + if( DAcqResult->TestBitNumber(1)) + { + cout << "WARNING: DSession::GoToEvent : event " << fCurrentEventNumber+1 << " is missing from the list!" << endl; + return -1; + } + + fCurrentEventNumber ++; + + if (GetStatus()==0 && fTracker->GetPlanesStatus() ) + { + SetStatus(fTracker->GetPlanesStatus()) ; + } + + // display current event number with variable frequency + Int_t frequency = 1; + if( fDebugSession) { cout << endl << endl; } + else if( fCurrentEventNumber > 100000) frequency = 10000; + else if( fCurrentEventNumber > 10000) frequency = 5000; + else if( fCurrentEventNumber > 1000) frequency = 500; + else if( fCurrentEventNumber > 10) frequency = 50; + if( fCurrentEventNumber/frequency*frequency == fCurrentEventNumber) + { + cout << "Real Event Nb " << fCurrentEventNumber << " "; + fWatch.Print(); + fWatch.Continue(); + } + + return fCurrentEventNumber; + } + else + { + if (!NextRawEvent(-1)) return -1; + return fCurrentEventNumber; + } +} + +//______________________________________________________________________________ +// + +void DSession::MakeTree() +{ + // Create a new ROOT file with Tree. + + // Not needed with new reading, JB 2008/10/13 + //fReader->Reset(); + //fCurrentEventNumber = 0; + fStatus = 0; + Int_t tCompressionLevel = 2; + + // If level = 1, only branches containing integers will be compressed. + // If level >= 2, all branches will be compressed with compression level-1. + + fSummaryFile = new TFile(fSummaryFilePathAndName, "RECREATE", fSummaryFileTitle); + fSummaryFile->SetCompressionLevel(tCompressionLevel); + fEvent = new DEvent(*fc); + + // Create a ROOT Tree and one branch + + //TTree::SetMaxTreeSize(1000*Long64_t(2000000000)); + fEventTree = new TTree("T", fSummaryFileTitle); + fEventTree->SetAutoSave(100000000); // autosave when 1 Mbyte written + fEventTree->Print(); + TBranch *b = fEventTree->Branch("fEvent","DEvent",&fEvent,64000,99); + b->SetAutoDelete(kFALSE); + + if( !fEventTree || !b ) printf("\n\n-*-*- ERROR DSession:MakeTree, something is wrong with the creation of the TTree!\n\n"); + + printf("DSssion, EventTree is prepared and will be filled with event data \n"); +} + +//_____________________________________________________________________________ +// +void DSession::Loop() +{ + cout << endl << endl << "Session: " << fEventsToDo << " events will be read" << endl << endl ; + + fWatch.Start(); // Start to count processing time, JB 2008/08/08 + + while(NextRawEvent() == kTRUE) { // event loop + //============== + Int_t Updt = fTracker->Update(); +//cout << __FILE__ << __LINE__ << endl; + //============== + if( fDebugSession) printf("\n\nDSession::Loop Event=%d, Updt=%d, f(Session)Status=%d, fPlanesStatus=%d\n", GetCurrentEventNumber(), Updt, GetStatus(), fTracker->GetPlanesStatus()); + +//cout << __FILE__ << __LINE__ << endl; + // kill events received after reset + if (Updt == 0) { // Condition "&& GetStatus() >=1" removed by JB, 2007 June +//cout << __FILE__ << __LINE__ << endl; + //============== + FillTree(); +//cout << __FILE__ << __LINE__ << endl; + //============== + } + else { +//cout << __FILE__ << __LINE__ << endl; + if( fDebugSession) cout << "DSession::Loop Something's wrong in Tracker update for event " << GetCurrentEventNumber() << ", No Tree filled" << endl; +//cout << __FILE__ << __LINE__ << endl; + } +//cout << __FILE__ << __LINE__ << endl; + + } // end event loop +//cout << __FILE__ << __LINE__ << endl; + //fEventTree->Print(); +} + +//______________________________________________________________________________ +// +void DSession::Scan() +{ + + DPlane *thePl = GetTracker()->GetPlane(fPlaneToScan) ; + + Int_t nu =thePl->GetStripsNu() ; + Int_t nv =thePl->GetStripsNv() ; + + char c = 'a'; + char stop = 's'; + while(NextRawEvent() == kTRUE && c != stop) { + if (fTracker->Update() != 0 ) cout << "Problem with some planes " << endl ; + if (GetStatus() >=1) { + Int_t ist = 1 ; + for (Int_t iu=1 ; iuGetRawValue(ist) << " " ; + ist++ ; + } + + } + cout << "s to stop" << endl ; + cin >> c ; + } + } + + cout << "------------------------" << endl ; + +} + +//______________________________________________________________________________ +// +void DSession::Finish() +{ + // Modified JB 2009/09/08 to print statistics of tracking + // Modified JB 2009/10/02 to print statistics of tree + // Modified JB 2010/10/13 to print end time + // Modified JB 2011/04/12 close weight file + // Modified SS 2011/12/14 save statistics to the logfile + + TDatime aTime; + fTracker->PrintStatistics(); + fAcq->PrintStatistics(); + ofstream logfile; + logfile.open("DSFProd.log",ios::app); + logfile<<"============================================"<PrintStatistics(logfile); + fAcq->PrintStatistics(logfile); + logfile.close(); + + printf("************************************\n"); + printf("Entries in TTree: %ld\n.", (long int)fEventTree->GetEntries()); // JB 2009/10/02, could be Long64_t + printf("************************************\n"); + + cout << endl << "TAF ends at "; + aTime.Print(); + + fSummaryFile->cd(); + fEventTree->Write(); + fSummaryFile->Close(); + //fWeightFile->Close(); // JB 2011/04/12 + +} + +//______________________________________________________________________________ +// +void DSession::FillTree() +{ + + // Fill the tree with the followinf information: + // statistics (ped, noise, # hits, ...) of each plane + // each hit info of each plane, note that each hit is associated to the nearest existing track + // each track info crossing each plane + // (note hit nb is negative for hits used in the track fit). + // + // Some plane may be skipped (use SetFillLevel(aLevel) to set): + // fFillLevel = 0 -> info (hits+tracks) of all planes written, + // fFillLevel = 1 -> only the full info of planes with status=3 (DUT) is written, + // for other planes, only the track info is written. + // + // Last modified: JB 2009/05/24, 2009/07/17 (too allow for multi-track) + // Last modified: JB 2009/08/26, to count track from 1 (not 0) + // Last modified: JB 2009/9/09, event and frame(-realEvent) number stored + // Last modified: JB 2011/03/14, plane status condition removed + // Last modified: JB 2011/06/30, printout of events + // Last modified: JB 2011/07/21, select which plane info are stored + // Last modified: JB 2014/08/29, indicate if track fitted with hit and new fill conditions + // Last modified: BB 2015/11/17, change for loop on track to do...while to be sure that the event is read + + DPlane *tPlane=nullptr; //nullptr instead of 0 + DTrack *tTrack=nullptr; //nullptr instead of 0 + DHit *tHit=nullptr; + Int_t tracksN(0), hitsN(0), pl(0); + Bool_t hitAssociated(false); + + // Event number is the counter of DSession, + // while the "real" event number from DAQ is stored as the frame number + // JB 2009/09/09 + fEvent->SetHeader( GetCurrentEventNumber(), fAcq->GetRunNumber(), 0, 0, 0, + fAcq->GetTriggers(), fAcq->GetFrames(), fAcq->GetTimestamps()); + fEvent->SetFrame( fAcq->GetRealEventNumber(), 0 ); + + tracksN = fTracker->GetTracksN(); // Number of tracks for this event + if (fDebugSession) printf("DSession::FillTree, Event Trig %d, current Event %d: %d track\n", fAcq->GetRealEventNumber(), GetCurrentEventNumber(), tracksN); + + // Loop on planes + //Int_t Npl(0); + //Npl=fTracker->GetPlanesN(); + for (pl = 1; pl <= fTracker->GetPlanesN(); pl++) { // Loop on planes + + tPlane = fTracker->GetPlane(pl); + if( fDebugSession) printf("DSession::FillTree got plane %d with status %d\n", pl, tPlane->GetStatus()); + + // for all planes which have been analyzed + // condition on Readout added by JB, 2007 June + // condition on Status removed by JB, 2011/03/14 + if ( GetCurrentEventNumber()>1 && tPlane->GetReadout()!=0 ) { // condition for storing info, modified JB 2014/08/29 + + if( fDebugSession) printf("DSession::FillTree adding authenticPlane %d\n", pl); + fEvent->AddAuthenticPlane(*tPlane, fAcq->GetRealEventNumber()); // basic info on planes + + // store hits, test condition on status and FillLevel added JB 2014/08/29 + if ( !fFillLevel || (tPlane->GetStatus() == 3)) { // + hitsN = tPlane->GetHitsN(); + if( fDebugSession) printf("DSession::FillTree adding %d authenticHit for plane %d\n", hitsN, pl); + + for (Int_t ht = 1; ht <= hitsN; ht++) { // loop on hits + tHit = tPlane->GetHit(ht); + tTrack = fTracker->nearest_track(tHit); // nearest track, JB 2009/07/17 +// printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\t%d\n", GetCurrentEventNumber(), tHit->GetNumber(), tPlane->GetHitsN(), tHit->GetStripsInCluster(), tHit->GetClusterPulseSum(), tHit->GetPulseHeight(0), tHit->GetPositionUhit(), tHit->GetPositionVhit()); // JB 2017/11/09 + if( fDebugSession>1 ) printf("DSession::FillTree got hit %d with seed %d and %d neighbours, nearest track %d\n", ht, tHit->GetIndexSeed(), tHit->GetStripsInCluster(), tTrack?tTrack->GetNumber():-1); // JB 2009/05/12 + fEvent->AddAuthenticHit(*tHit, fAcq->GetRealEventNumber(), *tTrack); // store hit along with nearest track + } //end loop on hits + } // end condition for storing hits + + // store track (A track is stored for each plane it crosses) + if(tracksN>0){ // condition added for calibration: + if( fDebugSession) printf("DSession::FillTree adding %d transparentPlane (track) for plane %d\n", tracksN, pl); + Int_t iteratorTrack = 1; + //for( Int_t it=1; it<=tracksN; it++) { // loop on tracks + + do{ + tTrack = fTracker->GetTrack(iteratorTrack); + tHit = fTracker->nearest_hit( tTrack, pl, hitAssociated); // nearest hit, JB 2009/07/17 + if( fDebugSession>1 ) printf("DSession::FillTree got track %d, %s hit %d\n", tTrack->GetNumber(), hitAssociated?"associated":"nearest", tHit?tHit->GetNumber():0); // JB 2014,08/29 + if(tHit != nullptr){ // BB 2015/11/18 : assuming that we add a transparent plane only when there is a hit, otherwise go to the next event + fEvent->AddTransparentPlane(*tPlane, *tTrack, *tHit, hitAssociated, *fTracker ); // store track along with nearest hit + } + iteratorTrack++; + }while(iteratorTrack <= tracksN); // end loop on tracks + } // end condition added for calibration + + } // end condition for storing info + + } // end of loop over planes + + if( fDebugSession) { + printf("DSession::FillTree gonna fill the tree with event:\n"); + fEvent->GetHeader().Print(); // JB 2011/06/30 + if( fDebugSession > 2 ) fEventTree->Print(); // JB 2011/06/30 + } + fEventTree->Fill(); + + fEvent->Clear(); + +} + +void DSession::ResetDaq() +{ + fEventsToDo = 0; + fCurrentEventNumber = 0; + + fAcq->Reset(); +} diff --git a/src/DSetup.cxx b/src/DSetup.cxx new file mode 100644 index 0000000..50513de --- /dev/null +++ b/src/DSetup.cxx @@ -0,0 +1,4256 @@ +// @(#)maf/dtools:$Name: $:$Id:DSetup.cxx v.1 2005/10/02 18:03:46 sha Exp $ +// Author : ? +// Last Modified, JB, 2008/10/13 +// Last Modified, JB, 2009/05/07 +// Last Modified, JB, 2009/05/25 +// Last Modified, RDM, 2009/08/25 +// Last Modified, JB, 2009/08/25 add configuration for MimosaPro analysis +// Last Modified, JB, 2009/08/26 allow for multi-submatrix +// Last Modified, JB, 2009/09/01 new param PlanesForTrackMinimum +// Last Modified, JB, 2010/08/23 new param TriggerMode for AcqParameter +// Last Modified, JB, 2010/09/06 new param NoiseScope for AnalysisParameter +// Last Modified, JB, 2011/04/12 SetResultsPath +// Last Modified, JB, 2011/07/07 to localize path names +// Last Modified, SS, 2011/11/14 to initialize eventBuildingMode +// Last Modified, JB, 2012/04/25 debugLevel>1 to dump original config file +// Last Modified, JB, 2013/01/16 new parsing methods, compatible with ANY config file format +// Last Modified, JB, 2013/06/20 ReadDAQBoardParameters +// Last Modified, JB, 2013/06/21 ReadAnalysisParameters, ReadTrackerParameters +// Last Modified, JB, 2013/07/17 almost all ReadXXX methods +// Last Modified, JB, 2013/08/13-22 ReadPlaneParameters, ReadDAQBoardParameters +// Last Modified, JB, 2013/08/29 ReadPlaneParameters +// Last Modified, JB, 2013/09/12 ReadSubmatrixParameters, ReadAnalysisParameters +// Last Modified, JB, 2013/11/08 ReadSubmatrixParameters +// Last Modified, JB, 2014/01/07 ReadPlaneParameters +// Last Modified, JB, 2014/01/21 ReadSubmatrixParameters +// Last Modified, JB, 2014/04/21 ReadPlaneParameters +// Last Modified: VR, 2014/06/29 add the SearchMoreHitDistance parameter to tracker paramameters +// Last Modified: VR, 2014/06/30 run number is get from DSession , not read anymore from config file +// Last Modified: VR, 2014/06/30 add the DataSubDirPrefix config in RunParameters +// Last Modified: VR, 2014/07/14 add the TrackingPlaneOrderType parameter +// Last Modified: VR, 2014/07/16 new string field comparison method : strstr replaced by strcmp to prevent error with fields string that contains another field string + Add WARNING when a field is not understood +// Last Modified: VR, 2014/07/16 Add field ClusterLimitRadius for DHit::Analyse_2_cog() +// Last Modified: AP, 2014/07/16 Added two new input parameters for each plane: +// - A .root file name with the map of the fake rate +// - A cut on the single pixel fake rate to identify a list of hot pixels +// Last Modified: AP, 2014/07/16 Added a list of hotpixels (two lists, one for line and one for column) +// This list is filled whenever the .root file is espesified/exist, and the +// FakeRateCut is in (0,1) +// At the end print out the list of hot pixels per plane +// Last Modified: VR, 2014/08/28 add mecanism to keep untracked hits from last event +// Last Modified: VR, 2014/08/29 add TrackingOrderLines, TrackingOrderPreTrack and TrackingOrderExtTrack : defines planes scan order during tracking for TracksFinder 2 +// Last Modified: VR, 2014/10/30 add the PreTrackHitsNbMinimum and HitsNbMinForFullTrack parameters +// Last Modified: VR, 2014/12/18 modify parameters for TracksFinder 2 +// Last Modified: JB, 2014/12/23 add Subtrack parameters in ReadTrackerParameters +// Last Modified: AP, 2015/03/10 add to parameters to the plane parameters block: PlaneThickness and PlaneMaterial. +// To be used for MC studies of telescope resolution. +// Last Modified: AP, 2015/03/10 add to tracker parameters block: BeamType and BeamMomentum +// +// Last Modified: JB+CB+PRL, 2015/03/24 new params for INFN ReadDAQBoard +// Last Modified: LC, 2015/10/14 GlobalAlignment Parameter Reading : Now optional +// Last Modified: JB 2017/11/20 ReadDAQBoardParameters for zero suppression option +// Last Modified: JB 2018/07/04 ReadRunParameters, added PixelGainRun parameter +// Last Modified: JB 2021/05/01 Handle source path as datapath + +/////////////////////////////////////////////////////////////// +// Class Description of DSetup // +// // +// Read Setup of the Acquisition, Telescope and Analysis +// from the configuration file (text format), +// defined from the run number. +// +// All the parameters need not to be present in the text +// file, but if they are indeed needed to run +// they should be initialized ! +// ** WARNING ** currently (June 2013) the situation is not cleaned +// and many paramameters are not initialized. +// +// This is the list of all known parameters by category: (in construction) +// MANDATORY means this parameter has to be in the config file +// 1st parameter means this parameter shall be the first in the list +// --> if one of these 2 rules is broken, the file parsing will crash! +// +// ############################################################################# +// Run Parameters +// ############################################################################# +// Affiliation = [optional] (char) {""} Labs involved in the data taking +// Signature = [optional] (char) {""} One or several names +// BeamTime = [optional] (char) {""} A date, any format +// Confidence = [optional] (char) {""} Possibly a brief description of the data taking +// DataPath = [MANDATORY](char) directory of the raw data +// DataSubDirPrefix = [optional] (char) {""} sub directory for data files, stored in DataPath/DataSubDirPrefixXXX/ with XXX the run number +// Extension = [optional] (char) {""} +// RunNumber = [OBSOLETE] RunNumber is get from DSession, set via gTAF->InitSession(...) +// EventsInFile = [MANDATORY for IMGBoardReader] (int) {0} +// StartIndex = [MANDATORY for IMGBoardReader] (int) {0} +// EndIndex = [MANDATORY for IMGBoardReader] (int) {0} +// NoiseRun = [optional] (int) {0} defines either the file with the noise for each pixel, or a specific method to remove noisy pixels (see DGlobalTools::VetoPixels) +// PixelGainRun = [optional] (int) {0} if not 0, defines the file with individual pixel gain map +// ----------------------------------------------------------------------------- + + +// ############################################################################# +// Parameters of the Tracker +// ############################################################################# +// "Planes" or "Ladders" has to be the first field +// ---------------------------------- +// Planes and their parameters +// ---------------------------------- +// Planes = [MANDATORY] (int) the nb of planes in the setup +// Ladders = [optional] (int) {0} the nb of ladders in the setup (may encompass several sensors) +// TimeLimit = [optional] (int) {-1} for sensor with timestamping, defines the maximum duration of a triggered event +// Resolution = [optional] (float,um) {-1.} the knonw spatial resolution in um of the reference planes, use 4.00 for MIMOSA 26 and 1.00 for MIMOSA 18 +// BeamType = [optional] (TString) {"pion"} type of the beam particles +// BeamMomentum = [optional] (float,GeV/c) {120.0GeV/c} momentum of the beam particles +// MediumMaterial = [optional] (TString) {"vacuum"} material of the medium containing the sensors: e.g. DryAir or Vacuum +// +// ---------------------------------- +// Clustering in planes +// ---------------------------------- +// HitsInPlaneMaximum = [MANDATORY] (int) the nb hits which will be reconstruted in each plane, 0 : not clustering +// KeepUnTrackedHitsBetw2evts =[optional] (int) {0} +// 1 memorise untracked hits between 2 evenements +// +// ---------------------------------- +// Tracking parameters +// ---------------------------------- +// TracksMaximum = [optional] (int) {0} the maximum nb of tracks which will be reconstructed, if set to 0, no tracking is performed +// TracksFinder = [optional] (int) {0} select the tracking method +// 0 for the original track finder : find_tracks() +// 1 for more options: find_tracks_1_opt() allows to order plane +// 2 for the one adapted for Interaction Vertex Imaging: find_tracks_2_ivi() +// TrackFittingAlg = [optional] (int) {0}: if 0, Use the default chi-square fitting; if 1, Enable MKalmanFilter fitting; if >1, not defined, use default +// HitsInPlaneTrackMaximum = [MANDATORY if TracksMaximum!=0 && TracksFinder==0] (int) +// PlanesForTrackMinimum = [MANDATORY if TracksMaximum!=0 && TracksFinder==0 ] (int) +// the min nb hits required to make a track +// the max nb hits in a plane allowed to consider using its hits for tracking +// SearchHitDistance = [MANDATORY if TracksMaximum<2] (float,um) +// the search distance to associate a hit to a track +// UseSlopeInTrackFinder = [optional for TracksFinder=0] (int) {1} +// SearchMoreHitDistance = [MANDATORY if TracksMaximum<2] (float,um) +// the search distance to associate a hit to a pre-track +// if 1, use the track slope to extrapolate track or if 0, use "flat" slope +// TrackingPlaneOrderType = [optional for TracksFinder=1] (int) {0} Try to make a track with looking on planes ... +// 0 in the same order than in the config file +// 1 ordered with the status (0,1,2) +// SubtrackNplanes = [optional] {0}: if non-zero indicates that each track will be refitted with a subset of the planes +// SubtrackPlanes = [MANDATORY if SubtrackNplanes!=0] list of planes (separated by ":" to be used by subtrack +// HitMonteCarlo = [optional] (int) {0}: +// DPrecAlignMethod = [optional] (int) {0} 0=Old DPrecAlign, 1=New DrecAlign -> Redifinitions of Matrices, Rotations and Plane Equations. +// +// ---------------------------------- +// Tracking parameters specifics for TracksFinder=2, all MANDATORY +// ---------------------------------- +// context : PreTrack = config. of algo. to build the start track (=pre-track) only made with hits in pre-track'planes +// context : ExtTrack = config. of algo. to try to extend the pre-track with hits in ext-track'planes +// context : FullTrack = config. of algo. for the full track (can be a pre-track not extended !) +// ----------------------- +// Tracking pass +// ----------------------- +// context : HitsNbMinimum = minimum number of hits to create/extend/save a pre/ext/full track +// context : HitsTypeUsed = 0:any kind ; 1:only new hits ; 2:only memorized hits +// context : HitsMaxDist = distance between hit/track and another hit to add it to the current track [um] +// context : [Pre/Ext]TrackPARAM = {valuePass1 valuePass2 ...} +// +// TrackingPass = (int) number of pass of the tracking algo +// PreTrackHitsNbMinimum = {(int)} +// PreTrackHitsTypeUsed = {(int)} +// PreTrackHitsMaxDist = {(float)} +// ExtTrackHitsNbMinimum = {(int)} +// ExtTrackHitsTypeUsed = {(int)} +// ExtTrackHitsMaxDist = {(float)} +// FullTrackHitsNbMinimum = {(int)} +// +// ----------------------- +// Tracking Planes Order +// ----------------------- +// context : TrackingOrderLineX: [NbPlanesPreTrack]{PTpl1 PTpl2 ...} [NbPlanesExtTrack]{ETpl1 ETpl2 ETpl3 ...} +// +// TrackingOrderLines = (int) number of lines like TrackingOrderLine1, ..., +// TrackingOrderLineN = definition : TrackingOrderLineN: [P#] {P1 P2 P3 ...} [P#] {P6 P7 P8 ...} +// example : TrackingOrderLine1: [3] {5 6 7} [4] {1 2 3 4} +// means : There is [3] planes to build a pre-track : 5,6 and 7 +// and [4] planes to build the ext-track : 1,2,3 and 4 + +// ---------------------------------- +// Vertexing parameters +// ---------------------------------- +// VertexMaximum = [optional] (int) {0} +// 0 : no vertexing, +// 1 : vertices will be searched with method find_tracks_and_vertex +// VertexConstraint = [optional] (int) {0} use a vertex constraint to start track +// +// ---------------------------------- +// Alignement parameters +// ---------------------------------- +// EventsForAlignmentFit = [optional] (int) {0} the nb pairs (track-hit) for one iteration of the alignment procedure + + +// ############################################################################# +// Parameters of the Ladder +// ############################################################################# +// "LadderID" has to be the first field +// LadderID = [MANDATORY] (int), ID of the ladder +// LadderName = [MANDATORY] (char), name AND type of the ladder, used to define plane positions +// could be "Plume", "Simple", "Salat", "Custom" +// Status = [MANDATORY] (int), same meaning as for Plane, +// LadderPositionX/Y/Z = [MANDATORY] (float,mm), same meaning as for Plane, +// LadderTiltX/Y/Z = [MANDATORY] (float,deg), same meaning as for Plane, +// NbOfPlanes = [MANDATORY] (int), nb of planes associated to this ladder +// If using "Custom", you need to define each planes associated +// with the following lines +// IncludedPlane = [MANDATORY if "Custom"] (int) the plane number as defined later in the configuration +// PlaneShiftU,V,W = [MANDATORY if "Custom"] (float,mm) relative shifts of this plane wrt ladder center +// PlaneTiltU,V,W = [MANDATORY if "Custom"] (float,deg) relative tilts of this plane wrt ladder center +// +// NOTE: +// The positions/tilts of planes belonging to a ladder are defined +// by the ladder definition. Any position settings of these planes +// in the configuration files are superseeded. +// + +// ############################################################################# +// Parameters For Global Alignment +// ############################################################################# +// +// Added : LC 31/08/2015 +// Track constraints : to fix the telescope geometry +// "FixTrackParamX" has to be the first field +// FixTrackParamX = value // value = 0 for telescope case !=0 if tilted telescope +// FixTrackParamY = value // value = 0 for telescope case !=0 if titled telescope +// ResoTrackParamX = value // SPS : value = 10-5 || DESY : value = 10-3 +// ResoTrackParamY = value // SPS : value = 10-5 || DESY : value = 10-3 +// ResoAlignParamTr = value // By default : reso = 100um // Translations values set to initial translations +// ResoAlignParamRot = value // By default : reso = 0.1 rad = 5.7 deg // Rotations values set to initial rotations +// + +// ############################################################################# +// Parameters for each detector plane +// ############################################################################# +// "Inputs" has to be the first field +// +// ---------------------------------- +// Data decoding +// ---------------------------------- +// Inputs = [MANDATORY] (int), 1st parameter = number of inputs needed to build all the channels, +// -> for each input, specify in the following order: +// ModuleType = [MANDATORY] (int) index for the desired type of modules +// according to the declaration order in Acquisition module +// ModuleNumber = [MANDATORY] (int) id in the set of modules of this type +// InputNumber = [MANDATORY] (int) id of the input of this module used +// ChannelNumber = [MANDATORY] (int) channel shift so that +// plane_channel_nb = input_channel_nb + ChannelNumber +// ChannelOffset = [optional] (int) {1} first channel in the input related +// to the plane +// Channels = [MANDATORY] (int) number of channels to read from this input +// StripselUse = [obsolete] used to define dead strips +// +// ---------------------------------- +// Readout and Analysis of pixels +// ---------------------------------- +// Name = [MANDATORY] (char) just for display for now +// Purppose = [MANDATORY] (char) just for display for now +// ParentLadder = [optional] (int) indicate if the plane belong to a ladder +// and which one +// Readout = [MANDATORY] (int) specifies the type of raw data +// 0 -> not read, +// 1 data not sparsified, +// 100 sparsified data. +// AnalysisMode = [MANDATORY] (int) controls the analysis +// 0 -> data read but no clustering, +// 1 -> strips, +// 2 -> pixels with analog output, +// 3 -> pixels with binary output. +// MimosaType = [optional] (int) {0} not clear (sorry!) +// FixedGlobalAlign= [optional] (int) {0} to fix the plan for global alignment procedure +// InitialPedestal = [obsolete] (int) superseded by InitialNoise +// # events to analyze before the first computation +// InitialNoise = [MANDATORY only if Readout<100] (int) +// # events to analyze before the first computation +// CacheSize = [MANDATORY only if Readout<100] (int) +// size of the set of events from which one is picked +// for computing the noise and pedestal +// HotPixelMapFile = [optional] (char) ROOT file name with fake rate map +// FakeRateCut = [MANDATORY if HotPixelMapFile] (float) Single pixel fake rate cut +// IfDigitize = [optional] (int) {0} # thresholds to emulate the digitization +// 0 (default) means no-digitization +// DigitizeThresholds = [MANDATORY if IfDigitize>0] (array of int) +// as many values as indicated, separated with ':' +// +// ---------------------------------- +// Position and size +// ---------------------------------- +// PositionsXYZ = [MANDATORY] (3 float,mm) position of the center of the plane, +// changed by the alignment procedure +// TiltZYX = [MANDATORY] (3 float,deg) +// rotation angles defining plane orientation, +// changed by the alignment procedure +// PitchUVW = [MANDATORY] (3 float,um) pitch in all directions +// (pitchW=sensitive layer thickness, not used yet) +// StripsUVW = [MANDATORY] (3 int) # collecting noted in all directions +// SizeUVW = [obsolete] computed from PitchUVW and StripsUVW +// size of the sensitive area, set to PitchUVW if not provided +// StripSizeUVW = [optional] (3 float,um) not used yet +// AlignementU/V = [obsolete] (float,mm) old alignment shift parameter +// AlignementTilt = [obsolete] (float,deg) old alignment angle parameter +// Deformed = [optional] (int) {0} if 0 then no deformation applied, +// if 1 then deformation applied from following coeff. +// coeffLegendreU = [MANDATORY if Deformed==1] (6 floats) values (separated by ":") +// coeff of the 6 first Legendre polynomials +// used to parametrize delat_W with respect to U coordinate +// coeffLegendreV = [MANDATORY if Deformed==1] (6 floats) 6 values (separated by ":") +// coeff of the 6 first Legendre polynomials +// used to parametrize delat_W with respect to V coordinate +// Mapping = [MANDATORY] (int) drives pixel position computation, +// 1 -> position at pixel center, +// 2 -> position considers staggering +// 3,4,5 -> ? +// Status = [MANDATORY] controls how this plane is used by the tracking +// 0 = Primary Reference, never aligned and used as track seed, +// 1 = Primary Reference, never aligned and used in tracking (not for seed) +// 2 = Secondary Reference, aligned and used in tracking (not for seed) +// 3 = Device Under Test (DUT), aligned but never used in tracking +// +// ---------------------------------- +// Cluster (=Hit) finder +// ---------------------------------- +// HitFinder = [optional] (int) {0} select the hit finder method, +// 0 -> standard +// 1 -> connected pixel +// 2 -> cog based with search radius, requires additional parameter +// ThreshNeighbourSN = [MANDATORY] (float) S/N or S cut on all the pixels +// (seed excluded) in the cluster for the hit finding +// ThreshSeedSN = [MANDATORY] (float) S/N or S cut on the seed pixel +// for the hit finding +// MaxNStrips = [optional] (int) {1000} maximal #strips allowed in cluster +// (corrected or set automaticaly by DCut depending on HitFinder) +// MinNStrips = [optional] (int) {1} minimal #strips required in cluster +// (corrected or set automaticaly by DCut depending on HitFinder) +// ClusterLimitU = [MANDATORY if HitFinder!=2] (float,um) maximal distance +// between the seed pixel and any other pixel in the hit +// ClusterLimitRadius= [MANDATORY if HitFinder==2] (float,um) maximal distance +// between the center of gravity and any other pixel in the hit +// CommonRegions = [optional] (int) {1} # regions to define +// for the common noise shift computation per event +// HitPositionAlgorithm = [MANDATORY] (int) controls how the hit position +// is estimated from the pixels info +// 1 = Center of Gravity, +// 2 = eta, +// 3 = kappa (not implemented yet) +// PlaneResolution = [optional] (float,um) expected plane resolution in both direction +// PlaneResolutionU = [optional] (float,um) expected plane resolution in U direction +// PlaneResolutionV = [optional] (float,um) expected plane resolution in V direction +// ResolutionFile = [optional] (char) not implemented yet +// ResolutionRegion = [optional] (?) not implemented yet +// PlaneThickness = [optional] (float,um) plane thickness. To be used for MC studies of telescope resolution +// PlaneMaterial = [optional] (char) plane material. Used to calculate multiple scattering angle from database. +// To be used for MC studies of telescope resolution. +// +// + + +// ############################################################################# +// Parameters for DAQ +// ############################################################################# +// "AcqModuleTypes" or "FileHeaderSize" has to be the first field +// AcqModuleTypes = [MANDATORY] (int) # different boards used in the DAQ +// TriggerMode = [optional] (int) method to deal with trigger info +// 0 -> ignore trigger info +// 1 -> each new trigger generates an event +// 2 -> trigger info is used to start or stop event reading +// 3 -> ignore trigger info but all events are 2 frames long +// EventBuildingMode = [obsolote] (int) {0} replaced by EventBuildingBoardMode +// BinaryCoding = [optional] (int) {0} 0 for one Endian, 1 for the other +// FileHeaderSize = [obsolete] (int) {0} size of additional header file +// EventBufferSize = [optional depends on DAQboard type, see below] (int) event size in Bytes +// FileHeaderLine = [optional] (int) {0} event header size in Bytes +// => renamed (2021/05/02) EventHeaderSize, but the old name still works +// EventTrailerSize = [optional] (int) {4} event trailer size in Bytes +// TimeRefFile = [optional] (char) name of the file where to get external time reference +// +// => Read the section devoted to the module type used below, +// to decide which of the previous parameters are mandatory or not + +// ############################################################################# +// Parameters for each Acquisition module type +// ############################################################################# +// "Name" has to be the first field +// Name = [MANDATORY] (char) generic name of such modules +// known names: "IMG", "TNT", "PXI", "PXIe", "GIG", "VME", +// "DecoderM18", "ALI22", "DecoderGeant", +// "IHEP", "MC", "MSIS" +// Type = [MANDATORY] (int) unique identifier for the module type +// Devices = [MANDATORY] (int) # module instances of this type, +// typically, one instance decode one file +// Inputs = [optional] (int) # identical data block (one per sensor typically) +// Channels = [optional] (int) # channels in one input (data block) +// EventBuildingBoardMode= [optional] (int) used to pass a flag +// Bits = [optional] (int) size in bits of words to read from file +// SignificantBits = [optional] (int) # significant bits per word +// NColumns = [optional] (int) # number of columns of sensor +// FirstTriggerChannel = [optional] (int) +// LastTriggerChannel = [optional] (int) +// NbOfFramesPerChannel = [optional] (int) # frames stored for each trigger/event +// DataFile or DataFile1 = [optional] (char) core name of data file +// if not provided, TAF will look for files like: +// RUN_XXXX_N.Extension, run_XXXX_N.Ext, RUNXXXX_N.Ext, runXXXX_N.Ext, +// RUN_XXXX.Ext, runXXXX.Ext, XXXX_N.Ext, XXXX.Ext +// where XXXX is the run number and N is the file number +// IfZeroSuppress = [optional] (int) {0} if non-zero rawdata are zero-suppress +// ThresholdZero = [MANDATORY if IfZeroSuppress>0] threshold value for zero-suppression +// MCTreeName = [optional] (char) tree name in the MC generated file +// +// --- Name: "IMG" +// Type = 10 for pixels / 11 for strips / 12 for pixels with multi-frame +// 13 for pixels with specifi arrangement of frame-ref & frame-signal +// 14 for 16 parallel outputs +// Inputs = [MANDATORY] (int) # identical data block (one per sensor typically) +// EventsInFile = [MANDATORY] (int) expected # events in a file +// StartIndex = [MANDATORY] (int) index of first data file +// EndIndex = [MANDATORY] (int) index of last data file +// Extension = [MANDATORY] (char) {"rz"} extension of data file +// TriggerMode = [MANDATORY] (int) method to deal with trigger info +// EventBuildingBoardMode or EventBuildingMode = [MANDATORY] +// EventBufferSize = [MANDATORY] (int) +// FileHeaderLine = [MANDATORY] (int) +// Bits: [MANDATORY] (int) if negative +// SignificantBits: [MANDATORY] (int) if negative +// NColumns: [MANDATORY] (int) +// NMultiFrames: [MANDATORY] (int) nb of frames registered when multiFraming +// DataFile: [MANDATORY] (char) typically "RUN_32844_" +// +// --- Name: "TNT" +// Type = 30 or 31 +// StartIndex = [MANDATORY] (int) index of first data file +// EndIndex = [MANDATORY] (int) index of last data file +// Extension = [MANDATORY] (char) {"rz"} extension of data file +// TimeLimit = [MANDATORY] (int) +// EventBufferSize = [MANDATORY] (int) +// TriggerMode = [MANDATORY] (int) method to deal with trigger info +// BinaryCoding = [MANDATORY] (int) +// Bits = [MANDATORY] (int) +// SignificantBits = [MANDATORY] (int) +// DataFile = [MANDATORY] (char) typically "CardXXXX_000" +// TriggerMode ->unused +// EventBuildingBoardMode -> unused +// FirstTriggerChannel, LastTriggerChannel, NbOfFramesPerChannel -> unused +// +// --- Name: "PXI" +// Type = 40 +// TriggerMode = [MANDATORY] (int) method to deal with trigger info +// BinaryCoding = [MANDATORY] (int) +// DataFile = [MANDATORY] typically "run_XXXX_" +// EventBufferSize, FileHeaderLine -> unused +// Channels, Bits, SignificantBits, EventBuildingBoardMode -> unused +// FirstTriggerChannel, LastTriggerChannel, NbOfFramesPerChannel -> unused +// +// --- Name: "PXIe" +// Type = 50 +// TriggerMode = [MANDATORY] (int) method to deal with trigger info +// BinaryCoding = [MANDATORY] (int) +// EventBuildingBoardMode +// EventBufferSize, FileHeaderLine -> unused +// Channels, Bits, SignificantBits -> unused +// FirstTriggerChannel, LastTriggerChannel, NbOfFramesPerChannel, DataFile -> unused +// +// --- Name: "GIG" +// Type = 60 +// TriggerMode, BinaryCoding, EventBufferSize, FileHeaderLine -> unused +// Channels, Bits, SignificantBits, EventBuildingBoardMode -> unused +// FirstTriggerChannel, LastTriggerChannel NbOfFramesPerChannel, DataFile -> unused +// +// --- Name: "VME" +// Type = 70 +// Extension = [MANDATORY] (char) {"rz"} extension of data file +// Inputs = [MANDATORY] (int) # identical data block (one per sensor typically) +// DataFile = [MANDATORY] (char) typically "FIFOdata_M28_RUN3_ch" +// TriggerMode, BinaryCoding, EventBufferSize, FileHeaderLine -> unused +// Channels, Bits, SignificantBits, EventBuildingBoardMode -> unused +// FirstTriggerChannel, LastTriggerChannel NbOfFramesPerChannel -> unused +// +// --- Name: "ALI22" +// Type = 80 +// DataFile = [MANDATORY] (char) typically "FIFOdata_M22" +// NbOfFramesPerChannel = [MANDATORY] (int) # frames stored for each trigger/event +// TriggerMode, BinaryCoding, EventBufferSize, FileHeaderLine -> unused +// Channels, Bits, SignificantBits, EventBuildingBoardMode -> unused +// FirstTriggerChannel, LastTriggerChannel, NbOfFramesPerChannel -> unused +// +// --- Name: "DecoderM18" +// Type = 90 +// Extension = [MANDATORY] (char) {"dat"} extension of data file +// DataFile = [MANDATORY] (char) typically "SIS3301dataZS_ch" +// TriggerMode, BinaryCoding, EventBufferSize, FileHeaderLine -> unused +// Channels, Bits, SignificantBits, EventBuildingBoardMode -> unused +// FirstTriggerChannel, LastTriggerChannel, NbOfFramesPerChannel -> unused +// PixelShift = [Optional] (int) {3} (in)famous kShift +// PixelShiftMod = [Optional] (int) {3} (in)famous kShift defined per Module +// AmpOffset = [Optional] (int) {32768} values subtracted to pulseheight +// AmpFactor = [Optional] (float) {1.} multiplier of the pulseheight +// Trailer = [Optional] {int) {0xfafafafa} expected frame tailer + +// +// --- Name: "DecoderGeant" +// Type = 100 +// DataFile = [MANDATORY] (char) typically "FILEdata_Geant_RUN1_ch" +// TriggerMode, BinaryCoding, EventBufferSize, FileHeaderLine -> unused +// Inputs, Channels, Bits, SignificantBits, EventBuildingBoardMode -> unused +// FirstTriggerChannel, LastTriggerChannelNbOfFramesPerChannel -> unused +// + +// --- Name: "MC" +// Type = 110 +// Inputs = [MANDATORY] (int) at least 1 +// DataFile = [MANDATORY] (char) typically "FILEdata_Geant_RUN1_ch" +// MCTreeName = [MANDATORY] (char) tree name in the MC generated file +// TriggerMode, BinaryCoding, EventBufferSize, FileHeaderLine -> unused +// Channels, Bits, SignificantBits, EventBuildingBoardMode -> unused +// FirstTriggerChannel, LastTriggerChannelNbOfFramesPerChannel -> unused +// + +// --- Name: "IHEP" +// Type = 120 +// Inputs = [MANDATORY] (int) # identical data block (# sensors typically) +// Devices = [MANDATORY] (int) # module instances of this type, +// EventBuildingBoardMode = [MANDATORY] (int) {0} drive how events are reconstructed +// DataFile = [MANDATORY] (char) the basename of rawdata file, typically "RUN264_2018-11-07-12-07-54_FullEvent" +// ==> Parameters needed from section: Run Parameters +// StartIndex = [MANDATORY] (int) index of first data file +// EndIndex = [MANDATORY] (int) index of last data file +// Extension = [MANDATORY] (char) {"??"} extension of data file +// NoiseRun = [MANDATORY] (int) {0} defines method to remove noisy pixels (see DGlobalTools::VetoPixels) +// ==> Parameters needed from section: Data Acquisition +// TriggerMode = [MANDATORY] (int) 1 +// + +// --- Name: "MSIS" +// This section is still preliminary (JB, 2021/05/02) +// Type = 130 +// Devices = [MANDATORY] (int) # module instances of this type, +// Inputs = [MANDATORY] (int) # identical data block (# sensors typically) +// EventBuildingBoardMode = [MANDATORY] (int) {0} drive how events are reconstructed +// DataFile = [MANDATORY] (char) the basename of rawdata file, typically "RUN_" +// ==> Parameters needed from section: Run Parameters +// StartIndex = [MANDATORY] (int) index of first data file +// EndIndex = [MANDATORY] (int) index of last data file +// Extension = [MANDATORY] (char) {"??"} extension of data file +// NoiseRun = [MANDATORY] (int) {0} defines method to remove noisy pixels (see DGlobalTools::VetoPixels) +// ==> Parameters needed from section: Data Acquisition +// BinaryCoding = [MANDATORY] (int) {0} 0 for one Endian, 1 for the other +// EventHeaderSize = [MANDATORY] (int) {0} event header size in Bytes +// EventTrailerSize = [MANDATORY] (int) {4} event trailer size in Bytes +// TriggerMode = [MANDATORY] (int) method to deal with trigger info +// +// + +// ############################################################################# +// Parameter for Final Analysis +// ############################################################################# +// "AnalysisGoal" or "MaxNbOfHits" or "StatisticCells" or "CmsNoiseCut" has to be the first field +// AnalysisGoal = [optional] (char) {""} drives type of histograms created, could be: +// cluster, track, calib, laser, vertex, fake, vector +// SavePlots = [optional] (int) {0} set to 1 to save all plots into a PDF file +// StatisticCells = [obsolete] +// CmsNoiseCut = [optional] (float) {3} upper SNR cut to use a pixel value in the CMS computation +// MaxNbOfHits = [MANDATORY] (int) max # hits allowed to consider events for analysis +// MinNbOfHits = [MANDATORY] (int) min # hits allowed to consider events for analysis +// TrackChi2Limit = [MANDATORY] (float) upper chi2 cut to consider a track for analysis +// MinHitsPerTrack = [optional] (int) minimum #hits per track (default is set with PlanesForTrackMinimum) +// MaxTracksExGeom = [optional] (int) {-1} inclusive max # tracks allowed in the ExGeomatrix below, set to -1 cancel this cut +// ExGeomatrix = [optional] (int) {0} geomatrix (of submatrix 0) to be used in the previous cut +// UserFlag = [optional] (int) whatever you want to use in User's stuff +// HistoChargeRange = [optional] (float) {5000} max charge displayed in histo +// HistoSNRRange = [optional] (float) {250} max SNR displayed in histo +// HistoNoiseRange = [optional] (int) {40} max noise displayed in histo +// Submatrices = [MANDATORY] (int) # submatrices defined below, at least 1 shall be specified +// +// Then for each submatrix declared +// PixelSizeU = [MANDATORY] (float) +// PixelSizeV = [MANDATORY] (float) +// PixelsInRaw = [MANDATORY] (int) +// PixelsInColumn = [MANDATORY] (int) +// Matrixtype = [optional] (int) {1} defines the mapping pixel-position +// 1 = orthogonal pixel network, +// 2 = staggered pixel network for elongated pixel, +// 3,4,5 = ? +// MaxNofPixelsInCluster = [optional] (int) {0} maximum # pixel allowed to consider a cluster for analysis, 0 means not used +// MinNofPixelsInCluster = [optional] (int) {1} minimum # pixel allowed to consider a cluster for analysis +// MinSeedCharge = [optional] (int) {-1000} minimal charge on the seed pixel to consider a cluster, units depends on calibration +// MinClusterCharge = [optional] (int) {-1000} minimal total charge to consider a cluster, units depends on calibration +// MinNeighbourCharge = [optional] (int) {-1000} minimal charge on pixels neighbouring the seed pixel, units depends on calibration +// MinSeedIndex = [optional] (int) {0} defines limit index of pixels to take into account +// MaxSeedIndex = [optional] (int) {0} defines limit index of pixels to take into account +// MinSeedCol = [optional] (int) {0} defines limit index of col to take into account +// MaxSeedCol = [optional] (int) {0} defines limit index of col to take into account +// MinSeedRow = [optional] (int) {0} defines limit index of row to take into account +// MaxSeedRow = [optional] (int) {0} defines limit index of row to take into account +// Calibration = [optional] (float) {1.} conversion factor between ADCunit and electrons +// NoiseScope = [MANDATORY] (float) noise multiplication factor, if 0. -> noise not used +// 4 geomatrix shall be specified, they define 4 ROI (region of interest) +// GeoMatrix0/1/2/3 = [MANDATORY] (float,um) minU: maxU: minV: maxV +// +// // +//////////////////////////////////////////////////////////// + +#include "DSetup.h" +#include "DSession.h" +#include "DR3.h" +#include "DGlobalTools.h" +#include "TApplication.h" +#include "TFile.h" +#include "TH1.h" +#include "TH2.h" +#include "TH1F.h" +#include "TH2F.h" +#include "TROOT.h" +#include "TVector2.h" + +#include + +ClassImp(DSetup) // DSetup of Test Beam Setup and Data Structure + + +DSetup::DSetup() { + + DSetupDebug = 0; + fFieldMaxLength = 100; + fFieldName = new Char_t[fFieldMaxLength]; + +} +//______________________________________________________________________________ +// +DSetup::DSetup(DSession& aSession) +{ + // Modified JB 2012/12/20 new member data "fieldName" + + fSession = &aSession; + + fFieldMaxLength = 100; + fFieldName = new Char_t[fFieldMaxLength]; + +} +//______________________________________________________________________________ +// +void DSetup::SetConfigPath(TString aCP) +{ + + fConfigPath = aCP; + if(DSetupDebug) cout << "DSetup::SetConfigPath "<< aCP << endl; + +} +//______________________________________________________________________________ +// +void DSetup::SetConfigFileName(TString aCFN) +{ + + fConfigFileName = aCFN; + if(DSetupDebug) cout << "DSetup::SetConfigFileName "<< aCFN << endl; + +} +//______________________________________________________________________________ +// +void DSetup::SetSourcePath(TString aSP) +{ + + fSourcePath = aSP; + if(DSetupDebug) cout << "DSetup::SetSourcePath "<< aSP << endl; + +} +//______________________________________________________________________________ +// +void DSetup::ReadRunParameters() +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Run Parameter + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // JB 2013/01/16 + // Modified JB 2013/08/19: default parameters setup + // Modified VR 2014/06/30: RunNumber is not read anymore, taken from DSession + // Modified VR 2014/06/30: Add the DataSubDirPrefix and test of mandatory config + // Modified JB 2018/07/04: Add PixelGainRun parameter + + cout << endl << " - Reading Run parameters" << endl; + + // ################################################ + // Set default values + // ################################################ + // Set default values for optional or mandatory parameters + RunParameter.Number = -1; + sprintf(RunParameter.Affiliation,""); + sprintf(RunParameter.Signature,""); + sprintf(RunParameter.BeamTime,""); + sprintf(RunParameter.Confidence,""); + sprintf(RunParameter.DataPath,"-1");// [MANDATORY] + sprintf(RunParameter.DataSubDirPrefix,""); + sprintf(RunParameter.Extension,""); + RunParameter.EventsInFile = 0;// [MANDATORY for IMGBoardReader] + RunParameter.StartIndex = 0;// [MANDATORY for IMGBoardReader] + RunParameter.EndIndex = 0;// [MANDATORY for IMGBoardReader] + RunParameter.NoiseRun = 0; + RunParameter.PixelGainRun = 0; + + if( !fSourcePath.IsNull() ) { // Read the path only if not set already + sprintf( RunParameter.DataPath, "%s", fSourcePath.Data()); + DGlobalTools aTool; + sprintf( RunParameter.DataPath, "%s", aTool.LocalizeDirName( RunParameter.DataPath)); // JB 2011/07/07 + } + + do { + + nextField(); + + if ( ! strcmp( fFieldName, "Affiliation" ) ) { + read_strings( RunParameter.Affiliation, RunParameter.tpsz); + } + else if( ! strcmp( fFieldName, "Signature" ) ) { + read_strings( RunParameter.Signature, RunParameter.tpsz); + } + else if( ! strcmp( fFieldName, "BeamTime" ) ) { + read_strings( RunParameter.BeamTime, RunParameter.tpsz); + } + else if( ! strcmp( fFieldName, "Confidence" ) ) { + read_strings( RunParameter.Confidence, RunParameter.tpsz); + } + else if( ! strcmp( fFieldName, "DataPath" ) ) { + if( fSourcePath.IsNull() ) { // Read the path only if not set already + read_strings( RunParameter.DataPath, RunParameter.tpsz); + } else { + sprintf( RunParameter.DataPath, "%s", fSourcePath.Data()); + } + DGlobalTools aTool; // JB 2011/07/18 + sprintf( RunParameter.DataPath, "%s", aTool.LocalizeDirName( RunParameter.DataPath)); // JB 2011/07/07 + } + else if( ! strcmp( fFieldName, "DataSubDirPrefix" ) ) { // VR 2014/06/30 + read_strings( RunParameter.DataSubDirPrefix, RunParameter.tpsz); + } + else if( ! strcmp( fFieldName, "Extension" ) ) { + read_strings( RunParameter.Extension, RunParameter.tpsz); + } + //VR 2014/06/30 RunNumber is set from DSession + else if( ! strcmp( fFieldName, "RunNumber" ) ) { + cout << "WARNING : parameter 'RunNumber' in config file is ignored, because it is redundant with InitSession command argument !" << endl; + getRidOfLine(); + } + else if( ! strcmp( fFieldName, "EventsInFile" ) ) { + read_item(RunParameter.EventsInFile); + } + else if( ! strcmp( fFieldName, "StartIndex" ) ) { + read_item(RunParameter.StartIndex); + } + else if( ! strcmp( fFieldName, "EndIndex" ) ) { + read_item(RunParameter.EndIndex); + } + else if( ! strcmp( fFieldName, "NoiseRun" ) ) { + read_item(RunParameter.NoiseRun); //YV 27/11/09 + } + else if( ! strcmp( fFieldName, "PixelGainRun" ) ) { + read_item(RunParameter.PixelGainRun); //JB 2018/07/04 + } + else + { + if ( strcmp( fFieldName, "Planes") && strcmp( fFieldName, "Ladders") ) + { + cout << "WARNING : parameter '" << fFieldName << "' in config file is not understood !" << endl; + getRidOfLine(); + } + } + } while ( strcmp( fFieldName, "Planes") && strcmp( fFieldName, "Ladders") ); + + + // Test of MANDATORY field settings + // VR 20014/06/30 + if ( !strcmp(RunParameter.DataPath,"-1")) + { + cout << " ERROR: The field 'DataPath' is MANDATORY in config file (section run parameters)" << endl; + gApplication->Terminate(); + } + +} +//______________________________________________________________________________ +// +void DSetup::ReadTrackerParameters() +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameters of the Tracker + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // JB 2013/01/16 + // Modified: LC 2013/??/?? new parameters for vertex finder + // Modified: JB 2013/06/21 new parameters to control track_finder + // Modified: JB 2013/07/17 new parameters to select track_finder method + // Modified: VR 2014/06/29 add the SearchMoreHitDistance parameter and test of mandatory config + // Modified: VR 2014/10/30 add the PreTrackHitsNbMinimum and HitsNbMinForFullTrack parameters and test of mandatory config + // Modified: VR 2014/12/18 modify all parameters for track_finder 2 (IVI) + // Modified: JB 2014/12/23 add Subtrack parameters + // Modified: LC 2015/01/?? add HitMonteCarlo + // Modified: LC 2015/01/31 add DprecAlignMethod + + cout << endl << " - Reading Parameters of the Tracker" << endl; + + + // ################################################ + // Set default values + // ################################################ + // ***************************** + // Planes config + // ***************************** + TrackerParameter.Planes = 0; + TrackerParameter.Ladders = 0; + TrackerParameter.TimeLimit = -1; + TrackerParameter.Resolution = -1.; + TrackerParameter.BeamType = TString(""); + TrackerParameter.BeamMomentum = 0.0; + TrackerParameter.MediumMaterial = TString(""); + TrackerParameter.HitsInPlaneMaximum = -1 ;//[MANDATORY] + + TrackerParameter.TracksMaximum = 0; + TrackerParameter.TracksFinder = 0; + TrackerParameter.TrackFittingAlg = 0; // QL 2016/05/26 + TrackerParameter.PlanesForTrackMinimum = -1;//[MANDATORY if TracksMaximum!=0 && TracksFinder==0 ] + TrackerParameter.HitsInPlaneTrackMaximum = -1;//[MANDATORY if TracksMaximum!=0 && TracksFinder==0 ] + TrackerParameter.SearchHitDistance = -1.;//[MANDATORY if TracksMaximum<2] + TrackerParameter.SearchMoreHitDistance = -1.;//[MANDATORY if TracksMaximum<2] + TrackerParameter.UseSlopeInTrackFinder = 1; + TrackerParameter.TrackingPlaneOrderType = 0; + TrackerParameter.KeepUnTrackedHitsBetw2evts = 0; + TrackerParameter.HitMonteCarlo = 0; // LC 2015/01 + TrackerParameter.DPrecAlignMethod = 0; // LC 2015/01/31 + + // ***************************** + // Tracking with track_finder 2 + // ***************************** + // all MANDATORY + TrackerParameter.TrackingPass = -1; + TrackerParameter.PreTrackHitsNbMinimum = NULL; + TrackerParameter.PreTrackHitsTypeUsed = NULL; + TrackerParameter.PreTrackHitsMaxDist = NULL; + TrackerParameter.ExtTrackHitsNbMinimum = NULL; + TrackerParameter.ExtTrackHitsTypeUsed = NULL; + TrackerParameter.ExtTrackHitsMaxDist = NULL; + TrackerParameter.FullTrackHitsNbMinimum = NULL; + + TrackerParameter.TrackingOrderLines = -1; + TrackerParameter.TrackingOrderPreTrack = NULL; + TrackerParameter.TrackingOrderExtTrack = NULL; + + TrackerParameter.SubtrackNplanes = 0; // JB 2014/12/23 + TrackerParameter.SubtrackPlanes = NULL; + + // ***************************** + // Vertexing + // ***************************** + TrackerParameter.VertexMaximum = 0; // no vertexing by default + TrackerParameter.VertexConstraint = 0; // use a vertex constraint to start track + // ***************************** + // Alignment + // ***************************** + TrackerParameter.EventsForAlignmentFit = 0; + + + do { + // ---------------------------------- + // Planes and their parameters + // ---------------------------------- + if ( ! strcmp( fFieldName, "Planes") ) { + read_item(TrackerParameter.Planes); + } + else if ( ! strcmp( fFieldName, "Ladders") ) { + read_item(TrackerParameter.Ladders); + } + else if( ! strcmp( fFieldName, "TimeLimit" ) ) { + read_item(TrackerParameter.TimeLimit); //RDM260609 + } + else if( ! strcmp( fFieldName, "Resolution" ) ) { + read_item(TrackerParameter.Resolution); // RDM250809 + } + else if( ! strcmp( fFieldName, "BeamMomentum" ) ) { + read_item(TrackerParameter.BeamMomentum); // 2015/03/10, AP Beam momentum in GeV/c + } + else if( ! strcmp( fFieldName, "BeamType" ) ) { // 2015/03/10, AP Beam type: e.g. e+/-, pi+/-, ... + read_TStrings( TrackerParameter.BeamType, 350); + } + else if( ! strcmp( fFieldName, "MediumMaterial" ) ) { // 2015/06/01, AP Material of the medium containing the sensors: e.g. Dry air, or Vacuum + read_TStrings( TrackerParameter.MediumMaterial, 350); + } + + // ---------------------------------- + // Clustering in planes + // ---------------------------------- + else if( ! strcmp( fFieldName, "HitsInPlaneMaximum" ) ) { + read_item(TrackerParameter.HitsInPlaneMaximum); + } + // ---------------------------------- + // Tracking parameters + // ---------------------------------- + else if( ! strcmp( fFieldName, "TracksMaximum" ) ) { + read_item(TrackerParameter.TracksMaximum); + } + else if( ! strcmp( fFieldName, "TracksFinder" ) ) { // JB 2013/07/17 + read_item(TrackerParameter.TracksFinder); + } + else if( ! strcmp( fFieldName, "TrackFittingAlg" ) ) { // QL 2016/05/26 + read_item(TrackerParameter.TrackFittingAlg); + } + else if( ! strcmp( fFieldName, "PlanesForTrackMinimum" ) ) { + read_item(TrackerParameter.PlanesForTrackMinimum); + } + else if( ! strcmp( fFieldName, "HitsInPlaneTrackMaximum" ) ) { + read_item(TrackerParameter.HitsInPlaneTrackMaximum); + } + else if( ! strcmp( fFieldName, "SearchHitDistance" ) ) { + read_item(TrackerParameter.SearchHitDistance); + } + else if( ! strcmp( fFieldName, "SearchMoreHitDistance" ) ) { + read_item(TrackerParameter.SearchMoreHitDistance); + } + else if( ! strcmp( fFieldName, "UseSlopeInTrackFinder" ) ) { // JB 2013/06/21 + read_item(TrackerParameter.UseSlopeInTrackFinder); + } + else if( ! strcmp( fFieldName, "TrackingPlaneOrderType" ) ) { // VR 2014/07/14 + read_item(TrackerParameter.TrackingPlaneOrderType); + } + else if( ! strcmp( fFieldName, "KeepUnTrackedHitsBetw2evts" ) ) { // VR 2014/08/26 + read_item(TrackerParameter.KeepUnTrackedHitsBetw2evts); + } + else if( ! strcmp( fFieldName, "HitMonteCarlo" ) ) { + read_item(TrackerParameter.HitMonteCarlo); + } + else if( ! strcmp( fFieldName, "DPrecAlignMethod" ) ) { + read_item(TrackerParameter.DPrecAlignMethod); + } + // ------------------------------------------- + // Tracking parameters for track_finder 2 + // ------------------------------------------- + // -*-*-*- Tracking Pass -*-*-*- + else if( ! strcmp( fFieldName, "TrackingPass" ) ) + { + read_item(TrackerParameter.TrackingPass); + cout << " -> Tracking pass = " << TrackerParameter.TrackingPass << endl ; + + if(TrackerParameter.TrackingPass>0) + { + Int_t nbOfReadingLoop = 0 ; + while(kTRUE) + { + // Exit the loop + if(TrackerParameter.PreTrackHitsNbMinimum && \ + TrackerParameter.PreTrackHitsTypeUsed && \ + TrackerParameter.PreTrackHitsMaxDist && \ + TrackerParameter.ExtTrackHitsNbMinimum && \ + TrackerParameter.ExtTrackHitsTypeUsed && \ + TrackerParameter.ExtTrackHitsMaxDist && \ + TrackerParameter.FullTrackHitsNbMinimum) { + cout << " -> Reading finished ! " << endl ; + break; + } + + if(nbOfReadingLoop > 20) { + cout << " -> ERROR: There is (a) missing parameter(s) : " << endl; + if(! TrackerParameter.PreTrackHitsNbMinimum) cout << " * PreTrackHitsNbMinimum list is not defined !" << endl ; + if(! TrackerParameter.PreTrackHitsTypeUsed) cout << " * PreTrackHitsTypeUsed list is not defined !" << endl ; + if(! TrackerParameter.PreTrackHitsMaxDist) cout << " * PreTrackHitsMaxDist list is not defined !" << endl ; + if(! TrackerParameter.ExtTrackHitsNbMinimum) cout << " * ExtTrackHitsNbMinimum list is not defined !" << endl ; + if(! TrackerParameter.ExtTrackHitsTypeUsed) cout << " * ExtTrackHitsTypeUsed list is not defined !" << endl ; + if(! TrackerParameter.ExtTrackHitsMaxDist) cout << " * ExtTrackHitsMaxDist list is not defined !" << endl ; + if(! TrackerParameter.FullTrackHitsNbMinimum) cout << " * FullTrackHitsNbMinimum list is not defined !" << endl ; + + gApplication->Terminate(); + } + + nextField(); + nbOfReadingLoop++; + + if ( ! strcmp( fFieldName, "PreTrackHitsNbMinimum") ) + { + TrackerParameter.PreTrackHitsNbMinimum = new Int_t[TrackerParameter.TrackingPass]; + cout << " -> PreTrackHitsNbMinimum {" ; + nextItem('{'); + for(Int_t iPass=1 ; iPass <=TrackerParameter.TrackingPass ; iPass++) + { + read_item(TrackerParameter.PreTrackHitsNbMinimum[iPass-1]); + cout << " " << TrackerParameter.PreTrackHitsNbMinimum[iPass-1] << " "; + } + cout << "}" << endl; + nextItem('}'); + } + else if ( ! strcmp( fFieldName, "PreTrackHitsTypeUsed") ) + { + TrackerParameter.PreTrackHitsTypeUsed = new Int_t[TrackerParameter.TrackingPass]; + cout << " -> PreTrackHitsTypeUsed {" ; + nextItem('{'); + for(Int_t iPass=1 ; iPass <=TrackerParameter.TrackingPass ; iPass++) + { + read_item(TrackerParameter.PreTrackHitsTypeUsed[iPass-1]); + cout << " " << TrackerParameter.PreTrackHitsTypeUsed[iPass-1] << " "; + } + cout << "}" << endl; + nextItem('}'); + } + else if ( ! strcmp( fFieldName, "PreTrackHitsMaxDist") ) + { + TrackerParameter.PreTrackHitsMaxDist = new Float_t[TrackerParameter.TrackingPass]; + cout << " -> PreTrackHitsMaxDist {" ; + nextItem('{'); + for(Int_t iPass=1 ; iPass <=TrackerParameter.TrackingPass ; iPass++) + { + read_item(TrackerParameter.PreTrackHitsMaxDist[iPass-1]); + cout << " " << TrackerParameter.PreTrackHitsMaxDist[iPass-1] << " "; + } + cout << "}" << endl; + nextItem('}'); + } + else if ( ! strcmp( fFieldName, "ExtTrackHitsNbMinimum") ) + { + TrackerParameter.ExtTrackHitsNbMinimum = new Int_t[TrackerParameter.TrackingPass]; + cout << " -> ExtTrackHitsNbMinimum {" ; + nextItem('{'); + for(Int_t iPass=1 ; iPass <=TrackerParameter.TrackingPass ; iPass++) + { + read_item(TrackerParameter.ExtTrackHitsNbMinimum[iPass-1]); + cout << " " << TrackerParameter.ExtTrackHitsNbMinimum[iPass-1] << " "; + } + cout << "}" << endl; + nextItem('}'); + } + else if ( ! strcmp( fFieldName, "ExtTrackHitsTypeUsed") ) + { + TrackerParameter.ExtTrackHitsTypeUsed = new Int_t[TrackerParameter.TrackingPass]; + cout << " -> ExtTrackHitsTypeUsed {" ; + nextItem('{'); + for(Int_t iPass=1 ; iPass <=TrackerParameter.TrackingPass ; iPass++) + { + read_item(TrackerParameter.ExtTrackHitsTypeUsed[iPass-1]); + cout << " " << TrackerParameter.ExtTrackHitsTypeUsed[iPass-1] << " "; + } + cout << "}" << endl; + nextItem('}'); + } + else if ( ! strcmp( fFieldName, "ExtTrackHitsMaxDist") ) + { + TrackerParameter.ExtTrackHitsMaxDist = new Float_t[TrackerParameter.TrackingPass]; + cout << " -> ExtTrackHitsMaxDist {" ; + nextItem('{'); + for(Int_t iPass=1 ; iPass <=TrackerParameter.TrackingPass ; iPass++) + { + read_item(TrackerParameter.ExtTrackHitsMaxDist[iPass-1]); + cout << " " << TrackerParameter.ExtTrackHitsMaxDist[iPass-1] << " "; + } + cout << "}" << endl; + nextItem('}'); + } + else if ( ! strcmp( fFieldName, "FullTrackHitsNbMinimum") ) + { + TrackerParameter.FullTrackHitsNbMinimum = new Int_t[TrackerParameter.TrackingPass]; + cout << " -> FullTrackHitsNbMinimum {" ; + nextItem('{'); + for(Int_t iPass=1 ; iPass <=TrackerParameter.TrackingPass ; iPass++) + { + read_item(TrackerParameter.FullTrackHitsNbMinimum[iPass-1]); + cout << " " << TrackerParameter.FullTrackHitsNbMinimum[iPass-1] << " "; + } + cout << "}" << endl; + nextItem('}'); + } + } + } + else + { + cout << " -> ERROR: The field 'TrackingPass' must be >0 ! " << endl; + gApplication->Terminate(); + } + } // end if tracking pass + + + // -*-*-*- Tracking Order -*-*-*- + else if( ! strcmp( fFieldName, "TrackingOrderLines" ) ) + { + read_item(TrackerParameter.TrackingOrderLines); + cout << " -> TrackingOrderLines = " << TrackerParameter.TrackingOrderLines << endl ; + if(TrackerParameter.TrackingOrderLines>0) + { + TrackerParameter.TrackingOrderPreTrack = new Int_t*[TrackerParameter.TrackingOrderLines]; + TrackerParameter.TrackingOrderExtTrack = new Int_t*[TrackerParameter.TrackingOrderLines]; + + Char_t field[100]; + Int_t aNbOfPlanes; + for(Int_t iOrder=1 ; iOrder <=TrackerParameter.TrackingOrderLines ; iOrder++) + { + nextField(); + sprintf(field, "TrackingOrderLine%d",iOrder); + cout << " -> Reading TrackingOrderLine " << iOrder << endl ; + if( !strcmp( fFieldName, field )) + { + nextItem('[');// pre-track planes # + read_item(aNbOfPlanes); + nextItem(']'); + cout << " -> Planes for pre-track = " << aNbOfPlanes << " : { "; + TrackerParameter.TrackingOrderPreTrack[iOrder-1] = new Int_t[aNbOfPlanes+1]; + TrackerParameter.TrackingOrderPreTrack[iOrder-1][0] = aNbOfPlanes; + + nextItem('{');// pre-track planes enumeration starts + for (Int_t iOrder2=1 ; iOrder2<=aNbOfPlanes ; iOrder2++) + { + read_item(TrackerParameter.TrackingOrderPreTrack[iOrder-1][iOrder2]); + cout << TrackerParameter.TrackingOrderPreTrack[iOrder-1][iOrder2] << " "; + } + nextItem('}');// pre-track planes enumeration finished + cout << "}" << endl; + + nextItem('[');// ful-track planes # + read_item(aNbOfPlanes); + nextItem(']'); + cout << " -> Planes for ext-track = " << aNbOfPlanes << " : { "; + TrackerParameter.TrackingOrderExtTrack[iOrder-1] = new Int_t[aNbOfPlanes+1]; + TrackerParameter.TrackingOrderExtTrack[iOrder-1][0] = aNbOfPlanes; + + nextItem('{');// ful-track planes enumeration starts + for (Int_t iOrder2=1 ; iOrder2<=aNbOfPlanes ; iOrder2++) + { + read_item(TrackerParameter.TrackingOrderExtTrack[iOrder-1][iOrder2]); + cout << TrackerParameter.TrackingOrderExtTrack[iOrder-1][iOrder2] << " "; + } + nextItem('}');// pre-track planes enumeration finished + cout << "}" << endl ; + } + else + { + cout << " -> Error : can't find line " << field << " in config file" << endl; + gApplication->Terminate(); + } + } + cout << " -> Reading finished ! " << endl ; + } + else + { + cout << " -> ERROR: The field 'TrackingOrderLines' must be >0 ! " << endl; + gApplication->Terminate(); + } + } // end if tracking order + + + // -*-*-*- Subtrack -*-*-*- + // JB 2014/12/23 + else if( ! strcmp( fFieldName, "SubtrackNplanes" ) || ! strcmp( fFieldName, "SubtrackNPlanes" ) ) { // if subtrack + read_item(TrackerParameter.SubtrackNplanes); + if ( TrackerParameter.SubtrackNplanes>0 ) { + TrackerParameter.SubtrackPlanes = new Int_t[TrackerParameter.SubtrackNplanes]; + cout << " Creating subtrack with " << TrackerParameter.SubtrackNplanes << " planes requested" << endl << " -> list of planes for subtrack: "; + nextField(); + if ( ! strcmp( fFieldName, "SubtrackPlanes" ) ) { + for ( Int_t iplane=0; iplane Reading finished ! " << endl ; + + // ******************************************************* + // Test of MANDATORY fields settings // VR 20014/06/30 + // ******************************************************* + if (TrackerParameter.HitsInPlaneMaximum == -1) + { + cout << " ERROR: The field 'HitsInPlaneMaximum' is MANDATORY in config file (section tracker parameters)" << endl; + gApplication->Terminate(); + } + + if(TrackerParameter.TracksMaximum > 0) + { + if (TrackerParameter.TracksFinder == 0) + { + if (TrackerParameter.SearchHitDistance == -1) + { + cout << " ERROR: The field 'SearchHitDistance' is MANDATORY in config file (section tracker parameters)" << endl; + gApplication->Terminate(); + } + if (TrackerParameter.PlanesForTrackMinimum == -1) + { + cout << " ERROR: The field 'PlanesForTrackMinimum' is MANDATORY in config file (section tracker parameters)" << endl; + gApplication->Terminate(); + } + if (TrackerParameter.HitsInPlaneTrackMaximum == -1) + { + cout << " ERROR: The field 'HitsInPlaneTrackMaximum' is MANDATORY in config file (section tracker parameters)" << endl; + gApplication->Terminate(); + } + } + else if (TrackerParameter.TracksFinder == 1) + { + if (TrackerParameter.PlanesForTrackMinimum == -1) + { + cout << " ERROR: The field 'PlanesForTrackMinimum' is MANDATORY in config file (section tracker parameters)" << endl; + gApplication->Terminate(); + } + if (TrackerParameter.HitsInPlaneTrackMaximum == -1) + { + cout << " ERROR: The field 'HitsInPlaneTrackMaximum' is MANDATORY in config file (section tracker parameters)" << endl; + gApplication->Terminate(); + } + if (TrackerParameter.SearchHitDistance == -1) + { + cout << " ERROR: The field 'SearchHitDistance' is MANDATORY in config file (section tracker parameters)" << endl; + gApplication->Terminate(); + } + if (TrackerParameter.SearchMoreHitDistance == -1) + { + cout << " ERROR: The field 'SearchMoreHitDistance' is MANDATORY in config file (section tracker parameters) when using TracksFinder: 1" << endl; + gApplication->Terminate(); + } + } + else if (TrackerParameter.TracksFinder == 2) + { + if (TrackerParameter.TrackingPass == -1) + { + cout << " ERROR: The field 'TrackingPass' is MANDATORY in config file (section tracker parameters) when using TracksFinder: 2" << endl; + gApplication->Terminate(); + } + if (TrackerParameter.TrackingOrderLines == -1) + { + cout << " ERROR: The field 'TrackingOrderLines' is MANDATORY in config file (section tracker parameters) when using TracksFinder: 2" << endl; + gApplication->Terminate(); + } + } + } + + if(DSetupDebug) { + cout << " #planes = " << TrackerParameter.Planes << endl; + if ( TrackerParameter.Ladders>0 ) { + cout << " #ladders = " << TrackerParameter.Ladders << endl; + } + } + + +} +//______________________________________________________________________________ +// +void DSetup::ReadExperimentGeometryParameters() +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Experiment Geometrical Parameters + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // VR 2015/01/16 + + cout << endl << " - Reading Experiment Geometrical Parameters " << endl; + + // ################################################ + // Set default values + // ################################################ + Float_t initValue[3] = {-666.0, -666.0, -666.0}; + + sprintf(IviGeometryParameter.GeometryName,"not defined"); + sprintf(IviGeometryParameter.GeometryVersion,"-1"); + IviGeometryParameter.BeamOrigin.SetValue(initValue); + IviGeometryParameter.BeamSlope.SetValue(initValue); + IviGeometryParameter.BeamDisplayStrongBegin.SetValue(initValue); + IviGeometryParameter.BeamDisplayStrongStop.SetValue(initValue); + IviGeometryParameter.BeamDisplayMediumBegin.SetValue(initValue); + IviGeometryParameter.BeamDisplayMediumStop.SetValue(initValue); + IviGeometryParameter.BeamDisplayLightBegin.SetValue(initValue); + IviGeometryParameter.BeamDisplayLightStop.SetValue(initValue); + sprintf(IviGeometryParameter.TargetType,"not defined"); + IviGeometryParameter.TargetSize.SetValue(initValue); + IviGeometryParameter.TargetRadius = -1.; + IviGeometryParameter.TargetLength = -1.; + sprintf(IviGeometryParameter.TargetAxis,"O"); + IviGeometryParameter.TargetCenter.SetValue(initValue); + IviGeometryParameter.TrackerOrigin.SetValue(initValue); + IviGeometryParameter.TrackerTilt.SetValue(initValue); + sprintf(IviGeometryParameter.VertexingMethod,"not defined"); + + + if ( !strcmp(fFieldName,"Inputs") || !strcmp(fFieldName, "LadderID") ) + { + cout << " -> No Experiment Geometrical Parameters to read (next item is '" << fFieldName << "')" << endl ; + return ; + } + + // ---------------------------------- + // IVI + // ---------------------------------- + cout << " -> IVI geometry : " << endl ; + do + { + if ( ! strcmp( fFieldName, "GeometryName") ) + { + read_strings(IviGeometryParameter.GeometryName, IviGeometryParameter.tpsz); + cout << " -> GeometryName: " << IviGeometryParameter.GeometryName << endl ; + } + else if ( ! strcmp( fFieldName, "GeometryVersion") ) + { + read_strings(IviGeometryParameter.GeometryVersion, IviGeometryParameter.tpsz); + cout << " -> GeometryVersion: " << IviGeometryParameter.GeometryVersion << endl ; + } + else if ( ! strcmp( fFieldName, "BeamOriginI") ) + { + read_r3(IviGeometryParameter.BeamOrigin); + cout << " -> BeamOrigin [mm]: I: " << IviGeometryParameter.BeamOrigin(0) << endl ; + cout << " J: " << IviGeometryParameter.BeamOrigin(1) << endl ; + cout << " K: " << IviGeometryParameter.BeamOrigin(2) << endl ; + } + else if ( ! strcmp( fFieldName, "BeamSlopeI") ) + { + read_r3(IviGeometryParameter.BeamSlope); + cout << " -> BeamSlope [/K] : I: " << IviGeometryParameter.BeamSlope(0) << endl ; + cout << " J: " << IviGeometryParameter.BeamSlope(1) << endl ; + cout << " K: " << IviGeometryParameter.BeamSlope(2) << endl ; + } + else if ( ! strcmp( fFieldName, "BeamDisplayStrongBeginI") ) + { + read_r3(IviGeometryParameter.BeamDisplayStrongBegin); + cout << " -> BeamDisplayStrongBegin [mm]: I: " << IviGeometryParameter.BeamDisplayStrongBegin(0) << endl ; + cout << " J: " << IviGeometryParameter.BeamDisplayStrongBegin(1) << endl ; + cout << " K: " << IviGeometryParameter.BeamDisplayStrongBegin(2) << endl ; + } + else if ( ! strcmp( fFieldName, "BeamDisplayStrongStopI") ) + { + read_r3(IviGeometryParameter.BeamDisplayStrongStop); + cout << " -> BeamDisplayStrongStop [mm]: I: " << IviGeometryParameter.BeamDisplayStrongStop(0) << endl ; + cout << " J: " << IviGeometryParameter.BeamDisplayStrongStop(1) << endl ; + cout << " K: " << IviGeometryParameter.BeamDisplayStrongStop(2) << endl ; + } + else if ( ! strcmp( fFieldName, "BeamDisplayMediumBeginI") ) + { + read_r3(IviGeometryParameter.BeamDisplayMediumBegin); + cout << " -> BeamDisplayMediumBegin [mm]: I: " << IviGeometryParameter.BeamDisplayMediumBegin(0) << endl ; + cout << " J: " << IviGeometryParameter.BeamDisplayMediumBegin(1) << endl ; + cout << " K: " << IviGeometryParameter.BeamDisplayMediumBegin(2) << endl ; + } + else if ( ! strcmp( fFieldName, "BeamDisplayMediumStopI") ) + { + read_r3(IviGeometryParameter.BeamDisplayMediumStop); + cout << " -> BeamDisplayMediumStop [mm]: I: " << IviGeometryParameter.BeamDisplayMediumStop(0) << endl ; + cout << " J: " << IviGeometryParameter.BeamDisplayMediumStop(1) << endl ; + cout << " K: " << IviGeometryParameter.BeamDisplayMediumStop(2) << endl ; + } + else if ( ! strcmp( fFieldName, "BeamDisplayLightBeginI") ) + { + read_r3(IviGeometryParameter.BeamDisplayLightBegin); + cout << " -> BeamDisplayLightBegin [mm]: I: " << IviGeometryParameter.BeamDisplayLightBegin(0) << endl ; + cout << " J: " << IviGeometryParameter.BeamDisplayLightBegin(1) << endl ; + cout << " K: " << IviGeometryParameter.BeamDisplayLightBegin(2) << endl ; + } + else if ( ! strcmp( fFieldName, "BeamDisplayLightStopI") ) + { + read_r3(IviGeometryParameter.BeamDisplayLightStop); + cout << " -> BeamDisplayLightStop [mm]: I: " << IviGeometryParameter.BeamDisplayLightStop(0) << endl ; + cout << " J: " << IviGeometryParameter.BeamDisplayLightStop(1) << endl ; + cout << " K: " << IviGeometryParameter.BeamDisplayLightStop(2) << endl ; + } + else if ( ! strcmp( fFieldName, "TargetType") ) + { + read_strings(IviGeometryParameter.TargetType, IviGeometryParameter.tpsz); + cout << " -> TargetType: " << IviGeometryParameter.TargetType << endl ; + } + else if ( ! strcmp( fFieldName, "TargetSizeI") ) + { + read_r3(IviGeometryParameter.TargetSize); + cout << " -> TargetSize [mm] : I: " << IviGeometryParameter.TargetSize(0) << endl ; + cout << " J: " << IviGeometryParameter.TargetSize(1) << endl ; + cout << " K: " << IviGeometryParameter.TargetSize(2) << endl ; + } + else if ( ! strcmp( fFieldName, "TargetRadius") ) + { + read_item(IviGeometryParameter.TargetRadius); + cout << " -> TargetRadius [mm] : " << IviGeometryParameter.TargetRadius << endl ; + } + else if ( ! strcmp( fFieldName, "TargetLength") ) + { + read_item(IviGeometryParameter.TargetLength); + cout << " -> TargetLength [mm] : " << IviGeometryParameter.TargetLength << endl ; + } + else if ( ! strcmp( fFieldName, "TargetAxis") ) + { + read_strings(IviGeometryParameter.TargetAxis,1); + cout << " -> TargetAxis : " << IviGeometryParameter.TargetAxis << endl ; + } + else if ( ! strcmp( fFieldName, "TargetCenterI") ) + { + read_r3(IviGeometryParameter.TargetCenter); + cout << " -> TargetCenter [mm]: I: " << IviGeometryParameter.TargetCenter(0) << endl ; + cout << " J: " << IviGeometryParameter.TargetCenter(1) << endl ; + cout << " K: " << IviGeometryParameter.TargetCenter(2) << endl ; + } + else if ( ! strcmp( fFieldName, "TrackerOriginI") ) + { + read_r3(IviGeometryParameter.TrackerOrigin); + cout << " -> TrackerOrigin [mm]: I: " << IviGeometryParameter.TrackerOrigin(0) << endl ; + cout << " J: " << IviGeometryParameter.TrackerOrigin(1) << endl ; + cout << " K: " << IviGeometryParameter.TrackerOrigin(2) << endl ; + } + else if ( ! strcmp( fFieldName, "TrackerTiltI") ) + { + read_r3(IviGeometryParameter.TrackerTilt); + cout << " -> TrackerTilt [deg]: I: " << IviGeometryParameter.TrackerTilt(0) << endl ; + cout << " J: " << IviGeometryParameter.TrackerTilt(1) << endl ; + cout << " K: " << IviGeometryParameter.TrackerTilt(2) << endl ; + } + else if ( ! strcmp( fFieldName, "VertexingMethod") ) + { + read_strings(IviGeometryParameter.VertexingMethod, IviGeometryParameter.tpsz); + cout << " -> VertexingMethod: " << IviGeometryParameter.VertexingMethod << endl ; + } + + nextField(); + } while ( strcmp(fFieldName,"Inputs") && strcmp(fFieldName,"LadderID") ); + + cout << " -> Reading finished ! (next item is '" << fFieldName << "')" << endl ; + +} + +//______________________________________________________________________________ +// +void DSetup::ReadLadderParameters( Int_t aLadderNumber) +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameters of a Ladder + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // JB 2013/01/16 + + // ################################################ + // Set default values + // ################################################ + pLadderParameter[aLadderNumber].LadderID = -1; + pLadderParameter[aLadderNumber].Status = -1; + sprintf(pLadderParameter[aLadderNumber].Name,""); + pLadderParameter[aLadderNumber].Planes = 0; + pLadderParameter[aLadderNumber].Position = DR3(0.0,0.0,0.0); + pLadderParameter[aLadderNumber].Tilt = DR3(0.0,0.0,0.0); + pLadderParameter[aLadderNumber].PlaneList = NULL; + pLadderParameter[aLadderNumber].PlaneShift = NULL; + pLadderParameter[aLadderNumber].PlaneTilt = NULL; + + if ( aLadderNumber<0 || TrackerParameter.Ladders<=aLadderNumber ) { + printf( "WARNING in ReadLadderParameters: trying to add ladder number %d, outside the limits [1 - %d]\n --> nothing done!\n", aLadderNumber+1, TrackerParameter.Ladders); + return; + } + else { + cout << endl << " - Reading Parameters of the Ladder " << aLadderNumber+1 << endl; + } + + // Init + Int_t nbOfPlanesAssociated = 0; + + do { + + if ( ! strcmp( fFieldName, "LadderID" ) ) { + read_item(pLadderParameter[aLadderNumber].LadderID); + if (DSetupDebug) cout << " ID = " << pLadderParameter[aLadderNumber].LadderID << endl; + } + else if( ! strcmp( fFieldName, "LadderName" ) ) { + read_strings( pLadderParameter[aLadderNumber].Name, pLadderParameter[aLadderNumber].tpsz); + if (DSetupDebug) cout << " Name = " << pLadderParameter[aLadderNumber].Name << endl; + } + else if( ! strcmp( fFieldName, "Status" ) ) { + read_item( pLadderParameter[aLadderNumber].Status); + /*if (DSetupDebug)*/ cout << " Status = " << pLadderParameter[aLadderNumber].Status << endl; + } + else if( ! strcmp( fFieldName, "LadderPositionX" ) ) { + read_r3(pLadderParameter[aLadderNumber].Position); + pLadderParameter[aLadderNumber].Position *= 1000.; // move from millimeters to microns + if(DSetupDebug) cout << " Position X = " << pLadderParameter[aLadderNumber].Position(0) << ", Y = " << pLadderParameter[aLadderNumber].Position(1) << ", Z = " << pLadderParameter[aLadderNumber].Position(2) << " microns" << endl; + } + else if( ! strcmp( fFieldName, "LadderTiltZ" ) ) { + read_r3(pLadderParameter[aLadderNumber].Tilt); + pLadderParameter[aLadderNumber].Tilt *= TMath::Pi()/180.; // conversion degree to radian + if(DSetupDebug) cout << " Tilt X = " << pLadderParameter[aLadderNumber].Tilt(0) << ", Y = " << pLadderParameter[aLadderNumber].Tilt(1) << ", Z = " << pLadderParameter[aLadderNumber].Tilt(2) << " rad" << endl; + } + else if ( ! strcmp( fFieldName, "NbOfPlanes" ) ) { + read_item(pLadderParameter[aLadderNumber].Planes); + pLadderParameter[aLadderNumber].PlaneList = new Int_t[pLadderParameter[aLadderNumber].Planes]; + pLadderParameter[aLadderNumber].PlaneShift = new DR3[pLadderParameter[aLadderNumber].Planes]; + pLadderParameter[aLadderNumber].PlaneTilt = new DR3[pLadderParameter[aLadderNumber].Planes]; + if (DSetupDebug) cout << " Nb of planes = " << pLadderParameter[aLadderNumber].Planes << endl; + } + else if( ! strcmp( fFieldName, "IncludedPlane" ) ) { + if ( nbOfPlanesAssociated >= pLadderParameter[aLadderNumber].Planes ) { + printf( "WARNING in ReadLadderParameters: trying to associate plane while maximum # planes (%d) already reached --> nothing done!\n", pLadderParameter[aLadderNumber].Planes); + } + else { // if planes can still be associated + read_item(pLadderParameter[aLadderNumber].PlaneList[nbOfPlanesAssociated]); + if(DSetupDebug) cout << " Associated plane " << nbOfPlanesAssociated << " is " << pLadderParameter[aLadderNumber].PlaneList[nbOfPlanesAssociated] << endl; + + // Force the reading of the two next info + nextField(); + if ( ! strcmp( fFieldName, "PlaneShiftU" ) ) { + read_r3(pLadderParameter[aLadderNumber].PlaneShift[nbOfPlanesAssociated]); + pLadderParameter[aLadderNumber].PlaneShift[nbOfPlanesAssociated] *= 1000.; // conversion from mm to um + if(DSetupDebug) cout << " Plane shift U = " << pLadderParameter[aLadderNumber].PlaneShift[nbOfPlanesAssociated](0) << ", V = " << pLadderParameter[aLadderNumber].PlaneShift[nbOfPlanesAssociated](1) << ", W = " << pLadderParameter[aLadderNumber].PlaneShift[nbOfPlanesAssociated](2) << " microns" << endl; + } + else { + printf( "WARNING in ReadLadderParameters: expecting Plane %d Shift information!\n", nbOfPlanesAssociated); + } + + nextField(); + if ( ! strcmp( fFieldName, "PlaneTiltU" ) ) { + read_r3(pLadderParameter[aLadderNumber].PlaneTilt[nbOfPlanesAssociated]); + pLadderParameter[aLadderNumber].PlaneTilt[nbOfPlanesAssociated] *= M_PI/180.; // conversion degree to radian + if(DSetupDebug) cout << " Plane Tilt U = " << pLadderParameter[aLadderNumber].PlaneTilt[nbOfPlanesAssociated](0) << ", V = " << pLadderParameter[aLadderNumber].PlaneTilt[nbOfPlanesAssociated](1) << ", W = " << pLadderParameter[aLadderNumber].PlaneTilt[nbOfPlanesAssociated](2) << " [rad]" << endl; + } + else { + printf( "WARNING in ReadLadderParameters: expecting Plane %d Tilt information!\n", nbOfPlanesAssociated); + } + + nbOfPlanesAssociated++; + } // end if planes can still be associated + } // end if field is IncludedPlane + else + { + if ( strcmp( fFieldName, "Inputs") && strcmp( fFieldName, "LadderID") && strcmp( fFieldName, "FileHeaderSize") ) + { + cout << "WARNING : parameter '" << fFieldName << "' in config file is not understood !" << endl; + getRidOfLine(); + } + } + + nextField(); + + } while ( strcmp( fFieldName, "Inputs") && strcmp( fFieldName, "LadderID") && strcmp( fFieldName, "FileHeaderSize") && strcmp( fFieldName, "FixTrackParamX") ); + + if( nbOfPlanesAssociated < pLadderParameter[aLadderNumber].Planes ) { + printf( "WARNING in ReadLadderParameters: only %d planes have been associated to ladder %d while %d were expected!\n", nbOfPlanesAssociated, pLadderParameter[aLadderNumber].LadderID, pLadderParameter[aLadderNumber].Planes); + } + + fAddedLadders++; + + /* + if(DSetupDebug) { + printf("Parameters for ladder %d of type %s:\n", pLadderParameter[aLadderNumber].LadderID, pLadderParameter[aLadderNumber].Name); + printf(" status = %d\n", pLadderParameter[aLadderNumber].Status); + printf(" contains %d ladders:\n", pLadderParameter[aLadderNumber].Planes); + for ( Int_t iplane=0; iplane absolute nb = %d\n", iplane, pLadderParameter[aLadderNumber].PlaneList[iplane]); + printf (" relative tilt : %.2f %.2f %.2f \n" + , pLadderParameter[aLadderNumber].PlaneTilt[iplane](0) + , pLadderParameter[aLadderNumber].PlaneTilt[iplane](1) + , pLadderParameter[aLadderNumber].PlaneTilt[iplane](2)); + printf (" relative shift : %.2f %.2f %.2f \n" + , pLadderParameter[aLadderNumber].PlaneShift[iplane](0) + , pLadderParameter[aLadderNumber].PlaneShift[iplane](1) + , pLadderParameter[aLadderNumber].PlaneShift[iplane](2)); + } + } + */ + + if ( ! strcmp( fFieldName, "LadderID") ) { // new ladder + ReadLadderParameters( fAddedLadders ); + } //end if new plane + else if ( ! strcmp( fFieldName, "Inputs") ) { // new plane + ReadPlaneParameters( fAddedPlanes ); + } //end if new plane + +} +//______________________________________________________________________________ +// +void DSetup::ReadGlobalAlignmentParameters() +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Global Alignment Parameters + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // Added : LC 31/08/2015 + + cout << endl << " - Reading Global Alignment Parameters " << endl; + + pGlobalAlignmentParameter.FixTrackParamX = 0.; + pGlobalAlignmentParameter.FixTrackParamY = 0.; + pGlobalAlignmentParameter.ResoTrackParamX = 1e-3; + pGlobalAlignmentParameter.ResoTrackParamY = 1e-3; + pGlobalAlignmentParameter.ResoAlignParamTr = 100.; + pGlobalAlignmentParameter.ResoAlignParamRot = 0.1; // rad + pGlobalAlignmentParameter.ResoAlignParamZ = 1e-6; // rad + pGlobalAlignmentParameter.ResoFixPlaneTr = 1e-6; + pGlobalAlignmentParameter.ResoFixPlaneRot = 1e-4; + + + if ( strcmp(fFieldName,"FixTrackParamX") ) + { + cout << " -> No Global Alignment Parameters to read (next item is '" << fFieldName << "')" << endl ; + return ; + } + + do { + + if ( ! strcmp( fFieldName, "FixTrackParamX" ) ) { + read_item(pGlobalAlignmentParameter.FixTrackParamX); + /*if (DSetupDebug)*/ cout << " Track parametrers X fixed to value " << pGlobalAlignmentParameter.FixTrackParamX << endl; + } + else if( ! strcmp( fFieldName, "FixTrackParamY" ) ) { + read_item(pGlobalAlignmentParameter.FixTrackParamY); + /*if (DSetupDebug)*/ cout << " Track parametrers Y fixed to value " << pGlobalAlignmentParameter.FixTrackParamY << endl; + } + else if( ! strcmp( fFieldName, "ResoTrackParamX" ) ) { + read_item(pGlobalAlignmentParameter.ResoTrackParamX); + /*if (DSetupDebug)*/ cout << " Track parameters X resolution = " << pGlobalAlignmentParameter.ResoTrackParamX << endl; + } + else if ( ! strcmp( fFieldName, "ResoTrackParamY" ) ) { + read_item(pGlobalAlignmentParameter.ResoTrackParamY); + /*if (DSetupDebug)*/ cout << " Track parameters Y resolution = " << pGlobalAlignmentParameter.ResoTrackParamY << endl; + } + else if( ! strcmp( fFieldName, "ResoAlignParamTr" ) ) { + read_item(pGlobalAlignmentParameter.ResoAlignParamTr); + /*if (DSetupDebug)*/ cout << " Alignemnt transaltions resolution = " << pGlobalAlignmentParameter.ResoAlignParamTr << endl; + } + else if( ! strcmp( fFieldName, "ResoAlignParamRot" ) ) { + read_item(pGlobalAlignmentParameter.ResoAlignParamRot); + pGlobalAlignmentParameter.ResoAlignParamRot *= TMath::Pi()/180.; + /*if (DSetupDebug)*/ cout << " Alignemnt rotations resolution = " << pGlobalAlignmentParameter.ResoAlignParamRot << endl; + } + else if( ! strcmp( fFieldName, "ResoFixPlaneTr" ) ) { + read_item(pGlobalAlignmentParameter.ResoFixPlaneTr); + /*if (DSetupDebug)*/ cout << " Fix Plane Rotations Resolution = " << pGlobalAlignmentParameter.ResoFixPlaneTr << endl; + } + else if( ! strcmp( fFieldName, "ResoFixPlaneRot" ) ) { + read_item(pGlobalAlignmentParameter.ResoFixPlaneRot); + /*if (DSetupDebug)*/ cout << " Fix Plane Rotations Resolution = " << pGlobalAlignmentParameter.ResoFixPlaneRot << endl; + pGlobalAlignmentParameter.ResoFixPlaneRot *= TMath::Pi()/180.; + } + else if( ! strcmp( fFieldName, "ResoAlignParamZ" ) ) { + read_item(pGlobalAlignmentParameter.ResoAlignParamZ); + /*if (DSetupDebug)*/ cout << " Alignemnt Translation Z Resolution = " << pGlobalAlignmentParameter.ResoAlignParamZ << endl; + } + + nextField(); + + } while ( strcmp( fFieldName, "Inputs") && strcmp( fFieldName, "FileHeaderSize") && strcmp( fFieldName, "GeometryName" ) && strcmp( fFieldName, "LadderID" ) ); + + cout << " -> Reading finished ! (next item is '" << fFieldName << "')" << endl ; + +} +//______________________________________________________________________________ +// +void DSetup::ReadPlaneParameters( Int_t aPlaneNumber) +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameters of the Planes + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // JB 2013/01/16 + // Modified JB 2013/07/17 new parameters HitFinder, IfDigitize, ... + // Modified JB 2013/08/13 set default valus for MimosaType, Max/MinNStrips + // Modified JB 2013/08/15 new ChannelOffset, PlaneResolution parameters + // Modified JB 2013/08/29 new Digitizer parameters + // Modified JB 2014/01/07 default for InitialPedestal and InitialNoise + // Modified JB 2014/04/21 new deformation parameters + // Modified AP 2014/07/31 new variables for hot pixel list: file name and fake rate cut + // Modified AP 2014/12 ? new Resolution options (U,V or by histograms) + + if ( aPlaneNumber<0 || TrackerParameter.Planes<=aPlaneNumber ) { + printf( "WARNING in ReadPlaneParameters: trying to add plane number %d, outside the limits [1 - %d]\n --> nothing done!\n", aPlaneNumber+1, TrackerParameter.Planes); + return; + } + else { + cout << endl << " - Reading Parameters of the Plane " << aPlaneNumber+1 << endl; + } + + // Initialize some default values for mandatory parameters + pPlaneParameter[aPlaneNumber].Inputs = 0; + for(int imd=0;imd=100 ) { + pPlaneParameter[aPlaneNumber].InitialPedestal = 0; + pPlaneParameter[aPlaneNumber].InitialNoise = 0; + } + } + else if( ! strcmp( fFieldName, "MimosaType" ) ) { + read_item(pPlaneParameter[aPlaneNumber].MimosaType); //RDM210509 + } + else if( ! strcmp( fFieldName, "AnalysisMode" ) ) { + read_item(pPlaneParameter[aPlaneNumber].AnalysisMode); + } + else if( ! strcmp( fFieldName, "HitFinder" ) ) { // JB 2013/07/17 + read_item(pPlaneParameter[aPlaneNumber].HitFinder); + } + else if( ! strcmp( fFieldName, "FixedGlobalAlign" ) ) { // JB 2013/07/17 + read_item(pPlaneParameter[aPlaneNumber].FixedGlobalAlign); + } + else if( ! strcmp( fFieldName, "HotPixelMapFile" ) ) { // AP 2014/07/31 + read_TStrings( HotPixelMapFile, 350); + } + else if( ! strcmp( fFieldName, "FractionToMask" ) ) { // AP 2014/07/31 + read_item(FractionToMask); + _FractionToMaskList.push_back(FractionToMask); + } + else if( ! strcmp( fFieldName, "FakeRateCut" ) ) { // AP 2015/12/01 + read_item(FakeRateCut); + _FakeRateCutList.push_back(FakeRateCut); + } + else if( ! strcmp( fFieldName, "InitialPedestal" ) ) { + read_item(pPlaneParameter[aPlaneNumber].InitialPedestal); + } + else if( ! strcmp( fFieldName, "InitialNoise" ) ) { + read_item(pPlaneParameter[aPlaneNumber].InitialNoise); + pPlaneParameter[aPlaneNumber].InitialPedestal = pPlaneParameter[aPlaneNumber].InitialNoise; // added to initialize when only InitialNoise is specified, JB 2014/01/07 + } + else if( ! strcmp( fFieldName, "CacheSize" ) ) { + read_item(pPlaneParameter[aPlaneNumber].CacheSize); + if(DSetupDebug) printf(" CacheSize : %d InitialPedestal : %d InitialNoise : %d\n", + pPlaneParameter[aPlaneNumber].CacheSize, + pPlaneParameter[aPlaneNumber].InitialPedestal, + pPlaneParameter[aPlaneNumber].InitialNoise); + } + else if( ! strcmp( fFieldName, "IfDigitize" ) || ! strcmp( fFieldName, "Ifdigitize" ) ) { // JB 2013/07/17 + read_item(pPlaneParameter[aPlaneNumber].IfDigitize); + // Force the reading of the thresholds right after the IfDigitize field, if non-zero + if( pPlaneParameter[aPlaneNumber].IfDigitize>0 ) { // if digitization required + if(DSetupDebug) printf( " Digitization emulation required over %d thresholds:\n", pPlaneParameter[aPlaneNumber].IfDigitize); + nextField(); + if( ! strcmp( fFieldName, "DigitizeThresholds" ) || ! strcmp( fFieldName, "Digitizethresholds" ) ) { // check there are the thresholds + for (Int_t k = 0; k < pPlaneParameter[aPlaneNumber].IfDigitize; k++) { + if( k>0 ) nextItem(':'); // already positionned for 1st value + read_item(pPlaneParameter[aPlaneNumber].DigitizeThresholds[k]); + if(DSetupDebug) printf( " thre[%d] = %d\n", k, pPlaneParameter[aPlaneNumber].DigitizeThresholds[k]); + } + } + else { // if the thresholds are missing + Error("DSetup", "In the configuration file, the field 'DigitizeThresholds' is expected right after the 'IfDigitize' one, with %d thresholds !", pPlaneParameter[aPlaneNumber].IfDigitize); + } + } // end if digitization required + } + else if( ! strcmp( fFieldName, "PositionsX" ) ) { + read_r3(pPlaneParameter[aPlaneNumber].Position); + pPlaneParameter[aPlaneNumber].Position *= 1000; // move from millimeters to microns + if(DSetupDebug) cout << " Position X = " << pPlaneParameter[aPlaneNumber].Position(0) << ", Y = " << pPlaneParameter[aPlaneNumber].Position(1) << ", Z = " << pPlaneParameter[aPlaneNumber].Position(2) << " microns" << endl; + } + else if( ! strcmp( fFieldName, "TiltZ" ) || ! strcmp( fFieldName, "Tilt1" ) ) { + // test with Tilt1 added to comply with MAF files, JB 2013/08/19 + read_r3(pPlaneParameter[aPlaneNumber].Tilt); + pPlaneParameter[aPlaneNumber].Tilt *= M_PI/180.; // conversion degree to radian + } + else if( ! strcmp( fFieldName, "AlignementU" ) ) { + read_item(pPlaneParameter[aPlaneNumber].AlignmentU); + } + else if( ! strcmp( fFieldName, "AlignementV" ) ) { + read_item(pPlaneParameter[aPlaneNumber].AlignmentV); + } + else if( ! strcmp( fFieldName, "AlignementTilt" ) ) { + read_item(pPlaneParameter[aPlaneNumber].AlignmentTilt); + pPlaneParameter[aPlaneNumber].AlignmentTilt *= TMath::DegToRad(); + if(DSetupDebug) cout << " AlignementU " << pPlaneParameter[aPlaneNumber].AlignmentU << ", AlignementV " << pPlaneParameter[aPlaneNumber].AlignmentV << ", AlignementTilt [deg] " << pPlaneParameter[aPlaneNumber].AlignmentTilt << endl; + } + else if( ! strcmp( fFieldName, "SizeU" ) ) { + read_r3(pPlaneParameter[aPlaneNumber].Size); + pPlaneParameter[aPlaneNumber].Size *= 1000; + if(DSetupDebug) printf (" Size : %f %f %f \n",pPlaneParameter[aPlaneNumber].Size(0),pPlaneParameter[aPlaneNumber].Size(1),pPlaneParameter[aPlaneNumber].Size(2)); + printf( "WARNING: you specify a Size for your strips, which is now ignored.\n The sensitive area is now computed from the Pitch and the nb of strips.\n"); + } + else if( ! strcmp( fFieldName, "StripsU" ) ) { + read_r3(pPlaneParameter[aPlaneNumber].Strips); + if(DSetupDebug) printf (" #strips : %f %f %f \n",pPlaneParameter[aPlaneNumber].Strips(0),pPlaneParameter[aPlaneNumber].Strips(1),pPlaneParameter[aPlaneNumber].Strips(2)); + } + else if( ! strcmp( fFieldName, "PitchU" ) ) { + read_r3(pPlaneParameter[aPlaneNumber].Pitch); + pPlaneParameter[aPlaneNumber].Pitch *= 1000; + if(DSetupDebug) printf (" strip pitch : %f %f %f \n",pPlaneParameter[aPlaneNumber].Pitch(0),pPlaneParameter[aPlaneNumber].Pitch(1),pPlaneParameter[aPlaneNumber].Pitch(2)); + // If Strip Size is not defined yet, set to Pitch, JB 2014/04/21 + if( pPlaneParameter[aPlaneNumber].StripSize(0)<1. ) { + pPlaneParameter[aPlaneNumber].StripSize = pPlaneParameter[aPlaneNumber].Pitch; + } + } + else if( ! strcmp( fFieldName, "StripSize" ) || ! strcmp( fFieldName, "StripSizeU" )) { + read_r3(pPlaneParameter[aPlaneNumber].StripSize); + pPlaneParameter[aPlaneNumber].StripSize *= 1000; + if(DSetupDebug) printf (" strip size : %f %f %f \n",pPlaneParameter[aPlaneNumber].StripSize(0),pPlaneParameter[aPlaneNumber].StripSize(1),pPlaneParameter[aPlaneNumber].StripSize(2)); + } + else if( ! strcmp( fFieldName, "Mapping" ) ) { + read_item(pPlaneParameter[aPlaneNumber].Mapping); + if(DSetupDebug) cout << " Mapping = " << pPlaneParameter[aPlaneNumber].Mapping << endl; + } + else if( ! strcmp( fFieldName, "ThreshNeighbourSN" ) || ! strcmp( fFieldName, "ThresNeighbourSN" ) ) { // additional condition (typo), JB 2013/08/19 + read_item(pPlaneParameter[aPlaneNumber].ThreshNeighbourSN); + } + else if( ! strcmp( fFieldName, "ThreshSeedSN" ) ) { + read_item(pPlaneParameter[aPlaneNumber].ThreshSeedSN); + if(DSetupDebug) cout << " Threshold SNR cuts, neighbour = " << pPlaneParameter[aPlaneNumber].ThreshNeighbourSN << " seed = " << pPlaneParameter[aPlaneNumber].ThreshSeedSN << endl ; + } + else if( ! strcmp( fFieldName, "MaximalNoise" ) || ! strcmp( fFieldName, "maximalNoise" ) || ! strcmp( fFieldName, "Maximalnoise" )) { + read_item(pPlaneParameter[aPlaneNumber].MaximalNoise); + if(DSetupDebug) cout << " Maximal noise cut on seed = " << pPlaneParameter[aPlaneNumber].MaximalNoise << endl ; + } + else if( ! strcmp( fFieldName, "MinimalNoise" ) || ! strcmp( fFieldName, "minimalNoise" ) || ! strcmp( fFieldName, "Minimalnoise" )) { + read_item(pPlaneParameter[aPlaneNumber].MinimalNoise); + if(DSetupDebug) cout << " Minimal noise cut on seed = " << pPlaneParameter[aPlaneNumber].MinimalNoise << endl ; + } + else if( ! strcmp( fFieldName, "MaxNStrips" ) ) { + read_item(pPlaneParameter[aPlaneNumber].MaxNStrips); + } + else if( ! strcmp( fFieldName, "MinNStrips" ) ) { + read_item(pPlaneParameter[aPlaneNumber].MinNStrips); + } + else if( ! strcmp( fFieldName, "ClusterLimit" ) || ! strcmp( fFieldName, "ClusterLimitU" )) { + read_r3(pPlaneParameter[aPlaneNumber].ClusterLimit); + pPlaneParameter[aPlaneNumber].ClusterLimit *= 1000; + } + else if( ! strcmp( fFieldName, "ClusterLimitRadius" ) ) { // VR 2014/07/16 + read_item(pPlaneParameter[aPlaneNumber].ClusterLimitRadius); + pPlaneParameter[aPlaneNumber].ClusterLimitRadius *= 1000; + } + else if( ! strcmp( fFieldName, "CommonRegions" ) ) { + read_item(pPlaneParameter[aPlaneNumber].CommonRegions); + } + else if( ! strcmp( fFieldName, "Status" ) ) { + read_item(pPlaneParameter[aPlaneNumber].Status); + if(DSetupDebug) cout << " Status of plane = " << pPlaneParameter[aPlaneNumber].Status << endl; + } + else if( ! strcmp( fFieldName, "ParentLadder" ) ) { + read_item(pPlaneParameter[aPlaneNumber].ParentLadderID); + if(DSetupDebug) cout << " Parent ladder ID = " << pPlaneParameter[aPlaneNumber].ParentLadderID << endl; + } + else if( ! strcmp( fFieldName, "PositionAlgorithm" ) ) { + read_item(pPlaneParameter[aPlaneNumber].HitPositionAlgorithm); + } + else if( ! strcmp( fFieldName, "PlaneResolution" ) ) { // JB 2013/08/15 + Float_t resolution; + read_item(resolution); + _ResolutionList.push_back(resolution); + //read_item(pPlaneParameter[aPlaneNumber].PlaneResolution); + } + else if( ! strcmp( fFieldName, "PlaneResolutionU" ) ) { // AP 2014/11/20 + Float_t resolution; + read_item(resolution); + _ResolutionUList.push_back(resolution); + //read_item(pPlaneParameter[aPlaneNumber].PlaneResolutionU); + } + else if( ! strcmp( fFieldName, "PlaneResolutionV" ) ) { // AP 2014/11/20 + Float_t resolution; + read_item(resolution); + _ResolutionVList.push_back(resolution); + //read_item(pPlaneParameter[aPlaneNumber].PlaneResolutionV); + } + else if( ! strcmp( fFieldName, "PlaneThickness" ) ) { // AP 2015/03/10 + read_item(pPlaneParameter[aPlaneNumber].PlaneThickness); + } + else if( ! strcmp( fFieldName, "PlaneMaterial" ) ) { // AP 2015/03/10 + read_TStrings( pPlaneParameter[aPlaneNumber].PlaneMaterial, 350); + } + else if( ! strcmp( fFieldName, "ResolutionFile" ) ) { // AP 2014/07/31 + read_TStrings( ResolutionFile, 350); + _ResolutionFileList.push_back(ResolutionFile); + } + else if( ! strcmp( fFieldName, "ResolutionRegion" ) ) { // AP 2014/11/20 + read_item(TheRegion.R_col[0]); + read_item(TheRegion.R_col[1]); + read_item(TheRegion.R_lin[0]); + read_item(TheRegion.R_lin[1]); + + if(TheRegion.R_col[0] == -1 || + TheRegion.R_col[1] == -1 || + TheRegion.R_lin[0] == -1 || + TheRegion.R_lin[1] == -1) { + cout << endl; + cout << "When specifying a region need to give 4 parameters. col_min, col_max, line_min and line_max. Check your inputs. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + _RegionList.push_back(TheRegion); + + } + else if( ! strcmp( fFieldName, "Digitizer" ) || ! strcmp( fFieldName, "Digitize" ) ) { // Digitization parameters, JB 2013/08/29 + read_item(pPlaneParameter[aPlaneNumber].IfDigitize); + if( pPlaneParameter[aPlaneNumber].IfDigitize>fMaxDigitalThresholds ) { + Warning("ReadPlaneParameters","Nb of digits specified %d, exceeds limit %d --> set back to limit", pPlaneParameter[aPlaneNumber].IfDigitize, fMaxDigitalThresholds); + pPlaneParameter[aPlaneNumber].IfDigitize = fMaxDigitalThresholds; + } + if(DSetupDebug) cout << " Digitize over " << pPlaneParameter[aPlaneNumber].IfDigitize << " thresholds:" << endl; + for ( Int_t ithre=0; ithre0) cout << " Deforming plane surface according to parameters:" << endl; + } + else if( ! strcmp( fFieldName, "coeffLegendreU" ) || ! strcmp( fFieldName, "coefflegendreU" ) ) { // JB 2014/04/21 + Int_t i=0; + if(DSetupDebug) cout << " along U:" ; + while (i<7) { + read_item( pPlaneParameter[aPlaneNumber].CoeffLegendreU[i]); + if(DSetupDebug) cout << " " << pPlaneParameter[aPlaneNumber].CoeffLegendreU[i]; + nextItem(':'); + i++; + } + if(DSetupDebug) cout << endl; + } // end U Deformation parameters + else if( ! strcmp( fFieldName, "coeffLegendreV" ) || ! strcmp( fFieldName, "coefflegendreV" ) ) { // JB 2014/04/21 + Int_t i=0; + if(DSetupDebug) cout << " along V:" ; + while (i<7) { + read_item( pPlaneParameter[aPlaneNumber].CoeffLegendreV[i]); + if(DSetupDebug) cout << " " << pPlaneParameter[aPlaneNumber].CoeffLegendreV[i] << endl; + nextItem(':'); + i++; + } + if(DSetupDebug) cout << endl; + } // end V Deformation parameters + else if( ! strcmp( fFieldName, "PlaneTimeLimit" ) || ! strcmp( fFieldName, "planetimelimit" ) ) { // JB 2015/05/26 + read_item(pPlaneParameter[aPlaneNumber].TimeLimit); + } + else + { + if ( strcmp( fFieldName, "Inputs") && strcmp( fFieldName, "LadderID") && strcmp( fFieldName, "FileHeaderSize") && strcmp( fFieldName, "ModuleTypes" ) && strcmp( fFieldName, "AcqModuleTypes" ) ) + { + cout << "WARNING : parameter '" << fFieldName << "' in config file is not understood !" << endl; + getRidOfLine(); + } + } + + nextField(); + + } while ( strcmp( fFieldName, "Inputs") && + strcmp( fFieldName, "LadderID") && + strcmp( fFieldName, "FileHeaderSize") && + strcmp( fFieldName, "ModuleTypes" ) && + strcmp( fFieldName, "AcqModuleTypes" ) && + strcmp( fFieldName, "FixTrackParamX") + ); + + + // Set specific parameters for HitFinder=2 + // AP ? + + if (pPlaneParameter[aPlaneNumber].HitFinder == 2) { + if(pPlaneParameter[aPlaneNumber].ClusterLimitRadius == -1) + { + cout << " ERROR: The field 'ClusterLimitRadius' is MANDATORY in config file when using HitFinder = 2 (section planes parameters)" << endl; + gApplication->Terminate(); + } + } + if (pPlaneParameter[aPlaneNumber].HitFinder != 2) { + if(pPlaneParameter[aPlaneNumber].ClusterLimit(0) == -1 || pPlaneParameter[aPlaneNumber].ClusterLimit(1) == -1) + { + cout << " ERROR: The field 'ClusterLimit' is MANDATORY in config file when using HitFinder != 2 (section planes parameters)" << endl; + gApplication->Terminate(); + } + } + + //Set of specific parameters for the hit spatial resolution + //AP 12/01/2015 + InitializePerformancesParams(aPlaneNumber); + + //Set specific parameters for hot pixel map + //AP 01/12/2015 + if(_FakeRateCutList.size() > 0 && _FractionToMaskList.size() == 0) { + GetListOfHotPixelsToMask_FakeRateCut(aPlaneNumber,HotPixelMapFile); + } + else if(_FakeRateCutList.size() == 0 && _FractionToMaskList.size() > 0) { + GetListOfHotPixelsToMask_FracToMask(aPlaneNumber,HotPixelMapFile); + } + else if(_FakeRateCutList.size() > 0 && _FractionToMaskList.size() > 0) { + cout << endl; + cout << "WARNING:: Both lists of FakeRateCut and FractionToMask have size > 0" << endl; + cout << " In order to define the list of hot pixels to mask just one of the lists can have size > 0." << endl; + cout << " Check your inputs. Doing nothing!!!" << endl; + cout << endl; + } + PrintListOfHotPixelsToMask(aPlaneNumber); + + _ResolutionList.clear(); + _ResolutionUList.clear(); + _ResolutionVList.clear(); + _RegionList.clear(); + _FractionToMaskList.clear(); + _FakeRateCutList.clear(); + _ResolutionFileList.clear(); + + if(pPlaneParameter[aPlaneNumber].PlaneThickness < 0) { + pPlaneParameter[aPlaneNumber].PlaneThickness = 1.0e-10; + cout << "No specification of PlaneThickness. Use default value of " << pPlaneParameter[aPlaneNumber].PlaneThickness << "um. (Insignificant multiple scattering)" << endl; + } + else cout << "PlaneThickness set to user value: " << pPlaneParameter[aPlaneNumber].PlaneThickness << "um." << endl; + + if(pPlaneParameter[aPlaneNumber].PlaneMaterial == TString("")) { + pPlaneParameter[aPlaneNumber].PlaneMaterial = TString("silicon"); + cout << "No specification of PlaneMaterial. Use default value of " << pPlaneParameter[aPlaneNumber].PlaneMaterial.Data() << "." << endl; + } + else { + cout << "PlaneMaterial set to user value: " << pPlaneParameter[aPlaneNumber].PlaneMaterial.Data() << endl; + } + + // --------- + // This is the end of plane parameters + + fAddedPlanes++; + + if ( ! strcmp( fFieldName, "Inputs") ) { // new plane + ReadPlaneParameters( fAddedPlanes ); + } //end if new plane + else if ( ! strcmp( fFieldName, "LadderID") ) { // new ladder + ReadLadderParameters( fAddedLadders ); + } //end if new plane + + /* + // Old parameters not used anymore + // JB 2013/01/15 + read_item(pPlaneParameter[aPlaneNumber].EtaCoefficientsN); + nextItem(':'); + for (j = 0; j < pPlaneParameter[aPlaneNumber].EtaCoefficientsN; j++) { + fConfigFileStream >> pPlaneParameter[aPlaneNumber].EtaCoefficient[j]; + } + if (DSetupDebug) cout << endl; + read_item(pPlaneParameter[aPlaneNumber].EtaLowLimit); + read_item(pPlaneParameter[aPlaneNumber].EtaHighLimit); + + read_item(pPlaneParameter[aPlaneNumber].KappaCoefficientsN); + nextItem(':'); + for (j = 0; j < pPlaneParameter[aPlaneNumber].KappaCoefficientsN; j++) { + fConfigFileStream >> pPlaneParameter[aPlaneNumber].KappaCoefficient[j]; + } + if (DSetupDebug) cout << endl; + read_item(pPlaneParameter[aPlaneNumber].KappaLowLimit); + read_item(pPlaneParameter[aPlaneNumber].KappaHighLimit); + + read_item(pPlaneParameter[aPlaneNumber].GammaCoefficientsN); + nextItem(':'); + for (j = 0; j < pPlaneParameter[aPlaneNumber].GammaCoefficientsN; j++) { + fConfigFileStream >> pPlaneParameter[aPlaneNumber].GammaCoefficient[j]; + } + if (DSetupDebug) cout << endl; + read_item(pPlaneParameter[aPlaneNumber].GammaLowLimit); + read_item(pPlaneParameter[aPlaneNumber].GammaHighLimit); + + + read_item(pPlaneParameter[aPlaneNumber].NoisyStripsN); + nextItem(':'); + for (j = 0; j < pPlaneParameter[aPlaneNumber].NoisyStripsN; j++) { + fConfigFileStream >> pPlaneParameter[aPlaneNumber].NoisyStripsIndex[j]; + if (DSetupDebug) cout << pPlaneParameter[aPlaneNumber].NoisyStripsIndex[j] << " "; + } + */ + +} +//______________________________________________________________________________ +// +void DSetup::ReadDAQParameters() +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameter of the Data Acquisition + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // JB 2013/01/16 + // Modified JB 2018/02/11 TimeReference option added + + cout << endl << " - Reading Parameter of the Data Acquisition " << endl; + + // ################################################ + // Set default values + // ################################################ + AcqParameter.FileHeaderSize = -1; + AcqParameter.EventBufferSize = -1; + AcqParameter.FileHeaderLine = -1; + AcqParameter.EventTrailerSize = 4; + AcqParameter.ModuleTypes = -1; + AcqParameter.BinaryCoding = -1; + AcqParameter.TriggerMode = 0; + AcqParameter.EventBuildingMode = 1; //SS 2011.11.14. Setting EventBuildingMode=1 by default. It can be changed during initialisation of the session or from the config file + sprintf(AcqParameter.TimeRefFile, ""); // JB 2018/02/11 + AcqParameter.IfExternalTimeRef = 0; + + do { + + if( ! strcmp( fFieldName, "FileHeaderSize" ) ) { + read_item(AcqParameter.FileHeaderSize); + } + else if( ! strcmp( fFieldName, "EventBufferSize" ) ) { + read_item(AcqParameter.EventBufferSize); + } + else if( ! strcmp( fFieldName, "FileHeaderLine" ) || ! strcmp( fFieldName, "FileHeaderLine[d]" ) + || ! strcmp( fFieldName, "EventHeaderSize" )) { + read_item(AcqParameter.FileHeaderLine); + AcqParameter.EventHeaderSize = AcqParameter.FileHeaderLine; + } + else if( ! strcmp( fFieldName, "EventTrailerSize" ) || ! strcmp( fFieldName, "eventtrailersize" )) { + read_item(AcqParameter.EventTrailerSize); + } + else if( ! strcmp( fFieldName, "ModuleTypes" ) || ! strcmp( fFieldName, "AcqModuleTypes" ) ) { + read_item(AcqParameter.ModuleTypes); + } + else if( ! strcmp( fFieldName, "BinaryCoding" ) ) { + read_item(AcqParameter.BinaryCoding); + } + else if( ! strcmp( fFieldName, "TriggerMode" ) ) { + read_item(AcqParameter.TriggerMode); + } + else if( ! strcmp( fFieldName, "EventBuildingMode" ) ) { + read_item(AcqParameter.EventBuildingMode); + } + else if( ! strcmp( fFieldName, "TimeRefFile" ) || ! strcmp( fFieldName, "timereffile" ) ) { + read_strings( AcqParameter.TimeRefFile, 100); + AcqParameter.IfExternalTimeRef = 1; + } + else + { + if ( strcmp( fFieldName, "Name") ) + { + cout << "WARNING : parameter '" << fFieldName << "' in config file is not understood !" << endl; + getRidOfLine(); + } + } + nextField(); + + } while ( strcmp( fFieldName, "Name") ); + + + if( DSetupDebug) { + cout << " header file size " << AcqParameter.FileHeaderSize << endl; + cout << " event buffer size " << AcqParameter.EventBufferSize << endl; + cout << " event header size " << AcqParameter.EventHeaderSize << endl; + cout << " event trailer size " << AcqParameter.EventTrailerSize << endl; + cout << " nb of mod types " << AcqParameter.ModuleTypes << endl; + cout << " endian coding " << AcqParameter.BinaryCoding << endl; + cout << " trigger mode " << AcqParameter.TriggerMode << endl; + cout << " event building mode " << AcqParameter.EventBuildingMode << endl; + if( AcqParameter.IfExternalTimeRef ) cout << " file for external time ref " << AcqParameter.TimeRefFile << endl; + } + +} +//______________________________________________________________________________ +// +void DSetup::ReadDAQBoardParameters( Int_t aBoardNumber) +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameter of the Data Acquisition boards in this run + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // JB 2013/01/16 + // Modified: JB 2013/06/20 correction to call ReadDAQBoardParameters at the end + // Modified: JB 2013/06/22 new EventBuildingBoardMode param + // Modified: JB 2013/08/16 manage different parameters for each input + // Modified: JB+CB+PLR 2015/03/24 additional parameter for INFN decoder + // Modified: JB 2016/09/20 new nMultiFrames param + // Modified: JB 2017/11/20 new IfZeroSuppress mode available + + sprintf(pAcqModuleParameter[aBoardNumber].Name,""); + pAcqModuleParameter[aBoardNumber].Devices = -1; + pAcqModuleParameter[aBoardNumber].Type = -1; + pAcqModuleParameter[aBoardNumber].EventBuildingBoardMode = -1; + pAcqModuleParameter[aBoardNumber].Inputs = -1; + for(int i=0;i nothing done!\n", aBoardNumber+1, AcqParameter.ModuleTypes); + return; + } + else { + cout << endl << " - Reading Parameters of the Data Acquisition board type " << aBoardNumber+1 << endl; + } + // Some default values + pAcqModuleParameter[aBoardNumber].EventBuildingBoardMode = AcqParameter.EventBuildingMode; // default, JB 2013/06/22 + pAcqModuleParameter[aBoardNumber].FirstTriggerChannel = 0; + pAcqModuleParameter[aBoardNumber].LastTriggerChannel = 0; + pAcqModuleParameter[aBoardNumber].NbOfFramesPerChannel[0] = 2; + pAcqModuleParameter[aBoardNumber].PixelShift = 3; // JB,CB,PLR 2015/03/24 + pAcqModuleParameter[aBoardNumber].AmpOffset = 32768; // JB,CB,PLR 2015/03/24 + pAcqModuleParameter[aBoardNumber].AmpFactor = 1.; // JB,CB,PLR 2015/03/24 + pAcqModuleParameter[aBoardNumber].Trailer = 0xfafafafa; // JB,CB,PLR 2015/03/24 + // Taking into account Pixel Shift, which could be defined: + // - globally with a single PixelShift + // - for each module with as many PixleShiftMod as module + for( Int_t iMod=0; iMod0 ) nextField(); + if( strstr( fFieldName, "DataFile" ) ) { + read_strings( pAcqModuleParameter[aBoardNumber].DeviceDataFile[iMod], pAcqModuleParameter[aBoardNumber].tpsz); + } + else { + printf( "WARNING in ReadDAQBoardParameters: field %s found while 'DataFile%d' expected!\n -> Board %d of type %d lacks rawdata connection.", fFieldName, iMod+1, iMod+1, aBoardNumber); + } + } + } + else if( ! strcmp( fFieldName, "PixelShiftMod" ) || ! strcmp( fFieldName, "PixelShiftMod1" ) ) { // JB,CB,PLR 2015/03/24 + // reading kShift for each device of this type + for( Int_t iMod=0; iMod0 ) nextField(); + if( strstr( fFieldName, "PixelShiftMod" ) ) { + read_item(pAcqModuleParameter[aBoardNumber].PixelShiftMod[iMod]); + } + else { + printf( "WARNING in ReadDAQBoardParameters: field %s found while 'PixelShiftMod%d' expected!\n -> Board %d of type %d lacks kShift.", fFieldName, iMod+1, iMod+1, aBoardNumber); + } + } + } + else if( ! strcmp( fFieldName, "IfZeroSuppress" ) || ! strcmp( fFieldName, "Ifzerosuppress" ) ) { // JB 2017/11/20 + read_item(pAcqModuleParameter[aBoardNumber].IfZeroSuppress); + // Force the reading of the threshold right after the IfZeroSuppress field, if non-zero + if( pAcqModuleParameter[aBoardNumber].IfZeroSuppress>0 ) { // if zero suppression required + nextField(); + if( ! strcmp( fFieldName, "ThresholdZero") || ! strcmp( fFieldName, "Thresholdzero" ) ) { // check there is a threshold + read_item(pAcqModuleParameter[aBoardNumber].ThresholdZero); + } + else { // if the threshold is missing + Error("DSetup", "In the configuration file, the field 'ThresholdZero' is expected right after the 'IfZeroSuppress' one!"); + } + } // end if zero suppression required + } + else + { + if ( strcmp( fFieldName, "StatisticCells") && strcmp( fFieldName, "CmsNoiseCut") && strcmp( fFieldName, "MaxNbOfHits") && strcmp( fFieldName, "Name") && strcmp( fFieldName, "AnalysisGoal") ) + { + cout << "WARNING : parameter '" << fFieldName << "' in config file is not understood !" << endl; + getRidOfLine(); + } + } + nextField(); + + } while ( strcmp( fFieldName, "StatisticCells") && strcmp( fFieldName, "CmsNoiseCut") && strcmp( fFieldName, "MaxNbOfHits") && strcmp( fFieldName, "Name") && strcmp( fFieldName, "AnalysisGoal") ); + + // Copy the parameters of the last specified input to the inputs + // for which they were not specified. + // This mechanism allows to declare N inputs while providing info just for one. + // JB 2013/08/16 + for (Int_t aInp=inputCounter+1; aInp0 ) { + cout << " ==> Zero suppression required with threshold = " << pAcqModuleParameter[aBoardNumber].ThresholdZero << endl; + } + } + + if ( ! strcmp( fFieldName, "Name") ) { // new board + ReadDAQBoardParameters( aBoardNumber+1 ); + } //end if new board + +} +//______________________________________________________________________________ +// +void DSetup::ReadAnalysisParameters() +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameter for Analysis + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // JB 2013/01/16 + // Modified: JB 2013/06/21 add MaxTracksExGeom and ExGeomatrix params + // Modified: JB 2013/07/17 new UserFlag param + // Modified: JB 2013/09/21 new histoRange param + // Modified: JB 2014/01/17 new AnalysisGoal param + + cout << endl << " - Reading Parameter for analysis" << endl; + + // ################################################ + // Set default values + // ################################################ + // Default values in case those parameters are set in the config file + AnalysisParameter.SavePlots = false; + AnalysisParameter.DoTelResolutionMC = false; + AnalysisParameter.MCEvents = 10000; + AnalysisParameter.MCSeed = 18383; + AnalysisParameter.MCDoDisplay = false; + AnalysisParameter.DoGaussianMS = true; + AnalysisParameter.ResolutionScanSteps = 10; + AnalysisParameter.ResolutionScanInit = 2.0; // microns + AnalysisParameter.ResolutionScanEnd = 8.0; // microns + + AnalysisParameter.CacheSize = 0; + AnalysisParameter.StatisticCells = 50; + AnalysisParameter.CmsNoiseCut = 3.; + AnalysisParameter.MaxNbOfHits = 1000; + AnalysisParameter.MinNbOfHits = 0; + AnalysisParameter.TrackChi2Limit = 1000.0; + AnalysisParameter.MinHitsPerTrack = TrackerParameter.PlanesForTrackMinimum; + AnalysisParameter.MaxTracksExGeom = -1; + AnalysisParameter.ExGeomatrix = 0; + + AnalysisParameter.Submatrices = 0; + AnalysisParameter.HistoChargeRange = 5000.; // e-, JB 2013/09/12 + AnalysisParameter.HistoSNRRange = 250; + AnalysisParameter.HistoNoiseRange = 40; // e- + for(int i=0;ifMaxSubmatrices ) { + printf( "WARNING: required number of submatrices %d exceeds maximum allowed %d!\n -> restricted to %d.\n", AnalysisParameter.Submatrices, fMaxSubmatrices, fMaxSubmatrices); + AnalysisParameter.Submatrices = fMaxSubmatrices; + } + } + else + { + if ( strcmp( fFieldName, "PixelSizeU" ) && !fConfigFileStream.eof() ) + { + cout << "WARNING : parameter '" << fFieldName << "' in config file is not understood !" << endl; + getRidOfLine(); + } + } + nextField(); + + } while ( strcmp( fFieldName, "PixelSizeU" ) && !fConfigFileStream.eof() ); + + if( DSetupDebug) { + cout << " - Final analysis cuts: " << endl; + cout << " Statistic cell size " << AnalysisParameter.StatisticCells << endl; + cout << " CMS cut " << AnalysisParameter.CmsNoiseCut << endl; + cout << " # hits max " << AnalysisParameter.MaxNbOfHits << endl; + cout << " # hits min " << AnalysisParameter.MinNbOfHits << endl; + cout << " Chi2 max " << AnalysisParameter.TrackChi2Limit << endl; + if ( AnalysisParameter.MaxTracksExGeom > -1 ) cout << " Max #tracks allowed in geomatrix " << AnalysisParameter.ExGeomatrix << " is " << AnalysisParameter.MaxTracksExGeom << endl; + cout << " # Submatrices " << AnalysisParameter.Submatrices << endl; + cout << endl; + } + + +} +//______________________________________________________________________________ +// +void DSetup::ReadSubmatrixParameters( Int_t aSubmatrixNumber) +{ + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameter for Submatrix + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // + // JB 2013/01/16 + // Modified JB 2013/07/17 Matrixtype introduced + // Modified: JB 2013/08/21,22 new SeedIndex/Col/Row limits + // Modified: JB 2013/09/12 new params MinNofPixelsInCluster + // Modified: JB 2013/11/08 new cuts on charges + // Modified: JB 2014/01/21 new cut on cluster charge + + if ( aSubmatrixNumber<0 || fMaxSubmatrices<=aSubmatrixNumber ) { + printf( "WARNING: trying to add submatrix %d beyond the maximum number allowed (%d)\n --> nothing done!\n", aSubmatrixNumber+1, fMaxSubmatrices); + return; + } + else { + cout << " * adding submatrix " << aSubmatrixNumber << endl; + } + + // some initialization + AnalysisParameter.Matrixtype[aSubmatrixNumber] = 1; + AnalysisParameter.Calibration[aSubmatrixNumber] = 1.; + AnalysisParameter.Geomatrices[aSubmatrixNumber] = 0; + AnalysisParameter.MinSeedIndex[aSubmatrixNumber] = 0; // JB 2013/08/21 + AnalysisParameter.MaxSeedIndex[aSubmatrixNumber] = 0; + AnalysisParameter.MinSeedCol[aSubmatrixNumber] = 0; // JB 2013/08/22 + AnalysisParameter.MaxSeedCol[aSubmatrixNumber] = 0; + AnalysisParameter.MinSeedRow[aSubmatrixNumber] = 0; // JB 2013/08/22 + AnalysisParameter.MaxSeedRow[aSubmatrixNumber] = 0; + AnalysisParameter.MinNofPixelsInCluster[aSubmatrixNumber] = 1; // JB 2013/09/12 + AnalysisParameter.MinSeedCharge[aSubmatrixNumber] = -1000.; // JB 2013/11/08 + AnalysisParameter.MinClusterCharge[aSubmatrixNumber] = -1000.; // JB 2014/01/21 + AnalysisParameter.MinNeighbourCharge[aSubmatrixNumber] = -1000.; // JB 2013/11/08 + + do { + if( ! strcmp( fFieldName, "PixelSizeU" ) ) { + read_item(AnalysisParameter.PixelSizeU[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "PixelSizeV" ) ) { + read_item(AnalysisParameter.PixelSizeV[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "PixelsInRaw" ) ) { + read_item(AnalysisParameter.PixelsInRaw[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "PixelsInColumn" ) ) { + read_item(AnalysisParameter.PixelsInColumn[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MinSeedIndex" ) ) { // JB 2013/08/21 + read_item(AnalysisParameter.MinSeedIndex[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MaxSeedIndex" ) ) { // JB 2013/08/21 + read_item(AnalysisParameter.MaxSeedIndex[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MinSeedCol" ) ) { // JB 2013/08/21 + read_item(AnalysisParameter.MinSeedCol[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MaxSeedCol" ) ) { // JB 2013/08/21 + read_item(AnalysisParameter.MaxSeedCol[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MinSeedRow" ) ) { // JB 2013/08/22 + read_item(AnalysisParameter.MinSeedRow[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MaxSeedRow" ) ) { // JB 2013/08/22 + read_item(AnalysisParameter.MaxSeedRow[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MaxNofPixelsInCluster" ) ) { + read_item(AnalysisParameter.MaxNofPixelsInCluster[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MinNofPixelsInCluster" ) ) { // JB 2013/09/12 + read_item(AnalysisParameter.MinNofPixelsInCluster[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MinSeedCharge" ) ) { // JB 2013/11/08 + read_item(AnalysisParameter.MinSeedCharge[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MinClusterCharge" ) ) { // JB 2014/01/21 + read_item(AnalysisParameter.MinClusterCharge[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "MinNeighbourCharge" ) ) { // JB 2013/11/08 + read_item(AnalysisParameter.MinNeighbourCharge[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "Matrixtype" ) ) { // JB 2013/07/17 + read_item(AnalysisParameter.Matrixtype[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "Calibration" ) ) { + read_item(AnalysisParameter.Calibration[aSubmatrixNumber]); + } + else if( ! strcmp( fFieldName, "NoiseScope" ) ) { + read_item(AnalysisParameter.NoiseScope[aSubmatrixNumber]); // JB 2010/09/06 + } + else if( strstr( fFieldName, "GeoMatrix" ) || strstr( fFieldName, "Geomatrix" ) ) { + if( AnalysisParameter.Geomatrices[aSubmatrixNumber] == fMaxGeomatrices ) { + printf( "WARNING in ReadSubmatrixParameters: maximum nb of Geomatrix reached, taking no more!\n"); + } + else { + read_item(AnalysisParameter.Umin[aSubmatrixNumber][AnalysisParameter.Geomatrices[aSubmatrixNumber]]); + nextItem(':'); + read_item(AnalysisParameter.Umax[aSubmatrixNumber][AnalysisParameter.Geomatrices[aSubmatrixNumber]]); + nextItem(':'); + read_item(AnalysisParameter.Vmin[aSubmatrixNumber][AnalysisParameter.Geomatrices[aSubmatrixNumber]]); + nextItem(':'); + read_item(AnalysisParameter.Vmax[aSubmatrixNumber][AnalysisParameter.Geomatrices[aSubmatrixNumber]]); + AnalysisParameter.Geomatrices[aSubmatrixNumber]++; + } + } + else + { + if ( strcmp( fFieldName, "PixelSizeU" )) + { + cout << "WARNING : parameter '" << fFieldName << "' in config file is not understood !" << endl; + getRidOfLine(); + } + } + + nextField(); + + } while ( strcmp( fFieldName, "PixelSizeU" ) && !fConfigFileStream.eof() ); + + if( DSetupDebug ) { + cout << " * Submatrix " << aSubmatrixNumber << endl; + cout << " pixel size U " << AnalysisParameter.PixelSizeU[aSubmatrixNumber] << " V " << AnalysisParameter.PixelSizeV[aSubmatrixNumber] << endl; + cout << " matrix type " << AnalysisParameter.Matrixtype[aSubmatrixNumber] << endl; + cout << " # pixels " << AnalysisParameter.PixelsInRaw[aSubmatrixNumber] << " in raw, " << AnalysisParameter.PixelsInColumn[aSubmatrixNumber] << " in column" << endl; + cout << " min - max # pixels in hit " << AnalysisParameter.MinNofPixelsInCluster[aSubmatrixNumber] << " - " << AnalysisParameter.MaxNofPixelsInCluster[aSubmatrixNumber] << endl; + cout << " range of seed index: " << AnalysisParameter.MinSeedIndex[aSubmatrixNumber] << " to " << AnalysisParameter.MaxSeedIndex[aSubmatrixNumber] << endl; + cout << " calibration " << AnalysisParameter.Calibration[aSubmatrixNumber] << endl; + cout << " noiseScope " << AnalysisParameter.NoiseScope[aSubmatrixNumber] << endl; + cout << " # Geomatrices " << AnalysisParameter.Geomatrices[aSubmatrixNumber] << endl; + for( Int_t il=0; ilIsBatch()) { + printf("ERROR ! Can't read file %s\nQuit (because in batch mode)\n", fConfigPathAndFileName.Data()); + gSystem->Exit(-1); + } + while( answer ) { + cout << "enter correct file name \n"; + cin >> fConfigFileName; + fConfigPathAndFileName = fConfigPath + fConfigFileName; + printf(" - Reading Setup from %s\n", fConfigPathAndFileName.Data()); + fConfigFileStream.open(fConfigPathAndFileName); + answer=fConfigFileStream.fail(); + } + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Run Parameter + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + ReadRunParameters(); + RunParameter.Number = fSession->GetRunNumber();// VR 20014/06/30 Set the run number from DSession(fRunNumber), which is set by MimosaAnalysis::InitSession(const Int_t TheRun) + if ( strcmp(RunParameter.DataSubDirPrefix,""))// VR 20014/06/30 + { + //if DataSubDirPrefix is given, concatenate it with the run number to the DataPath + sprintf( RunParameter.DataPath, "%s/%s%d/", RunParameter.DataPath,RunParameter.DataSubDirPrefix, RunParameter.Number ); // VR 2014/06/30 + } + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameters of the Tracker + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + ReadTrackerParameters(); + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameters For Global Alignement + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + ReadGlobalAlignmentParameters(); + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameters of the Experiment Geometry + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + //ReadExperimentGeometryParameters(); //Valerian 2015/02/02@18h50 : if this method causes bug, tell me so I can correct bug (In a previous commit it was comment ?!) + + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + // Parameters of the Planes + // -+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+--+-+-+-+-+- + pPlaneParameter = NULL; + ChannelUse = NULL; + pPlaneParameter = new PlaneParameter_t[TrackerParameter.Planes]; + //ChannelUse = new Int_t*[TrackerParameter.Planes]; + //for(int iplane=0;iplaneAccessPathName(tWeightFileName)) { + Info("ReadConfiguration","%s doesn't exist you have to make a new one (Make New Eta Function gTAF->MakeEta())! ",tWeightFileName); + fWeightFile = new TFile(tWeightFileName,"CREATE"); + } + else { + fWeightFile = new TFile(tWeightFileName); + } + //fWeightFile->Close(); // JB, Sept 2008 + */ + + cout << endl << " -*-*- DSetup User Constructor DONE -*-*- " << endl; + +} +//______________________________________________________________________________ +// +DSetup::DSetup(const DSetup& c) +{ + copy(c); +} + +//______________________________________________________________________________ +// +DSetup& DSetup::operator=(const DSetup& a) +{ + copy(a); + return *this; +} + +void DSetup::copy(const DSetup& a) +{ + // Prepare a Copy into this class +} + +//______________________________________________________________________________ +// +void DSetup::nextItem(Char_t delimiter) +{ + // Move the file parsing pointer to the character "delimiter" + + Char_t c; + do { + fConfigFileStream >> c; + if (DSetupDebug>1) cout << c; + } while (c != delimiter); +} + +//______________________________________________________________________________ +// +void DSetup::nextField() +{ + // Move the file parsing pointer to the character "delimiter" + // store in fFieldName the previous chain of characters + // (skipping spaces, new lines and the delimiter) + // + // Modified JB 2012/12/20 include recording of fieldName + // Modified JB 2013/01/16 skip comment lines + + Char_t delimiter = ':'; + Int_t k = 0; + Char_t c, previousC; + do { + fConfigFileStream >> c; + //cout << "|" << c << "|"; + if( c != '\n' && c != ' ' && c != delimiter && c != '.') { + fFieldName[k] = c; + previousC = c; + } + if( (c == '\n') || (c == ' ') || (k==fFieldMaxLength-1) || (c == '.')) + { + k = 0; + } + else if (c != delimiter) { + k++; + } + if ( c=='/' && previousC=='/' ) { + getRidOfLine(); + k = 0; + } + //cout << "k=" << k ; + } while (c != delimiter && !fConfigFileStream.eof() ); + fFieldName[k]='\0'; + if (DSetupDebug>1) cout << "field = " << fFieldName << endl; +} + +//______________________________________________________________________________ +// +void DSetup::read_r3(DR3 &arg) +{ + // Modified BH 2013/08/21 memory leak removed + + Double_t co[3] = {0., 0., 0.}; // BH 2013/08/21 + for (Int_t k = 0; k < 3; k++) { + if( k>0 ) nextItem(':'); // already positionned for 1st value + fConfigFileStream >> co[k]; + if (DSetupDebug>1) cout << co[k] << endl; + arg.SetValue(co); + } +} + +//______________________________________________________________________________ +// +void DSetup::read_item(Int_t &arg) +{ + //nextItem(':'); + fConfigFileStream >> arg; + if (DSetupDebug>1){ + cout << "value = " << arg << endl; + } +} + +//______________________________________________________________________________ +// +void DSetup::read_item(UInt_t &arg) +{ + //nextItem(':'); + fConfigFileStream >> arg; + if (DSetupDebug>1){ + printf("value =%d/%x\n",arg,arg); + } +} + +//______________________________________________________________________________ +// +void DSetup::read_item(Float_t &arg) +{ + + // reads values from configuration file + + //nextItem(':'); + fConfigFileStream >> arg; + if (DSetupDebug>1) cout << "value = " << arg << endl; +} + +//______________________________________________________________________________ +// +void DSetup::read_strings(Char_t *aString, Int_t aLength) +{ + + // reads a string of a given max length from configuration file + // The strings is expected to be contained by double quotes : " + // JB 2009/05/25 + + Int_t k = 0; + Char_t c; + // First, go to the " delimiter + //nextItem('"'); + do { + fConfigFileStream >> c; + //cout << c; + } while (c != '"'); + // Now, read the value up to the next " delimiter + do { + fConfigFileStream >> c; + //cout << c; + if ((c != '"') && (k < aLength)) { + aString[k] = c; + k++; + } + } while (c != '"'); + aString[k]='\0'; // end properly the string when it is shorter than max length + if (DSetupDebug>1) cout << "value = " << aString << endl; + +} +//______________________________________________________________________________ +// +void DSetup::read_TStrings(TString& TheString, Int_t aLength) +{ + + Char_t aString[500]; + // reads a string of a given max length from configuration file + // The strings is expected to be contained by double quotes : " + // JB 2009/05/25 + + Int_t k = 0; + Char_t c; + // First, go to the " delimiter + //nextItem('"'); + do { + fConfigFileStream >> c; + //cout << c; + } while (c != '"'); + // Now, read the value up to the next " delimiter + do { + fConfigFileStream >> c; + //cout << c; + if ((c != '"') && (k < aLength)) { + aString[k] = c; + k++; + } + } while (c != '"'); + aString[k]='\0'; // end properly the string when it is shorter than max length + if (DSetupDebug>1) cout << "value = " << aString << endl; + + TheString = TString(aString); + +} +//______________________________________________________________________________ +// +void DSetup::getRidOfLine() +{ + + // Simply get rid of all character till the line ends, + // line is not expected to exceeds 200 charaters. + // + // JB, 2013/01/16 + + Char_t line[250]; + fConfigFileStream.getline( line, 250); + +} +//______________________________________________________________________________ +// +void DSetup::InitializePerformancesParams(int aPlaneNumber) +{ + + pPlaneParameter[aPlaneNumber].PlanePerformancesList.clear(); + + if(_ResolutionFileList.size() > 0) { + pPlaneParameter[aPlaneNumber].UsingTrackerResolution = false; + + //NOTE: currently using histogram with residues (huCGwidth_vs_Mult and hvCGwidth_vs_Mult) instead of resolution. Will correction this later + TString TheMultName = TString("npix_c"); + TString TheHistoName_ResolU = TString("huCGwidth_vs_Mult"); + TString TheHistoName_ResolV = TString("hvCGwidth_vs_Mult"); + if(_ResolutionFileList.size() == 1) { + for(int ireg=0;iregScale(1.0/hMultiplicity->GetEntries()); + + TheHistoName = TheHistoName_ResolU; + hResolutionU = (TH1F*)ResolutionVsMultFile.Get(TheHistoName.Data()); + if(hResolutionU == NULL) { + cout << endl; + cout << "Histogram with name " << TheHistoName.Data() << " is not found in ROOT file " << _ResolutionFileList[ireg].Data() + << " for plane " << aPlaneNumber << " and region " << ireg+1 << "doesn't exits. Check your inputs. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + TheHistoName = TheHistoName_ResolV; + hResolutionV = (TH1F*)ResolutionVsMultFile.Get(TheHistoName.Data()); + if(hResolutionV == NULL) { + cout << endl; + cout << "Histogram with name " << TheHistoName.Data() << " is not found in ROOT file " << _ResolutionFileList[ireg].Data() + << " for plane " << aPlaneNumber << " and region " << ireg+1 << "doesn't exits. Check your inputs. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + PlanePerformances_t AResolutionVsMult; + AResolutionVsMult.Region.R_col[0] = 0; + AResolutionVsMult.Region.R_col[1] = pPlaneParameter[aPlaneNumber].Strips(0); + AResolutionVsMult.Region.R_lin[0] = 0; + AResolutionVsMult.Region.R_lin[1] = pPlaneParameter[aPlaneNumber].Strips(1); + + AResolutionVsMult.GlobalPlaneResolution = -1.0; + AResolutionVsMult.GlobalPlaneResolutionU = -1.0; + AResolutionVsMult.GlobalPlaneResolutionV = -1.0; + + AResolutionVsMult.MultProb.clear(); + AResolutionVsMult.MultProbCumul.clear(); + AResolutionVsMult.ResolutionU.clear(); + AResolutionVsMult.ResolutionV.clear(); + for(int imult=0;imultGetXaxis()->GetNbins();imult++) { + AResolutionVsMult.ResolutionU.push_back(hResolutionU->GetBinContent(imult+1)); + AResolutionVsMult.ResolutionV.push_back(hResolutionV->GetBinContent(imult+1)); + } + for(int imult=0;imultGetXaxis()->GetNbins();imult++) { + if(imult+1 < hResolutionU->GetXaxis()->GetNbins()) { + double prob = hMultiplicity->GetBinContent(hMultiplicity->FindBin(imult+1)); + AResolutionVsMult.MultProb.push_back(prob); + } + else { + double prob = 0.0; + for(int kkk=0;kkkGetXaxis()->GetNbins();kkk++) { + double c = hMultiplicity->GetBinCenter(kkk+1); + if(c >= imult+1) { + prob += hMultiplicity->GetBinContent(kkk+1); + } + } + AResolutionVsMult.MultProb.push_back(prob); + } + } + double prob_cumul = 0.0; + for(int imult=0;imultScale(1.0/hMultiplicity->GetEntries()); + + TheHistoName = TheHistoName_ResolU; + hResolutionU = (TH1F*)ResolutionVsMultFile.Get(TheHistoName.Data()); + if(hResolutionU == NULL) { + cout << endl; + cout << "Histogram with name " << TheHistoName.Data() << " is not found in ROOT file " << _ResolutionFileList[ireg].Data() + << " for plane " << aPlaneNumber << " and region " << ireg+1 << "doesn't exits. Check your inputs. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + TheHistoName = TheHistoName_ResolV; + hResolutionV = (TH1F*)ResolutionVsMultFile.Get(TheHistoName.Data()); + if(hResolutionV == NULL) { + cout << endl; + cout << "Histogram with name " << TheHistoName.Data() << " is not found in ROOT file " << _ResolutionFileList[ireg].Data() + << " for plane " << aPlaneNumber << " and region " << ireg+1 << "doesn't exits. Check your inputs. Exiting now!!!" << endl; + cout << endl; + assert(false); + } + + PlanePerformances_t AResolutionVsMult; + AResolutionVsMult.Region.R_col[0] = _RegionList[ireg].R_col[0]; + AResolutionVsMult.Region.R_col[1] = _RegionList[ireg].R_col[1]; + AResolutionVsMult.Region.R_lin[0] = _RegionList[ireg].R_lin[0]; + AResolutionVsMult.Region.R_lin[1] = _RegionList[ireg].R_lin[1]; + + AResolutionVsMult.GlobalPlaneResolution = -1.0; + AResolutionVsMult.GlobalPlaneResolutionU = -1.0; + AResolutionVsMult.GlobalPlaneResolutionV = -1.0; + + AResolutionVsMult.MultProb.clear(); + AResolutionVsMult.MultProbCumul.clear(); + AResolutionVsMult.ResolutionU.clear(); + AResolutionVsMult.ResolutionV.clear(); + for(int imult=0;imultGetXaxis()->GetNbins();imult++) { + AResolutionVsMult.ResolutionU.push_back(hResolutionU->GetBinContent(imult+1)); + AResolutionVsMult.ResolutionV.push_back(hResolutionV->GetBinContent(imult+1)); + } + for(int imult=0;imultGetXaxis()->GetNbins();imult++) { + if(imult+1 < hResolutionU->GetXaxis()->GetNbins()) { + double prob = hMultiplicity->GetBinContent(hMultiplicity->FindBin(imult+1)); + AResolutionVsMult.MultProb.push_back(prob); + } + else { + double prob = 0.0; + for(int kkk=0;kkkGetXaxis()->GetNbins();kkk++) { + double c = hMultiplicity->GetBinCenter(kkk+1); + if(c >= imult+1) { + prob += hMultiplicity->GetBinContent(kkk+1); + } + } + AResolutionVsMult.MultProb.push_back(prob); + } + } + double prob_cumul = 0.0; + for(int imult=0;imult 0 || _ResolutionVList.size() > 0) { + pPlaneParameter[aPlaneNumber].UsingTrackerResolution = false; + if(_ResolutionUList.size() != _ResolutionVList.size()) { + cout << endl; + cout << "Need to specify both the same number of PlaneResolutionU and PlaneResolutionV parameters for Plane " << aPlaneNumber+1 + << ". Check your inputs. Exiting now!!!" + << endl; + cout << endl; + assert(false); + } + + if(_ResolutionUList.size() == 1 && _ResolutionVList.size() == 1) { + PlanePerformances_t AResolutionVsMult; + AResolutionVsMult.Region.R_col[0] = 0; + AResolutionVsMult.Region.R_col[1] = pPlaneParameter[aPlaneNumber].Strips(0); + AResolutionVsMult.Region.R_lin[0] = 0; + AResolutionVsMult.Region.R_lin[1] = pPlaneParameter[aPlaneNumber].Strips(1); + + AResolutionVsMult.GlobalPlaneResolution = -1.0; + AResolutionVsMult.GlobalPlaneResolutionU = _ResolutionUList[0]; + AResolutionVsMult.GlobalPlaneResolutionV = _ResolutionVList[0]; + + AResolutionVsMult.MultProb.clear(); + AResolutionVsMult.MultProbCumul.clear(); + AResolutionVsMult.ResolutionU.clear(); + AResolutionVsMult.ResolutionV.clear(); + pPlaneParameter[aPlaneNumber].PlanePerformancesList.push_back(AResolutionVsMult); + } + else { + if(_ResolutionUList.size() != _RegionList.size()) { + cout << endl; + cout << "Number of PlaneResolutionU/PlaneResolutionV parameters given (" << _ResolutionUList.size() + << ") is different from number of Regions given (" << _RegionList.size() + << "). Check you inputs. Exiting now!!!!" << endl; + cout << endl; + assert(false); + } + + //Check that the regions defined agree with the sensor limits and that they not overlap with each others + CheckRegionsOverlaps(aPlaneNumber); + CheckForBadRegions(aPlaneNumber); + + for(int ireg=0;ireg 0) { + pPlaneParameter[aPlaneNumber].UsingTrackerResolution = false; + if(_ResolutionList.size() == 1) { + PlanePerformances_t AResolutionVsMult; + AResolutionVsMult.Region.R_col[0] = 0; + AResolutionVsMult.Region.R_col[1] = pPlaneParameter[aPlaneNumber].Strips(0); + AResolutionVsMult.Region.R_lin[0] = 0; + AResolutionVsMult.Region.R_lin[1] = pPlaneParameter[aPlaneNumber].Strips(1); + + AResolutionVsMult.GlobalPlaneResolution = _ResolutionList[0]; + AResolutionVsMult.GlobalPlaneResolutionU = -1; + AResolutionVsMult.GlobalPlaneResolutionV = -1; + + AResolutionVsMult.MultProb.clear(); + AResolutionVsMult.MultProbCumul.clear(); + AResolutionVsMult.ResolutionU.clear(); + AResolutionVsMult.ResolutionV.clear(); + pPlaneParameter[aPlaneNumber].PlanePerformancesList.push_back(AResolutionVsMult); + } + else { + if(_ResolutionList.size() != _RegionList.size()) { + cout << endl; + cout << "Number of PlaneResolution parameters given (" << _ResolutionUList.size() + << ") is different from number of Regions given (" << _RegionList.size() + << "). Check you inputs. Exiting now!!!!" << endl; + cout << endl; + assert(false); + } + + //Check that the regions defined agree with the sensor limits and that they not overlap with each others + CheckRegionsOverlaps(aPlaneNumber); + CheckForBadRegions(aPlaneNumber); + + for(int ireg=0;ireg= " << imult+1; + cout << endl; + } + cout << endl; + } + } + else { + //Different regions defined: + cout << "Found " << pPlaneParameter[aPlaneNumber].PlanePerformancesList.size() + << " regions for Plane " << aPlaneNumber+1 << "." + << endl; + for(int ireg=0;ireg= " << imult+1; + cout << endl; + } + cout << endl; + } + } + } + + return; + +} +//______________________________________________________________________________ +// +void DSetup::CheckRegionsOverlaps(int aPlaneNumber) +{ + + bool RegionsOverlap = false; + for(int ireg=0;ireg= _RegionList[ireg].R_col[0] && Corners[icorners][0] <= _RegionList[ireg].R_col[1]) && + (Corners[icorners][1] >= _RegionList[ireg].R_lin[0] && Corners[icorners][1] <= _RegionList[ireg].R_lin[1])) { + RegionsOverlap = true; + cout << "region " << ireg+1 << " overlaps with region " << jreg+1 << endl; + break; + } + } + if(RegionsOverlap) break; + } + if(RegionsOverlap) break; + } + if(RegionsOverlap) { + cout << endl; + cout << "At least a couple of the regions defined for plane " << aPlaneNumber << " overlap. Check you inputs. Exiting now!!!!" << endl; + cout << endl; + assert(false); + } + + return; + +} +//______________________________________________________________________________ +// +void DSetup::CheckForBadRegions(int aPlaneNumber) +{ + + bool BadRegion = false; + for(int ireg=0;ireg pPlaneParameter[aPlaneNumber].Strips(0)-1 || + _RegionList[ireg].R_lin[0] < 0 || + _RegionList[ireg].R_lin[1] > pPlaneParameter[aPlaneNumber].Strips(1)-1 + ) { + BadRegion = true; + cout << "Region " << ireg+1 << " has limits outside sensor limits!. Region col = (" << _RegionList[ireg].R_col[0] << "," << _RegionList[ireg].R_col[1] << "), lin = (" + << _RegionList[ireg].R_lin[0] << "," << _RegionList[ireg].R_lin[1] << "). Sensor col = (" << 0 << "," << pPlaneParameter[aPlaneNumber].Strips(0)-1 + << "), lin = (" << 0 << "," << pPlaneParameter[aPlaneNumber].Strips(1)-1 << ")" + << endl; + break; + } + } + if(BadRegion) { + cout << endl; + cout << "At least a of the regions defined for Plane " << aPlaneNumber+1 << " overlap is outside of the sensor limits. Check you inputs. Exiting now!!!!" << endl; + cout << endl; + assert(false); + } + + return; + +} +//______________________________________________________________________________ +// +void DSetup::GetListOfHotPixelsToMask_FracToMask(int aPlaneNumber, + TString HotPixelMapFile) +{ + + pPlaneParameter[aPlaneNumber].HotPixelList_lin.clear(); + pPlaneParameter[aPlaneNumber].HotPixelList_col.clear(); + pPlaneParameter[aPlaneNumber].HotPixelList_index.clear(); + + //Do nothing if hot pixel list for masking is not requested + if(_FractionToMaskList.size() == 0 || HotPixelMapFile == TString("")) return; + + TH2F* h2HotPixelMap = NULL; + TH1F* h1HotPixelList = NULL; + TFile FakeRateMapFile(HotPixelMapFile.Data(),"READ"); + if(!FakeRateMapFile.IsOpen()) { + //Warning message when ROOT file doesn't exists. Do nothing. + cout << endl; + cout << " WARNNING: ROOT file " << HotPixelMapFile.Data() + << " with fake rate map for plane " << aPlaneNumber+1 + << " doesn't exist. Doing nothing, list of hot is left empty." << endl; + cout << endl; + + return; + } + /* + else { + cout << endl; + cout << "Opening file " << HotPixelMapFile.Data() << ", with contents:" << endl; + FakeRateMapFile.ls(); + cout << endl; + } + */ + + h2HotPixelMap = (TH2F*)FakeRateMapFile.Get("h2HotPixelMap"); + if(h2HotPixelMap == NULL) { // if occupancy h2 map doest not exists + //Warning message when ROOT file exists, but fake rate map histogram is not found. Do nothing. + cout << endl; + cout << " WARNNING: Fake rate map histogram h2HotPixelMap is not found in ROOT file " << HotPixelMapFile.Data() + << " for plane " << aPlaneNumber+1 << ". Doing nothing, list of hot is left empty." << endl; + cout << endl; + } // end if occupancy h2 map does not exist + else { + //if h2 map exists + //h2HotPixelMap->SetDirectory(0); + cout << "Looping over the fake-rate map to find hot pixels. Plane " << aPlaneNumber+1 << endl; + //Loop over the fake rate map to identify the hot pixels + + if(_FractionToMaskList.size() == 1) { + cout << "Specified a single Fraction to Mask of " << _FractionToMaskList[0]*100 << "% for whole matrix of plane " << aPlaneNumber+1 << endl; + //If only specified a singl FakeRateCut, then apply the cut over the full matrix of pixels + double RU_tmp[2]; + RU_tmp[0] = h2HotPixelMap->GetXaxis()->GetXmin()+0.5; + RU_tmp[1] = h2HotPixelMap->GetXaxis()->GetXmax()+0.5; + double RV_tmp[2]; + RV_tmp[0] = h2HotPixelMap->GetYaxis()->GetXmin()+0.5; + RV_tmp[1] = h2HotPixelMap->GetYaxis()->GetXmax()+0.5; + + if(!(RU_tmp[0] == 0 && RU_tmp[1] == pPlaneParameter[aPlaneNumber].Strips(0) && + RV_tmp[0] == 0 && RV_tmp[1] == pPlaneParameter[aPlaneNumber].Strips(1))) { + cout << "WARNING: the range of the hot pixels map histrograms don't agree with the number of pixels of the matrix:" << endl; + cout << "WARNING: U-range = (" << RU_tmp[0] << "," << RU_tmp[1] << "), and expects (0," << pPlaneParameter[aPlaneNumber].Strips(0) << ")" << endl; + cout << "WARNING: V-range = (" << RV_tmp[0] << "," << RV_tmp[1] << "), and expects (0," << pPlaneParameter[aPlaneNumber].Strips(1) << ")" << endl; + cout << "WARNING: Maybe need to check your inputs!!!" << endl; + } + + //Put the pixels in a map which is ordered from the lowest to the highest fake-rate + std::vector _fake_map; + _fake_map.clear(); + for(Int_t iy=0;iyGetYaxis()->GetNbins();iy++) { + Int_t lin = Int_t(h2HotPixelMap->GetYaxis()->GetBinCenter(iy+1)); + for(Int_t ix=0;ixGetXaxis()->GetNbins();ix++) { + Int_t col = Int_t(h2HotPixelMap->GetXaxis()->GetBinCenter(ix+1)); + double fake_rate = h2HotPixelMap->GetBinContent(ix+1,iy+1)/100.0; + + if(fake_rate > 0.0) { + APixel_t Mypixel; + Mypixel.col = col; + Mypixel.lin = lin; + Mypixel.fake = fake_rate; + _fake_map.push_back(Mypixel); + } + + } + } + for(int iii=2;iii<=int(_fake_map.size());iii++) { + for(int jjj=0;jjj<=int(_fake_map.size())-iii;jjj++) { + double fake_jjj = _fake_map[jjj].fake; + double fake_jjjp1 = _fake_map[jjj+1].fake; + + if(fake_jjj < fake_jjjp1) { + APixel_t aux_pixel = _fake_map[jjj]; + _fake_map[jjj] = _fake_map[jjj+1]; + _fake_map[jjj+1] = aux_pixel; + } + } + } + + //Define the number of pixels to mask based on mask fraction + int Npixels = h2HotPixelMap->GetXaxis()->GetNbins()*h2HotPixelMap->GetYaxis()->GetNbins(); + int NtoMask = int(Npixels*_FractionToMaskList[0]); + + int counter = 0; + for(int i=0;i NtoMask) break; + int col = _fake_map[i].col; + int lin = _fake_map[i].lin; + //double fake = _fake_map[i].fake; + //cout << "(col,lin) = (" << col << "," << lin << "), value = " << fake << endl; + + pPlaneParameter[aPlaneNumber].HotPixelList_lin.push_back(lin); + pPlaneParameter[aPlaneNumber].HotPixelList_col.push_back(col); + } + + _fake_map.clear(); + } + else if(_FractionToMaskList.size() > 1) { + //Specified more than one FakeRateCut + + if(_FractionToMaskList.size() != _RegionList.size()) { + //Check that the FakeRateCut list has the same size as the Region list. If not exit and do nothing. + cout << endl; + cout << "WARNING: FractionToMaskList size (" << _FractionToMaskList.size() << ") if different from region list size (" << _RegionList.size() << ")" << endl; + cout << "WARNING: no attempt to build hot pixels list. Check your inputs!!!" << endl; + cout << endl; + +// FakeRateMapFile.Close(); + +// return; + } + else { + //Check that the regions defined agree with the sensor limits and that they not overlap with each others + CheckRegionsOverlaps(aPlaneNumber); + CheckForBadRegions(aPlaneNumber); + + cout << "List of Fraction to Mask for different regions:" << endl; + for(int ireg=0;ireg _fake_map; + _fake_map.clear(); + + //Apply the fake rate cut depending on the regions defined + for(Int_t iy=0;iyGetYaxis()->GetNbins();iy++) { + Int_t lin = Int_t(h2HotPixelMap->GetYaxis()->GetBinCenter(iy+1)); + for(Int_t ix=0;ixGetXaxis()->GetNbins();ix++) { + Int_t col = Int_t(h2HotPixelMap->GetXaxis()->GetBinCenter(ix+1)); + + if((col >= _RegionList[ireg].R_col[0] && col <= _RegionList[ireg].R_col[1]) && (lin >= _RegionList[ireg].R_lin[0] && lin <= _RegionList[ireg].R_lin[1])) { + double fake_rate = h2HotPixelMap->GetBinContent(ix+1,iy+1)/100.0; + Npixels++; + + if(fake_rate > 0.0) { + APixel_t Mypixel; + Mypixel.col = col; + Mypixel.lin = lin; + Mypixel.fake = fake_rate; + _fake_map.push_back(Mypixel); + } + } + + } + } + for(int iii=2;iii<=int(_fake_map.size());iii++) { + for(int jjj=0;jjj<=int(_fake_map.size())-iii;jjj++) { + double fake_jjj = _fake_map[jjj].fake; + double fake_jjjp1 = _fake_map[jjj+1].fake; + + if(fake_jjj < fake_jjjp1) { + APixel_t aux_pixel = _fake_map[jjj]; + _fake_map[jjj] = _fake_map[jjj+1]; + _fake_map[jjj+1] = aux_pixel; + } + } + } + + int NtoMask = int(Npixels*_FractionToMaskList[ireg]); + + int counter = 0; + for(int i=0;i NtoMask) break; + int col = _fake_map[i].col; + int lin = _fake_map[i].lin; + //double fake = _fake_map[i].fake; + //cout << "Region " << ireg+1 << ": (col,lin) = (" << col << "," << lin << "), value = " << fake << endl; + pPlaneParameter[aPlaneNumber].HotPixelList_lin.push_back(lin); + pPlaneParameter[aPlaneNumber].HotPixelList_col.push_back(col); + } + _fake_map.clear(); + + } //end of loop over regions + + } // end of if fake-rate list size is equal to ragion list size + + } // end of if fake-rate list size is higher than one +// FakeRateMapFile.Close(); + +// return; + + } // end if occupancy h2 map exists + + if(_FractionToMaskList.size() == 1) { + cout << "Looping over the fake-rate list to find hot pixels. Plane " << aPlaneNumber+1 << endl; + cout << "Specified a single Fraction to Mask of " << _FractionToMaskList[0]*100 << "% for whole matrix of plane " << aPlaneNumber+1 << endl; + //Only use hot pixel list by global index when fake-rate list size is equal to 1 + h1HotPixelList = (TH1F*)FakeRateMapFile.Get(Form("h1HotPixelListPl%d",aPlaneNumber+1)); + if(h1HotPixelList != NULL) { // if occupancy h1 list exists + //h1HotPixelList->SetDirectory(0); + + int Npixels = 0; + std::vector _fake_map; + _fake_map.clear(); + for(Int_t iindex=0;iindexGetXaxis()->GetNbins();iindex++) { + double fake_rate = h1HotPixelList->GetBinContent(iindex+1)/100.0; + Npixels++; + + if(fake_rate > 0.0) { + //Use the col variable of APixel_t object to store the value of the pixels index + //Set always the lin varianle to -1 + APixel_t Mypixel; + Mypixel.col = iindex; + Mypixel.lin = -1; + Mypixel.fake = fake_rate; + _fake_map.push_back(Mypixel); + } + } + for(int iii=2;iii<=int(_fake_map.size());iii++) { + for(int jjj=0;jjj<=int(_fake_map.size())-iii;jjj++) { + double fake_jjj = _fake_map[jjj].fake; + double fake_jjjp1 = _fake_map[jjj+1].fake; + + if(fake_jjj < fake_jjjp1) { + APixel_t aux_pixel = _fake_map[jjj]; + _fake_map[jjj] = _fake_map[jjj+1]; + _fake_map[jjj+1] = aux_pixel; + } + } + } + + int NtoMask = int(Npixels*_FractionToMaskList[0]); + + int counter = 0; + for(int i=0;i NtoMask) break; + int index = _fake_map[i].col; + //double fake = _fake_map[i].fake; + //cout << "index = " << index << ", value = " << fake << endl; + pPlaneParameter[aPlaneNumber].HotPixelList_index.push_back(index); + } + _fake_map.clear(); + +// FakeRateMapFile.Close(); + +// return; + + } // end if occupancy h1 list exists + } // end if FakeRateCut list is == 1 + + FakeRateMapFile.Close(); + + return; + +} +//______________________________________________________________________________ +// +void DSetup::GetListOfHotPixelsToMask_FakeRateCut(int aPlaneNumber, + TString HotPixelMapFile) +{ + + + pPlaneParameter[aPlaneNumber].HotPixelList_lin.clear(); + pPlaneParameter[aPlaneNumber].HotPixelList_col.clear(); + pPlaneParameter[aPlaneNumber].HotPixelList_index.clear(); + + //Do nothing if hot pixel list for masking is not requested + if(_FakeRateCutList.size() == 0 || HotPixelMapFile == TString("")) return; + + TH2F* h2HotPixelMap = NULL; + TH1F* h1HotPixelList = NULL; + TFile FakeRateMapFile(HotPixelMapFile.Data(),"READ"); + if(!FakeRateMapFile.IsOpen()) { + //Warning message when ROOT file doesn't exists. Do nothing. + cout << endl; + cout << " WARNNING: ROOT file " << HotPixelMapFile.Data() + << " with fake rate map for plane " << aPlaneNumber+1 + << " doesn't exist. Doing nothing, list of hot is left empty." << endl; + cout << endl; + + return; + } + /* + else { + cout << endl; + cout << "Opening file " << HotPixelMapFile.Data() << ", with contents:" << endl; + FakeRateMapFile.ls(); + cout << endl; + } + */ + + h2HotPixelMap = (TH2F*)FakeRateMapFile.Get("h2HotPixelMap"); + if(h2HotPixelMap == NULL) { // if occupancy h2 map doest not exists + //Warning message when ROOT file exists, but fake rate map histogram is not found. Do nothing. + cout << endl; + cout << " WARNNING: Fake rate map histogram h2HotPixelMap is not found in ROOT file " << HotPixelMapFile.Data() + << " for plane " << aPlaneNumber+1 << ". Doing nothing, list of hot is left empty." << endl; + cout << endl; + } // end if occupancy h2 map does not exist + else { + //if h2 map exists + //h2HotPixelMap->SetDirectory(0); + cout << "Looping over the fake-rate map to find hot pixels. Plane " << aPlaneNumber+1 << endl; + //Loop over the fake rate map to identify the hot pixels + + if(_FakeRateCutList.size() == 1) { + cout << "Specified a single FakeRateCut of " << _FakeRateCutList[0]*100 << "% for whole matrix of plane " << aPlaneNumber+1 << endl; + //If only specified a singl FakeRateCut, then apply the cut over the full matrix of pixels + double RU_tmp[2]; + RU_tmp[0] = h2HotPixelMap->GetXaxis()->GetXmin()+0.5; + RU_tmp[1] = h2HotPixelMap->GetXaxis()->GetXmax()+0.5; + double RV_tmp[2]; + RV_tmp[0] = h2HotPixelMap->GetYaxis()->GetXmin()+0.5; + RV_tmp[1] = h2HotPixelMap->GetYaxis()->GetXmax()+0.5; + + if(!(RU_tmp[0] == 0 && RU_tmp[1] == pPlaneParameter[aPlaneNumber].Strips(0) && + RV_tmp[0] == 0 && RV_tmp[1] == pPlaneParameter[aPlaneNumber].Strips(1))) { + cout << "WARNING: the range of the hot pixels map histrograms don't agree with the number of pixels of the matrix:" << endl; + cout << "WARNING: U-range = (" << RU_tmp[0] << "," << RU_tmp[1] << "), and expects (0," << pPlaneParameter[aPlaneNumber].Strips(0) << ")" << endl; + cout << "WARNING: V-range = (" << RV_tmp[0] << "," << RV_tmp[1] << "), and expects (0," << pPlaneParameter[aPlaneNumber].Strips(1) << ")" << endl; + cout << "WARNING: Maybe need to check your inputs!!!" << endl; + } + + //Put the pixels in a map which is ordered from the lowest to the highest fake-rate + for(Int_t iy=0;iyGetYaxis()->GetNbins();iy++) { + Int_t lin = Int_t(h2HotPixelMap->GetYaxis()->GetBinCenter(iy+1)); + for(Int_t ix=0;ixGetXaxis()->GetNbins();ix++) { + Int_t col = Int_t(h2HotPixelMap->GetXaxis()->GetBinCenter(ix+1)); + double fake_rate = h2HotPixelMap->GetBinContent(ix+1,iy+1)/100.0; + + if(fake_rate >= _FakeRateCutList[0]) { + pPlaneParameter[aPlaneNumber].HotPixelList_lin.push_back(lin); + pPlaneParameter[aPlaneNumber].HotPixelList_col.push_back(col); + } + + } + } + + } + else if(_FakeRateCutList.size() > 1) { + //Specified more than one FakeRateCut + + if(_FakeRateCutList.size() != _RegionList.size()) { + //Check that the FakeRateCut list has the same size as the Region list. If not exit and do nothing. + cout << endl; + cout << "WARNING: FakeRateCutList size (" << _FakeRateCutList.size() << ") if different from region list size (" << _RegionList.size() << ")" << endl; + cout << "WARNING: no attempt to build hot pixels list. Check your inputs!!!" << endl; + cout << endl; + +// FakeRateMapFile.Close(); + +// return; + } + else { + //Check that the regions defined agree with the sensor limits and that they not overlap with each others + CheckRegionsOverlaps(aPlaneNumber); + CheckForBadRegions(aPlaneNumber); + + cout << "List of fake-rate cuts for different regions:" << endl; + for(int ireg=0;iregGetYaxis()->GetNbins();iy++) { + Int_t lin = Int_t(h2HotPixelMap->GetYaxis()->GetBinCenter(iy+1)); + for(Int_t ix=0;ixGetXaxis()->GetNbins();ix++) { + Int_t col = Int_t(h2HotPixelMap->GetXaxis()->GetBinCenter(ix+1)); + + if((col >= _RegionList[ireg].R_col[0] && col <= _RegionList[ireg].R_col[1]) && (lin >= _RegionList[ireg].R_lin[0] && lin <= _RegionList[ireg].R_lin[1])) { + double fake_rate = h2HotPixelMap->GetBinContent(ix+1,iy+1)/100.0; + if(fake_rate >= _FakeRateCutList[ireg]) { + pPlaneParameter[aPlaneNumber].HotPixelList_lin.push_back(lin); + pPlaneParameter[aPlaneNumber].HotPixelList_col.push_back(col); + } + } + + } + } + + } //end of loop over regions + + } // end of if fake-rate list size is equal to ragion list size + } // end of if fake-rate list size is higher than one + +// FakeRateMapFile.Close(); + +// return; + + } // end if occupancy h2 map exists + + if(_FakeRateCutList.size() == 1) { + cout << "Looping over the fake-rate list to find hot pixels. Plane " << aPlaneNumber+1 << endl; + cout << "Specified a single Fake-rate cut of " << _FakeRateCutList[0]*100 << "% for whole matrix of plane " << aPlaneNumber+1 << endl; + //Only use hot pixel list by global index when fake-rate list size is equal to 1 + h1HotPixelList = (TH1F*)FakeRateMapFile.Get(Form("h1HotPixelListPl%d",aPlaneNumber+1)); + if(h1HotPixelList != NULL) { // if occupancy h1 list exists + //h1HotPixelList->SetDirectory(0); + + for(Int_t iindex=0;iindexGetXaxis()->GetNbins();iindex++) { + double fake_rate = h1HotPixelList->GetBinContent(iindex+1)/100.0; + +// cout << "Testing index " << iindex << "in list with " << fake_rate << " against " << _FakeRateCutList[0] << endl; + if(fake_rate >= _FakeRateCutList[0]) pPlaneParameter[aPlaneNumber].HotPixelList_index.push_back(iindex); + } + +// FakeRateMapFile.Close(); + +// return; + + } // end if occupancy h1 list exists + } // end if FakeRateCut list is == 1 + + FakeRateMapFile.Close(); + + return; + +} +//______________________________________________________________________________ +// +void DSetup::PrintListOfHotPixelsToMask(int aPlaneNumber) +{ + + if(pPlaneParameter[aPlaneNumber].HotPixelList_lin.size() > 0) { + cout << endl; + cout << "Hot pixels for Plane " << aPlaneNumber+1 << ": The " << pPlaneParameter[aPlaneNumber].HotPixelList_lin.size() + << " hottest pixels (from 2D map) are masked" + << endl; + if(DSetupDebug && pPlaneParameter[aPlaneNumber].HotPixelList_lin.size() > 0) { + //if(pPlaneParameter[aPlaneNumber].HotPixelList_lin.size() > 0) { + cout << " line column" << endl; + for(int i_hot = 0;i_hot 0) { + cout << endl; + cout << " --> same list ordered by 1D index with " << pPlaneParameter[aPlaneNumber].HotPixelList_index.size() << " pixels." << endl; + } + + return; + +} +//______________________________________________________________________________ +// +DSetup::~DSetup() +{ + + delete pPlaneParameter; + + delete pLadderParameter; + + delete pAcqModuleParameter; + +} +//______________________________________________________________________________ +// diff --git a/src/DStrip.cxx b/src/DStrip.cxx new file mode 100644 index 0000000..bf616f4 --- /dev/null +++ b/src/DStrip.cxx @@ -0,0 +1,681 @@ +// @(#)maf/dtools:$Name: $:$Id:DStrip.cxx v.3 2005/10/02 18:03:46 sha Exp $ +// Author : ? +// Last Modified, JB 2009/05/25 +// Last Modified, JB 2014/01/07 SetPedestal + + //////////////////////////////////////////////////////////// + // Class Description of DStrip // + // // + // // + //////////////////////////////////////////////////////////// + + +#include "DStrip.h" +#include "DSetup.h" +#include "DPlane.h" +#include "DR3.h" + +ClassImp(DStrip) // Description of Single Detector DStrip +//______________________________________________________________________________ +// +DStrip::DStrip() +{ + // DStrip default constructor +} + +//______________________________________________________________________________ +// + +DStrip::~DStrip() +{ + // DStrip default destructor + + delete [] fNeighbourList; +} + +//______________________________________________________________________________ +// +DStrip::DStrip(DPlane& aPlane, const Int_t aStripIndex, DR3& aPosition, DR3& aSize) +{ + // constructor of a Strip or Pixel + // + // Last modified: JB, 2008/10/15 + + //cout << "BUILDING strip " << aStripIndex << endl; + + fPlane = &aPlane; + fc = &fPlane->GetSetup(); + fDebugStrip = fPlane->GetDebug(); + fPlaneNumber = fPlane->GetPlaneNumber(); + fPosition = aPosition; + fSize = aSize; + fStripIndex = aStripIndex; + + if(fDebugStrip>1 && (fStripIndex<2 || fStripIndex>fPlane->GetStripsN()-3) ) printf("DStrip: building strip %d from plane %d with (%d,%d) strips and (%f,%f)=%f bound\n", aStripIndex, fPlaneNumber, fPlane->GetStripsNu(), fPlane->GetStripsNv(), fc->GetPlanePar(fPlaneNumber).ClusterLimit(0), fc->GetPlanePar(fPlaneNumber).ClusterLimit(1), fc->GetPlanePar(fPlaneNumber).ClusterLimit.Length()); + fBound = fc->GetPlanePar(fPlaneNumber).ClusterLimit.Length(); + + //--calculate max number of elements in a cluster for 2-dim plane PIXELS (MIMOSA): + if( fPlane->GetStripsNu() > 1 && fPlane->GetStripsNv() > 1 ) { + fNeighbourCountMaximum = (Int_t) ( (1 + 2 * fc->GetPlanePar(fPlaneNumber).ClusterLimit(0)/fc->GetPlanePar(fPlaneNumber).Pitch(0)) * (1 + 2 * fc->GetPlanePar(fPlaneNumber).ClusterLimit(1)/fc->GetPlanePar(fPlaneNumber).Pitch(1)) ); + } // -- and for STRIP planes: + else { + fNeighbourCountMaximum = (Int_t) (1 + 2 * fBound/fc->GetPlanePar(fPlaneNumber).Pitch(0)); + } + + if(fDebugStrip>2 && fStripIndex<2) printf("DStrip: building strip %d from plane %d with %d neighbours max in %f um.\n", fStripIndex, fPlaneNumber, fNeighbourCountMaximum, fBound); + + // at fBound 0.2 mm and a pitch perp. to strips get 0.2/0.05 = 4 + // take this times two for both sides, adjacent to seed strip + // add 1 since seed is part of its own neighbourhood + + fNeighbourCount = 0; + fNeighbourList = new DStrip*[fNeighbourCountMaximum]; + + fFound = kFALSE; + fUsePulse = kTRUE; + + fRawValue = 0.; + fRawFrame1Value = 0.; + fRawFrame2Value = 0.; + + fInitialPedestal= 0.; + fInitialTMS = 0.; + fSumCount = 0; + fSumSquareCount = 0; + fSumValue = 0.; + fSumSquareValue = 0.; + fCommonMode = 0.; + fWeightPedestal = 10; + fWeightNoise = 10; + // three following lines to avoid use of UpdateXXX(), JB + fPedestal = 0; + fCommonMode = 0; + fNoise = 0.01; + + fNoiseCacheIndex = 0; + fPedestalCacheIndex= 0; + + fCacheSize = fc->GetPlanePar(fPlaneNumber).CacheSize; + + for(Int_t i = 0; i < fCacheSize; i++) { + fPedestalCache[i] = 0.; + fNoiseCache[i] = 0.; + } +} +//______________________________________________________________________________ + +Float_t DStrip::GetPulseHeightToNoise(){ //YV 04/06/09 convert to double + //Double_t DStrip::GetPulseHeightToNoise(){ + //----ADC + //----abm8 + Int_t tReadout; + tReadout=fc->GetPlanePar(fPlaneNumber).Readout; + if((tReadout==10)||(tReadout==12)||(tReadout==13)){ + if (fNoise > 0.0) + fNoise = 0.01; + if((tReadout==12)||(tReadout==13)){ + fNoise = 1.0; + } + return fPulseHeight / fNoise; + }else{ + if (fNoise > 0.0) + return fPulseHeight / fNoise; + else + return 0.0; + } +} +//______________________________________________________________________________ +// + +DStrip* DStrip::GetNeighbour(Int_t aNI) +{ + + if ( aNI <= fNeighbourCount ) + return fNeighbourList[aNI]; + else { + printf(" WARNING from DStrip: Impossible to return requested NeighbourStrip %d over %d neighbours, return this instead\n", aNI, fNeighbourCount); + return this; + } +} + +//______________________________________________________________________________ +// +void DStrip::SumValue() +{ + // external value replaced by data member fRawValue + // JB 2009/05/25 + + Float_t bV; + + if(fPedestalCacheIndex >= fCacheSize) { + fPedestalCacheIndex = 0; + bV = aSignalSupressedValue(fPedestalCache, fCacheSize); + //if( fStripIndex==25) printf("SV: index=%d, valueCache=%f, count=%d, newV=%f\n", fStripIndex, bV, fSumCount, fRawValue); + + fSumValue += bV; // test + fSumCount++; + } + + fPedestalCache[fPedestalCacheIndex++] = fRawValue; + +} + +//______________________________________________________________________________ +// +void DStrip::SumSquareValue() +{ + // external value replaced by data member fRawValue + // JB 2009/05/25 + + Float_t bV; + + if(fNoiseCacheIndex >= fCacheSize ) { + fNoiseCacheIndex = 0; + bV = aSignalSupressedValue(fNoiseCache, fCacheSize); // suppress extrema + // cout << fNoiseCacheIndex << " - " << bV << endl; + //if( fStripIndex==25) printf("SQV: index=%d, valueCache=%f, count=%d, newV=%f\n", fStripIndex, bV, fSumSquareCount, fRawValue); + + fSumSquareValue += (bV*bV); + fSumSquareCount++; + } + + fNoiseCache[fNoiseCacheIndex++] = fRawValue; + +} + +//______________________________________________________________________________ +// +void DStrip::InitPedestal() + { + if (fSumCount != 0) { + fInitialPedestal = fSumValue / fSumCount; + fPedestal = fInitialPedestal; + fSumValue = 0.; + fSumCount = 0; + fPedestalCacheIndex = 0; + for(Int_t i = 0; i < fCacheSize; i++) + fPedestalCache[i] = 0.; + } else { + printf(" strip %d has zero entries for pedestal initialization, investigate\n", fStripIndex); + fInitialPedestal = 0.; + } + //----ADC + Int_t tReadout; + tReadout=fc->GetPlanePar(fPlaneNumber).Readout; + if((tReadout==12)||(tReadout==13)){ + fInitialPedestal = 0.; + } + //----ADC +} +//______________________________________________________________________________ +// +void DStrip::InitNoise() +{ + // initializes the noise using the first N events + // the initial noise is normally higher. + // the initial noise is convoluted with common mode error, + // common mode variation are order of 15% from single strip noise in telescope silicon + + Float_t tVariance; + + if (fPedestal == 0. ) { + printf(" warning for strip %d, will try to initialize pedestal", fStripIndex); + InitPedestal(); + } + + tVariance = fabs(fSumSquareValue - fSumValue * fSumValue / fSumSquareCount ) / (fSumSquareCount - 1 ); + + fNoise = sqrt( tVariance ); + //----abm8 + Int_t tReadout; + tReadout=fc->GetPlanePar(fPlaneNumber).Readout; + if(tReadout==10){ + fNoise = 0.01; + } + //----ADC + if((tReadout==12)||(tReadout==13)){ + // if(fNoise < 0.01){ + fNoise = 1.0; + // } + } + //----ADC + printf(" fSumSquareValue %f, fSumValue %f, fSumSquareCount %d, fSumCount %d, fPedestal %f, tVariance %f, fNoise %f\n", fSumSquareValue, fSumValue, fSumSquareCount, fSumCount, fPedestal, tVariance, fNoise); + + + // reset buffer and couter + + fPedestalCacheIndex = 0; + fNoiseCacheIndex = 0; + for(Int_t i = 0; i < fCacheSize; i++) { + fPedestalCache[i] = 0.; + fNoiseCache[i] = 0.; + } + +} + +//______________________________________________________________________________ +// + +void DStrip::InitNoiseAndPedestal() { + Float_t tVariance; + + if (fSumCount != 0) { + fInitialPedestal = fSumValue / fSumCount; + tVariance = fabs(fSumSquareValue-fSumValue*fSumValue/fSumSquareCount )/(fSumSquareCount-1); + + fNoise = sqrt( tVariance ); + //if( fStripIndex==25) printf("Init: index=%d, sum=%f, count=%d, var=%f, count=%d\n", fStripIndex, fSumValue, fSumCount, tVariance, fSumSquareCount); + + fPedestal = fInitialPedestal; + fPedestalCacheIndex = 0; + fNoiseCacheIndex = 0; + for(Int_t i = 0; i < fCacheSize; i++) { + fPedestalCache[i] = 0.; + fNoiseCache[i] = 0.; + } + } + else { + printf(" strip %d has zero entries for pedestal initialization, ped & noise set to 0 BUT investigate!\n", fStripIndex); + fInitialPedestal = 0.; + fPedestal = 0.; + fNoise = 0. ; + } + //----abm8 + Int_t tReadout; + tReadout=fc->GetPlanePar(fPlaneNumber).Readout; + if(tReadout==10){ + fNoise = 0.01; + } + //----ADC + if((tReadout==12)||(tReadout==13)){ + // if(fNoise < 0.01){ + fNoise = 1.0; + fInitialPedestal = 0.; + fPedestal = 0.; + // } + } + //----ADC + //---- When only absolute value of charge is available, force pedestal at 0., JB & CD, Sept 2007 + if( tReadout==16 ){ + fInitialPedestal = 0.; + fPedestal = 0.; + tVariance = fSumSquareValue/(fSumSquareCount-1); + fNoise = sqrt( tVariance ); + } + //----absolute value +} + +//______________________________________________________________________________// + + +void DStrip::Update() { + + // update pedestal (for ref.system) + UpdatePedestal(fRawValue); + + // update signal + UpdateSignal(fRawValue); + + // update noise (for ref.system) + UpdateNoise(fPulseHeight); + +} + +//______________________________________________________________________________// + +void DStrip::UpdatePedestalAndNoise() +{ + Float_t tVariance; + +// if ((fStripIndex==1) || (fStripIndex==2)){ +// } + + if((fRawValue-fPedestal-fCommonMode)/fNoise<3.){ + fSumSquareValue+=(fRawValue-fPedestal-fCommonMode)*(fRawValue-fPedestal-fCommonMode); + fSumValue+=(fRawValue-fCommonMode-fPedestal); + fSumSquareCount++; + fSumCount++; + tVariance = (fSumSquareValue-fSumValue*fSumValue/fSumSquareCount )/(fSumSquareCount-1); + //if( fStripIndex==25) printf("Updte: index=%d, sum=%f, count=%d, var=%f, count=%d\n", fStripIndex, fSumValue, fSumCount, tVariance, fSumSquareCount); + //----pedestal + //fPedestal=fSumValue/fSumCount; //standard version -> BUG ???? + fPedestal= fPedestal * (fSumCount-1.0)/ (fSumCount) + (fRawValue-fCommonMode) / (fSumCount); + //UpdatePedestal(fRawValue); + //------ + fNoise = sqrt( tVariance ); + } +// if((fPlaneNumber==9)&&(fStripIndex<512)){ +// } + +// if ((fStripIndex==1) || (fStripIndex==2)){ +// } + + //----abm8 + Int_t tReadout; + tReadout=fc->GetPlanePar(fPlaneNumber).Readout; + if(tReadout==10){ + fNoise = 0.01; + } + //----ADC + if((tReadout==12)||(tReadout==13)){ + // if(fNoise < 0.01){ + fNoise = 1.0; + fInitialPedestal = 0.; + fPedestal = 0.; + // } + } + //----ADC +} + + +//______________________________________________________________________________ +// + +void DStrip::UpdatePedestal(Float_t tRV) { + + Float_t bRV; + if(fPedestalCacheIndex >= fCacheSize) { + + fPedestalCacheIndex = 0; + + bRV = median(fPedestalCache, fCacheSize); + + fPedestal = ( (fWeightPedestal - 1. ) * fPedestal + bRV ) / fWeightPedestal; + } + + fPedestalCache[fPedestalCacheIndex++] = tRV - fCommonMode; + //----ADC + Int_t tReadout; + tReadout=fc->GetPlanePar(fPlaneNumber).Readout; + if((tReadout==12)||(tReadout==13)){ + // if(fNoise < 0.01){ + fInitialPedestal = 0.; + fPedestal = 0.; + // } + } + //----ADC +} + +//______________________________________________________________________________ +// +void DStrip::UpdateNoise(Float_t tSV) +{ + + Float_t bSV; + + if(fNoiseCacheIndex >= fCacheSize ) { + fNoiseCacheIndex = 0; + bSV = aSignalSupressedValue(fNoiseCache, fCacheSize); + + fNoise = sqrt(((fWeightNoise - 1.)*fNoise*fNoise+bSV*bSV)/fWeightNoise ); + } + + fNoiseCache[fNoiseCacheIndex++] = tSV; + + //----abm8 + Int_t tReadout; + tReadout=fc->GetPlanePar(fPlaneNumber).Readout; + if(tReadout==10){ + fNoise = 0.01; + } + //----ADC + if((tReadout==12)||(tReadout==13)){ + // if(fNoise < 0.01){ + fNoise = 1.0; + // } + } + //----ADC +} + +//______________________________________________________________________________ +// + +void DStrip::UpdateSignal() { + fPulseHeight = fRawValue - fPedestal - fCommonMode; +} + +void DStrip::UpdateSignal(Float_t tRV) { + fPulseHeight = tRV - fPedestal - fCommonMode; + +} +//______________________________________________________________________________ + +void DStrip::SetNoise(Float_t tNV){ + + fNoise = tNV; + + fPedestalCacheIndex = 0; + fNoiseCacheIndex = 0; + for(Int_t i = 0; i < fCacheSize; i++) { + fPedestalCache[i] = 0.; + fNoiseCache[i] = 0.; + } +} +//______________________________________________________________________________ + +void DStrip::SetPedestal(Float_t tPV){ + + // added JB 2014/01/07 + + fPedestal = tPV; + + fPedestalCacheIndex = 0; + fNoiseCacheIndex = 0; + for(Int_t i = 0; i < fCacheSize; i++) { + fPedestalCache[i] = 0.; + fNoiseCache[i] = 0.; + } +} + + +//______________________________________________________________________________// + +void DStrip::SetRawValue(Float_t tRV) { + + fRawValue = tRV; + +} +//______________________________________________________________________________// + +void DStrip::SetRawFrame1Value(Float_t tRV) + { + + fRawFrame1Value = tRV; +} +//______________________________________________________________________________// + +void DStrip::SetRawFrame2Value(Float_t tRV) +{ + + fRawFrame2Value = tRV; +} + +//______________________________________________________________________________ +// + +Float_t DStrip::median(Float_t* z, const Int_t N) +{ + // median is an estimator for mean + // order array ascending or descending, then take value at half size + + Float_t r; + + if (N==1) { + + r=z[1]; + + } else { + + for(Int_t k = 0; k < N-1; k++){ + r = z[k]; + z[k] = (r <= z[k+1]) ? r : z[k+1]; + z[k+1] = (r > z[k+1]) ? r : z[k+1]; + } + if (N%2 == 0) + r = (z[N/2-1] + z[N/2])/2.; + else + r = z[(N+1)/2-1]; + + } + return r; +} + +//______________________________________________________________________________ +// + +Float_t DStrip::aSignalSupressedValue(Float_t* pfc, const Int_t N) { + Int_t exti; + Float_t result; + + if (N==1) { + result = pfc[0]; + } + else { + exti = extremumIndex(pfc, N); + result = fabs(pfc[0]) < fabs(pfc[exti]) ? pfc[0] : pfc[1]; + } + + return result; + +} + +//______________________________________________________________________________ +// + +Int_t DStrip::extremumIndex(const Float_t* d, + const Int_t N) +{ + + // it's the index of the element with maximum amplitude (+ or -). + + Int_t ext; + ext = N-1; + + for (Int_t k = 0; k < N-1; k++) + ext = (fabs(d[ext]) > fabs(d[k])) ? ext : k; + return ext; +} + +//______________________________________________________________________________ +// +Int_t DStrip::Introduce(DStrip &aStrip) +{ + // find out about neighbouring strips, fill list with neighbours + // the strip itself might get introduced to itself!! + + DStrip *sh; + Int_t k; + + // only for debug messages + Int_t minIndex=200, maxIndex=260; + + if(fDebugStrip>2 && minIndex %f).\n", fStripIndex, aStrip.GetStripIndex(), Distance(aStrip), fBound); + if ((Distance(aStrip) <= fBound) // check wheather strip in Neighbourhood + && (fNeighbourCount < fNeighbourCountMaximum)) { // and wheather limit reached + fNeighbourList[fNeighbourCount] = &aStrip; // assign neighbour + + + // For STRIPS detector + // order neighbours with distance + // so that neighbour[0] is seed itself + // and higher indices are adjacent with increasing distance + + if ( fc->GetPlanePar(fPlaneNumber).AnalysisMode < 2 ) { + k = fNeighbourCount; + while (k > 0 && Distance(aStrip) < Distance(*fNeighbourList[k-1]) ) { + sh = fNeighbourList[k-1]; + fNeighbourList[k-1] = &aStrip; + fNeighbourList[k] = sh; + k--; + } + } + + // For PIXELS detector + // do nothing + + + fNeighbourCount++; + if(fDebugStrip>2 && minIndexGetPlanePar(fPlaneNumber).AnalysisMode == 2 ) { + for (Int_t i=1; i< fNeighbourCount; i++){ + if(i!=fStripIndex){ + NeighbourCharge += fNeighbourList[i]->GetPulseHeight(); + NeighbourNoise += fNeighbourList[i]->GetNoise()* + fNeighbourList[i]->GetNoise(); + } + } + NeighbourNoise=sqrt(NeighbourNoise); + //Float_t s2n = NeighbourCharge/NeighbourNoise; + //if(s2n<3) answer=kTRUE; + } + return 0; // end of method return +} + diff --git a/src/DTrack.cxx b/src/DTrack.cxx new file mode 100644 index 0000000..3a3680c --- /dev/null +++ b/src/DTrack.cxx @@ -0,0 +1,1002 @@ +// @(#)maf/dtools:$Name: $:$Id:DTrack.cxx v.1 2005/10/02 18:03:46 sha Exp $ +//*-- Copyright: RD42 +// Author : Dirk Meier 98/01/07 +// Last modified : JB 2009/05/25 +// Last Modified: JB 2009/07/20 +// Last Modified: JB 2009/09/11 makechi2 +// Last Modified: JB 2009/09/14 Analyse +// Last Modified: JB 2010/11/25 Analyse (new fit algorithm) +// Last Modified: JB 2011/07/25 destructor +// Last Modified: JB 2012/05/07 new mechanism to store hits +// Last Modified: JB 2012/08/20 debug is now set by DTracker +// Last Modified: JB 2012/08/27 Analyse, strip-telescope tracking +// Last Modified: VR 2014/06/29 Add GetDistTr2Hit() and fDistTr2Hit, computed in makeChiSquare() +// Last Modified: VR 2014/11/07 Add fHitsMemorized and accessor +// Last Modified: LC 2014/12/08 Add MonteCarlo Tracks from DHitMonteCarlo +// Last Modified: LC 2014/12/15 Remove MC tracks. and hitMC collection. + + ////////////////////////////////////////////////////////////////// + // Class Description of DTrack // + // // + // A particle track from e.g. accelerator passing the tracker // + // The track is measured by the tracker with its silicon // + // reference planes // + // The track is e.g. a straight line // + // The line is found by a fit to the hits in the silicon planes // + // // + ////////////////////////////////////////////////////////////////// + + +//*KEEP,CopyRight. +/************************************************************************ + * Copyright(c) 1998, RD42@CERN, DiamondTracking + ***********************************************************************/ +//*KEND. + +//*KEEP,DTrack. +#include "DTrack.h" +#include "DTracker.h" +//*KEEP,DLine. +#include "DLine.h" +//*KEEP,DHit. +#include "DHit.h" +//#include "DHitMonteCarlo.h" +//*KEEP,DR3. +#include "DR3.h" +//*KEEP,DPlane. +#include "DPlane.h" +//*KEEP,DPrecAlign. +#include "DPrecAlign.h" +//*KEEP,DParticle. +#include "DParticle.h" +//*KEND. +#include "DTrackFitter.h" +#include "MKalmanFilter.h" + +ClassImp(DTrack) // Description of a Track + +//extern int fopen_lockfile(); // JB, removed for inline compilation +//extern FILE * VG_Lockfile; +//______________________________________________________________________________ +// +DTrack::DTrack( Int_t maxNHits) +{ + fDebugTrack = 0; + fTrackNumber = -1; // CD, Nov 2007, JB 2009/07/20 + fLineTrajectory = new DLine(); + fParticle = new DParticle(); + fTangent = new DR3(); + fMaxNHits = maxNHits; // JB 2012/05/07 + fHitList = new DHit*[fMaxNHits]; // these are pointers to hits to make one track, JB 2012/05/07 + //fHitListMC = new DHitMonteCarlo*[fMaxNHits]; + fValid = kFALSE; + fShareHit = 0; // CD, Nov 2007 + fMaxHitsPerPlane= 0; // JB 2009/05/25 + //if(0) fopen_lockfile(); + SetVertex(0.,0.,0.); +} + + +//______________________________________________________________________________ +// +DTrack::DTrack() // /!\ 2 hits only /!\ Default constructor. To put DTrack objects in a container :) +{ + fDebugTrack = 0; + fTrackNumber = -1; // CD, Nov 2007, JB 2009/07/20 + fLineTrajectory = new DLine(); + fParticle = new DParticle(); + fTangent = new DR3(); + fMaxNHits = 3; // JB 2012/05/07 + fHitList = new DHit*[fMaxNHits]; // 2 hits minimum to make the track. + fValid = kFALSE; + fShareHit = 0; // CD, Nov 2007 + fMaxHitsPerPlane= 0; // JB 2009/05/25 + //if(0) fopen_lockfile(); + SetVertex(0.,0.,0.); + fHitsMemorized = 0; +} + + +//______________________________________________________________________________ +// +DTrack::DTrack(const DTrack& aTrack) +{ + fDebugTrack = aTrack.GetDebug(); // JB 2012/09/20 + fTrackNumber = aTrack.GetNumber(); // CD, Nov 2007, JB 2009/07/20 + fLineTrajectory = new DLine(aTrack.GetLinearFit()); + fParticle = new DParticle(aTrack.GetParticle()); + fTangent = new DR3(aTrack.GetTangent()); + // New mechanism to store hits + // JB 2012/05/07 + fMaxNHits = aTrack.GetMaxNHits(); + fHitList = new DHit*[fMaxNHits]; + //for( Int_t iHit=0; iHit< aTrack.GetHitsNumber(); iHit++ ) { + // fHitList[iHit] = (DHit*)(aTrack.GetHit( iHit)); + //} + fValid = kFALSE; + fShareHit = aTrack.GetShareHit(); // CD, Nov 2007 + fMaxHitsPerPlane= aTrack.GetMaxHitsPerPlane(); // JB, 2009/05/25 + //if(0) fopen_lockfile(); + //SetVertex(0.,0.,0.); + fHitsMemorized = aTrack.GetHitsMemorizedNumber(); +} + +//______________________________________________________________________________ +// +DTrack::DTrack(DTrack* aTrack) +{ + + fLineTrajectory = new DLine(aTrack->GetLinearFit()); + fParticle = new DParticle(aTrack->GetParticle()); + fTangent = new DR3(aTrack->GetTangent()); + + fMaxNHits = aTrack->GetMaxNHits(); + fHitList = new DHit*[fMaxNHits]; + + //std::cout<<"Constructor by copy, DTRACK !!!!!!!!!!!!!!!!!"<GetHitsNumber(); ++iHit ) { + fHitList[iHit] = (DHit*)(aTrack->GetHit(iHit)); + } + + fValid = kFALSE; +} +//______________________________________________________________________________ +// +DTrack::DTrack(DR3 Origin, DR3 Slope) +{ + + //Bluilding a DTrack object from the original and slope vectors + + fDebugTrack = 0; + fTrackNumber = -1; + fLineTrajectory = new DLine(); + fParticle = new DParticle(); + fTangent = new DR3(); + fMaxNHits = 2; + fHitList = new DHit*[fMaxNHits]; + fValid = kFALSE; + fShareHit = 0; + fMaxHitsPerPlane= 0; + SetVertex(0.,0.,0.); + fHitsMemorized = 0; + + DR3 tLineFitOrigin; // origin in the tracker system + DR3 tLineFitSlope; // slope along z-axis in tracker system + Float_t tDx=0., tDy=0., tDz=1.; + DR3 tLineFitDirection; // calculated from slope in z direction + Float_t tLength = 0.; + + tLineFitOrigin(0) = Origin(0); + tLineFitOrigin(1) = Origin(1); + tLineFitOrigin(2) = Origin(2); + tLineFitSlope(0) = Slope(0); + tLineFitSlope(1) = Slope(1); + tLineFitSlope(2) = Slope(2); + + tDx = tLineFitSlope(0); + tDy = tLineFitSlope(1); + tDz = 1/sqrt(tDx * tDx + tDy * tDy + 1); + + tLineFitDirection = (tLineFitSlope * tDz); + fLineTrajectory->SetValue(tLineFitOrigin,tLineFitDirection,tLineFitSlope,tLength); + +} +//______________________________________________________________________________ +// +void DTrack::copy(const DTrack& aTrack) +{ + *fLineTrajectory = aTrack.GetLinearFit(); + *fParticle = aTrack.GetParticle(); + *fTangent = aTrack.GetTangent(); + fHitsMemorized = aTrack.GetHitsMemorizedNumber(); +} + +//______________________________________________________________________________ +// +DTrack::~DTrack() +{ + delete fLineTrajectory; + //delete fHitList; no needed, JB 2011/07/25 + delete fParticle; + delete fTangent; + delete fHitList; // JB 2012/05/07 +} + +//____________________________________________________________________________ +// +void DTrack::Reset() +{ + fLineTrajectory->Zero(); + fParticle->Vacuum(); + fTangent->Zero(); + fValid = kFALSE; + fDeltaOrigineX = 0.0 ; + fDeltaOrigineY = 0.0 ; + fHitsMemorized = 0; +} + +//_____________________________________________________________________________ +// +Bool_t DTrack::Analyze( Int_t aNumber, DHit** aHitList, Int_t nHits, Float_t resolution) +{ + + // Fits the track in a linear approximation from the collection of hits. + // The fit depends on the number of hits (fHits) in the collection: + // If fHits>=3 : least square method, + // If fHits==2 : line drawn from two points, + // If fHits==1 : choice by changing the comments (see in code), + // choice 1: the track is perpendicular to the plane (slope=0, origin=hit), + // choice 2: the track has a fixed slope and origin=hit, + // choice 3: use a specified vertex as a second point. + // -> default is choice 1. + // + // Returns kTRUE if the track is good enough, kFALSE otherwise. + // + // Specific cases with 1 or 2 hits added by JB, 2007 June + // Fit with Pixel planes added by JB, 2007 August + // track number added, JB 2009/07/17 + // Fit in tracker frame since 2010/11/25 + // + // Modified JB 2009/09/14, to handle AnalysisMode>=2 + // Last Modified JB, 2010/11/25 Use new DPrecAlign mechanism for Plane position + // Last Modified JB, 2012/05/07 Fix bug on fHitList which was properly stored + // Last Modified JB, 2012/08/28 Allow strip-telescope track fitting again + + fTrackNumber = aNumber; // JB 2009/07/17 + fHits = nHits; + fValid = kFALSE; + + DPrecAlign *hitAlignment; + DR3 aPosition; + + // The following line was not insuring the permanent copy of the pointers + // and hence was pointing to the wrong hits after the next track treatment. + //fHitList = aHitList; + // The following lines manage properly the hit pointers + // which are now permanently attached to this track. + // JB 2012/05/07 + for( Int_t iHit=0; iHitGetIsFromPreviousEvent())fHitsMemorized++; + + + //============ + // Case with only one hit, assume the track slope is null + //============ + // The track origin is taken from the hit position in the plane + if( fHits==1) { + + DR3 bPosition( *(fHitList[0]->GetPosition()) ); + if(fDebugTrack) printf("DTrack::Analyse track with %d hit taking origin uvw(%.1f, %.1f, %.1f) from it and slope fixed\n", fHits, bPosition(0), bPosition(1), bPosition(2) ); + + hitAlignment = fHitList[0]->GetPlane()->GetPrecAlignment(); + aPosition = hitAlignment->TransformHitToTracker( *(fHitList[0]->GetPosition()) ); + + //============ + // CHOICE 1, the track has a no slope + + tLineFitOrigin(0) = aPosition(0); + tLineFitOrigin(1) = aPosition(1); + tLineFitSlope(0) = 0.; //-aPosition(0)/fHitList[0]->GetPlane()->GetPosition()(2); // 0. + tLineFitSlope(1) = 0.; //-aPosition(1)/fHitList[0]->GetPlane()->GetPosition()(2); // 0. + + // end choice 1 + + // CHOICE 2, tracks with constant slope. +/* + const Double_t thetaX = 0.; + const Double_t thetaY = 10.; // in deg. + const Double_t thetaZ = 0.; + //const Double_t z0 = 0.; + + tLineFitOrigin(0) = aPosition(0); + tLineFitOrigin(1) = aPosition(1); + tLineFitOrigin(2) = aPosition(2); + // Slope on Y only : + tLineFitSlope(0) = tan(thetaY*TMath::Pi()/180.0); + tLineFitSlope(1) = 0.; +*/ + // end choice 2 + + // CHOICE 3, build the track with a second point (the vertex) +/* + Double_t x0 = fVertexX; // the vertex position + Double_t y0 = fVertexY; + Double_t z0 = fVertexZ; + + Double_t x1 = aPosition(0); + Double_t y1 = aPosition(1); + Double_t z1 = aPosition(2); + + // std::cout<<"Set vertex coordinate : X = "<GetPlane()->GetPlaneNumber() , aPosition(0), aPosition(1), aPosition(2)); + + } + + + //============ + // Case with only two 2D hits, no fit + //============ + // The track slope and origin are simply taken from the difference of the two hit positions + else if( fHits==2) { + + if(fDebugTrack) printf("DTrack::Analyse track with %d hits taking origin and slope from a simple difference\n", fHits); + +// DR3 aPosition; +// Double_t u0 = fHitList[0]->GetPositionUhit() + fHitList[0]->GetPlane()->GetPositionU(); +// Double_t v0 = fHitList[0]->GetPositionVhit() + fHitList[0]->GetPlane()->GetPositionV(); +// // Shifting and rotating hit 0 was added by JB, 2008/10/21 +// aPosition.SetValue( u0, v0 ,0.); +// aPosition = fHitList[0]->GetPlane()->PlaneToTracker( aPosition); +// Double_t x0 = aPosition(0); +// Double_t y0 = aPosition(1); +// Double_t u1 = fHitList[1]->GetPositionUhit() + fHitList[1]->GetPlane()->GetPositionU(); +// Double_t v1 = fHitList[1]->GetPositionVhit() + fHitList[1]->GetPlane()->GetPositionV(); +// aPosition.SetValue( u1, v1 ,0.); +// aPosition = fHitList[1]->GetPlane()->PlaneToTracker( aPosition); +// Double_t x1 = aPosition(0); +// Double_t y1 = aPosition(1); +// Double_t z0 = fHitList[0]->GetPlane()->GetPosition()(2); +// Double_t z1 = fHitList[1]->GetPlane()->GetPosition()(2); + + hitAlignment = fHitList[0]->GetPlane()->GetPrecAlignment(); + aPosition = hitAlignment->TransformHitToTracker( *(fHitList[0]->GetPosition()) ); + Double_t x0 = aPosition(0); + Double_t y0 = aPosition(1); + Double_t z0 = aPosition(2); + hitAlignment = fHitList[1]->GetPlane()->GetPrecAlignment(); + aPosition = hitAlignment->TransformHitToTracker( *(fHitList[1]->GetPosition()) ); + Double_t x1 = aPosition(0); + Double_t y1 = aPosition(1); + Double_t z1 = aPosition(2); + + if( fDebugTrack) printf( "DTrack::Analyze hit[pl %d]=(%.2f, %.2f, %.2f) hit[pl %d]=(%.2f, %.2f, %.2f)\n",fHitList[0]->GetPlane()->GetPlaneNumber() , x0, y0, z0, fHitList[1]->GetPlane()->GetPlaneNumber(), x1, y1, z1); + + if( z1-z0 != 0.) { + tLineFitOrigin(0) = (z1*x0-z0*x1)/(z1-z0); + tLineFitOrigin(1) = (z1*y0-z0*y1)/(z1-z0); + tLineFitSlope(0) = (x1-x0)/(z1-z0); + tLineFitSlope(1) = (y1-y0)/(z1-z0); + } + else { + printf("DTrack WARNING two hits at same z = %.3f = %.3f, cannot fit track !\n", z0, z1); + } + + } + + //============ + // Case with only two 1D hits (from STRIPs), no fit + //============ + // The track origin is taken from the hit position in the plane + // JB 2013/08/25 + else if( fHits==2 && fHitList[0]->GetPlane()->GetAnalysisMode() == 1 ) { + + if(fDebugTrack) printf("DTrack::Analyse track with %d hits taking origin and slope from a simple difference\n", fHits); + + Double_t x=1.e12, y=1.e12; + Bool_t foundX = kFALSE; + Bool_t foundY = kFALSE; + + for (Int_t ht = 1; ht <= fHits; ht++){ // loop on hit list + + hitAlignment = fHitList[ht-1]->GetPlane()->GetPrecAlignment(); + hitAlignment->TransformHitToTracker( *(fHitList[ht-1]->GetPosition()) ); + aPosition = hitAlignment->TransformHitToTracker( *(fHitList[ht-1]->GetPosition()) ); + + if( fabs(cos(hitAlignment->GetRotations()[0])) < 0.1 ) { // vertical position + y = aPosition(1); + foundY = kTRUE; + } + else { + x = aPosition(0); + foundY = kTRUE; + } + + } // end loop on hit list + + if( foundX && foundX ) { + tLineFitOrigin(0) = x; + tLineFitOrigin(1) = y; + tLineFitSlope(0) = 0.; + tLineFitSlope(1) = 0.; + } + else { + Warning("DTrack::Analyze","Did not found both X(%s) and Y(%s) -> no track!", (foundX?"yes":"no"), (foundY?"yes":"no")); + } + + if( fDebugTrack) printf( "DTrack::Analyze 2 1D hits from planes %d and %d at x,y =(%.2f, %.2f)\n", fHitList[0]->GetPlane()->GetPlaneNumber(), fHitList[1]->GetPlane()->GetPlaneNumber(), x, y); + + } + + //============ + // Least square fit when more than two hits + // + // afit is the 4 elements vector containing the line parameters in 3D + // (x, y) = (afit[0]+z*afit[1], afit[2]+zafit[3]) + // + // first compute the 4x4 matrix(2D fit) depending on the case Strip or Pixels + // then the chi2 minimization is equivalent to a matrix inversion + // + // This part was changed by JB 2010/11/25 to implement a least square fit + // algo in the tracker frame, not anymore from the position in the plane frame + //============ + else { // fHits>2 + + if(fDebugTrack) printf("DTrack::Analyse track with %d hits fitting\n", fHits); + + Double_t fact[4]; + Double_t varm[4][4]; + Double_t covm[4][4]; + Double_t afit[4]; + Double_t uvec[4]; + + //-- Case for STRIPS + // still fit in the plane frame + // taken from John's code. See also section 4.1.6 of Dirk Meier's thesis, page 127 to 130 + // Sign of fact[2] and fact[3] was set to -sin() to match new alignement, + // changed by JB 2012/08/27 + if( fHitList[0]->GetPlane()->GetAnalysisMode() == 1 ) { // if strips + vzero(&afit[0],4); + vzero(&varm[0][0],4*4); + vzero(&covm[0][0],4*4); + vzero(&uvec[0],4); + vzero(&fact[0],4); + + for (Int_t ht = 1; ht <= fHits; ht++){ // loop on hit list + fact[0] = cos( fHitList[ht-1]->GetPlane()->GetTilt()(0) ); + fact[1] = cos( fHitList[ht-1]->GetPlane()->GetTilt()(0) ) * fHitList[ht-1]->GetPlane()->GetPosition()(2); + fact[2] = -sin( fHitList[ht-1]->GetPlane()->GetTilt()(0) ); + fact[3] = -sin( fHitList[ht-1]->GetPlane()->GetTilt()(0) ) * fHitList[ht-1]->GetPlane()->GetPosition()(2); + + for (Int_t j = 0; j < 4; j++) { + uvec[j] += ( fact[j] * ( fHitList[ht-1]->GetPositionUhit() + fHitList[ht-1]->GetPlane()->GetPositionU() )/(resolution * resolution) ); + for (Int_t k = 0; k < 4; k++) { + varm[j][k] += ( fact[j] * fact[k] / (resolution * resolution) ); + } + } + + if( fDebugTrack) printf( "DTrack::Analyze for STRIPS hit[pl %d] positionU = %.2f\n",fHitList[ht-1]->GetPlane()->GetPlaneNumber(), fHitList[ht-1]->GetPositionUhit() ); + + + hitAlignment = fHitList[ht-1]->GetPlane()->GetPrecAlignment(); + aPosition = hitAlignment->TransformHitToTracker( *(fHitList[ht-1]->GetPosition()) ); + + if( fDebugTrack) printf( "DTrack::Analyze for STRIPS hit %d plane %d tilt = %.1f %.1f %.1f", ht, fHitList[ht-1]->GetPlane()->GetPlaneNumber(), hitAlignment->GetRotations()[0], hitAlignment->GetRotations()[1], hitAlignment->GetRotations()[2] ); + + if( fabs(cos(hitAlignment->GetRotations()[0])) < 0.1 ) { // vertical position + if( fDebugTrack) printf( ", vertical position = %.1f\n", aPosition(1)); + uvec[2] += aPosition(1)/(resolution * resolution); + uvec[3] += aPosition(1)*aPosition(2)/(resolution * resolution); + + varm[2][0] = 0.; + varm[2][1] = 0.; + varm[2][2] += 1./(resolution * resolution); + varm[2][3] += aPosition(2)/(resolution * resolution); + varm[3][0] = 0.; + varm[3][1] = 0.; + varm[3][2] += aPosition(2)/(resolution * resolution); + varm[3][3] += aPosition(2)*aPosition(2)/(resolution * resolution); + } + else { // horizontal position + if( fDebugTrack) printf( ", horizontal position = %.1f\n", aPosition(0)); + uvec[0] += aPosition(0)/(resolution * resolution); + uvec[1] += aPosition(0)*aPosition(2)/(resolution * resolution); + + varm[0][0] += 1./(resolution * resolution); + varm[0][1] += aPosition(2)/(resolution * resolution); + varm[0][2] = 0.; + varm[0][3] = 0.; + varm[1][0] += aPosition(2)/(resolution * resolution); + varm[1][1] += aPosition(2)*aPosition(2)/(resolution * resolution); + varm[1][2] = 0.; + varm[1][3] = 0.; + } + } //end loop on hit list + + } // end if strips + + //-- Case for PIXELS (Added by JB, 2007 August) + // fit in the telescope frame since 2010/11/25 + else if ( fHitList[0]->GetPlane()->GetAnalysisMode() >= 2 ){ // if pixels, JB 2009/09/14 for >=2 + vzero(&afit[0],4); + vzero(&varm[0][0],4*4); + vzero(&covm[0][0],4*4); + vzero(&uvec[0],4); + + for (Int_t ht = 1; ht <= fHits; ht++){ // loop on hits + + hitAlignment = fHitList[ht-1]->GetPlane()->GetPrecAlignment(); + aPosition = hitAlignment->TransformHitToTracker( *(fHitList[ht-1]->GetPosition()) ); + double resolutionU = fHitList[ht-1]->GetResolutionUhit(); + double resolutionV = fHitList[ht-1]->GetResolutionVhit(); + + /* + if(fHitList[0]->GetPlane()->GetAnalysisMode() == 1) { // if strips + if( fabs(cos(hitAlignment->GetRotations()[0])) < 0.1 ) { // vertical position + uvec[2] += aPosition(1)/(resolution * resolution); + uvec[3] += aPosition(1)*aPosition(2)/(resolution * resolution); + + varm[2][0] = 0.; + varm[2][1] = 0.; + varm[2][2] += 1./(resolution * resolution); + varm[2][3] += aPosition(2)/(resolution * resolution); + varm[3][0] = 0.; + varm[3][1] = 0.; + varm[3][2] += aPosition(2)/(resolution * resolution); + varm[3][3] += aPosition(2)*aPosition(2)/(resolution * resolution); + } + else { + uvec[0] += aPosition(0)/(resolution * resolution); + uvec[1] += aPosition(0)*aPosition(2)/(resolution * resolution); + + varm[0][0] += 1./(resolution * resolution); + varm[0][1] += aPosition(2)/(resolution * resolution); + varm[0][2] = 0.; + varm[0][3] = 0.; + varm[1][0] += aPosition(2)/(resolution * resolution); + varm[1][1] += aPosition(2)*aPosition(2)/(resolution * resolution); + varm[1][2] = 0.; + varm[1][3] = 0.; + } + } + else {*/ + + /* + //Previous way of doing tracking using only one global resolution for U and V + uvec[0] += aPosition(0)/(resolution * resolution); + uvec[1] += aPosition(0)*aPosition(2)/(resolution * resolution); + uvec[2] += aPosition(1)/(resolution * resolution); + uvec[3] += aPosition(1)*aPosition(2)/(resolution * resolution); + + varm[0][0] += 1./(resolution * resolution); + varm[0][1] += aPosition(2)/(resolution * resolution); + varm[0][2] = 0.; + varm[0][3] = 0.; + varm[1][0] += aPosition(2)/(resolution * resolution); + varm[1][1] += aPosition(2)*aPosition(2)/(resolution * resolution); + varm[1][2] = 0.; + varm[1][3] = 0.; + varm[2][0] = 0.; + varm[2][1] = 0.; + varm[2][2] += 1./(resolution * resolution); + varm[2][3] += aPosition(2)/(resolution * resolution); + varm[3][0] = 0.; + varm[3][1] = 0.; + varm[3][2] += aPosition(2)/(resolution * resolution); + varm[3][3] += aPosition(2)*aPosition(2)/(resolution * resolution); + */ + + //New way of doing tracking using a resolution on U and V for each hit + uvec[0] += aPosition(0)/(resolutionU * resolutionU); + uvec[1] += aPosition(0)*aPosition(2)/(resolutionU * resolutionU); + uvec[2] += aPosition(1)/(resolutionV * resolutionV); + uvec[3] += aPosition(1)*aPosition(2)/(resolutionV * resolutionV); + + varm[0][0] += 1./(resolutionU * resolutionU); + varm[0][1] += aPosition(2)/(resolutionU * resolutionU); + varm[0][2] = 0.; + varm[0][3] = 0.; + varm[1][0] += aPosition(2)/(resolutionU * resolutionU); + varm[1][1] += aPosition(2)*aPosition(2)/(resolutionU * resolutionU); + varm[1][2] = 0.; + varm[1][3] = 0.; + varm[2][0] = 0.; + varm[2][1] = 0.; + varm[2][2] += 1./(resolutionV * resolutionV); + varm[2][3] += aPosition(2)/(resolutionV * resolutionV); + varm[3][0] = 0.; + varm[3][1] = 0.; + varm[3][2] += aPosition(2)/(resolutionV * resolutionV); + varm[3][3] += aPosition(2)*aPosition(2)/(resolutionV * resolutionV); + + //} + + } // en loop on hits + + } // end if pixels + + //-- Unknown case + else{ // unknown mode + printf("WARNING from DTrack::Analyze, unkown AnalysisMode %d for plane %d, STOP!\n", fHitList[0]->GetPlane()->GetAnalysisMode(), fHitList[0]->GetPlane()->GetPlaneNumber()); + return fValid; + } + + // invert matrix + invert(4,&varm[0][0],&covm[0][0]); + + // multiply matrix by measurements vector + + for (Int_t j = 0; j < 4; j++) { + for (Int_t k = 0; k < 4; k++) { + afit[j] += covm[j][k] * uvec[k]; + } + } +/* + // Test New Track Fitting : + DR3 initialTrackDirections(afit[1], afit[3], 1.); + DR3 initialTrackOrigin(afit[0], afit[2], 0.); + + std::cout<<" hit Number = "<ProcessHits(); + + DR3 fittedTrackDirections = trackFit->GetTrackDirections(); + DR3 fittedTrackOrigin = trackFit->GetTrackOrigin(); + + delete trackFit; + + std::cout<<"Track Direction : Avant/Apres :"<SetValue(tLineFitOrigin,tLineFitDirection,tLineFitSlope,tLength); + + makeChiSquare(resolution); + + if(fDebugTrack) printf("DTrack::Analyse track with %d hits is x=%.4f z + %.4f and y=%.4f z + %.4f with chi2=%f\n", fHits, tLineFitSlope(0), tLineFitOrigin(0), tLineFitSlope(1), tLineFitOrigin(1), fChiSquare); + + + //============ + // put here to analyse the quality of the tracks. YG + //============ + fValid = kTRUE; + + for( Int_t iHit=0; iHitGetPlane()->GetHitsN() > fMaxHitsPerPlane ) { // JB, 2009/05/25 + fValid = kFALSE; + if(fDebugTrack) printf("DTrack::Analyse track rejected because %d > %d hits in plane %d\n", fHitList[iHit]->GetPlane()->GetHitsN(), fMaxHitsPerPlane, fHitList[iHit]->GetPlane()->GetPlaneNumber()); + } + } + + // Requires the track is almost horizontal, JB Sept 2007 + Double_t maxSlope = 10.0; // 0.105; + if( TMath::Abs(tDx)>maxSlope || TMath::Abs(tDy)>maxSlope ) { + fValid = kFALSE; + if(fDebugTrack) printf("DTrack::Analyse track rejected because slope (%f, %f) > %f\n", tDx, tDy, maxSlope); + } + + /* + if( fValid ) { + // Refit track with just two 2D points to mitigate multiple scattering + // Special trick for DESY runs + Int_t listOfPlanes[4] = { 3, 4, 5, 6}; // for strip telescope + ReFit( 4, listOfPlanes); + // end of refit + } + */ + + return fValid; +} + +// __________________________________________________________________________ +// +void DTrack::makeChiSquare(Float_t dhs){ + // Computes the chi2 of the fit track using dhs as the error + // + // Computation in V dim added by JB, August 2007. + // Test for pixels changed to analysisMode>=2 changed by JB 2009/09/11 + // Computation structure (not value) slightly changed for better clarity, JB 2013/08/27 + // Compute fDistTr2Hit, by VR 2014/06/29 + + Float_t tdU, tdV; + Float_t tUtrack, tVtrack; + Double_t reducedU, reducedV, reduced; + Int_t ndfU, ndfV, ndf; + Int_t hitDim; + DPlane *aPlane; + fDistTr2Hit=0.0; + + // Initialization + fChiSquare = fChiSquareU = fChiSquareV = 0.0; + if(fHitList[0]->GetPlane()->GetAnalysisMode() == 1) { // if strips + ndfU = -4; // indeed, two parameters are fit per dimemsions which both use U in plane frame + ndfV = 0; + hitDim = 1; + if( fHits<=4 ) return; // return 0. for chisquare if there is less than 2 hits + } //end if strips + else { // if pixels + ndfU = ndfV = -2; // indeed, two parameters are fit per dimemsions (4 in all) + hitDim = 2; + if( fHits<=2 ) return; // return 0. for chisquare if there is less than 2 hits + } // end if pixels + + + + // Loop on hits + for (Int_t ht = 0; ht < fHits; ht++){ + aPlane = fHitList[ht]->GetPlane(); + tUtrack = Intersection(aPlane)(0); + //tdU = (fHitList[ht]->GetPositionUhit() - tUtrack) / dhs; + tdU = (fHitList[ht]->GetPositionUhit() - tUtrack) / fHitList[ht]->GetResolutionUhit(); + ndfU++; + fChiSquareU += tdU * tdU; + if(fDebugTrack) printf( " makeChiSquare: Delta_U: hit %d, plane %d, hu=%.1f, tu=%.1f, deltaU=%.1f, chi2U=%.1f\n", ht, aPlane->GetPlaneNumber(), fHitList[ht]->GetPositionUhit(), tUtrack, tdU, fChiSquareU); + + // only for pixel detector + if( aPlane->GetAnalysisMode() >= 2 ) { // >=2 JB 2009/09/11 + tVtrack = Intersection(aPlane)(1); + //tdV = (fHitList[ht]->GetPositionVhit() - tVtrack) / dhs; + tdV = (fHitList[ht]->GetPositionVhit() - tVtrack) / fHitList[ht]->GetResolutionVhit(); + ndfV++; + fChiSquareV += tdV * tdV; + fDistTr2Hit += sqrt(tdU*tdU+tdV*tdV); + if(fDebugTrack) printf( " makeChiSquare: Delta_V: plane %d, hv=%.1f, tv=%.1f, deltaV=%.1f, chi2V=%.1f\n", aPlane->GetPlaneNumber(), fHitList[ht]->GetPositionVhit(), tVtrack, tdV, fChiSquareV); + } + } // end loop on hits + fDistTr2Hit = fDistTr2Hit/fHits; + + // Final computation + // ndfV and fChiSquareV = 0 if only strips + //reducedU = fChiSquareU / ndfU / (dhs*dhs); + reducedU = fChiSquareU / ndfU; + reducedV = 0; + //if( ndfV>0 ) reducedV = fChiSquareV / ndfV / (dhs*dhs); + if( ndfV>0 ) reducedV = fChiSquareV / ndfV; + ndf = ndfU + ndfV; + fChiSquare = fChiSquareU + fChiSquareV; + //reduced = fChiSquare / ndf / (dhs*dhs); + reduced = fChiSquare / ndf; + + if(fDebugTrack) printf("DTrack::MakeChiSquare with %d %dD-hits, Sum(DU^2)=%.1f / ndfU=%d ==> %.1f, Sum(DV^2)=%.1f / ndfV=%d ==> %.1f, Sum(DU^2+DV^2)=%f / ndf=%d ==> %.1f, resol=%f\n", fHits, hitDim, fChiSquareU, ndfU, reducedU, fChiSquareV, ndfV, reducedV, fChiSquare, ndf, reduced, dhs); + + fChiSquareU = reducedU; + fChiSquareV = reducedV; + fChiSquare = reduced; + +} + +//_____________________________________________________________________________ +// +void DTrack::vzero(Double_t *array, Int_t N) +{ + for (Int_t j = 0; j < N; j++) + array[j] = 0.0; +} + +//_____________________________________________________________________________ +// +void DTrack::invert(Int_t n, Double_t *a, Double_t *b) +{ + // taken from John's tta code + Double_t q[15][15]; + Double_t e; + Int_t i,j,k; + + vzero(&q[0][0],15*15); + + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + b[i*n+j] = a[i*n+j]; + + for (i = 0; i < n; i++) + if (b[i*n+i] != 0.0) q[i][i] = 1.; + + for (k = 0; k < n; k++) { + if (b[k*n+k] != 0.0 ) { + for (i = 0; i < n; i++) { + if (i != k) { + e = b[i*n+k]; + for (j = 0; j < n; j++) { + b[i*n+j] -= e * b[k*n+j] / b[k*n+k]; + if (j == k ) b[i*n+j] = 0.0; + q[i][j] -= e * q[k][j] / b[k*n+k]; + } + } + } + } + } + + for (i = 0; i < n; i++) { + e = b[i*n+i]; + if (e == 0.0) e = 1.; + for (j = 0; j < n; j++){ + b[i*n+j] = q[i][j]/e; + } + } + +} + +//______________________________________________________________________________ +// +DR3 DTrack::Intersection(DPlane *aPlane) +{ + + // calculates the Intersection of the Track with the plane in + // the coordinate system of the plane. This gives the intersection (u_track,v_track,0) + // + // JB 2010/11/25 + + return aPlane->Intersection( this);//GetPrecAlignment()->TransformTrackToPlane( GetLinearFit().GetOrigin()(0), GetLinearFit().GetOrigin()(1), GetLinearFit().GetOrigin()(2), GetLinearFit().GetSlopeZ()(0), GetLinearFit().GetSlopeZ()(1)); + +} + +void DTrack::SetVertex(Float_t vertexX, Float_t vertexY, Float_t vertexZ) +{ + fVertexX = vertexX; + fVertexY = vertexY; + fVertexZ = vertexZ; +} + +//______________________________________________________________________________ +// +/* +DR3 DTrack::Intersection(DPlane *aPlane) +{ + + // functions deprecated USE NEW DPRECALIGN MECHANISM (JB 2010/11/25) + + // calculates the Intersection of the Track with the plane in + // the coordinate system of the plane. This gives the intersection (u_track,v_track,0) + + DR3 result(GetLinearFit().GetOrigin()); // track origin in xyz tracker coordinates + result += GetLinearFit().GetSlopeZ() * aPlane->GetPosition()(2); // intersection in xyz frame at z_plane + result = aPlane->Rotate_TrackerToPlane( result ); // now rotate to the uvd frame + DR3 offset(aPlane->GetPositionU(),aPlane->GetPositionV(),0.); // this is the offset of the plane + result -= offset; + return result; + +} +*/ + + +//_____________________________________________________________________________ +// +Bool_t DTrack::ReFit( Int_t nPlanes, Int_t *ListOfPlanes) +{ + + // Refit the track parameter with the subset of specified planes. + // Not that the initial chi2 is not changed, + // so that a quality cut can still be applied. + // + // JB 2013/08/24 + + fDebugTrack=2; + + if(fDebugTrack) Info("DTrack::Refit", "Track %d will be refitted from %d points to %d points!", fTrackNumber, fHits, nPlanes); + + Int_t nFoundPlanes = 0; + + // Test there is enough planes + if( fHitsGetPlane()->GetPlaneNumber() == ListOfPlanes[iPlane] ) { + newHitList[ht] = aHit; + nFoundPlanes++; + break; + } + } + } // end on hit list + + // If all required hits found, try to refit + // If successful, replace the current track fit with the new one + Bool_t fitSuccess = kFALSE; + if (nFoundPlanes == nPlanes) { + DTrack *newTrack = new DTrack(); + if(fDebugTrack) printf(" Refiting...\n"); + fitSuccess = newTrack->Analyze( fTrackNumber, newHitList, nPlanes, 4.); + if( fitSuccess ) { + if(fDebugTrack>1) { + printf( " --> Refit successfull: \n"); + printf(" old track with %d hits was x=%.4f z + %.4f and y=%.4f z + %.4f with chi2=%f\n", fHits, fLineTrajectory->GetSlopeZ()(0), fLineTrajectory->GetOrigin()(0), fLineTrajectory->GetSlopeZ()(1), fLineTrajectory->GetOrigin()(1), fChiSquare); + } + DLine *aLinearFit = &(newTrack->GetLinearFit()); + SetLinearFit( aLinearFit ); + if(fDebugTrack>1) printf(" new track with %d hits was x=%.4f z + %.4f and y=%.4f z + %.4f with chi2=%f\n", fHits, fLineTrajectory->GetSlopeZ()(0), fLineTrajectory->GetOrigin()(0), fLineTrajectory->GetSlopeZ()(1), fLineTrajectory->GetOrigin()(1), fChiSquare); + + } + delete newTrack; + } + else { + Warning("DTrack::Refit", "Refit fails because only %d requested planes found among the %d hits\n", nPlanes, fHits); + } + + fDebugTrack=0; + + //delete[] newHitList; + return fitSuccess; + +} +//_____________________________________________________________________________ +// +void DTrack::SetLinearFit2(DLine* aLine) +{ + + //cout << "Dtrack::SetLinearFit2:: Origin = (" << aLine->GetOrigin()(0) << "," << aLine->GetOrigin()(1) << "," << aLine->GetOrigin()(2) << ")" << endl; + //cout << "Dtrack::SetLinearFit2:: Direction = (" << aLine->GetDirection()(0) << "," << aLine->GetDirection()(1) << "," << aLine->GetDirection()(2) << ")" << endl; + //cout << "Dtrack::SetLinearFit2:: SlopeZ = (" << aLine->GetSlopeZ()(0) << "," << aLine->GetSlopeZ()(1) << "," << aLine->GetSlopeZ()(2) << ")" << endl; + //cout << "Dtrack::SetLinearFit2:: Length = " << aLine->GetLength() << endl; + + fLineTrajectory->SetValue(aLine->GetOrigin(), + aLine->GetDirection(), + aLine->GetSlopeZ(), + aLine->GetLength()); + + return; + +} diff --git a/src/DTrackFitter.cxx b/src/DTrackFitter.cxx new file mode 100644 index 0000000..8dc380d --- /dev/null +++ b/src/DTrackFitter.cxx @@ -0,0 +1,480 @@ +#include +#include "DR3.h" +#include "MGlobalAlign.h" +#include "DHit.h" +#include "DLine.h" +#include +#include "DTrackFitter.h" +// DTrackFitter Class : LC 2015/06/24 + +//_____________________________________________________________________________ +// + +DTrackFitter::DTrackFitter(Int_t trackParamNumber, Int_t hitNumber, Int_t localAxisNumber, Bool_t ifMultipleScattering, DHit** hitList, DR3 initialTrackParameters, DR3 initialTrackOrigin) +{ + + _hitNumber = hitNumber; + _localAxisNumber = localAxisNumber; + _trackParametersNumber = trackParamNumber; + _multipleScatteringFit = ifMultipleScattering; + + _fHitList = hitList; + _initialTrackParameters = initialTrackParameters; + _initialTrackOrigin = initialTrackOrigin; + + Int_t _dimResiduals = _hitNumber*_localAxisNumber; + + // Define Matrices : + _derivativeTrackMatrix = new TMatrixD(_dimResiduals, _trackParametersNumber); + _covarianceMatrix = new TMatrixD(_dimResiduals, _dimResiduals); + _covarianceMatrixMS = new TMatrixD(_dimResiduals, _dimResiduals); + _inverseCovarianceMatrix = new TMatrixD(_dimResiduals, _dimResiduals); + _finalMatrix = new TMatrixD(_trackParametersNumber, _trackParametersNumber); + _inverseFinalMatrix = new TMatrixD(_trackParametersNumber, _trackParametersNumber); + + // Define Vectors : + _residualsVector = new TVectorD(_dimResiduals); + _residualsVectorMS = new TVectorD(_dimResiduals); + _trackParameters = new TVectorD(_trackParametersNumber); + _trackParametersCorrections = new TVectorD(_trackParametersNumber); + _finalVector = new TVectorD(_dimResiduals); + + for(Int_t i=0 ; i<_trackParametersNumber ; ++i) { + + if(i==0 || i==1) (*_trackParameters)[i] = _initialTrackParameters(i); + else if(i>1) (*_trackParameters)[i] = _initialTrackOrigin(i-2); + } + +} + +//_____________________________________________________________________________ +// + +DTrackFitter::~DTrackFitter() +{ + _derivativeTrackMatrix->Zero(); + _covarianceMatrix->Zero(); + _covarianceMatrixMS->Zero(); + _inverseCovarianceMatrix->Zero(); + _finalMatrix->Zero(); + _inverseFinalMatrix->Zero(); + + _residualsVector->Zero(); + _residualsVectorMS->Zero(); + _trackParameters->Zero(); + _trackParametersCorrections->Zero(); + _finalVector->Zero(); + + delete _derivativeTrackMatrix; + delete _covarianceMatrix; + delete _covarianceMatrixMS; + delete _inverseCovarianceMatrix; + delete _finalMatrix; + delete _inverseFinalMatrix; + + delete _residualsVector; + delete _residualsVectorMS; + delete _trackParameters; + delete _trackParametersCorrections; + delete _finalVector; + +} + +// Compute Intersection U : +Double_t DTrackFitter::ComputeTrackIntersectionU(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint) +{ + + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t intersectionU = (trackPoint(0)-translations(0)-trackDirectionX*( rotMat[6]*(trackPoint(0)-translations(0))+rotMat[7]*(trackPoint(1)-translations(1))+rotMat[8]*(trackPoint(2)-translations(2)) )/( trackDirectionX*rotMat[6]+trackDirectionY*rotMat[7]+rotMat[8] ) )*rotMat[0]+(trackPoint(1)-translations(1)-trackDirectionY*( rotMat[6]*(trackPoint(0)-translations(0))+rotMat[7]*(trackPoint(1)-translations(1))+rotMat[8]*(trackPoint(2)-translations(2)) )/( trackDirectionX*rotMat[6]+trackDirectionY*rotMat[7]+rotMat[8] ) )*rotMat[1]+(trackPoint(2)-translations(2)-( rotMat[6]*(trackPoint(0)-translations(0))+rotMat[7]*(trackPoint(1)-translations(1))+rotMat[8]*(trackPoint(2)-translations(2)) )/( trackDirectionX*rotMat[6]+trackDirectionY*rotMat[7]+rotMat[8] ))*rotMat[2]; + + return intersectionU; + +} + +// Compute Intersection V : +Double_t DTrackFitter::ComputeTrackIntersectionV(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint) +{ + + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t intersectionV = (trackPoint(0)-translations(0)-trackDirectionX*( rotMat[6]*(trackPoint(0)-translations(0))+rotMat[7]*(trackPoint(1)-translations(1))+rotMat[8]*(trackPoint(2)-translations(2)) )/( trackDirectionX*rotMat[6]+trackDirectionY*rotMat[7]+rotMat[8] ))*rotMat[3]+(trackPoint(1)-translations(1)-trackDirectionY*( rotMat[6]*(trackPoint(0)-translations(0))+rotMat[7]*(trackPoint(1)-translations(1))+rotMat[8]*(trackPoint(2)-translations(2)) )/( trackDirectionX*rotMat[6]+trackDirectionY*rotMat[7]+rotMat[8] ))*rotMat[4]+(trackPoint(2)-translations(2)-( rotMat[6]*(trackPoint(0)-translations(0))+rotMat[7]*(trackPoint(1)-translations(1))+rotMat[8]*(trackPoint(2)-translations(2)) )/( trackDirectionX*rotMat[6]+trackDirectionY*rotMat[7]+rotMat[8] ))*rotMat[5]; + + return intersectionV; + +} + +//_____________________________________________________________________________ +// + +Double_t DTrackFitter::ComputeResidualDerivative_U_AboutTrackDirectionX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = (((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*trackDirectionX*sin(rotations(1))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2) + ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))))*cos(rotations(1))*cos(rotations(0)) + ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*(cos(rotations(0))*sin(rotations(2))*sin(rotations(1)) - cos(rotations(2))*sin(rotations(0)))*trackDirectionY*sin(rotations(1))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2) + ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*(cos(rotations(2))*cos(rotations(0))*sin(rotations(1)) + sin(rotations(2))*sin(rotations(0)))*sin(rotations(1))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2); + + return -newDerivative; + +} + +//_____________________________________________________________________________ +// + +Double_t DTrackFitter::ComputeResidualDerivative_U_AboutTrackDirectionY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = -((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*trackDirectionX*cos(rotations(1))*cos(rotations(1))*cos(rotations(0))*sin(rotations(2))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2) - (cos(rotations(0))*sin(rotations(2))*sin(rotations(1)) - cos(rotations(2))*sin(rotations(0)))*(((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*trackDirectionY*cos(rotations(1))*sin(rotations(2))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2) - ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1)))) - ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*(cos(rotations(2))*cos(rotations(0))*sin(rotations(1)) + sin(rotations(2))*sin(rotations(0)))*cos(rotations(1))*sin(rotations(2))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2); + + return -newDerivative; +} + +//_____________________________________________________________________________ +// + +Double_t DTrackFitter::ComputeResidualDerivative_V_AboutTrackDirectionX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = (((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*trackDirectionX*sin(rotations(1))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2) + ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))))*cos(rotations(1))*sin(rotations(0)) + ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*(sin(rotations(2))*sin(rotations(1))*sin(rotations(0)) + cos(rotations(2))*cos(rotations(0)))*trackDirectionY*sin(rotations(1))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2) + ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*(cos(rotations(2))*sin(rotations(1))*sin(rotations(0)) - cos(rotations(0))*sin(rotations(2)))*sin(rotations(1))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2); + + return -newDerivative; + +} + +//_____________________________________________________________________________ +// + +Double_t DTrackFitter::ComputeResidualDerivative_V_AboutTrackDirectionY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY, DR3 trackPoint) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = -((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*trackDirectionX*cos(rotations(1))*cos(rotations(1))*sin(rotations(2))*sin(rotations(0))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2) - (sin(rotations(2))*sin(rotations(1))*sin(rotations(0)) + cos(rotations(2))*cos(rotations(0)))*(((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*trackDirectionY*cos(rotations(1))*sin(rotations(2))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2) - ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1)))) - ((translations(2) - trackPoint(2))*cos(rotations(2))*cos(rotations(1)) + (translations(1) - trackPoint(1))*cos(rotations(1))*sin(rotations(2)) - (translations(0) - trackPoint(0))*sin(rotations(1)))*(cos(rotations(2))*sin(rotations(1))*sin(rotations(0)) - cos(rotations(0))*sin(rotations(2)))*cos(rotations(1))*sin(rotations(2))/pow( (trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))), 2); + + return -newDerivative; + +} + +Double_t DTrackFitter::ComputeResidualDerivative_U_AboutTrackPointX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = (trackDirectionX*sin(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) + 1.0)*cos(rotations(1))*cos(rotations(0)) + (cos(rotations(0))*sin(rotations(2))*sin(rotations(1)) - cos(rotations(2))*sin(rotations(0)))*trackDirectionY*sin(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) + (cos(rotations(2))*cos(rotations(0))*sin(rotations(1)) + sin(rotations(2))*sin(rotations(0)))*sin(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))); + + return -newDerivative; + +} + +Double_t DTrackFitter::ComputeResidualDerivative_U_AboutTrackPointY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = -trackDirectionX*cos(rotations(1))*cos(rotations(1))*cos(rotations(0))*sin(rotations(2))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - (cos(rotations(0))*sin(rotations(2))*sin(rotations(1)) - cos(rotations(2))*sin(rotations(0)))*(trackDirectionY*cos(rotations(1))*sin(rotations(2))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - 1.0) - (cos(rotations(2))*cos(rotations(0))*sin(rotations(1)) + sin(rotations(2))*sin(rotations(0)))*cos(rotations(1))*sin(rotations(2))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))); + + return -newDerivative; + +} + +Double_t DTrackFitter::ComputeResidualDerivative_U_AboutTrackPointZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = -trackDirectionX*cos(rotations(2))*cos(rotations(1))*cos(rotations(1))*cos(rotations(0))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - (cos(rotations(0))*sin(rotations(2))*sin(rotations(1)) - cos(rotations(2))*sin(rotations(0)))*trackDirectionY*cos(rotations(2))*cos(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - (cos(rotations(2))*cos(rotations(0))*sin(rotations(1)) + sin(rotations(2))*sin(rotations(0)))*(cos(rotations(2))*cos(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - 1.0); + + + return -newDerivative; + +} + +Double_t DTrackFitter::ComputeResidualDerivative_V_AboutTrackPointX(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = (trackDirectionX*sin(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) + 1.0)*cos(rotations(1))*sin(rotations(0)) + (sin(rotations(2))*sin(rotations(1))*sin(rotations(0)) + cos(rotations(2))*cos(rotations(0)))*trackDirectionY*sin(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) + (cos(rotations(2))*sin(rotations(1))*sin(rotations(0)) - cos(rotations(0))*sin(rotations(2)))*sin(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))); + + return -newDerivative; + +} + +Double_t DTrackFitter::ComputeResidualDerivative_V_AboutTrackPointY(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = -trackDirectionX*cos(rotations(1))*cos(rotations(1))*sin(rotations(2))*sin(rotations(0))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - (sin(rotations(2))*sin(rotations(1))*sin(rotations(0)) + cos(rotations(2))*cos(rotations(0)))*(trackDirectionY*cos(rotations(1))*sin(rotations(2))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - 1.0) - (cos(rotations(2))*sin(rotations(1))*sin(rotations(0)) - cos(rotations(0))*sin(rotations(2)))*cos(rotations(1))*sin(rotations(2))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))); + + return -newDerivative; + +} + +Double_t DTrackFitter::ComputeResidualDerivative_V_AboutTrackPointZ(Int_t planeIndex, Double_t trackDirectionX, Double_t trackDirectionY) +{ + DPrecAlign* alignParameters = _map_DPrecAlign[planeIndex]; + DR3 translations = alignParameters->GetTranslationsDR3(); + DR3 rotations = alignParameters->GetRotationsDR3(); + //Double_t* rotMat = alignParameters->GetRotationMatrix(); + + Double_t newDerivative = -trackDirectionX*cos(rotations(2))*cos(rotations(1))*cos(rotations(1))*sin(rotations(0))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - (sin(rotations(2))*sin(rotations(1))*sin(rotations(0)) + cos(rotations(2))*cos(rotations(0)))*trackDirectionY*cos(rotations(2))*cos(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - (cos(rotations(2))*sin(rotations(1))*sin(rotations(0)) - cos(rotations(0))*sin(rotations(2)))*(cos(rotations(2))*cos(rotations(1))/(trackDirectionY*cos(rotations(1))*sin(rotations(2)) + cos(rotations(2))*cos(rotations(1)) - trackDirectionX*sin(rotations(1))) - 1.0); + + return -newDerivative; + +} + +void DTrackFitter::SetCovarianceMatrixMS() +{ + + // Var(U_k) = sigma_k^2 + Sum{ (x_k-x_j)^2 theta_0^2 } sum on j Stocker les infos dans une map ? ou un vector ? std::map > _planeInformations; + // --> 3 vector : std::vector _thetaMS std::vector trackExtrapolation + + /* + // Variances : + for(Int_t i=1 ; i<(_hitNumber) ; ++i) { + + for(Int_t k=0 ; k0) std::cout<<"i/j = "<GetIfMCBoardReader()) MCInfoHolder = fAcq->GetMCInfoHolder(); + + fDebugTracker = fc->GetDebug(); + fPlanesN = fc->GetTrackerPar().Planes; // the number of planes in the tracker + fPlanesStatus = 0 ; // initialize at "initalization" step + + fPlaneArray = new TObjArray(fPlanesN); + fLadderArray = new TObjArray(fPlanesN/12); + + fTrackerGeometry = new TBRIK("Tracker","DT","void",40,40,90); + fTrackerNode = new TNode("Tracker","Tracker","Tracker"); + fTrackerNode->cd(); + + fListTrackSeedDevs = new Int_t[fPlanesN]; // JB 2011/03/14 + fListFixRefDevs = new Int_t[fPlanesN]; + fListVarRefDevs = new Int_t[fPlanesN]; + fListTestDevs = new Int_t[fPlanesN]; + + Int_t ts = 0; + Int_t fx = 0; + Int_t vr = 0; + Int_t dut = 0; // added JB 2007 June + + DPlane *aPlane=0; // a pointer to a plane + DLadder *aLadder=0; // a pointer to a Ladder. + fNumberOfLadders = 0; // Number of Ladders in the tracker. + + Int_t planeStatus, planeReadout; + //Int_t planeAnalysisMode; // usefull state of plane + + fTracksMaximum = fc->GetTrackerPar().TracksMaximum; + fHitsMaximum = fPlanesN; // preliminary + fHitList = new DHit*[fHitsMaximum]; // these are pointers to hits to make one track, + // hits itself are generated in the device constructor + + fNumberOfLadders = fc->GetTrackerPar().Ladders; + + Int_t planesLadder = 0; // Number of planes in ladders. + for(Int_t laddersIter=0 ; laddersIterGetLadderPar(laddersIter).Planes; + if (fDebugTracker) { + cout << " There are " << fNumberOfLadders << " ladders to declare." << endl; + cout << " There are " << planesLadder << " planes associated to ladders." << endl; + cout << " --> only " << fPlanesN-planesLadder << " planes will be declared as independent." << endl; + } + + if(fPlanesN-planesLadder != 0) { // if there is some individual planes + + for (Int_t pl = 1; pl <= fPlanesN-planesLadder; pl++){ + if (fDebugTracker) cout << "plane=" << pl << " "; + aPlane = new DPlane(*this, pl, 0); + fPlaneArray->Add(aPlane); + planeStatus = ((DPlane*)fPlaneArray->At(pl-1))->GetStatus(); + planeReadout = fc->GetPlanePar(pl).Readout; + //planeAnalysisMode = fc->GetPlanePar(pl).AnalysisMode; + if (fDebugTracker) cout << " status=" << planeStatus << " readout=" << planeReadout; + + // Modify fix, var and DUT planes counting + // JB, 2007 June and 2011/03/14 for status=0 + // JB, 2011/06/21 to separate seed and fixed ref. + if( planeReadout>0 ) { // if 0, plane is not analyzed, exclude from tracking + + if ( planeStatus == 0 ){ // fixed reference for track seed + if (fDebugTracker) cout << " seed ref=" << fx << endl; + fListTrackSeedDevs[ts++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + } + + else if ( planeStatus == 1){ // fixed reference not track seed + if (fDebugTracker) cout << " fixed ref=" << fx << endl; + fListFixRefDevs[fx++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + } + + else if ( planeStatus == 2 || planeStatus == 3 ){ // variable reference or DUT + if (fDebugTracker) cout << " variable ref=" << vr << endl; + fListVarRefDevs[vr++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + if( planeStatus == 3) { // DUT + if (fDebugTracker) cout << " also device under test=" << vr << endl; + fListTestDevs[dut++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + } + } + + else { + cout << endl << "WARNING plane " << pl << " has an unknown status " << planeStatus << endl; + } + + // if ( planeAnalysisMode==1 && planeStatus!=3 ) { // consider all strips as seed for tracking, JB 2012/08/23 + // if (fDebugTracker) cout << " seed ref=" << fx << endl; + // fListTrackSeedDevs[ts++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + // } + + } // end if readout !=0 + else { + if (fDebugTracker) cout << " not analyzed -> out of tracker!" << endl; + } + } // end loop on planes + cout << endl; + } // end if there is some individual planes + + if(fNumberOfLadders !=0) { + + if (fDebugTracker) std::cout<<"Number Of Ladders = "<GetLadderPar(laddersIter).LadderID; + Int_t planesPerLadder = fc->GetLadderPar(laddersIter).Planes; + TString ladderName = fc->GetLadderPar(laddersIter).Name; + DR3 tilt = fc->GetLadderPar(laddersIter).Tilt; + Int_t status = fc->GetLadderPar(laddersIter).Status; + + if (fDebugTracker) std::cout<<"Ladder "<SetLadderType(ladderName); + //fLadderArray->Add(aLadder); + + if (fDebugTracker) std::cout<<" ladder status = "<GetLadderPar(laddersIter).PlaneList[iterPlanes-1]; + } + else { + planeNumber = fPlanesN-planesLadder + laddersIter*planesPerLadder+iterPlanes; + } + + if (fDebugTracker) cout << endl << " DTracker: Adding tracker plane=" << planeNumber << " as " << iterPlanes << "th plane." << endl; + + aPlane = new DPlane(*this, planeNumber, ladderID); + fPlaneArray->Add(aPlane); + //planeStatus = ((DPlane*)fPlaneArray->At(planeNumber-1))->GetStatus(); + planeStatus = status; // plane status shall be superseded by ladder's one + planeReadout = fc->GetPlanePar(planeNumber-1).Readout; + //planeAnalysisMode = fc->GetPlanePar(planeNumber-1).AnalysisMode; + + //std::cout<<"iterPlanes = "<AddPlane(aPlane,iterPlanes); + + if (fDebugTracker) cout << " Plane " << planeNumber << " with status=" << planeStatus << " readout=" << planeReadout << " added to ladder " << ladderID << " as plane " << iterPlanes << endl; + + // Modify fix, var and DUT planes counting + // JB, 2007 June and 2011/03/14 for status=0 + // JB, 2011/06/21 to separate seed and fixed ref. + // JB, 2014/03/17 to assign correct plane number + if( planeReadout>0 ) { // if 0, plane is not analyzed, exclude from tracking + + if ( planeStatus == 0 ){ // fixed reference for track seed + if (fDebugTracker) cout << " seed ref=" << fx << endl; + fListTrackSeedDevs[ts++] = planeNumber; + } + + else if ( planeStatus == 1){ // fixed reference not track seed + if (fDebugTracker) cout << " fixed ref=" << fx << endl; + fListFixRefDevs[fx++] = planeNumber; + } + + else if ( planeStatus == 2 || planeStatus == 3 ){ // variable reference or DUT + if (fDebugTracker) cout << " variable ref=" << vr << endl; + fListVarRefDevs[vr++] = planeNumber; + if( planeStatus == 3) { // DUT + if (fDebugTracker) cout << " also device under test=" << vr << endl; + fListTestDevs[dut++] = planeNumber; + } + } + + else { + cout << endl << "WARNING plane " << planeNumber << " has an unknown status " << planeStatus << endl; + } + + // if ( planeAnalysisMode==1 && planeStatus!=3 ) { // consider all strips as seed for tracking, JB 2012/08/23 + // if (fDebugTracker) cout << " seed ref=" << fx << endl; + // fListTrackSeedDevs[ts++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + // } + + } // end if readout !=0 + else { + if (fDebugTracker) cout << " not analyzed -> out of tracker!" << endl; + } + } // end loop on planes + cout << endl; + fLadderArray->Add(aLadder); + + } // end loop on ladders. + } // end test on number of ladders + /* + if(fPlanesN-planesPerLadder != 0) { + + for (Int_t pl = 1; pl <= fPlanesN; pl++){ + if (fDebugTracker) cout << "plane=" << pl << " "; + aPlane = new DPlane(*this, pl, 0); + fPlaneArray->Add(aPlane); + planeStatus = ((DPlane*)fPlaneArray->At(pl-1))->GetStatus(); + planeReadout = fc->GetPlanePar(pl).Readout; + planeAnalysisMode = fc->GetPlanePar(pl).AnalysisMode; + if (fDebugTracker) cout << " status=" << planeStatus << " readout=" << planeReadout; + + // Modify fix, var and DUT planes counting + // JB, 2007 June and 2011/03/14 for status=0 + // JB, 2011/06/21 to separate seed and fixed ref. + if( planeReadout>0 ) { // if 0, plane is not analyzed, exclude from tracking + + if ( planeStatus == 0 ){ // fixed reference for track seed + if (fDebugTracker) cout << " seed ref=" << fx << endl; + fListTrackSeedDevs[ts++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + } + + else if ( planeStatus == 1){ // fixed reference not track seed + if (fDebugTracker) cout << " fixed ref=" << fx << endl; + fListFixRefDevs[fx++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + } + + else if ( planeStatus == 2 || planeStatus == 3 ){ // variable reference or DUT + if (fDebugTracker) cout << " variable ref=" << vr << endl; + fListVarRefDevs[vr++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + if( planeStatus == 3) { // DUT + if (fDebugTracker) cout << " also device under test=" << vr << endl; + fListTestDevs[dut++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + } + } + + else { + cout << endl << "WARNING plane " << pl << " has an unknown status " << planeStatus << endl; + } + + // if ( planeAnalysisMode==1 && planeStatus!=3 ) { // consider all strips as seed for tracking, JB 2012/08/23 + // if (fDebugTracker) cout << " seed ref=" << fx << endl; + // fListTrackSeedDevs[ts++] = ((DPlane*)fPlaneArray->At(pl-1))->GetPlaneNumber(); + // } + + } // end if readout !=0 + else { + if (fDebugTracker) cout << " not analyzed -> out of tracker!" << endl; + } + } // end loop on planes + cout << endl; + } + */ + + fTracksFinder = fc->GetTrackerPar().TracksFinder; // JB 2013/07/17, then VR 2014/06/29 + + fTrackSeedDevs = ts; // number of track seed planes + fFixRefDevs = fx; // number of fixed reference planes + fVarRefDevs = vr; // number of variable reference planes + fTestDevs = dut;// number of DUT planes + + fSearchHitDistance = (Double_t)fc->GetTrackerPar().SearchHitDistance; // JB, 2009/05/25 + fSearchMoreHitDistance = (Double_t)fc->GetTrackerPar().SearchMoreHitDistance; // VR, 2014/06/29 + fKeepUnTrackedHitsBetw2evts = fc->GetTrackerPar().KeepUnTrackedHitsBetw2evts; // VR, 2014/08/26 + fTrackingPlaneOrderType = (Int_t) fc->GetTrackerPar().TrackingPlaneOrderType;// VR, 2014/07/14 + + if( fTracksMaximum>0 ) { // if tracking required + + printf("DTracker, Track Seed : %d:",ts); + for( Int_t ip=0; ip The tracking method for pixel telescope is the original one : find_tracks()" << endl; + cout << " -> Using " << fSearchHitDistance << " max um distance between hits to a track" << endl; + break; + case 1 : + cout << " -> The tracking method for pixel telescope is the one with more options : find_tracks_1_opt()" << endl; + cout << " -> Using " << fSearchHitDistance << " um max distance between hits to do the pre-track" << endl; + cout << " -> Using " << fSearchMoreHitDistance << " um max distance between hits and the pre-track to associate them" << endl; + cout << " -> Using the TrackingPlaneOrderType type " << fTrackingPlaneOrderType << endl; + break; + case 2 : + cout << " -> The tracking method for pixel telescope is the IVI one : find_tracks_2_ivi()" << endl; + //--------------------------------- + // Tracking Pass + //--------------------------------- + fTrackingPass = fc->GetTrackerPar().TrackingPass; + fPreTrackHitsNbMinimum = fc->GetTrackerPar().PreTrackHitsNbMinimum; + fPreTrackHitsTypeUsed = fc->GetTrackerPar().PreTrackHitsTypeUsed; + fPreTrackHitsMaxDist = fc->GetTrackerPar().PreTrackHitsMaxDist; + fExtTrackHitsNbMinimum = fc->GetTrackerPar().ExtTrackHitsNbMinimum; + fExtTrackHitsTypeUsed = fc->GetTrackerPar().ExtTrackHitsTypeUsed; + fExtTrackHitsMaxDist = fc->GetTrackerPar().ExtTrackHitsMaxDist; + fFullTrackHitsNbMinimum = fc->GetTrackerPar().FullTrackHitsNbMinimum; + + cout << " -> Doing " << fTrackingPass << " pass : " << endl; + for (Int_t iPass = 1 ; iPass <= fTrackingPass ; iPass++) + { + cout << " -> Pass " << iPass << " : " << endl ; + cout << " -> Pre-tracks parameters :" << endl ; + cout << " -> PreTrackHitsNbMinimum = " << fPreTrackHitsNbMinimum[iPass-1] << " hits" << endl ; + cout << " -> PreTrackHitsTypeUsed = " << fPreTrackHitsTypeUsed[iPass-1]; + switch(fPreTrackHitsTypeUsed[iPass-1]) + { + case 0 : + cout << " : all hits can be used" << endl ; + break; + case 1 : + cout << " : only new hits can be used" << endl ; + break; + case 2 : + cout << " : only memorized hits can be used" << endl ; + break; + default : + cout << " : !!! UNKNOWN !!! All hits will be used instead" << endl ; + fPreTrackHitsTypeUsed[iPass-1] = 0 ; + break; + } + cout << " -> PreTrackHitsMaxDist = " << fPreTrackHitsMaxDist[iPass-1] << " um" << endl ; + cout << " -> Ext-tracks parameters :" << endl ; + cout << " -> ExtTrackHitsNbMinimum = " << fExtTrackHitsNbMinimum[iPass-1] << " hits" << endl ; + cout << " -> PreTrackHitsTypeUsed = " << fExtTrackHitsTypeUsed[iPass-1] ; + switch(fExtTrackHitsTypeUsed[iPass-1]) + { + case 0 : + cout << " : all hits can be used" << endl ; + break; + case 1 : + cout << " : only new hits can be used" << endl ; + break; + case 2 : + cout << " : only memorized hits can be used" << endl ; + break; + default : + cout << " : !!! UNKNOWN !!! All hits will be used instead" << endl ; + fPreTrackHitsTypeUsed[iPass-1] = 0 ; + break; + } + cout << " -> ExtTrackHitsMaxDist = " << fExtTrackHitsMaxDist[iPass-1] << " um" << endl ; + cout << " -> Full-tracks parameters :" << endl ; + cout << " -> FullTrackHitsNbMinimum = " << fFullTrackHitsNbMinimum[iPass-1] << " hits" << endl ; + } + cout << endl; + + //--------------------------------- + // Tracking Scann pass + //--------------------------------- + Int_t nbPlanes, PlaneNb; + fTrackingOrderLines = fc->GetTrackerPar().TrackingOrderLines; + cout << " -> Doing " << fTrackingOrderLines << " scans for each tracking pass : " << endl; + fTrackingOrderPreTrack = new Int_t*[fTrackingOrderLines]; + fTrackingOrderExtTrack = new Int_t*[fTrackingOrderLines]; + + for (Int_t iStrategy = 0 ; iStrategy < fTrackingOrderLines ; iStrategy++) + { + cout << " -> Tracking scan " << iStrategy +1 << " :" << endl ; + //--------------------- + // Pre tracks + //--------------------- + nbPlanes = fc->GetTrackerPar().TrackingOrderPreTrack[iStrategy][0]; + cout << " -> First " << nbPlanes << " planes are scanned to try to build pre-tracks : "<< endl; + fTrackingOrderPreTrack[iStrategy] = new Int_t[nbPlanes+1]; + fTrackingOrderPreTrack[iStrategy][0] = nbPlanes ; + + for (Int_t iPlane=1 ; iPlane <= nbPlanes ; iPlane++) + { + PlaneNb = fc->GetTrackerPar().TrackingOrderPreTrack[iStrategy][iPlane]-1;//WARNING take care with the -1 ! + fTrackingOrderPreTrack[iStrategy][iPlane] = PlaneNb; + cout << " -> " << iPlane << ") plane " << PlaneNb+1 << " : " << ((DPlane*)(fPlaneArray->At(PlaneNb)))->GetPlanePurpose() << endl; + } + + //--------------------- + // Ext tracks + //--------------------- + nbPlanes = fc->GetTrackerPar().TrackingOrderExtTrack[iStrategy][0]; + cout << " -> Then " << nbPlanes << " planes are scanned to try to extend each pre-track : "<< endl; + fTrackingOrderExtTrack[iStrategy] = new Int_t[nbPlanes+1]; + fTrackingOrderExtTrack[iStrategy][0] = nbPlanes ; + + for (Int_t iPlane=1 ; iPlane <= nbPlanes ; iPlane++) + { + PlaneNb = fc->GetTrackerPar().TrackingOrderExtTrack[iStrategy][iPlane]-1; + fTrackingOrderExtTrack[iStrategy][iPlane] = PlaneNb; + cout << " -> " << iPlane << ") plane " << PlaneNb+1 << " : " << ((DPlane*)(fPlaneArray->At(PlaneNb)))->GetPlanePurpose() << endl; + } + } + break; + case 3 : + cout << " -> BEAST II Pattern recognition on PLUME Ladders " << endl; + fBeaster = new DBeaster(this); + break; + default : + cout << " -> The tracking method for pixel telescope is unknown !!!" << endl; + if(fTracksMaximum) gApplication->Terminate(); + break; + } + + } // end if tracking required + + + // Init of fRequiredHits removed since it is call by SetAlignStatus, JB 2013/08/27 + if(fTracksMaximum) SetAlignmentStatus(2); // assume alignment of tracker is done by default, JB 2011/06/21 + + fVertexMaximum = fc->GetTrackerPar().VertexMaximum; + if(fVertexMaximum) cout << " Vertex will be searched for (" << fVertexMaximum << " maximum)." << endl; + + fUseSlopeInExtrapolation = fc->GetTrackerPar().UseSlopeInTrackFinder; // JB 2013/06/21 + fUseVertexConstraint = fc->GetTrackerPar().VertexConstraint; // JB 2013/06/21 + + + fTrack = new DTrack*[fTracksMaximum]; + fTracksN = 0; + fTrackVoid = new DTrack( fHitsMaximum); + for (Int_t tr = 0; tr < fTracksMaximum; tr++) + { + fTrack[tr] = new DTrack( fHitsMaximum); + fTrack[tr]->SetMaxHitsPerPlane( fc->GetTrackerPar().HitsInPlaneTrackMaximum); // JB 2009/05/25 + //fTrack[tr]->SetVertex(0.,0.,0.); + } + + // Counter of tracks over all event + // [0]= all tracks, [i>0]=track with i planes + // JB 2009/09/08 + fTrackCount = new Int_t[fPlanesN]; + for( Int_t ip=0; ip0]= #track with plane i + // JB 2014/08/29 + fTrackCountPerPlane = new Int_t[fPlanesN+1]; // correction, JB 2015/03/17 + for( Int_t ip=0; ipGetTrackerPar().SubtrackNplanes; // 2 + if ( fTracksMaximum>0 && fSubTrackPlanesN>0 ) { + printf( "\nDTracker will make subtracks of %d hits out of full tracks (%d hits):\n with planes ", fSubTrackPlanesN, fHitsMaximum); + fSubTrackPlaneIds = new Int_t[fSubTrackPlanesN]; + fSubTrack = new DTrack*[fTracksMaximum]; +// fSubTrackPlaneIds[0] = 3; // adapted to M34 analysis August 2013 DESY +// fSubTrackPlaneIds[1] = 4; +// printf( "%d, %d\n", fSubTrackPlaneIds[0], fSubTrackPlaneIds[1]); + for (Int_t iplane=0; iplaneGetTrackerPar().SubtrackPlanes[iplane]; + printf( "%d ", fSubTrackPlaneIds[iplane]); + } + printf("\n************************\n"); + for (Int_t tr = 0; tr < fTracksMaximum; tr++) { + fSubTrack[tr] = new DTrack( fSubTrackPlanesN); + } + + } + else { + fSubTrackPlaneIds = NULL; + fSubTrack = NULL; + } + + // Variables for Kalman tracks + // QL 2016/05/26 + fTrackFittingAlg = fc->GetTrackerPar().TrackFittingAlg; + if ( fTrackFittingAlg == kKalman){ + // fKalEnabled = kTRUE; + //else + // fKalEnabled = kFALSE; + //if(fKalEnabled){ + printf("\nDTracker will use KalmanFilter to refit the track!\n"); + //fKalTrack = new DTrack[fTracksMaximum]; + } + cout << endl << " -+-+- DTracker User Constructor DONE -+-+- " << endl; +} + +//______________________________________________________________________________ +// +DTracker::~DTracker() +{ + // DTracker default destructor + + delete [] fTrack; + delete [] fHitList; + delete [] fPlaneArray; + delete [] fLadderArray; + + delete [] fTrackerNode; + delete [] fTrackerGeometry; + delete [] fListTrackSeedDevs; + delete [] fListFixRefDevs; + delete [] fListVarRefDevs; + delete [] fListTestDevs; + delete fTrackVoid; + + delete [] fSubTrackPlaneIds; // JB 2014/12/15 + delete [] fSubTrack; + + //if(fKalEnabled){ // QL 2016/05/26 + // delete [] fKalTrack; + //} + +} + +//______________________________________________________________________________ +// +DPlane* DTracker::GetPlane(Int_t aPlaneNumber) +{ + return (DPlane*)fPlaneArray->At(aPlaneNumber-1); +} + +DLadder* DTracker::GetLadder(Int_t aLadderNumber) +{ + return (DLadder*)fLadderArray->At( aLadderNumber-1 ); +} + +//______________________________________________________________________________ +// +void DTracker::Align(DTrack *aTrack) +{ + DPlane *p; + + for (Int_t pl = 0; pl < 1; pl++) { + p = GetPlane(fListVarRefDevs[pl]); + p->Align(aTrack, kTRUE); + } + +} + +//______________________________________________________________________________ +// +DTrack* DTracker::GetTrack(Int_t aTN) +{ + if(aTN <= fTracksN && aTN >= 1) + return fTrack[aTN-1]; + else{ + // printf(" DTracker, request to nonexistent track #%d, returning Void-Track !\n",aTN); + return fTrackVoid; + } +} + +//______________________________________________________________________________ +// +DTrack* DTracker::GetSubTrack(Int_t aTN) +{ + if(aTN <= fTracksN && aTN >= 1) + return fSubTrack[aTN-1]; + else{ + // printf(" DTracker, request to nonexistent subtrack #%d, returning Void-Track !\n",aTN); + return fTrackVoid; + } +} + +//______________________________________________________________________________ +// +void DTracker::SetAlignmentStatus(Int_t aStatusValue) +{ + // Set the alignment status of the tracker which drives + // the types of planes used to build tracks + // and the planes which is aligned in the AlignTracker procedure. + // The minimal number of hits to make a track is set accordingly. + // + // Modified JB 2009/07/20 + // Modified JB 2009/09/01 + // Modified JB 2011/06/21 + // Modified JB 2012/08/28 add condition for strip-telescope + // Modified JB 2013/08/19 correctly set required hits for status=0 + + fAlignmentStatus = aStatusValue; + + cout << endl << "***********************************************" << endl; + cout << "Tracker alignment status set to " << fAlignmentStatus << endl; + + if( fAlignmentStatus == 0 ) { + cout << " Now only the " << fTrackSeedDevs << " fixed (primary) reference planes used for track seed are used in tracking." << endl << endl; + SetRequiredHits( 1 ); // change from 1 to fTrackSeedDevs, JB 2013/08/19, and then changed back + } + + else if( fAlignmentStatus == 1 ) { + cout << " Now all the " << fFixRefDevs+fTrackSeedDevs << " fixed (primary) reference planes are used in tracking." << endl << endl; + if( ((DPlane*)fPlaneArray->At(0))->GetAnalysisMode() == 1 ) { // STRIP telescope case + cout << " --> STRIP tracking setup detected! <--" << endl; + SetRequiredHits( fFixRefDevs+fTrackSeedDevs ); + } + else { // PIXEL telescope case + // here we assume that there is the same number of ref. facing each seed plane + SetRequiredHits( fFixRefDevs/fTrackSeedDevs+1 ); + } + } + + else if( fAlignmentStatus >= 2 ) { + cout << " Now all reference planes ( " << fFixRefDevs+fTrackSeedDevs << " primaries and " << fVarRefDevs-fTestDevs << " secondaries) are used in tracking." << endl << endl; + SetRequiredHits( fc->GetTrackerPar().PlanesForTrackMinimum ); + } + + else { + cout << "WARNING: (" << aStatusValue << ") is not a valid option, assuming 2." << endl; + SetAlignmentStatus(2); +// fAlignmentStatus = 2; +// cout << " Now all reference planes ( " << fFixRefDevs << " primaries and " << fVarRefDevs-fTestDevs << " secondaries) are used in tracking." << endl << endl; +// SetRequiredHits( fc->GetTrackerPar().PlanesForTrackMinimum ); + } + cout << "***********************************************" << endl; + +} + +//______________________________________________________________________________ +// +void DTracker::SetDebug(Int_t aDebug) +{ + // Initialize or update the debug level + // update also the level for planes + // JB 2009/05/12 + // Modified: JB 2012/08/20 to set DTrack object debug level + + fDebugTracker = aDebug; + + for (Int_t pl = 1; pl <= fPlanesN; pl++) { + GetPlane(pl)->SetDebug( aDebug); + } + + for (Int_t tr = 0; tr < fTracksMaximum; tr++) { + fTrack[tr]->SetDebug( aDebug); + } + + cout << "DTracker debug updated to " << fDebugTracker << endl; +} + +//______________________________________________________________________________ +// +void DTracker::SetRequiredHits(Int_t aNumber) +{ + // JB 2009/09/18 + // Modified JB 2012/08/28 add condition for strip-telescope + + fRequiredHits=aNumber; + cout<At(0))->GetAnalysisMode() == 1 ) { + if( fRequiredHits<2 ) Fatal("DTracker::SetRequiredHits", "----> ERROR, you are asking for tracking (TracksMaximum > 0) but not enough fixed strip-plane to define a track (Status: 0 or 1), STOPPING."); + else if( fRequiredHits==2 ) Warning("DTracker::SetRequiredHits", "----> WARNING, you are asking for tracking (TracksMaximum > 0) but there are just enough (2) fixed strip-plane to define a track (Status: 0 or 1), tracks will have a ZERO SLOPE."); // 2 fixed strips allowed, JB 2013/08/27 + } + + // PIXEL telescope case + else { + if (fTrackSeedDevs==0) Fatal("DTracker::SetRequiredHits", "----> ERROR, you are asking for tracking (TracksMaximum > 0) but no plane has been declared as track seed (Status: 0), STOPPING."); + else if (fRequiredHits==1) Warning("DTracker::SetRequiredHits"," ----> WARNING in DTracker, you have less than 2 fixed reference planes, tracks will have a ZERO SLOPE.\n"); // condition changed by JB, 2007 June + } + } + +} + +//______________________________________________________________________________ +// +Int_t DTracker::Update() +{ + // Modified JB 2009/08/31, authorize track finding with 2 planes + // Modified JB 2009/10/02, Init of plane + // Modified JB 2013/06/11, Test to decide vertexing + + Int_t fOk = 0 ; // should stay at 0 if everything's OK + Int_t fPlInit = 0 ; // to count how many planes are initialized + + for (Int_t plane = 1; plane <= fPlanesN; plane++) { + //============ + fOk += (Int_t)(GetPlane(plane)->Update()); // fOK incremented if something's wrong + //============ + // Check if the plane is initialized or not + // also set init immediately in analysis mode >=100, JB 2009/10/02 + if( fc->GetPlanePar(plane).AnalysisMode>=100 || fc->GetPlanePar(plane).InitialNoise < fAcq->GetEventNumber()+1 ) fPlInit++; // JB 2009/05/26 + if(fDebugTracker) printf(" DTracker::Update plane %d updated, OK=%d, #init=%d \n", plane, fOk, fPlInit); + } + + if (fKeepUnTrackedHitsBetw2evts)// VR 2014.08.28 + { + if(fDebugTracker) printf("\n *-*-* Mecanism for adding previous'event'untracked'hits starts *-*-* \n\n"); + for( Int_t iPlane=0; iPlane < fPlanesN; iPlane++ ) + { + DPlane *aPlane = (DPlane*)fPlaneArray->At(iPlane); + if(fDebugTracker) printf(" *** Plane %d : %s ***\n",iPlane+1, aPlane->GetPlanePurpose() ); + + // Add last'event'unstracked'hits to the current list + aPlane->SetHitsNewN(aPlane->GetHitsN()); + aPlane->SetHitsOldN(aPlane->GetHitsUnTrackedLastEventN()); + aPlane->SetHitsN (aPlane->GetHitsNewN() + aPlane->GetHitsOldN()); + if(fDebugTracker) printf("New hits : %d ; Old hits : %d ; Total hits : %d.\n",aPlane->GetHitsNewN(), aPlane->GetHitsOldN(), aPlane->GetHitsN()); + + + if(fDebugTracker) printf("->Setting new hits as new ones : hits # "); + for (Int_t inewHit = 1 ; inewHit <= aPlane->GetHitsNewN() ; inewHit++) + { + aPlane->GetHit(inewHit)->SetIsFromPreviousEvent(0); + if(fDebugTracker) printf("%d [%p]{%.0f;%.0f;%.0f}", aPlane->GetHit(inewHit)->GetNumber(),aPlane->GetHit(inewHit),aPlane->GetHit(inewHit)->GetPositionUhit(),aPlane->GetHit(inewHit)->GetPositionVhit(),aPlane->GetHit(inewHit)->GetPositionWhit() ); + } + if(fDebugTracker) printf("\n"); + + + if(fDebugTracker) printf("->Adding olds hits to current list : hits # (hits memorized #) : "); + for (Int_t ioldHit = 1 ; ioldHit <= aPlane->GetHitsOldN() ; ioldHit++) + { + aPlane->GetHit(aPlane->GetHitsNewN() + ioldHit)->clone(aPlane->GetHitUnTrackedLastEvent(ioldHit),0); + //aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->SetNumber((aPlane->GetHitsNewN() + ioldHit)); + if(fDebugTracker) printf("%d[%p]{%.0f;%.0f;%.0f} (%d[%p]{%.0f;%.0f;%.0f}) ", aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->GetNumber(),aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit)),aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->GetPositionUhit(),aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->GetPositionVhit(),aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->GetPositionWhit(), aPlane->GetHitUnTrackedLastEvent(ioldHit)->GetNumber(), aPlane->GetHitUnTrackedLastEvent(ioldHit),aPlane->GetHitUnTrackedLastEvent(ioldHit)->GetPositionUhit(),aPlane->GetHitUnTrackedLastEvent(ioldHit)->GetPositionVhit(),aPlane->GetHitUnTrackedLastEvent(ioldHit)->GetPositionWhit()); + } + if(fDebugTracker) printf("\n\n"); + + } + if(fDebugTracker) printf("\n *-*-* Mecanism for adding previous'event'untracked'hits finished *-*-* \n\n"); + } + + if (fPlanesStatus==0) { // still in initializing step + // Update the status if all planes have been initialized + if(fPlInit==fPlanesN) { + fPlanesStatus = 1 ; + cout << endl << "The Tracker status just changed to " << fPlanesStatus << endl; + } + } + else { // initialize step done + // If trackig required + if(fPlanesN>=2 && fTracksMaximum){ // check config file asks for tracks (JB, June 2007, > upgraded to >= JB 2009/08/31) + // Check if we build tracks with the strip telescope or not + //============ + + if( GetPlane(1)->GetAnalysisMode()==1 ) { // strip-telescope + find_tracks_withStrips(); + } + else { // pixel-telescope + // VR 2014/06/29 tracking method depends on TracksFinder config. + if(fTracksFinder==0) find_tracks(); + else if (fTracksFinder==1) find_tracks_1_opt(); + else if (fTracksFinder==2) find_tracks_2_ivi(); + else if (fTracksFinder==3){ + std::cout << "***** find_tracks_Beast *****" << '\n'; + find_tracks_Beast(); + } + } + if( fVertexMaximum ) { // If vertexing required, JB/LC 2013/06/11 + find_vertex(); + find_tracks_and_vertex(); + } + //============ + //if (1<=fTracksN && fTracksN<=fTracksMaximum) fOk--; // condition changed by JB, 2007 June + //if(fDebugTracker) printf("DTracker::Update after find_tracks tracksN=%d, OK=%d\n", fTracksN, fOk); + } + else if(fTracksMaximum){// if no tracks found while tracking requested, issue a warning + cout << " Event " << fAcq->GetRealEventNumber() << " no track finding because less than 2 planes (calibration?)" << endl;// only warns the use if fTrackmaximum was not set to 0 in cfg file + fTracksN=0; + } + } + + if (fKeepUnTrackedHitsBetw2evts) {// VR 2014.08.28 + if(fDebugTracker) printf("\n *-*-* Mecanism for saving current'event'untracked'hits starts *-*-* \n\n"); + for( Int_t iPlane=0; iPlane < fPlanesN; iPlane++ ) { + DPlane *aPlane = (DPlane*)fPlaneArray->At(iPlane); + if(fDebugTracker) printf(" *** Plane %d : %s ***\n",iPlane+1, aPlane->GetPlanePurpose() ); + + Int_t UnTracked = 0; + if(fDebugTracker) printf("->Copying untracked hits to the untrack hits memory : hits memorized # : "); + for (Int_t iHit = 1 ; iHit <= aPlane->GetHitsNewN() ; iHit++) + { + if (!aPlane->GetHit(iHit)->GetFound() && !aPlane->GetHit(iHit)->GetIsFromPreviousEvent()) + { + aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->clone(aPlane->GetHit(iHit),0); + aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->SetIsFromPreviousEvent(1); + if(fDebugTracker) printf("%d[%p]{%.0f;%.0f;%.0f} ", aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->GetNumber(), aPlane->GetHitUnTrackedLastEvent(UnTracked+1),aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->GetPositionUhit(),aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->GetPositionVhit(),aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->GetPositionWhit()); + UnTracked += 1; + } + } + if(fDebugTracker) printf("\n"); + + aPlane->SetHitsUnTrackedLastEventN(UnTracked); + if(fDebugTracker) printf("%d untracked hits memorized !\n\n",UnTracked); + } + if(fDebugTracker) printf("\n *-*-* Mecanism for saving current'event'untracked'hits finished *-*-* \n\n"); + } + + + + if(fDebugTracker) printf("DTracker::Update finaly OK=%d\n", fOk); + return fOk; +} + +//______________________________________________________________________________ +// +Int_t DTracker::UpdateMC() +{ + + // Function to do tracking of hit generated by MC code which generates tracks + // including with multiple scattering and sensor spatial resolution + // Modified AP 2015/03/11 + + Int_t fOk = 0; // should stay at 0 if everything's OK + Int_t fPlInit = 0; // to count how many planes are initialized + + for (Int_t plane = 1; plane <= fPlanesN; plane++) { + //============ + //fOk += (Int_t)(GetPlane(plane)->Update()); // fOK incremented if something's wrong + //============ + // Check if the plane is initialized or not + // also set init immediately in analysis mode >=100, JB 2009/10/02 + //if( fc->GetPlanePar(plane).AnalysisMode>=100 || fc->GetPlanePar(plane).InitialNoise < fAcq->GetEventNumber()+1 ) fPlInit++; // JB 2009/05/26 + fPlInit++; + if(fDebugTracker) printf(" DTracker::Update plane %d updated, OK=%d, #init=%d \n", plane, fOk, fPlInit); + } + + if(fKeepUnTrackedHitsBetw2evts){ // VR 2014.08.28 + if(fDebugTracker) printf("\n *-*-* Mecanism for adding previous'event'untracked'hits starts *-*-* \n\n"); + for(Int_t iPlane=0; iPlane < fPlanesN; iPlane++ ) { + DPlane *aPlane = (DPlane*)fPlaneArray->At(iPlane); + if(fDebugTracker) printf(" *** Plane %d : %s ***\n",iPlane+1, aPlane->GetPlanePurpose() ); + + // Add last'event'unstracked'hits to the current list + aPlane->SetHitsNewN(aPlane->GetHitsN()); + aPlane->SetHitsOldN(aPlane->GetHitsUnTrackedLastEventN()); + aPlane->SetHitsN (aPlane->GetHitsNewN() + aPlane->GetHitsOldN()); + if(fDebugTracker) printf("New hits : %d ; Old hits : %d ; Total hits : %d.\n",aPlane->GetHitsNewN(), aPlane->GetHitsOldN(), aPlane->GetHitsN()); + + + if(fDebugTracker) printf("->Setting new hits as new ones : hits # "); + for (Int_t inewHit = 1 ; inewHit <= aPlane->GetHitsNewN() ; inewHit++) { + aPlane->GetHit(inewHit)->SetIsFromPreviousEvent(0); + if(fDebugTracker) printf("%d [%p]{%.0f;%.0f;%.0f}", + aPlane->GetHit(inewHit)->GetNumber(), + aPlane->GetHit(inewHit), + aPlane->GetHit(inewHit)->GetPositionUhit(), + aPlane->GetHit(inewHit)->GetPositionVhit(), + aPlane->GetHit(inewHit)->GetPositionWhit()); + } + if(fDebugTracker) printf("\n"); + + + if(fDebugTracker) printf("->Adding olds hits to current list : hits # (hits memorized #) : "); + for (Int_t ioldHit = 1 ; ioldHit <= aPlane->GetHitsOldN() ; ioldHit++) { + aPlane->GetHit(aPlane->GetHitsNewN() + ioldHit)->clone(aPlane->GetHitUnTrackedLastEvent(ioldHit),0); + if(fDebugTracker) printf("%d[%p]{%.0f;%.0f;%.0f} (%d[%p]{%.0f;%.0f;%.0f}) ", + aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->GetNumber(), + aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit)), + aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->GetPositionUhit(), + aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->GetPositionVhit(), + aPlane->GetHit((aPlane->GetHitsNewN() + ioldHit))->GetPositionWhit(), + aPlane->GetHitUnTrackedLastEvent(ioldHit)->GetNumber(), + aPlane->GetHitUnTrackedLastEvent(ioldHit), + aPlane->GetHitUnTrackedLastEvent(ioldHit)->GetPositionUhit(), + aPlane->GetHitUnTrackedLastEvent(ioldHit)->GetPositionVhit(), + aPlane->GetHitUnTrackedLastEvent(ioldHit)->GetPositionWhit()); + } + if(fDebugTracker) printf("\n\n"); + + } + if(fDebugTracker) printf("\n *-*-* Mecanism for adding previous'event'untracked'hits finished *-*-* \n\n"); + } + + if(fPlanesStatus==0) { // still in initializing step + // Update the status if all planes have been initialized + if(fPlInit==fPlanesN) { + fPlanesStatus = 1; + cout << endl << "The Tracker status just changed to " << fPlanesStatus << endl; + } + } + + if(fPlanesStatus==0) { // still in initializing step + // Update the status if all planes have been initialized + if(fPlInit==fPlanesN) { + fPlanesStatus = 1; + cout << endl << "The Tracker status just changed to " << fPlanesStatus << endl; + } + } + else { // initialize step done + // If trackig required + if(fPlanesN>=2 && fTracksMaximum) { // check config file asks for tracks (JB, June 2007, > upgraded to >= JB 2009/08/31) + // Check if we build tracks with the strip telescope or not + //============ + if(GetPlane(1)->GetAnalysisMode()==1) { // strip-telescope + find_tracks_withStrips(); + } + else { // pixel-telescope + // VR 2014/06/29 tracking method depends on TracksFinder config. + if(fTracksFinder==0) { + //cout << "DTracker::UpdateMC:: Calling function find_tracks()" << endl; + find_tracks(); + } + else if (fTracksFinder==1) find_tracks_1_opt(); + else if (fTracksFinder==2) find_tracks_2_ivi(); + else if (fTracksFinder==3) find_tracks_Beast(); + } + if( fVertexMaximum ) { // If vertexing required, JB/LC 2013/06/11 + find_vertex(); + find_tracks_and_vertex(); + } + //============ + //if (1<=fTracksN && fTracksN<=fTracksMaximum) fOk--; // condition changed by JB, 2007 June + //if(fDebugTracker) printf("DTracker::Update after find_tracks tracksN=%d, OK=%d\n", fTracksN, fOk); + } + else if(fTracksMaximum){// if no tracks found while tracking requested, issue a warning + // only warns the use if fTrackmaximum was not set to 0 in cfg file + cout << " Event " << fAcq->GetRealEventNumber() << " no track finding because less than 2 planes (calibration?)" << endl; + fTracksN=0; + } + } + + if (fKeepUnTrackedHitsBetw2evts) {// VR 2014.08.28 + if(fDebugTracker) printf("\n *-*-* Mecanism for saving current'event'untracked'hits starts *-*-* \n\n"); + for( Int_t iPlane=0; iPlane < fPlanesN; iPlane++ ) { + DPlane *aPlane = (DPlane*)fPlaneArray->At(iPlane); + if(fDebugTracker) printf(" *** Plane %d : %s ***\n",iPlane+1, aPlane->GetPlanePurpose() ); + + Int_t UnTracked = 0; + if(fDebugTracker) printf("->Copying untracked hits to the untrack hits memory : hits memorized # : "); + for (Int_t iHit = 1 ; iHit <= aPlane->GetHitsNewN() ; iHit++) { + if (!aPlane->GetHit(iHit)->GetFound() && !aPlane->GetHit(iHit)->GetIsFromPreviousEvent()) { + aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->clone(aPlane->GetHit(iHit),0); + aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->SetIsFromPreviousEvent(1); + if(fDebugTracker) printf("%d[%p]{%.0f;%.0f;%.0f} ", aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->GetNumber(), aPlane->GetHitUnTrackedLastEvent(UnTracked+1),aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->GetPositionUhit(),aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->GetPositionVhit(),aPlane->GetHitUnTrackedLastEvent(UnTracked+1)->GetPositionWhit()); + UnTracked += 1; + } + } + if(fDebugTracker) printf("\n"); + + aPlane->SetHitsUnTrackedLastEventN(UnTracked); + if(fDebugTracker) printf("%d untracked hits memorized !\n\n",UnTracked); + } + if(fDebugTracker) printf("\n *-*-* Mecanism for saving current'event'untracked'hits finished *-*-* \n\n"); + } + + if(fDebugTracker) printf("DTracker::Update finaly OK=%d\n", fOk); + + return fOk ; + +} +//_____________________________________________________________________________ +// +void DTracker::find_tracks(){ + // Original method to find tracks (TracksFinder==0) + //-------------------------------- + // Try to make a track with all hits of the "seed" reference planes (status=0). + // For each of such hits, a track is extrapolated to the other planes and + // the nearest hit within a search window is added to the track. If no hit + // lies within the search window, the plane is skipped. + // When all planes have been searched, the track is fitted with all its associated hits. + // + // Note that there are two options for the track extrapolation: + // fUseSlopeInExtrapolation==0 => done with no slope, + // that means perpendicularly with respect to the seed plane. + // fUseSlopeInExtrapolation >0 => done with the current track slope. + // The parameter fUseSlopeInExtrapolation is set through the + // + // Planes are used in the tracking depending on their status + // and the value of the Tracker Align Status. The rule is that the plane + // is included if PlaneStatus<=TrackerAlignStatus. + // + // This method has been completely reshaped to allow for multi-track event + // and best hit selection. + // + // + // JB 2009/05/22 + // Modified: JB 2009/08/25, track numbering + // Modified: JB 2009/09/01, no more update of fRequiredHits + // Modified: JB 2011/03/14, use several sensors for track seed + // Modified: JB 2011/07/25, search the next hit along the temporary track path + // Modified: SS 2011/10/26, rollback of the calculation of the hit-track distance + // Modified: JB 2012/04/02, fix in condition to include planes depending on alignment + // Modified: JB 2012/09/07, new condition on firstHit + // Modified: JB 2013/06/21, new parameter fUseSlopeInExtrapolation + // Modified: VR 2014/06/29, bug fixed : hits not associated to a track a cleared even if fRequiredHits is not reached + + DPlane *aPlane = NULL; + DHit *aHit = NULL; + DTrack aTrack( fPlanesN); + aTrack.SetDebug( fDebugTracker); + DR3 extrapolation; + Int_t oldfHits = 0; + DPlane *oldPlane = NULL; + Double_t minDistance = 1.e9; + Double_t aDistance, distanceWithoutSlope, distancewithSlope; + DHit *bestHit=0; + Float_t tPlaneResolution=fc->GetTrackerPar().Resolution; + DR3 hitPosition; // usefull for temporary computation check + + // fRequiredHits is no longer updated here, JB 2009/09/01 + if( fDebugTracker) printf(" DTracker::find_tracks %d hits required, alignStatus %d\n", fRequiredHits, fAlignmentStatus); + + // Reset counters and arrays + fTracksN = 0; + for(Int_t trk = 1; trk <= fTracksMaximum; trk++) fTrack[trk-1]->Reset(); + + // ================== + // Loop on reference planes usable for track seed + DPlane *firstPlane; + for( Int_t iseed=0; iseedGetPlaneNumber(), + firstPlane->GetPlanePurpose(), + firstPlane->GetHitsN()); + + for( Int_t iFirstHit=1; iFirstHit<=firstPlane->GetHitsN() ; iFirstHit++) { // loop on first hits, pay attention that hit numbering start at 1 + if( fTracksN >= fTracksMaximum ) break; // if max track number reach, stop + fHits = 0; + oldfHits = 0; + oldPlane = firstPlane; + for(Int_t hit = 0; hit < fHitsMaximum; hit++) fHitList[hit]=0; + if(fDebugTracker>1) cout << " DTracker::find_tracks Hit list reseted" << endl; + + // test if the hit was associated before, + // this test allows to manage several firstPlanes + // JB 2012/09/07 + if( firstPlane->GetHit( iFirstHit )->GetFound() ) continue; + + fHitList[fHits] = firstPlane->GetHit( iFirstHit ); + fHitList[fHits]->SetFound(); // not really needed, because never tested in the following + if( fDebugTracker) printf(" DTracker::find_tracks hit %d number %d from plane %d (%s) found %d at (%.1f, %.1f)\n", + fHits, + fHitList[fHits]->GetNumber(), + firstPlane->GetPlaneNumber(), + firstPlane->GetPlanePurpose(), + fHitList[fHits]->GetFound(), + fHitList[fHits]->GetPositionUhit(), + fHitList[fHits]->GetPositionVhit()); + fHits++; + + // ================== + // Loop on all planes to find a matching hit in them + // exclude the first plane + // always exclude DUT + // exclude Variable refenreces if alignement is not done yet + for( Int_t iPlane=0; iPlane< fPlanesN; iPlane++ ) { // loop on planes + aPlane = (DPlane*)fPlaneArray->At(iPlane); + + // check plane is valid + if( aPlane->GetPlaneNumber() != firstPlane->GetPlaneNumber() + //&& !( aPlane->GetStatus()==0) // not mandatory but could be faster, JB 2011/03/14. However, you need to comment this to have all the reference plane in status 0 + && ( aPlane->GetStatus()<=fAlignmentStatus ) // condition changed, JB 2012/04/02 + && !( aPlane->GetStatus()==3 ) ) { // if valid plane + if(fDebugTracker>1) printf(" DTracker::find_tracks checking plane %d (%s) with %d hits\n", + aPlane->GetPlaneNumber(), + aPlane->GetPlanePurpose(), + aPlane->GetHitsN()); + + // find the extrapolation of the current track to this plane: + // if the number of hits in the track has changed -> recompute the track, + // if the plane has changed -> recompute the intersection. + // JB 2011/07/25 + if( fHits != oldfHits) { + aTrack.Analyze( -1, fHitList, fHits, tPlaneResolution); + if( fDebugTracker) printf(" track origin (%.1f, %.1f, %.1f) slope (%.1f, %.1f, %.1f)\n", + aTrack.GetLinearFit().GetOrigin()(0), aTrack.GetLinearFit().GetOrigin()(1), aTrack.GetLinearFit().GetOrigin()(2), + aTrack.GetLinearFit().GetSlopeZ()(0), aTrack.GetLinearFit().GetSlopeZ()(1), aTrack.GetLinearFit().GetSlopeZ()(2)); + oldfHits = fHits; + } + + if( oldPlane->GetPlaneNumber() != aPlane->GetPlaneNumber() ) { + extrapolation = aPlane->Intersection( &aTrack); //aTrack.Intersection( aPlane); + if( fDebugTracker) printf(" track extrapolation at plane %d (%s) (z=%.1f) uvw= (%.1f, %.1f, %.1f)\n", + aPlane->GetPlaneNumber(), + aPlane->GetPlanePurpose(), + aPlane->GetPosition()(2), + extrapolation(0), extrapolation(1), extrapolation(2)); + oldPlane = aPlane; + } + + // loop on all hits of this plane and keep the nearest one + minDistance = 1.e9; + aDistance=distanceWithoutSlope=distancewithSlope=1.e9; + bestHit=0; + for( Int_t iHit=1; iHit <= aPlane->GetHitsN(); iHit++ ) { // loop on plane hits + aHit = aPlane->GetHit( iHit); + if( fDebugTracker>1) printf(" DTracker::find_tracks trying for hit %d number %d from plane %d (%s) found %d\n", + fHits, aHit->GetNumber(), + aPlane->GetPlaneNumber(), + aPlane->GetPlanePurpose(), + aHit->GetFound()); + if( aHit->GetFound()==kTRUE ) continue; // skip hit already found + + distanceWithoutSlope = (fHitList[0])->Distance( aHit); + distancewithSlope = aHit->Distance( &extrapolation); // JB 2011/07/25 + + //-------- IMPORTANT CHOICE for track extrapolation + // switch the value of aDistance between distanceWithoutSlope or distancewithSlope + // SS 2011/10/26 - rollback to the method with no slope. + // now choice made by new parameter, JB 2013/06/21 + if(fUseSlopeInExtrapolation > 0) aDistance = distancewithSlope; + else aDistance = distanceWithoutSlope; + + //----------------------- + + if(fDebugTracker > 1) { + hitPosition.SetValue( *(fHitList[0]->GetPosition())); + hitPosition = fHitList[0]->GetPlane()->PlaneToTracker( hitPosition); + hitPosition = aPlane->TrackerToPlane( hitPosition); + printf("#hits=%d (uvw) hit0(%.1f,%.1f) extra(%.1f,%.1f) newHit(%.1f,%.1f) distWOslope=%.1f, distWslope=%.1f (lim %f)\n", + fHits, + hitPosition(0), + hitPosition(1), + extrapolation(0), + extrapolation(1), + aHit->GetPositionUhit(), + aHit->GetPositionVhit(), + distanceWithoutSlope, + distancewithSlope, + fSearchHitDistance); + printf(" at (%.1f, %.1f)+(%.1f, %.1f)-(%.1f, %.1f)=(%.1f, %.1f) dist=%.1f %f\n", + aHit->GetPositionUhit(), aHit->GetPositionVhit(), + aHit->GetPlane()->GetPosition()(0), aHit->GetPlane()->GetPosition()(1), + (fHitList[0])->GetPlane()->GetPosition()(0), (fHitList[0])->GetPlane()->GetPosition()(1), + (aHit->GetPositionUhit())+(aHit->GetPlane()->GetPosition()(0))-((fHitList[0])->GetPlane()->GetPosition()(0))-((fHitList[0])->GetPositionUhit()), + (aHit->GetPositionVhit())+(aHit->GetPlane()->GetPosition()(1))-((fHitList[0])->GetPlane()->GetPosition()(1))-((fHitList[0])->GetPositionVhit()), + aDistance, + fSearchHitDistance); + } + + if( aDistance < fSearchHitDistance && aDistance < minDistance ) { + minDistance = aDistance; + bestHit = aHit; + } + } // end loop on plane hits + + // if a hit has been found, add the hit + if( bestHit ) { + fHitList[fHits] = bestHit; + fHitList[fHits]->SetFound(); + if( fDebugTracker) printf(" DTracker::find_tracks hit %d selected from plane %d (%s) hit #%d found %d\n", + fHits, + aPlane->GetPlaneNumber(), + aPlane->GetPlanePurpose(), + fHitList[fHits]->GetNumber(), + fHitList[fHits]->GetFound()); + fHits++; + } + } // end if valid plane + } // end loop on planes + + // We have now a list of hits + // if they are numerous enough, try to make the track + if( fDebugTracker) printf(" DTracker::find_tracks trying with %d hits over %d required, alignStatus %d\n", fHits, fRequiredHits, fAlignmentStatus); + if (fHits >= fRequiredHits) { + + // *************************************************************** + // fTracksN+1 to start track numbering at 1, JB 2009/08/25 + // Increment counters over all events, JB 2009/09/08 + if (fTrack[fTracksN]->Analyze( fTracksN+1, fHitList, fHits, tPlaneResolution)) { + fTrackCount[0] += 1; + fTrackCount[fHits] += 1; + fTrackCountPerPlane[0] += 1; + for ( Int_t iHit=0; iHitGetPlane()->GetPlaneNumber() ] += 1; + } + // if subtrack mechanism requested, refit with subset of planes + // JB 2015/12/15 + if ( fSubTrackPlanesN>0 ) { + MakeSubTrack( fTrack[fTracksN], fHitList, fHits); + } + // if fTrackFittingAlg == 1, refit the track with MKalmanFilter method + // QL 2016/05/26 + if (fTrackFittingAlg == kKalman){ + MakeKalTrack(fTrack[fTracksN], fHitList, fHits); + } + // if fTrackFittingAlg == 2, refit the track with MKalmanFilter method + // QL 2016/05/26 + if (fTrackFittingAlg == kChi2MS){ + MakeLeastChi2Track(fTrack[fTracksN], fHitList, fHits); + } + fTracksN++; + } + else { + // if track not selected, free all hits + // JB 2011/03/14 + for( Int_t iHit=0; iHitSetFound(kFALSE); + if(fDebugTracker) printf("DTracker::find_track set hit[%d] # %d of plane %d (%s) free.\n", + iHit, + fHitList[iHit]->GetNumber(), + fHitList[iHit]->GetPlane()->GetPlaneNumber(), + fHitList[iHit]->GetPlane()->GetPlanePurpose()); + } + } + // *************************************************************** + } + else { + // VR 2014/06/29 + // If track not selected due to fRequiredHits no reached, free all hits + for( Int_t iHit=0; iHitSetFound(kFALSE); + if(fDebugTracker) printf("DTracker::find_track set hit[%d] # %d of plane %d (%s) free.\n", + iHit, + fHitList[iHit]->GetNumber(), + fHitList[iHit]->GetPlane()->GetPlaneNumber(), + fHitList[iHit]->GetPlane()->GetPlanePurpose()); + } + } + if( fDebugTracker) printf(" %d tracks found\n", fTracksN); + } // end loop on first hits + } // end loop on seed planes + +} + +//_____________________________________________________________________________ +// +void DTracker::find_tracks_1_opt() +{ + // Method to find tracks like find_tracks() but with more options. + // Method chosen if fTracksFinder==1 (config param TracksFinder==1) + // + // Allows to track through planes in a pre-defined order + // if fTrackingPlaneOrderType = 0, use order defined by plane nb + // if fTrackingPlaneOrderType = 1, order defined by plane status + // first Status 0, then 1 and 2 + // + // Allows to change the search distance depending on the nb of hits already associated + // when only 1 hit, use fSearchMoreHitDistance + // when at least 2 hits, use fSearchMoreHitDistance + // + //---------------------------------------------------------------- + // + // Created : VR 2014/07/14, adapted from find_tracks() + + DPlane *aPlane; + DHit *aHit; + DTrack aTrack( fPlanesN); + aTrack.SetDebug( fDebugTracker); + DR3 extrapolation; + Int_t oldfHits = 0; + DPlane *oldPlane; + Double_t minDistance = 1.e9; + Double_t aDistance, distanceWithoutSlope, distancewithSlope; + DHit *bestHit=0; + Float_t tPlaneResolution=fc->GetTrackerPar().Resolution; + DR3 hitPosition; // usefull for temporary computation check + + // fRequiredHits is no longer updated here, JB 2009/09/01 + if( fDebugTracker) printf(" DTracker::find_tracks_1_opt %d hits required, alignStatus %d\n", fRequiredHits, fAlignmentStatus); + + std::vector PlanesToAnalyseOrder; + std::vector PlanesStatus0; + std::vector PlanesStatus1; + std::vector PlanesStatus2; + std::vector PlanesStatus3; + PlanesToAnalyseOrder.clear(); + PlanesStatus0.clear(); + PlanesStatus1.clear(); + PlanesStatus2.clear(); + PlanesStatus3.clear(); + + for( Int_t iPlane=0; iPlane< fPlanesN; iPlane++) + { + aPlane = (DPlane*)fPlaneArray->At(iPlane); + if (aPlane->GetStatus() == 0) PlanesStatus0.push_back(iPlane); + if (aPlane->GetStatus() == 1) PlanesStatus1.push_back(iPlane); + if (aPlane->GetStatus() == 2) PlanesStatus2.push_back(iPlane); + if (aPlane->GetStatus() == 3) PlanesStatus3.push_back(iPlane); + } + + if (fTrackingPlaneOrderType == 0) + { + for( Int_t iPlane=0; iPlane< fPlanesN; iPlane++) + { + aPlane = (DPlane*)fPlaneArray->At(iPlane); + if(aPlane->GetStatus() <= fAlignmentStatus) PlanesToAnalyseOrder.push_back(iPlane); + } + } + + if (fTrackingPlaneOrderType == 1) + { + if(fAlignmentStatus>=0) for( Int_t iPlane=0; iPlane=1) for( Int_t iPlane=0; iPlane=2) for( Int_t iPlane=0; iPlane=3) for( Int_t iPlane=0; iPlaneAt(PlanesToAnalyseOrder.at(iPlane)); + printf(" %d) plane %d (%s) with status %d \n",iPlane,aPlane->GetPlaneNumber(),aPlane->GetPlanePurpose(),aPlane->GetStatus() ); + } + } + + + + // Reset counters and arrays + fTracksN = 0; + for(Int_t trk = 1; trk <= fTracksMaximum; trk++) fTrack[trk-1]->Reset(); + + // ================== + // Loop on reference planes usable for track seed + DPlane *firstPlane; + for( Int_t iseed=0; iseedGetPlaneNumber(),firstPlane->GetPlanePurpose(), firstPlane->GetHitsN()); + + for( Int_t iFirstHit=1; iFirstHit<=firstPlane->GetHitsN() ; iFirstHit++) // loop on first hits, pay attention that hit numbering start at 1 + { + if( fTracksN >= fTracksMaximum ) break; // if max track number reach, stop + fHits = 0; + oldfHits = 0; + oldPlane = firstPlane; + for(Int_t hit = 0; hit < fHitsMaximum; hit++) fHitList[hit]=0; + if(fDebugTracker>1) cout << " DTracker::find_tracks_1_opt Hit list reseted" << endl; + + // test if the hit was associated before, + // this test allows to manage several firstPlanes + // JB 2012/09/07 + if( firstPlane->GetHit( iFirstHit )->GetFound() ) continue; + + fHitList[fHits] = firstPlane->GetHit( iFirstHit ); + fHitList[fHits]->SetFound(); // not really needed, because never tested in the following + if( fDebugTracker) printf(" DTracker::find_tracks_1_opt hit %d number %d from plane %d (%s) found %d at (%.1f, %.1f)\n", fHits, fHitList[fHits]->GetNumber(), firstPlane->GetPlaneNumber(),firstPlane->GetPlanePurpose(), fHitList[fHits]->GetFound(), fHitList[fHits]->GetPositionUhit(), fHitList[fHits]->GetPositionVhit()); + fHits++; + + // ================== + // Loop on all planes to find a matching hit in them + // exclude the first plane + // always exclude DUT + // exclude Variable refenreces if alignement is not done yet + for( Int_t iPlane=0; iPlane< fPlanesN; iPlane++ ) + { // loop on planes + aPlane = (DPlane*)fPlaneArray->At(PlanesToAnalyseOrder.at(iPlane)); + + Bool_t preTrack = 0; // Does a "pre-track" made with 2 hits exists ? + // check plane is valid + if( aPlane->GetPlaneNumber() != firstPlane->GetPlaneNumber() + //&& !( aPlane->GetStatus()==0) // not mandatory but could be faster, JB 2011/03/14. However, you need to comment this to have all the reference plane in status 0 + && ( aPlane->GetStatus()<=fAlignmentStatus ) // condition changed, JB 2012/04/02 + && !( aPlane->GetStatus()==3 ) ) + { // if valid plane + if(fDebugTracker>1) printf(" DTracker::find_tracks_1_opt checking plane %d (%s) with %d hits\n", aPlane->GetPlaneNumber(),aPlane->GetPlanePurpose(), aPlane->GetHitsN()); + + // find the extrapolation of the current track to this plane: + // if the number of hits in the track has changed -> recompute the track, + // if the plane has changed -> recompute the intersection. + // JB 2011/07/25 + if( fHits != oldfHits) + { + aTrack.Analyze( -1, fHitList, fHits, tPlaneResolution); + if( fDebugTracker) printf(" track origin (%.1f, %.1f, %.1f) slope (%.1f, %.1f, %.1f)\n", aTrack.GetLinearFit().GetOrigin()(0), aTrack.GetLinearFit().GetOrigin()(1), aTrack.GetLinearFit().GetOrigin()(2), aTrack.GetLinearFit().GetSlopeZ()(0), aTrack.GetLinearFit().GetSlopeZ()(1), aTrack.GetLinearFit().GetSlopeZ()(2)); + oldfHits = fHits; + } + if( oldPlane->GetPlaneNumber() != aPlane->GetPlaneNumber() ) + { + extrapolation = aPlane->Intersection( &aTrack); //aTrack.Intersection( aPlane); + if( fDebugTracker) printf(" track extrapolation at plane %d (%s) (z=%.1f) uvw= (%.1f, %.1f, %.1f)\n", aPlane->GetPlaneNumber(), aPlane->GetPlanePurpose(), aPlane->GetPosition()(2), extrapolation(0), extrapolation(1), extrapolation(2)); + oldPlane = aPlane; + } + + // loop on all hits of this plane and keep the nearest one + minDistance = 1.e9; + aDistance=distanceWithoutSlope=distancewithSlope=1.e9; + bestHit=0; + for( Int_t iHit=1; iHit <= aPlane->GetHitsN(); iHit++ ) + { // loop on plane hits + aHit = aPlane->GetHit( iHit); + if( fDebugTracker>1) printf(" DTracker::find_tracks_1_opt trying for hit %d number %d from plane %d (%s) found %d\n",fHits, aHit->GetNumber(), aPlane->GetPlaneNumber(),aPlane->GetPlanePurpose(), aHit->GetFound()); + if( aHit->GetFound()==kTRUE ) continue; // skip hit already found + + distanceWithoutSlope = (fHitList[0])->Distance( aHit); + distancewithSlope = aHit->Distance( &extrapolation); // JB 2011/07/25 + + //-------- IMPORTANT CHOICE for track extrapolation + // switch the value of aDistance between distanceWithoutSlope or distancewithSlope + // SS 2011/10/26 - rollback to the method with no slope. + // now choice made by new parameter, JB 2013/06/21 + if( fUseSlopeInExtrapolation > 0 ) aDistance = distancewithSlope; + else aDistance = distanceWithoutSlope; + //----------------------- + + if( fDebugTracker>1) + { + hitPosition.SetValue( *(fHitList[0]->GetPosition())); + hitPosition = fHitList[0]->GetPlane()->PlaneToTracker( hitPosition); + hitPosition = aPlane->TrackerToPlane( hitPosition); + printf("#hits=%d (uvw) hit0(%.1f,%.1f) extra(%.1f,%.1f) newHit(%.1f,%.1f) distWOslope=%.1f, distWslope=%.1f (lim %f)\n", fHits, hitPosition(0), hitPosition(1), extrapolation(0), extrapolation(1), aHit->GetPositionUhit(), aHit->GetPositionVhit(), distanceWithoutSlope, distancewithSlope, fSearchHitDistance); + printf(" at (%.1f, %.1f)+(%.1f, %.1f)-(%.1f, %.1f)=(%.1f, %.1f) dist=%.1f %f\n", aHit->GetPositionUhit(), aHit->GetPositionVhit(), aHit->GetPlane()->GetPosition()(0), aHit->GetPlane()->GetPosition()(1), (fHitList[0])->GetPlane()->GetPosition()(0), (fHitList[0])->GetPlane()->GetPosition()(1), (aHit->GetPositionUhit())+(aHit->GetPlane()->GetPosition()(0))-((fHitList[0])->GetPlane()->GetPosition()(0))-((fHitList[0])->GetPositionUhit()), (aHit->GetPositionVhit())+(aHit->GetPlane()->GetPosition()(1))-((fHitList[0])->GetPlane()->GetPosition()(1))-((fHitList[0])->GetPositionVhit()), aDistance, fSearchHitDistance); + } + + if (!preTrack && aDistance < fSearchHitDistance) // Trying to associate a 2nd hit ? + { + if( aDistance < minDistance ) + { + minDistance = aDistance; + bestHit = aHit; + preTrack = 1; + } + } + else if (preTrack && aDistance < fSearchMoreHitDistance) // Trying to associate more hits than 2 firsts + { + if( aDistance < minDistance ) + { + minDistance = aDistance; + bestHit = aHit; + } + } + } // end loop on plane hits + + // if a hit has been found, add the hit + if( bestHit ) + { + fHitList[fHits] = bestHit; + fHitList[fHits]->SetFound(); + if( fDebugTracker) printf(" DTracker::find_tracks_1_opt hit %d selected from plane %d (%s) hit #%d found %d\n", fHits, aPlane->GetPlaneNumber(),aPlane->GetPlanePurpose(), fHitList[fHits]->GetNumber(), fHitList[fHits]->GetFound()); + fHits++; + } + + } // end if valid plane + + } // end loop on planes + + // We have now a list of hits + // if they are numerous enough, try to make the track + if( fDebugTracker) printf(" DTracker::find_tracks_1_opt trying with %d hits over %d required, alignStatus %d\n", fHits, fRequiredHits, fAlignmentStatus); + if (fHits >= fRequiredHits) + { + // *************************************************************** + // fTracksN+1 to start track numbering at 1, JB 2009/08/25 + // Increment counters over all events, JB 2009/09/08 + if (fTrack[fTracksN]->Analyze( fTracksN+1, fHitList, fHits, tPlaneResolution)) + { + fTrackCount[0] += 1; + fTrackCount[fHits] += 1; + fTrackCountPerPlane[0] += 1; + for ( Int_t iHit=0; iHitGetPlane()->GetPlaneNumber() ] += 1; + } + fTracksN++; + } + // if track not selected, free all hits + // JB 2011/03/14 + else + { + for( Int_t iHit=0; iHitSetFound(kFALSE); + if(fDebugTracker) printf("DTracker::find_track set hit[%d] # %d of plane %d (%s) free.\n", iHit, fHitList[iHit]->GetNumber(), fHitList[iHit]->GetPlane()->GetPlaneNumber(),fHitList[iHit]->GetPlane()->GetPlanePurpose()); + } + } + // *************************************************************** + } + // VR 2014/06/29 + // If track not selected due to fRequiredHits no reached, free all hits + else + { + for( Int_t iHit=0; iHitSetFound(kFALSE); + if(fDebugTracker) printf("DTracker::find_track set hit[%d] # %d of plane %d (%s) free.\n", iHit, fHitList[iHit]->GetNumber(), fHitList[iHit]->GetPlane()->GetPlaneNumber(),fHitList[iHit]->GetPlane()->GetPlanePurpose()); + } + } + if( fDebugTracker) printf(" %d tracks found\n", fTracksN); + } // end loop on first hits + + } // end loop on seed planes + +} + +//_____________________________________________________________________________ +// +void DTracker::find_tracks_2_ivi() +{ + + // Method to find tracks adapted for Interaction Vertex Imaging + // Method chosen if fTracksFinder==2 (config param TracksFinder==2) + // + // Read the DSetup.cxx comments for a description of the parameters + // + //---------------------------------------------------------------- + // + // Created : VR 2014/07/14, adapted from find_tracks() + // TODO : add track computation between steps parameter + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// < CONFIGURATION EXEMPLE > +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +// // ************************************ +// // General +// // ************************************ +// TracksFinder: 2 +// TracksMaximum: 1000 +// KeepUnTrackedHitsBetw2evts: 1 +// HitsInPlaneTrackMaximum: 1000 +// +// // ************************************ +// // Specific to TracksFinder:2 +// // ************************************ +// // PreTrack = config. of algo. to build the start track (=pre-track) only made with hits in pre-track'planes +// // ExtTrack = config. of algo. to try to extend the pre-track with hits in ext-track'planes +// // FullTrack = config. of algo. for the full track (can be a pre-track not extended !) +// // ----------------------- +// // Tracking pass +// // ----------------------- +// // HitsNbMinimum = minimum number of hits to create/extend/save a pre/ext/full track +// // HitsTypeUsed = 0:any kind ; 1:only new hits ; 2:only memorized hits +// // HitsMaxDist = distance between hit/track and another hit to add it to the current track [um] +// // [Pre/Ext]TrackPARAM = {valuePass1 valuePass2 ...} +// +// TrackingPass: 2 +// +// PreTrackHitsNbMinimum: {2 2} +// PreTrackHitsTypeUsed: {0 2} +// PreTrackHitsMaxDist: {8370 30000} +// +// ExtTrackHitsNbMinimum: {1 0} +// ExtTrackHitsTypeUsed: {0 2} +// ExtTrackHitsMaxDist: {2000 2001} +// +// FullTrackHitsNbMinimum: {3 2} +// // ----------------------- +// // Tracking Planes Order +// // ----------------------- +// // TrackingOrderLineX: [NbPlanesPreTrack]{PTpl1 PTpl2 ...} [NbPlanesExtTrack]{ETpl1 ETpl2 ETpl3 ...} +// +// TrackingOrderLines: 4 +// TrackingOrderLine1: [4]{3 4 7 8} [4]{2 1 6 5} +// TrackingOrderLine2: [4]{7 8 3 4} [4]{6 5 2 1} +// TrackingOrderLine3: [4]{2 1 6 5} [4]{3 4 7 8} +// TrackingOrderLine4: [4]{6 5 2 1} [4]{7 8 3 4} + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +//-------------------------- +// Declarations + Initialize +//-------------------------- + // Parameters asked for a pass + Int_t PreTrackHitsNbMinimum; + Int_t PreTrackHitsTypeUsed; + Float_t PreTrackHitsMaxDist; + Int_t ExtTrackHitsNbMinimum; + Int_t ExtTrackHitsTypeUsed; + Float_t ExtTrackHitsMaxDist; + Int_t FullTrackHitsNbMinimum; + + // Parameters asked for a tracking line + Int_t nbPlanesPreTrack; + Int_t nbPlanesExtTrack; + + // Initialize tracks + fTracksN = 0; + for(Int_t trk = 1; trk <= fTracksMaximum; trk++) fTrack[trk-1]->Reset(); + + // Values during analysis + // Hits + DHit *hitFirst; + DHit *aHit; + Int_t nbHitsFirstPlanePreTrack; + Int_t nbHitsCurrentPlanePreTrack; + Int_t nbHitsCurrentPlaneExtTrack; + Int_t nbPreTrackHitsCurrentTrack; + Int_t nbExtTrackHitsCurrentTrack; + Bool_t isFromPreviousEvent; + Bool_t aCandidateHitInThisPlane; + Double_t bestDistance; + Double_t distance; + // Track + DTrack aTrack(fPlanesN); + aTrack.SetDebug(fDebugTracker); + // Planes + DR3 intersection; + DPlane *planeFirstPreTrack; + DPlane *planeCurrentPreTrack; + DPlane *planeCurrentExtTrack; + + // General values + Float_t tPlaneResolution=fc->GetTrackerPar().Resolution; + + // Display + TString info1 = " "; + TString info2 = " "; + TString info3 = " "; + TString info4 = " "; + TString info5 = " "; + TString info6 = " "; + TString info7 = " "; + TString info8 = " "; + +//-------------------------- +// Work +//-------------------------- + if(fDebugTracker) printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* \n"); + if(fDebugTracker) printf("*-*-* Tracking with DTracker::find_tracks_2_ivi() starts *-*-* \n"); + if(fDebugTracker) printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* \n\n"); + + //************************** + // for all tracking pass + //************************** + for(Int_t iTrackingPass = 0 ; iTrackingPass < fTrackingPass ; iTrackingPass++) + { + if(fDebugTracker) cout << info1 << "*-*-*-*-*-*-*-*-*-*-*-*-*-*" << endl; + if(fDebugTracker) cout << info1 << "*-* Pass # " << iTrackingPass+1 << "/" << fTrackingPass << " starts *-*" << endl; + if(fDebugTracker) cout << info1 << "*-*-*-*-*-*-*-*-*-*-*-*-*-*" << endl; + + PreTrackHitsNbMinimum = fPreTrackHitsNbMinimum[iTrackingPass]; + PreTrackHitsTypeUsed = fPreTrackHitsTypeUsed[iTrackingPass]; + PreTrackHitsMaxDist = fPreTrackHitsMaxDist[iTrackingPass]; + ExtTrackHitsNbMinimum = fExtTrackHitsNbMinimum[iTrackingPass]; + ExtTrackHitsTypeUsed = fExtTrackHitsTypeUsed[iTrackingPass]; + ExtTrackHitsMaxDist = fExtTrackHitsMaxDist[iTrackingPass]; + FullTrackHitsNbMinimum = fFullTrackHitsNbMinimum[iTrackingPass]; + + if(fDebugTracker) + { + cout << info1 << "-> Parameters for pre-track :" << endl; + cout << info2 << "-> PreTrackHitsNbMinimum = " << PreTrackHitsNbMinimum << endl ; + cout << info2 << "-> PreTrackHitsTypeUsed = " << PreTrackHitsTypeUsed ; + switch(PreTrackHitsTypeUsed) + { + case 0 : + cout << " : all hits can be used" << endl ; + break; + case 1 : + cout << " : only new hits can be used" << endl ; + break; + case 2 : + cout << " : only memorized hits can be used" << endl ; + break; + default : + cout << " : !!! UNKNOWN !!!" << endl ; + break; + } + cout << info2 << "-> PreTrackHitsMaxDist = " << PreTrackHitsMaxDist << endl ; + + cout << info1 << "-> Parameters for ext-track :" << endl; + cout << info2 << "-> ExtTrackHitsNbMinimum = " << ExtTrackHitsNbMinimum << endl ; + cout << info2 << "-> ExtTrackHitsTypeUsed = " << ExtTrackHitsTypeUsed ; + switch(ExtTrackHitsTypeUsed) + { + case 0 : + cout << " : all hits can be used" << endl ; + break; + case 1 : + cout << " : only new hits can be used" << endl ; + break; + case 2 : + cout << " : only memorized hits can be used" << endl ; + break; + default : + cout << " : !!! UNKNOWN !!!" << endl ; + break; + } + cout << info2 << "-> ExtTrackHitsMaxDist = " << ExtTrackHitsMaxDist << endl ; + + cout << info1 << "-> Parameters for full-track :" << endl; + cout << info2 << "-> FullTrackHitsNbMinimum = " << FullTrackHitsNbMinimum << endl ; + cout << endl ; + } + + //************************** + // for each tracking line + //************************** + for(Int_t iTrackingLine = 0 ; iTrackingLine < fTrackingOrderLines ; iTrackingLine++) + { + if(fDebugTracker) cout << info2 << "***------------------------------***" << endl; + if(fDebugTracker) cout << info2 << "*** Tracking Line # " << iTrackingLine+1 << "/" << fTrackingOrderLines << " starts ***" << endl; + if(fDebugTracker) cout << info2 << "***------------------------------***" << endl; + + //--------------------------------- + // Initialize this tracking line + //--------------------------------- + nbPlanesPreTrack = fTrackingOrderPreTrack[iTrackingLine][0]; + nbPlanesExtTrack = fTrackingOrderExtTrack[iTrackingLine][0]; + if(fDebugTracker) + { + cout << info2 << "-> " << nbPlanesPreTrack << " planes scanned for pre-track : " << endl ; + for (Int_t iPlanePreTrack=1 ; iPlanePreTrack <= nbPlanesPreTrack ; iPlanePreTrack++) + { + Int_t PlanePreTrackNb = fTrackingOrderPreTrack[iTrackingLine][iPlanePreTrack]; + cout << info3 << "-> " << iPlanePreTrack << ") plane " << PlanePreTrackNb+1 << " : " << ((DPlane*)(fPlaneArray->At(PlanePreTrackNb)))->GetPlanePurpose() << endl ; + } + + cout << info2 << "-> " << nbPlanesExtTrack << " planes scanned for ext-track : " << endl ; + for (Int_t iPlaneExtTrack=1 ; iPlaneExtTrack <= nbPlanesExtTrack ; iPlaneExtTrack++) + { + Int_t PlaneExtTrackNb = fTrackingOrderExtTrack[iTrackingLine][iPlaneExtTrack]; + cout << info3 << "-> " << iPlaneExtTrack << ") plane " << PlaneExtTrackNb+1 << " : " << ((DPlane*)(fPlaneArray->At(PlaneExtTrackNb)))->GetPlanePurpose() << endl ; + } + cout << endl ; + } + + //----------------------------------------- + // Scanning hits of first pre-track plane + //----------------------------------------- + // select the first plane in the pre-track-planes-list (in current tracking line) + planeFirstPreTrack = (DPlane*)(fPlaneArray->At(fTrackingOrderPreTrack[iTrackingLine][1])); + nbHitsFirstPlanePreTrack = planeFirstPreTrack->GetHitsN(); + if(fDebugTracker) cout << info2 << "-> First plane for pre-track is # " << fTrackingOrderPreTrack[iTrackingLine][1]+1 ; + if(fDebugTracker) cout << " : " << planeFirstPreTrack->GetPlanePurpose() << " with " << nbHitsFirstPlanePreTrack << " hits" << endl; + + //----------------------------------------------------------------- + // loop on these hits, pay attention that hit numbering start at 1 ! + //----------------------------------------------------------------- + for(Int_t iHitFirstPlane=1 ; iHitFirstPlane <= nbHitsFirstPlanePreTrack ; iHitFirstPlane++) + { + //################################### + // Tests and infos about this hit + //################################### + if( fTracksN >= fTracksMaximum ) + { + cout << info2 << "!!! Tracking stops because max tracks nb reached : " << fTracksN << " tracks !!!" << endl; + return ; // if max track number reach, stop + } + + hitFirst = planeFirstPreTrack->GetHit(iHitFirstPlane); + if(fDebugTracker) cout << info3 << "°°°°°°°°°°°" << endl; + if(fDebugTracker) cout << info3 << "° Hit " << iHitFirstPlane << "/" << nbHitsFirstPlanePreTrack << " °" << endl; + if(fDebugTracker) cout << info3 << "°°°°°°°°°°°" << endl; + + if(hitFirst->GetFound()) + { + if(fDebugTracker) cout << info4 << "-> Is ever associated to a track, skip it" << endl; + continue; + } + else + { + if(fDebugTracker) cout << info4 << "-> Is NOT ever associated to a track, keep it" << endl; + } + + isFromPreviousEvent = hitFirst->GetIsFromPreviousEvent(); + if(isFromPreviousEvent) + { + if(fDebugTracker) cout << info4 << "-> Is memorized from last event" << endl; + switch(PreTrackHitsTypeUsed) + { + case 0 : + if(fDebugTracker) cout << info5 << "-> All hits can be used, keep it" << endl; + break; + case 1 : + if(fDebugTracker) cout << info5 << "-> Only new hits can be used, skip it" << endl; + continue; + break; + case 2 : + if(fDebugTracker) cout << info5 << "-> Only memorized hits can be used, keep it" << endl; + break; + default : + cout << " There is a hit selection bug in code !!!" << endl; + break; + } + } + else + { + if(fDebugTracker) cout << info4 << "-> Is NOT memorized from last event = is a new hit" << endl; + switch(PreTrackHitsTypeUsed) + { + case 0 : + if(fDebugTracker) cout << info5 << "-> All hits can be used, keep it" << endl; + break; + case 1 : + if(fDebugTracker) cout << info5 << "-> Only new hits can be used, keep it" << endl; + break; + case 2 : + if(fDebugTracker) cout << info5 << "-> Only memorized hits can be used, skip it" << endl; + continue; + break; + default : + cout << " There is a hit selection bug in code !!!" << endl; + break; + } + } + + if( fDebugTracker) + { + cout << info4 ; + printf("-> Is located at (u=%.1f, v=%.1f, w=%.1f)um in plane frame, (x=%.1f, y=%.1f, z=%.1f)um in tracker frame\n",\ + hitFirst->GetPositionUhit(), hitFirst->GetPositionVhit(), hitFirst->GetPositionWhit(),\ + planeFirstPreTrack->PlaneToTracker(*(hitFirst->GetPosition()))(0),planeFirstPreTrack->PlaneToTracker(*(hitFirst->GetPosition()))(1),planeFirstPreTrack->PlaneToTracker(*(hitFirst->GetPosition()))(2)); + } + + //################################### + // Prepare a track + //################################### + for(Int_t hit = 0; hit < fHitsMaximum; hit++) fHitList[hit]=0; // reset the current-track'hits list + + hitFirst->SetFound(1); + fHitList[0] = hitFirst; + fHits = 1 ; + + //################################### + // BUILDING A PRE-TRACK + //################################### + if(fDebugTracker) cout << info4 << "-> Creating the pre-track # " << fTracksN+1 << endl; + if(fDebugTracker) cout << info4 << "-----------------"<< endl; + if(fDebugTracker) cout << info4 << "- Pre-Track # "<< fTracksN+1 << " -" << endl; + if(fDebugTracker) cout << info4 << "-----------------"<< endl; + + //----------------------------------------------------------------------------- + // 1) Pre-Track made with 1 hit, perpendicular the current plane (the first one !) + //----------------------------------------------------------------------------- + if( fDebugTracker) cout << info4 << "-> Computing the pre-track # " << fTracksN+1 << " (perpendicular to the plane)..." << endl ; + aTrack.Analyze( -1, fHitList, fHits, tPlaneResolution); + if( fDebugTracker) cout << info4 ; + if( fDebugTracker) printf("-> Pre-track # %d made with %d hit : origin (x=%.1f, y=%.1f, z=%.1f)um and slope (%.1f, %.1f, %.1f) in tracker frame\n",\ + fTracksN+1, aTrack.GetHitsNumber(),\ + aTrack.GetLinearFit().GetOrigin()(0), aTrack.GetLinearFit().GetOrigin()(1), aTrack.GetLinearFit().GetOrigin()(2),\ + aTrack.GetLinearFit().GetSlopeZ()(0), aTrack.GetLinearFit().GetSlopeZ()(1), aTrack.GetLinearFit().GetSlopeZ()(2)); + + //------------------------------------------------------------------------------------------------------------------------------------ + // 2) Trying to add hits to this pre-track : for each other pre-track planes, try to add the nearest hit from the preTrack + //------------------------------------------------------------------------------------------------------------------------------------ + if(fDebugTracker) cout << info4 << "-> Trying to add hits to this pre-track # " << fTracksN+1 << " : scanning " << nbPlanesPreTrack-1 << " others pre-track planes" << endl; + for(Int_t iOthersPlanesPreTrack=2 ; iOthersPlanesPreTrack <= nbPlanesPreTrack ; iOthersPlanesPreTrack++) + { + planeCurrentPreTrack = (DPlane*)(fPlaneArray->At(fTrackingOrderPreTrack[iTrackingLine][iOthersPlanesPreTrack])); + nbHitsCurrentPlanePreTrack = planeCurrentPreTrack->GetHitsN(); + if(fDebugTracker) cout << info5 << "-> Scanning pre-track plane " << (iOthersPlanesPreTrack) << "/" << (nbPlanesPreTrack) << " : #" ; + if(fDebugTracker) cout << fTrackingOrderPreTrack[iTrackingLine][iOthersPlanesPreTrack]+1 << " " << planeCurrentPreTrack->GetPlanePurpose() ; + if(fDebugTracker) cout << " with " << nbHitsCurrentPlanePreTrack << " hits" << endl; + + aCandidateHitInThisPlane=kFALSE; + for( Int_t iHit=1; iHit <= nbHitsCurrentPlanePreTrack; iHit++ ) + { + aHit = planeCurrentPreTrack->GetHit(iHit); + if(fDebugTracker) cout << info6 << "-> Hit number " << aHit->GetNumber() << "/" << nbHitsCurrentPlanePreTrack << endl ; + + if( aHit->GetFound()==kTRUE ) + { + if(fDebugTracker) cout << info7 << "-> Is ever associated to a track, skip it." << endl ; + continue; + } + + isFromPreviousEvent = aHit->GetIsFromPreviousEvent(); + if(isFromPreviousEvent) + { + if(fDebugTracker) cout << info7 << "-> Is memorized from last event" << endl; + switch(PreTrackHitsTypeUsed) + { + case 0 : + if(fDebugTracker) cout << info8 << "-> All hits can be used, keep it" << endl; + break; + case 1 : + if(fDebugTracker) cout << info8 << "-> Only new hits can be used, skip it" << endl; + continue; + break; + case 2 : + if(fDebugTracker) cout << info8 << "-> Only memorized hits can be used, keep it" << endl; + break; + default : + cout << " There is a hit selection bug in code !!!" << endl; + break; + } + } + else + { + if(fDebugTracker) cout << info7 << "-> Is NOT memorized from last event = is a new hit" << endl; + switch(PreTrackHitsTypeUsed) + { + case 0 : + if(fDebugTracker) cout << info8 << "-> All hits can be used, keep it" << endl; + break; + case 1 : + if(fDebugTracker) cout << info8 << "-> Only new hits can be used, keep it" << endl; + break; + case 2 : + if(fDebugTracker) cout << info8 << "-> Only memorized hits can be used, skip it" << endl; + continue; + break; + default : + cout << " There is a hit selection bug in code !!!" << endl; + break; + } + } + + distance = (fHitList[0])->Distance( aHit); //TODO Good distance ? + if (distance>PreTrackHitsMaxDist) + { + if(fDebugTracker) printf("%s-> Is at %e.0 um from 1st hit, too far away (> %e.0 um), skip it.\n",\ + info7.Data(), distance, PreTrackHitsMaxDist); + continue; + } + + if(! aCandidateHitInThisPlane) + { + if(fDebugTracker) printf("%s-> Is the first candidate, at %e.0 um from 1st hit, in search radius (<= %e.0 um)\n",\ + info7.Data(), distance, PreTrackHitsMaxDist); + fHitList[fHits] = aHit; + aCandidateHitInThisPlane=kTRUE; + bestDistance=distance; + } + else + { + if(fDebugTracker) printf("%s-> Is a new candidate, at %e.0 um from 1st hit, in search radius (<= %e.0 um), ",\ + info7.Data(), distance, PreTrackHitsMaxDist); + if(distance %e.0 um), is skipped\n",distance,bestDistance); + } + } + } + + if(aCandidateHitInThisPlane) + { + fHitList[fHits]->SetFound(); + fHits++; + if(fDebugTracker) printf("%s-> A hit is considered in this plane, and associated to the pre-track # %d, wich is now made with %d hits (but not re-computed !)\n",\ + info6.Data(), fTracksN+1, fHits); + } + else + { + if(fDebugTracker) printf("%s-> No hit was found in this plane, pre-track # %d is still made with %d hits\n",\ + info6.Data(), fTracksN+1,fHits); + } + } + if(fDebugTracker) cout << info5 << "-> All other pre-track planes was scanned " << endl ; + + //------------------------------------------------------------------------------------------------------------------------------------ + // 3) Trying to build the pre-track : + //------------------------------------------------------------------------------------------------------------------------------------ + if(fDebugTracker) cout << info4 << "-> Trying to build pre-track # " << fTracksN+1 << " with " << fHits << " hits" << endl ; + + if (fHits>=PreTrackHitsNbMinimum) + { + if(fDebugTracker) printf("%s-> Enought hits (%d >= %d) to build the pre-track # %d : computing slope ... \n",\ + info6.Data(),fHits,PreTrackHitsNbMinimum,fTracksN+1); + + if (fTrack[fTracksN]->Analyze( fTracksN+1, fHitList, fHits, tPlaneResolution)) + { + //This pre-track is deleted -if needed- during the full-track processing + if(fDebugTracker) printf("%s-> Pre-track # %d is built with %d hits\n",info6.Data(), fTracksN+1,fHits); + } + else + { + if(fDebugTracker) printf("%s-> Pre-track # %d building crashed !!!!!\n",info6.Data(), fTracksN+1); + for (Int_t iHit=0; iHitSetFound(0); + if(fDebugTracker) printf("%s-> The %d hits are set unfounded.\n",info7.Data(), fHits); + continue; + } + } + else + { + if(fDebugTracker) printf("%s-> Not enought hits (%d < %d) to build the pre-track # %d \n",\ + info6.Data(),fHits,PreTrackHitsNbMinimum,fTracksN+1); + for (Int_t iHit=0; iHitSetFound(0); + if(fDebugTracker) printf("%s-> The %d hits are set unfounded.\n",info7.Data(), fHits); + continue; + } + + //------------------------------------------------------------------------------------------------------------------------------------ + // 4) Trying to extend the pre-track : + //------------------------------------------------------------------------------------------------------------------------------------ + nbPreTrackHitsCurrentTrack = fHits ; + nbExtTrackHitsCurrentTrack = 0 ; + + if(fDebugTracker) cout << info4 << "-> Trying to extend pre-track # " << fTracksN+1 << " with " << nbPreTrackHitsCurrentTrack << " pre-track hits" << endl ; + if(fDebugTracker) cout << info4 << "-----------------"<< endl; + if(fDebugTracker) cout << info4 << "- Ext-Track # "<< fTracksN+1 << " -" << endl; + if(fDebugTracker) cout << info4 << "-----------------"<< endl; + + //-------------------------- + // 4.1) For each ext-track planes, try to add the nearest hit from the preTrack + //-------------------------- + if(fDebugTracker) cout << info4 << "-> Trying to add hits to pre-track # " << fTracksN+1 << " scanning " << nbPlanesExtTrack << " ext-track planes" << endl ; + + for(Int_t iPlanesExtTrack=1 ; iPlanesExtTrack <= nbPlanesExtTrack ; iPlanesExtTrack++) + { + planeCurrentExtTrack = (DPlane*)(fPlaneArray->At(fTrackingOrderExtTrack[iTrackingLine][iPlanesExtTrack])); + nbHitsCurrentPlaneExtTrack = planeCurrentExtTrack->GetHitsN(); + if(fDebugTracker) cout << info5 << "-> Scanning ext-track plane " << iPlanesExtTrack << "/" << nbPlanesExtTrack << " : #"; + if(fDebugTracker) cout << fTrackingOrderExtTrack[iTrackingLine][iPlanesExtTrack]+1 << " " << planeCurrentExtTrack->GetPlanePurpose(); + if(fDebugTracker) cout << " with " << nbHitsCurrentPlaneExtTrack<< " hits" << endl; + + intersection = planeCurrentExtTrack->Intersection(fTrack[fTracksN]); + if(fDebugTracker) printf("%s-> Track # %d intersection with this plane at z=%.1f is (u=%.1f, v=%.1f, w=%.1f)um in plane frame, (x=%.1f, y=%.1f, z=%.1f)um in tracker frame\n",\ + info6.Data(), fTracksN+1,\ + planeCurrentExtTrack->GetPosition()(2), intersection(0), intersection(1), intersection(2),\ + planeCurrentExtTrack->PlaneToTracker(intersection)(0),planeCurrentExtTrack->PlaneToTracker(intersection)(1),planeCurrentExtTrack->PlaneToTracker(intersection)(2)); + + aCandidateHitInThisPlane=kFALSE; + for( Int_t iHit=1; iHit <= nbHitsCurrentPlaneExtTrack; iHit++ ) + { + aHit = planeCurrentExtTrack->GetHit(iHit); + if(fDebugTracker) cout << info6 << "-> Hit number " << aHit->GetNumber() << "/" << nbHitsCurrentPlaneExtTrack << " " ; + + if( aHit->GetFound()==kTRUE ) + { + if(fDebugTracker) cout << "is ever associated, skip it." << endl ; + continue; + } + + isFromPreviousEvent = aHit->GetIsFromPreviousEvent(); + if(isFromPreviousEvent) + { + if(fDebugTracker) cout << info7 << "-> Is memorized from last event" << endl; + switch(ExtTrackHitsTypeUsed) + { + case 0 : + if(fDebugTracker) cout << info8 << "-> All hits can be used, keep it" << endl; + break; + case 1 : + if(fDebugTracker) cout << info8 << "-> Only new hits can be used, skip it" << endl; + continue; + break; + case 2 : + if(fDebugTracker) cout << info8 << "-> Only memorized hits can be used, keep it" << endl; + break; + default : + cout << " There is a hit selection bug in code !!!" << endl; + break; + } + } + else + { + if(fDebugTracker) cout << info7 << "-> Is NOT memorized from last event = is a new hit" << endl; + switch(ExtTrackHitsTypeUsed) + { + case 0 : + if(fDebugTracker) cout << info8 << "-> All hits can be used, keep it" << endl; + break; + case 1 : + if(fDebugTracker) cout << info8 << "-> Only new hits can be used, keep it" << endl; + break; + case 2 : + if(fDebugTracker) cout << info8 << "-> Only memorized hits can be used, skip it" << endl; + continue; + break; + default : + cout << " There is a hit selection bug in code !!!" << endl; + break; + } + } + + distance = aHit->Distance( &intersection);//TODO Good distance ? + if (distance>ExtTrackHitsMaxDist) + { + if(fDebugTracker) printf("is at %e.0 um from intersection, too far away (> %e.0 um), skip it.\n",distance,ExtTrackHitsMaxDist); + continue; + } + + if(! aCandidateHitInThisPlane) + { + if(fDebugTracker) printf("is the first candidate, at %e.0 um from intersection, in search radius (<= %e.0 um)\n",distance,ExtTrackHitsMaxDist); + fHitList[fHits] = aHit; + aCandidateHitInThisPlane=kTRUE; + bestDistance=distance; + } + else + { + if(fDebugTracker) printf("is a new candidate, at %e.0 um from intersection, in search radius (<= %e.0 um), ",distance,ExtTrackHitsMaxDist); + if(distance %e.0 um), is skipped\n",distance,bestDistance); + } + } + } + + if(aCandidateHitInThisPlane) + { + fHitList[fHits]->SetFound(); + fHits++; + nbExtTrackHitsCurrentTrack++; + if(fDebugTracker) printf("%s-> A hit is considered in this plane, and associated to the ext-track # %d, wich is now made with %d hits : %d pre-hit(s) and %d ext-hit(s) (but not re-computed !)\n",\ + info6.Data(), fTracksN+1, fHits, nbPreTrackHitsCurrentTrack, nbExtTrackHitsCurrentTrack); + } + else + { + if(fDebugTracker) printf("%s-> No hit was found in this plane, ext-track # %d is still made with %d hits : %d pre-hit(s) and %d ext-hit(s)\n",\ + info6.Data(), fTracksN+1,fHits, nbPreTrackHitsCurrentTrack, nbExtTrackHitsCurrentTrack); + } + } + if(fDebugTracker) cout << info5 << "-> All ext-track planes was scanned " << endl ; + + //-------------------------- + // 4.2) Trying to build a full track + //-------------------------- + if(fDebugTracker) cout << info4 << "-> Trying to build full-track # " << fTracksN+1 << " with " << fHits << " hits " ; + if(fDebugTracker) cout << "( " << nbPreTrackHitsCurrentTrack << " + " << nbExtTrackHitsCurrentTrack << " ) " << endl ; + if(fDebugTracker) cout << info4 << "------------------"<< endl; + if(fDebugTracker) cout << info4 << "- Full-Track # "<< fTracksN+1 << " -" << endl; + if(fDebugTracker) cout << info4 << "------------------"<< endl; + + if (fHits>=FullTrackHitsNbMinimum && nbExtTrackHitsCurrentTrack>=ExtTrackHitsNbMinimum) + { + if(fDebugTracker) printf("%s-> Enought ext-hits (%d >= %d) AND total hits (%d >= %d) to build the full-track # %d : computing slope ... \n",\ + info4.Data(), nbExtTrackHitsCurrentTrack, ExtTrackHitsNbMinimum, fHits,FullTrackHitsNbMinimum,fTracksN+1); + + if (fTrack[fTracksN]->Analyze( fTracksN+1, fHitList, fHits, tPlaneResolution)) + { + fTracksN++; + fTrackCount[0] += 1; + fTrackCount[fHits] += 1; + fTrackCountPerPlane[0] += 1; + for ( Int_t iHit=0; iHitGetPlane()->GetPlaneNumber() ] += 1; + if(fDebugTracker) printf("%s-> Full-track # %d is built with %d hits ( %d + %d )\n\n\n",\ + info5.Data(), fTracksN, fHits, nbPreTrackHitsCurrentTrack, nbExtTrackHitsCurrentTrack); + } + else + { + if(fDebugTracker) printf("%s-> Full-track # %d building crashed !!!!!\n",info5.Data(), fTracksN+1); + for (Int_t iHit=0; iHitSetFound(0); + if(fDebugTracker) printf("%s-> The %d hits are set unfounded, track # %d is deleted.\n\n\n",\ + info6.Data(), fHits, fTracksN+1); + fTrack[fTracksN]->Reset(); + continue; + } + } + else + { + if (fHits Not enought total hits (%d < %d) to build the full-track # %d\n",\ + info5.Data(), fHits,FullTrackHitsNbMinimum, fTracksN+1); + } + else if (nbExtTrackHitsCurrentTrack Not enought ext-hits (%d < %d) to build the ext-track # %d (and so the full-track)\n",\ + info5.Data(), nbExtTrackHitsCurrentTrack, ExtTrackHitsNbMinimum, fTracksN+1); + } + else + { + printf(" !!! BUG !!! see code ... \n"); + } + + for (Int_t iHit=0; iHitSetFound(0); + if(fDebugTracker) printf("%s-> The %d hits are set unfounded, track # %d is deleted.\n\n\n",\ + info6.Data(), fHits, fTracksN+1); + fTrack[fTracksN]->Reset(); + continue; + } + } + + + if(fDebugTracker) cout << info2 << "***------------------------------***" << endl; + if(fDebugTracker) cout << info2 << "*** Tracking Line # " << iTrackingLine+1 << "/" << fTrackingOrderLines << " finished ***" << endl; + if(fDebugTracker) cout << info2 << "***------------------------------***" << endl << endl ; + } + + if(fDebugTracker) cout << info1 << "*-*-*-*-*-*-*-*-*-*-*-*-*-*" << endl; + if(fDebugTracker) cout << info1 << "*-* Pass # " << iTrackingPass+1 << "/" << fTrackingPass << " finished *-*" << endl; + if(fDebugTracker) cout << info1 << "*-*-*-*-*-*-*-*-*-*-*-*-*-*" << endl << endl ; + + } + + if(fDebugTracker) printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* \n"); + if(fDebugTracker) printf("*-*-* Tracking with DTracker::find_tracks_2_ivi() finished *-*-* \n"); + if(fDebugTracker) printf("*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-* \n"); + +} + +//_____________________________________________________________________________ +// +void DTracker::find_tracks_and_vertex(){ + + // Try to make a track with all hits of the "seed" reference planes (status=0). + // For each of such hits, a track is extrapolated to the other planes and + // the nearest hit within a search window is added to the track. If no hit + // lies within the search window, the plane is skipped. + // When all planes have been searched, the track is fitted with all its associated hits. + // + // Note that currently the track extrapolation is done with no slope, + // that means perpendicularly with respect to the seed plane. + // The code to update the slope with each added hits exists but yielded + // slightly worst results in SPS beam test (120 GeV pions). So this second + // method is still not used. You can however choose it by changing the + /// commented lines at the "IMPORTANT CHOICE" comments in the code. + // + // Planes are used in the tracking depending on their status + // and the value of the Tracker Align Status. The rule is that the plane + // is included if PlaneStatus<=TrackerAlignStatus. + // + // This method has been completely reshaped to allow for multi-track event + // and best hit selection. + // + // + // JB 2009/05/22 + // Modified: JB 2009/08/25, track numbering + // Modified: JB 2009/09/01, no more update of fRequiredHits + // Modified: JB 2011/03/14, use several sensors for track seed + // Modified: JB 2011/07/25, search the next hit along the temporary track path + // Modified: SS 2011/10/26, rollback of the calculation of the hit-track distance + // Modified: JB 2012/04/02, fix in condition to include planes depending on alignment + // Modified: JB 2012/09/07, new condition on firstHit + +/* + NodeData* data = new NodeData(0,1,1.235); // nodeNumber, hitNumber, Chi2. + + TreeNode* T = new TreeNode(); + T->SetData(data); + + NodeData* data_1 = new NodeData(1,1,2.2365); + T->AddChildren(1, data_1); // hitNumber, data :) + + TreeNode* T1_1 = T->GetNode(1); + + NodeData* data_1_1 = new NodeData(1,2,3.215); + T->AddChildren(2, data_1_1); + + TreeNode* T1_2 = T->GetNode(2); + + std::cout<<" Node Number = "<GetData()->GetNodeNumber() << " HitNumber = " << T->GetData()->GetHitNumber() + <<" Chi2 = "<< T->GetData()->GetChi2() << std::endl; + + std::cout<<" Node Number = "<GetNode(1)->GetData()->GetNodeNumber() << " HitNumber = " << T->GetNode(1)->GetData()->GetHitNumber() + <<" Chi2 = "<< T->GetNode(1)->GetData()->GetChi2() << std::endl; + + std::cout<<" Node Number = "<GetNode(2)->GetData()->GetNodeNumber() << " HitNumber = " << T->GetNode(2)->GetData()->GetHitNumber() + <<" Chi2 = "<< T->GetNode(2)->GetData()->GetChi2() << std::endl; +*/ + + DPlane *aPlane; + DHit *aHit; + DTrack aTrack( fPlanesN); + aTrack.SetDebug( fDebugTracker); + DR3 extrapolation; + Int_t oldfHits = 0; + DPlane *oldPlane; + Double_t minDistance = 1.e9; + Double_t aDistance, distanceWithoutSlope, distancewithSlope; + DHit *bestHit=0; + Float_t tPlaneResolution=fc->GetTrackerPar().Resolution; + DR3 hitPosition; // usefull for temporary computation check + + // fRequiredHits is no longer updated here, JB 2009/09/01 + //if( fDebugTracker) printf(" DTracker::find_tracks %d hits required, alignStatus %d\n", fRequiredHits, fAlignmentStatus); + + // Reset counters and arrays + fTracksN = 0; + for(Int_t trk = 1; trk <= fTracksMaximum; trk++) fTrack[trk-1]->Reset(); + + // ================== + // Loop on reference planes usable for track seed + DPlane *firstPlane; + for( Int_t iseed=0; iseedGetPlaneNumber(), firstPlane->GetHitsN()); + + //std::vector vectorTree; + + for( Int_t iFirstHit=1; iFirstHit<=firstPlane->GetHitsN() ; iFirstHit++) { // loop on first hits, pay attention that hit numbering start at 1 + if( fTracksN >= fTracksMaximum ) break; // if max track number reach, stop + fHits = 0; + oldfHits = 0; + oldPlane = firstPlane; + for(Int_t hit = 0; hit < fHitsMaximum; hit++) fHitList[hit]=0; + //if(fDebugTracker>1) cout << " DTracker::find_tracks Hit list reseted" << endl; + + // test if the hit was associated before, + // this test allows to manage several firstPlanes + // JB 2012/09/07 + if( firstPlane->GetHit( iFirstHit )->GetFound() ) continue; + + fHitList[fHits] = firstPlane->GetHit( iFirstHit ); + fHitList[fHits]->SetFound(); // not really needed, because never tested in the following + //if( fDebugTracker) printf(" DTracker::find_tracks hit %d number %d from plane %d found %d at (%.1f, %.1f)\n", fHits, fHitList[fHits]->GetNumber(), firstPlane->GetPlaneNumber(), fHitList[fHits]->GetFound(), fHitList[fHits]->GetPositionUhit(), fHitList[fHits]->GetPositionVhit()); + +/* + NodeData* data0 = new NodeData(0,1,0); // nodeNumber, hitNumber, Chi2. + TreeNode* T0 = new TreeNode(); + T0->SetData(data); +*/ + + fHits++; + + // ================== + // Loop on all planes to find a matching hit in them + // exclude the first plane + // always exclude DUT + // exclude Variable refenreces if alignement is not done yet + for( Int_t iPlane=0; iPlane< fPlanesN; iPlane++ ) { // loop on planes + aPlane = (DPlane*)fPlaneArray->At(iPlane); + + // check plane is valid + if( aPlane->GetPlaneNumber() != firstPlane->GetPlaneNumber() + && !( aPlane->GetStatus()==0) // not mandatory but could be faster, JB 2011/03/14. + && ( aPlane->GetStatus()<=fAlignmentStatus ) // condition changed, JB 2012/04/02 + && !( aPlane->GetStatus()==3 ) ) { // if valid plane + //if(fDebugTracker>1) printf(" DTracker::find_tracks checking plane %d with %d hits\n", aPlane->GetPlaneNumber(), aPlane->GetHitsN()); + + // find the extrapolation of the current track to this plane: + // if the number of hits in the track has changed -> recompute the track, + // if the plane has changed -> recompute the intersection. + // JB 2011/07/25 + if( fHits != oldfHits) { + aTrack.Analyze( -1, fHitList, fHits, tPlaneResolution); + //if( fDebugTracker) printf(" track origin (%.1f, %.1f, %.1f) slope (%.1f, %.1f, %.1f)\n", aTrack.GetLinearFit().GetOrigin()(0), aTrack.GetLinearFit().GetOrigin()(1), aTrack.GetLinearFit().GetOrigin()(2), aTrack.GetLinearFit().GetSlopeZ()(0), aTrack.GetLinearFit().GetSlopeZ()(1), aTrack.GetLinearFit().GetSlopeZ()(2)); + oldfHits = fHits; + } + if( oldPlane->GetPlaneNumber() != aPlane->GetPlaneNumber() ) { + extrapolation = aPlane->Intersection( &aTrack); //aTrack.Intersection( aPlane); + //if( fDebugTracker) printf(" track extrapolation at plane %d (z=%.1f) uvw= (%.1f, %.1f, %.1f)\n", aPlane->GetPlaneNumber(), aPlane->GetPosition()(2), extrapolation(0), extrapolation(1), extrapolation(2)); + oldPlane = aPlane; + } + + // loop on all hits of this plane and keep the nearest one + minDistance = 1.e9; + aDistance=distanceWithoutSlope=distancewithSlope=1.e9; + bestHit=0; + for( Int_t iHit=1; iHit <= aPlane->GetHitsN(); iHit++ ) { // loop on plane hits + aHit = aPlane->GetHit( iHit); + if( fDebugTracker>1) printf(" DTracker::find_tracks trying for hit %d number %d from plane %d found %d\n",fHits, aHit->GetNumber(), aPlane->GetPlaneNumber(), aHit->GetFound()); + if( aHit->GetFound()==kTRUE ) continue; // skip hit already found + + distanceWithoutSlope = (fHitList[0])->Distance( aHit); + distancewithSlope = aHit->Distance( &extrapolation); // JB 2011/07/25 + + //-------- IMPORTANT CHOICE for track extrapolation + // switch the value of aDistance between distanceWithoutSlope or distanceWithSlope + // SS 2011/10/26 - rollback to the method with no slope. + aDistance = distancewithSlope; + //----------------------- + + //if( fDebugTracker>1) { + // hitPosition.SetValue( *(fHitList[0]->GetPosition())); + // hitPosition = fHitList[0]->GetPlane()->PlaneToTracker( hitPosition); + // hitPosition = aPlane->TrackerToPlane( hitPosition); + // printf("#hits=%d (uvw) hit0(%.1f,%.1f) extra(%.1f,%.1f) newHit(%.1f,%.1f) distWOslope=%.1f, distWslope=%.1f (lim %f)\n", fHits, hitPosition(0), hitPosition(1), extrapolation(0), extrapolation(1), aHit->GetPositionUhit(), aHit->GetPositionVhit(), distanceWithoutSlope, distancewithSlope, fSearchHitDistance); + // printf(" at (%.1f, %.1f)+(%.1f, %.1f)-(%.1f, %.1f)=(%.1f, %.1f) dist=%.1f %f\n", aHit->GetPositionUhit(), aHit->GetPositionVhit(), aHit->GetPlane()->GetPosition()(0), aHit->GetPlane()->GetPosition()(1), (fHitList[0])->GetPlane()->GetPosition()(0), (fHitList[0])->GetPlane()->GetPosition()(1), (aHit->GetPositionUhit())+(aHit->GetPlane()->GetPosition()(0))-((fHitList[0])->GetPlane()->GetPosition()(0))-((fHitList[0])->GetPositionUhit()), (aHit->GetPositionVhit())+(aHit->GetPlane()->GetPosition()(1))-((fHitList[0])->GetPlane()->GetPosition()(1))-((fHitList[0])->GetPositionVhit()), aDistance, fSearchHitDistance); + //} + + if( aDistance < fSearchHitDistance && aDistance < minDistance ) { + minDistance = aDistance; + bestHit = aHit; + } + } // end loop on plane hits + + // if a hit has been found, add the hit + if( bestHit ) { + fHitList[fHits] = bestHit; + fHitList[fHits]->SetFound(); + //if( fDebugTracker) printf(" DTracker::find_tracks hit %d selected from plane %d hit #%d found %d\n", fHits, aPlane->GetPlaneNumber(), fHitList[fHits]->GetNumber(), fHitList[fHits]->GetFound()); + fHits++; + } + + } // end if valid plane + + } // end loop on planes + + // We have now a list of hits + // if they are numerous enough, try to make the track + //if( fDebugTracker) printf(" DTracker::find_tracks trying with %d hits over %d required, alignStatus %d\n", fHits, fRequiredHits, fAlignmentStatus); + if (fHits >= fRequiredHits) { + // *************************************************************** + // fTracksN+1 to start track numbering at 1, JB 2009/08/25 + // Increment counters over all events, JB 2009/09/08 + if (fTrack[fTracksN]->Analyze( fTracksN+1, fHitList, fHits, tPlaneResolution)) { + fTrackCount[0] += 1; + fTrackCount[fHits] += 1; + fTrackCountPerPlane[0] += 1; + for ( Int_t iHit=0; iHitGetPlane()->GetPlaneNumber() ] += 1; + } + fTracksN++; + } + // if track not selected, free all hits + // JB 2011/03/14 + else { + for( Int_t iHit=0; iHitSetFound(kFALSE); + //if(fDebugTracker) printf("DTracker::find_track set hit[%d] # %d of plane %d free.\n", iHit, fHitList[iHit]->GetNumber(), fHitList[iHit]->GetPlane()->GetPlaneNumber()); + } + } + // *************************************************************** + //if( fDebugTracker) printf(" %d tracks found\n", fTracksN); + } + + } // end loop on first hits + + } // end loop on seed planes + +} + + +//_____________________________________________________________________________ +// +void DTracker::find_tracks_withStrips(){ + + // Try to make a track with the most significant hit + // of each of the reference strip detectors. + // Most significant means with the highest pulseheight on the seed pixel. + // Only one track is built ! + // + // Planes are used in the tracking depending on their status + // and the value of the Tracker Align Status. The rule is that the plane + // is included if PlaneStatus<=TrackerAlignStatus. + // + // + // Copied from MAF, JB 2012/08/23 + // Modified: JB 2012/08/27 to add condition on hit presence for each plane + + DPlane *aPlane; + //DHit *aHit; + DTrack aTrack( fPlanesN); + aTrack.SetDebug( fDebugTracker); + Float_t tPlaneResolution=fc->GetTrackerPar().Resolution; + + // fRequiredHits is no longer updated here, JB 2009/09/01 + if( fDebugTracker) printf(" DTracker::find_tracks WITH STRIPS %d hits required, alignStatus %d\n", fRequiredHits, fAlignmentStatus); + + // Reset counters and arrays + fTracksN = 0; + for(Int_t trk = 1; trk <= fTracksMaximum; trk++) fTrack[trk-1]->Reset(); + fHits = 0; + + // ================== + // Loop on all planes to find a matching hit in them + // exclude DUT + // exclude planed not aligned + for( Int_t iPlane=0; iPlane< fPlanesN; iPlane++ ) { // loop on planes + aPlane = (DPlane*)fPlaneArray->At(iPlane); + + // check plane is valid + if( aPlane->GetStatus()<=fAlignmentStatus + && aPlane->GetStatus()!=3 + && (fAlignmentStatus>=2 || aPlane->GetHitsN()==1) // use single-hit event when aligning, JB 2012/10/29 --> condition removed JB 2013/08/19 + ) { // if valid plane + if(fDebugTracker>1) printf(" DTracker::find_tracks checking plane %d with %d hits\n", aPlane->GetPlaneNumber(), aPlane->GetHitsN()); + if( aPlane->GetHitsN() > 0 ) { // if a hit is there, JB 2012/08/27 + fHitList[fHits] = aPlane->GetPrincipalHit(); + fHitList[fHits]->SetFound(); + if( fDebugTracker) printf(" DTracker::find_tracks hit %d selected from plane %d hit #%d found %d\n", fHits, aPlane->GetPlaneNumber(), fHitList[fHits]->GetNumber(), fHitList[fHits]->GetFound()); + fHits++; + } // end if a hit is there + } // end if valid plane + + } // end loop on planes + + // We have now a list of hits + // if they are numerous enough, try to make the track + if( fDebugTracker) printf(" DTracker::find_tracks trying with %d hits over %d required, alignStatus %d\n", fHits, fRequiredHits, fAlignmentStatus); + if (fHits >= fRequiredHits) { + // *************************************************************** + // fTracksN+1 to start track numbering at 1, JB 2009/08/25 + // Increment counters over all events, JB 2009/09/08 + if (fTrack[fTracksN]->Analyze( fTracksN+1, fHitList, fHits, tPlaneResolution)) { + fTrackCount[0] += 1; + fTrackCount[fHits] += 1; + fTrackCountPerPlane[0] += 1; + for ( Int_t iHit=0; iHitGetPlane()->GetPlaneNumber() ] += 1; + } + fTracksN++; + } + // if track not selected, free all hits + // JB 2011/03/14 + else { + for( Int_t iHit=0; iHitSetFound(kFALSE); + if(fDebugTracker) printf("DTracker::find_track set hit[%d] # %d of plane %d free.\n", iHit, fHitList[iHit]->GetNumber(), fHitList[iHit]->GetPlane()->GetPlaneNumber()); + } + } + // *************************************************************** + if( fDebugTracker) printf(" %d tracks found\n", fTracksN); + } + +} + + +//_____________________________________________________________________________ +// +void DTracker::SetPlanesForSubTrack(Int_t nPlanes, Int_t *planeIds) { + + // Set the list of plane IDs to be used for fitting subtrack + // technicaly also book memory for the necessary array + // + // JB 2015/08/21 + + fSubTrackPlanesN = nPlanes; + + if ( fSubTrackPlanesN>0 ) { + if ( fSubTrackPlaneIds==NULL ) { + fSubTrackPlaneIds = new Int_t[fSubTrackPlanesN]; + } + // reninit anyway the plane IDs, in case they changed + for (Int_t iPlane=0; iPlaneGetNumber(), nHits, fSubTrackPlanesN); + + // First check a subset of planes has been specified + if( fSubTrackPlanesN<=0 ) { + printf("WARNING in DTracker, MakeSubTrack called when no (%d) subset of planes indicated -> NOP\n", fSubTrackPlanesN); + return; + } + + // Trim the original hit list + DHit **hitSubset = new DHit*[fSubTrackPlanesN]; + Int_t nHitsSelected = 0; + + for ( Int_t iHit=0; iHitGetPlane()->GetPlaneNumber() == fSubTrackPlaneIds[iPlane] ) { + hitSubset[nHitsSelected] = aHitList[iHit]; + if( fDebugTracker>1 ) printf(" hit %d(in track) or %d(in plane) in specified plane %d -> selected as hit nb %d\n", iHit, hitSubset[nHitsSelected]->GetNumber(), fSubTrackPlaneIds[iPlane], nHitsSelected); + nHitsSelected++; + } + } + } + + // Finally refit the track + Float_t tPlaneResolution=fc->GetTrackerPar().Resolution; + Int_t subtrackNb = aTrack->GetNumber()-1; + fSubTrack[subtrackNb]->Reset(); + + if ( fSubTrack[subtrackNb]->Analyze( aTrack->GetNumber(), hitSubset, nHitsSelected, tPlaneResolution) ) { + if( fDebugTracker ) printf(" subtrack %d successfully fit with %d hits\n", fSubTrack[subtrackNb]->GetNumber(), nHitsSelected); + } + + delete[] hitSubset; // not sure + +} + + +//_____________________________________________________________________________ +// +void DTracker::MakeKalTrack( DTrack *aTrack, DHit** aHitList, Int_t nHits) { + + // Refit a track with Kalman Filter&Smoother, + // Limits of this function(not Kalman Algorithm): + // ! Requires MC simulation parameters! + // ! Only deal with tracks in +z direction + // ! Only estimate for one DUT test (propagate the track to DUT) + // ! nHits >= 2 and hits are in right order (increasing z) + // + // Created QL 2016/05/26 + + if( fDebugTracker) printf("DTracker::MakeKalTrack for track %d from %d hits.\n", aTrack->GetNumber(), nHits); + + string particle = fc->GetTrackerPar().BeamType.Data(); + Double_t momentum = fc->GetTrackerPar().BeamMomentum; + //string MediumMaterial = fc->GetTrackerPar().MediumMaterial.Data(); + DGlobalTools aTool; + Double_t mass = aTool.GetMass(particle); + Double_t charge = aTool.GetCharge(particle); + if (nHits < 2||momentum <= 0||mass <= 0||charge<=0){ + printf("DTracker::MakeKalTrack: The results of Kal are not guaranteed! KalmanFilter exit\n"); + return ; + } + + if ( fHitList[0]->GetPlane()->GetAnalysisMode() < 2 ){ // if not pixels + printf("DTracker::MakeKalTrack: Only implemented for pixels!\n"); + return ;// Quit + } + + fDebugTracker = aHitList[0]->GetDebug(); // aHitList is always fHitList! + if(fDebugTracker) printf("DTracker::MakeKalTrack: track number %d\n", aTrack->GetNumber()); + + Double_t energy = TMath::Sqrt(mass*mass + momentum*momentum); + + //Prepare TList of Hits and Planes(Scatter Plane) + TObjArray aPlaneArray = *fPlaneArray; + aPlaneArray.Sort(); + TList aHitTList; + for (Int_t i = 0; i < nHits; i++) + aHitTList.Add(aHitList[i]); + aHitTList.Sort(); + if(fDebugTracker){ + aHitTList.Print(); + aPlaneArray.Print(); + } + + Int_t planeStatus, planeReadout; + + DPrecAlign *hitAlignment; + DR3 aPosition; + DR3 tLineFitOrigin; // origin in the tracker system + DR3 tLineFitSlope; // slope along z-axis in tracker system + double resolutionU = fHitList[0]->GetResolutionUhit(); + double resolutionV = fHitList[0]->GetResolutionVhit(); + double sigmaMS = fHitList[0]->GetPlane()->GetSigmaThetaMS(); + Double_t meas[2] = {0,0}; // measurements in x(U) and y(V) + Double_t measCov[4] = {0,0,0,0}; // measurement covariance + + Double_t thickness = 0; + Double_t x0Layer = 0; + //Kalman filter + MKalmanFilter myKF(mass, energy, charge); + myKF.setSmootherEnabled(kTRUE); + Bool_t isSmootherUsed = myKF.isSmootherEnabled();// switch to smoother or not! + + //init + hitAlignment = fHitList[0]->GetPlane()->GetPrecAlignment(); + aPosition = hitAlignment->TransformHitToTracker( *(fHitList[0]->GetPosition()) ); + DLine* preLineFit = aTrack->GetLinearFit2(); + DR3 aSlopeZ = preLineFit->GetSlopeZ(); + Double_t tKFpar[4] = {aPosition(0), aSlopeZ(0), aPosition(1), aSlopeZ(1)};// kal initializer + //Double_t tKFpar[4] = {aPosition(0), 0, aPosition(1), 0};// kal initializer + //Double_t tKFpar[4] = {0, 0, aPosition(1), 0};// kal initializer + Double_t tKFcov22 = /*8e-7;*/sigmaMS*sigmaMS; + Double_t tKFcov11 = resolutionU*resolutionU + tKFcov22*pow(aPosition(2),2);//Only for my simulation! + Double_t tKFcov33 = resolutionV*resolutionV + tKFcov22*pow(aPosition(2),2);//Only for my simulation! + Double_t tKFcov12 = 0;//(tKFcov22) * aPosition(2); + tKFcov22 = 8e-7; + //Double_t tKFcov[16] = { + // tKFcov11, sigmaMS*sigmaMS*aPosition(2), 0, 0, + // sigmaMS*sigmaMS*aPosition(2),sigmaMS*sigmaMS , 0,0, + // 0,0,tKFcov33, sigmaMS*sigmaMS*aPosition(2), + // 0,0,sigmaMS*sigmaMS*aPosition(2),sigmaMS*sigmaMS}; // Kal initializer // 8e-7 + //Double_t tKFcov[16] = { + // tKFcov11, 0, 0, 0, + // 0,sigmaMS*sigmaMS , 0,0, + // 0,0,tKFcov33, sigmaMS*sigmaMS*aPosition(2), + // 0,0,sigmaMS*sigmaMS*aPosition(2),sigmaMS*sigmaMS}; // Kal initializer // 8e-7 + Double_t tKFcov[16] = { + tKFcov11, tKFcov12, 0, 0, + tKFcov12, tKFcov22, 0, 0, + 0, 0,tKFcov33, tKFcov12, + 0, 0,tKFcov12, tKFcov22}; // Kal initializer // 8e-7 + Double_t zLayer = aPosition(2); // Kal initializer + Double_t z1stLayer = zLayer; + + // kF init + myKF.initKalZParCov(zLayer, tKFpar, tKFcov); // + + DHit *aHit = (DHit*)aHitTList.First(); + DHit *rightHit = NULL; // The closest hit in the right side of DUT + DPlane* aPlane = aHit->GetPlane(); + Int_t FirstPlane = aPlaneArray.IndexOf(aPlane); + Int_t lastPlane = 0; + Int_t iDUT = 999; // Have to be a large value! + for (Int_t pl = 0; pl GetStatus(); + Int_t planeNumber = planeInArr->GetPlaneNumber(); + Int_t planeNumber_pre = 1; + if (pl != 0) + planeNumber_pre = ((DPlane*)aPlaneArray.At(pl-1))->GetPlaneNumber(); + planeReadout = fc->GetPlanePar(planeNumber).Readout; + if (fDebugTracker) cout << "Plane " << planeNumber << " status=" << planeStatus << " readout=" << planeReadout<0&& planeStatus==3) iDUT = pl; + if (pl < FirstPlane) + continue; // start from the plane containing the 1st hit + + aPlane = aHit->GetPlane(); + Int_t iHitPlane = aPlaneArray.IndexOf(aPlane); // iHitPlane changes as aHit does + + // MS related: material before current layer! + //cout << "here?" << endl; + thickness = fc->GetPlanePar(planeNumber_pre).PlaneThickness; + TString material = fc->GetPlanePar(planeNumber_pre).PlaneMaterial; + //cout << "here1?" << endl; + x0Layer = aTool.GetX0(material.Data()); + //cout << "here2?" << endl; + if (fDebugTracker) cout << "Plane " << planeNumber << " Material=" << material << " thickness=" << thickness<0&&planeStatus<3&&iHitPlane==pl){// a plane for tracking + if(iHitPlane>iDUT && rightHit ==NULL){ + rightHit = aHit;// find the closest hit in the right side of DUT + } + hitAlignment = aHit->GetPlane()->GetPrecAlignment(); + aPosition = hitAlignment->TransformHitToTracker( *(aHit->GetPosition()) ); + resolutionU = aHit->GetResolutionUhit(); + resolutionV = aHit->GetResolutionVhit(); + // KF propatete + if(iHitPlane != FirstPlane) + myKF.propagateTo(aPosition(2), thickness, thickness/x0Layer); + + // KF update + if(fDebugTracker){ + printf("DTracker::MakeKalTrack: \n"); + printf("At Z=%f, Propagated ", aPosition(2)); + myKF.print(); + printf("INFO: plane %i, thickness(%f), x0(%f), pos(%f,%f,%f), resolution(%f, %f)\n", ((DPlane*)aPlaneArray.At(iHitPlane))->GetPlaneNumber(), thickness, x0Layer, aPosition(0), aPosition(1), aPosition(2), resolutionU, resolutionV); + + } + meas[0] = aPosition(0); + meas[1] = aPosition(1); + measCov[0] = resolutionU*resolutionU; + measCov[3] = resolutionV*resolutionV; + zLayer = aPosition(2); + myKF.updateAlt(zLayer, meas, measCov); + if(fDebugTracker){ + printf("DTracker::MakeKalTrack: \n"); + printf("At Z=%f, Updated ", zLayer); + myKF.print(); + } + + if (aHit == (DHit*)aHitTList.Last()){ + lastPlane = iHitPlane; + break;// the last hit, end the loop + } + else + aHit = (DHit*)aHitTList.After(aHit);// Go to next hit + } + else{ // plane only for scattering + DPlane* aPlane = (DPlane*)aPlaneArray.At(pl); + hitAlignment = aPlane->GetPrecAlignment(); + DR3 intersectionPos = aPlane->Intersection(aTrack); + intersectionPos = hitAlignment->TransformHitToTracker(intersectionPos); + myKF.propagateTo(intersectionPos(2), thickness, thickness/x0Layer); + if(fDebugTracker){ + printf("At Z=%f, Propagated ", intersectionPos(2)); + myKF.print(); + } + } + + }//end plane loop + if(fDebugTracker){ + printf("DTracker::MakeKalTrack (In Sorted Array) FirstDetLayer:%i, LastDetLayer:%i, DUT:%i\n", FirstPlane, lastPlane, iDUT); + } + + // Extrapolate to DUT + if(iDUT > lastPlane){ + for(Int_t iPlane = lastPlane+1; iPlane<=iDUT; iPlane++){ + aPlane = (DPlane*)aPlaneArray.At(iPlane-1); + Int_t PlN_pre = aPlane->GetPlaneNumber(); + // MS related: + thickness = fc->GetPlanePar(PlN_pre).PlaneThickness; + TString material = fc->GetPlanePar(PlN_pre).PlaneMaterial; + x0Layer = aTool.GetX0(material.Data()); + + aPlane = (DPlane*)aPlaneArray.At(iPlane); + hitAlignment = aPlane->GetPrecAlignment(); + DR3 intersectionPos = aPlane->Intersection(aTrack); + intersectionPos = hitAlignment->TransformHitToTracker(intersectionPos); + myKF.propagateTo(intersectionPos(2), thickness, thickness/x0Layer); + } + } + else if(iDUT < FirstPlane){ + if(isSmootherUsed && myKF.smoothTo(z1stLayer)){ + if(fDebugTracker){ + printf("DTracker::MakeKalTrack: Smoothing finished successfully!\n"); + printf("At Z=%f, Smoothed ", z1stLayer); + myKF.print(); + } + } + else{ + printf("DTracker::MakeKalTrack Smoothing failed! Using a backward filter instead!\n"); + //exit(0); + //myKF.clearSmoother(); + //myKF.setSmootherEnabled(kFALSE); + myKF.reset(); // reset some states but not change the initialization + + /// Backward filter! + aHit = (DHit*)aHitTList.Before(aHit); + for(Int_t iPlane = lastPlane-1; iPlane >= FirstPlane; iPlane--){ + DPlane* aHitPlane = (DPlane*)aHit->GetPlane();// hit plane + aPlane = (DPlane*)aPlaneArray.At(iPlane); // current plane + Int_t PlN = aPlane->GetPlaneNumber(); + // MS related: + thickness = fc->GetPlanePar(PlN).PlaneThickness; + TString material = fc->GetPlanePar(PlN).PlaneMaterial; + x0Layer = aTool.GetX0(material.Data()); + + hitAlignment = aPlane->GetPrecAlignment(); + if(aPlane != aHitPlane){ + DR3 intersectionPos = aPlane->Intersection(aTrack); + intersectionPos = hitAlignment->TransformHitToTracker(intersectionPos); + myKF.propagateBackTo(intersectionPos(2), thickness, thickness/x0Layer); + } + else{ // Hit plane + aPosition = hitAlignment->TransformHitToTracker( *(aHit->GetPosition())); + meas[0] = aPosition(0); + meas[1] = aPosition(1); + resolutionU = aHit->GetResolutionUhit(); + resolutionV = aHit->GetResolutionVhit(); + measCov[0] = resolutionU*resolutionU; + measCov[1] = resolutionV*resolutionV; + zLayer = aPosition(2); + myKF.propagateBackTo(zLayer, thickness, thickness/x0Layer); + myKF.updateBack(zLayer, meas, measCov); + if(fDebugTracker){ + printf("DTracker::MakeKalTrack Backward Filter\n"); + printf("At Z=%f, Updated ", zLayer); + myKF.print(); + } + if(aHit == aHitTList.First()) + break; + else + aHit = (DHit*)aHitTList.Before(aHit); + } + } + + } + + for(Int_t iPlane = FirstPlane-1; iPlane>=iDUT; iPlane--){ + aPlane = (DPlane*)aPlaneArray.At(iPlane); + Int_t PlN = aPlane->GetPlaneNumber(); + // MS related: + thickness = fc->GetPlanePar(PlN).PlaneThickness; + TString material = fc->GetPlanePar(PlN).PlaneMaterial; + x0Layer = aTool.GetX0(material.Data()); + + aPlane = (DPlane*)aPlaneArray.At(iPlane); + hitAlignment = aPlane->GetPrecAlignment(); + DR3 intersectionPos = aPlane->Intersection(aTrack); + intersectionPos = hitAlignment->TransformHitToTracker(intersectionPos); + myKF.propagateBackTo(intersectionPos(2), thickness, thickness/x0Layer); + if(fDebugTracker){ + printf("At Z=%f, Propagated ", intersectionPos(2)); + myKF.print(); + } + } + + } + else{ // iDUT is in the middle of the telescope + // + DPlane* rightPlane = rightHit->GetPlane(); + hitAlignment = rightPlane->GetPrecAlignment(); + aPosition = hitAlignment->TransformHitToTracker( *(rightHit->GetPosition()) ); + if(myKF.smoothTo(aPosition(2))){ + if(fDebugTracker){ + printf("DTracker::MakeKalTrack: Smoothing finished successfully!\n"); + printf("At Z=%f, Smoothed ", z1stLayer); + myKF.print(); + } + } + else{ + printf("ERROR: DTracker::MakeKalTrack Smoothing failed!\n"); + exit(0); + } + Int_t iRightPlane = aPlaneArray.IndexOf(rightPlane); + for(Int_t iPlane = iRightPlane-1; iPlane>=iDUT; iPlane--){ + aPlane = (DPlane*)aPlaneArray.At(iPlane); + Int_t PlN = aPlane->GetPlaneNumber(); + // MS related: + thickness = fc->GetPlanePar(PlN).PlaneThickness; + TString material = fc->GetPlanePar(PlN).PlaneMaterial; + x0Layer = aTool.GetX0(material.Data()); + + aPlane = (DPlane*)aPlaneArray.At(iPlane); + hitAlignment = aPlane->GetPrecAlignment(); + DR3 intersectionPos = aPlane->Intersection(aTrack); + intersectionPos = hitAlignment->TransformHitToTracker(intersectionPos); + myKF.propagateBackTo(intersectionPos(2), thickness, thickness/x0Layer); + if(fDebugTracker){ + printf("At Z=%f, Propagated ", intersectionPos(2)); + myKF.print(); + } + } + + } + + const Double_t* resultPar = myKF.getPar(); + const Double_t* resultCov = myKF.getCov(); + + tLineFitOrigin(0) = /*fittedTrackOrigin(0);*/ resultPar[0]; + tLineFitOrigin(1) = /*fittedTrackOrigin(1);*/ resultPar[2]; + tLineFitOrigin(2) = 0; + tLineFitSlope(0) = /*fittedTrackDirections(0);*/ resultPar[1]; + tLineFitSlope(1) = /*fittedTrackDirections(1);*/ resultPar[3]; + tLineFitSlope(2) = 1.0; + + Float_t tDx, tDy, tDz; + DR3 tLineFitDirection; + tDx = tLineFitSlope(0); + tDy = tLineFitSlope(1); + tDz = 1/sqrt(tDx * tDx + tDy * tDy + 1); + tLineFitDirection = (tLineFitSlope * tDz); + + DLine tFittedLine; + tFittedLine.SetValue(tLineFitOrigin,tLineFitDirection,tLineFitSlope,0.); + aTrack->SetLinearFit2(&tFittedLine); + + Double_t sigmX = sqrt(resultCov[0]); + Double_t sigmY = sqrt(resultCov[10]); + if(fDebugTracker){ + printf("DTracker::MakeKalTrack: TrackParam(x, slopeX, y, slopeY) = (%f, %f, %f, %f); Track Uncertainty(%f, %f)!\n",resultPar[0], resultPar[1], resultPar[2], resultPar[3], sigmX, sigmY); + printf("DTracker::MakeKalTrack: linearChisquareMethod Uncertainty(%f, %f)", aTrack->GetDeltaOrigineX(), aTrack->GetDeltaOrigineY()); + } + aTrack->SetDeltaOrigineX(sigmX); + aTrack->SetDeltaOrigineY(sigmY); +} + + +//_____________________________________________________________________________ +// +void DTracker::MakeLeastChi2Track( DTrack *aTrack, DHit** aHitList, Int_t nHits) { + + // Refit a track by using Least Chi-square fitting, + // Limits of this function(not this Algorithm): + // ! Requires MC simulation parameters! + // ! Only deal with tracks in +z direction + // ! Only estimate for one DUT test (propagate the track to DUT) + // ! nHits >= 2 and hits are in right order (increasing z) + // + // Created QL 2016/06/08 + + if( fDebugTracker) printf("DTracker::MakeLeastChi2Track for track %d from %d hits.\n", aTrack->GetNumber(), nHits); + + string particle = fc->GetTrackerPar().BeamType.Data(); + Double_t momentum = fc->GetTrackerPar().BeamMomentum; + //string MediumMaterial = fc->GetTrackerPar().MediumMaterial.Data(); + DGlobalTools aTool; + Double_t mass = aTool.GetMass(particle); + Double_t charge = aTool.GetCharge(particle); + if (nHits < 2||momentum <= 0||mass <= 0||charge<=0){ + printf("DTracker::MakeLeastChi2Track: The results of Kal are not guaranteed! KalmanFilter exit\n"); + return ; + } + + if ( fHitList[0]->GetPlane()->GetAnalysisMode() < 2 ){ // if not pixels + printf("DTracker::MakeLeastChi2Track: Only implemented for pixels!\n"); + return ;// Quit + } + + fDebugTracker = aHitList[0]->GetDebug(); // aHitList is always fHitList! + if(fDebugTracker) printf("DTracker::MakeLeastChi2Track: track number %d\n", aTrack->GetNumber()); + + //Double_t energy = TMath::Sqrt(mass*mass + momentum*momentum); + + //Prepare TList of Hits and Planes(Scatter Plane) + TObjArray aPlaneArray = *fPlaneArray; + aPlaneArray.Sort(); + TList aHitTList; + for (Int_t i = 0; i < nHits; i++) + aHitTList.Add(aHitList[i]); + aHitTList.Sort(); + if(fDebugTracker){ + aHitTList.Print(); + aPlaneArray.Print(); + } + + Int_t planeStatus, planeReadout; + + DPrecAlign *preAlignment; + DR3 aPosition; + DR3 tLineFitOrigin; // origin in the tracker system + DR3 tLineFitSlope; // slope along z-axis in tracker system + double resolutionU; + double resolutionV; + double sigmaMS; + + + ///Least Chi-Square + MLeastChiSquare myLChi2X; // Just test it with two line fitting in X/Y. + MLeastChiSquare myLChi2Y; + // a temporary implementation + std::vector *tXMeasArr = myLChi2X.GetPtrMeasArray(); + std::vector *tXSigmaArr = myLChi2X.GetPtrSigmaArray(); + std::vector *tXZArr = myLChi2X.GetPtrZArray(); + std::vector *tXSigmaMSArr = myLChi2X.GetPtrSigmaMSArray(); + std::vector *tXZScatterArr = myLChi2X.GetPtrZScatterArray(); + + std::vector *tYMeasArr = myLChi2Y.GetPtrMeasArray(); + std::vector *tYSigmaArr = myLChi2Y.GetPtrSigmaArray(); + std::vector *tYZArr = myLChi2Y.GetPtrZArray(); + std::vector *tYSigmaMSArr = myLChi2Y.GetPtrSigmaMSArray(); + std::vector *tYZScatterArr = myLChi2Y.GetPtrZScatterArray(); + + Int_t iDUT = 999; + DHit* aHit = (DHit*)aHitTList.First(); + for (Int_t pl = 0; pl GetStatus(); + Int_t planeNumber = planeInArr->GetPlaneNumber(); + planeReadout = fc->GetPlanePar(planeNumber).Readout; + + if (fDebugTracker) cout << "Plane " << planeNumber << " status=" << planeStatus << " readout=" << planeReadout<0&& planeStatus==3) iDUT = pl; + + DPlane* aPlane = aHit->GetPlane(); + Int_t iHitPlane = aPlaneArray.IndexOf(aPlane); // iHitPlane changes as aHit does + + // MS related: material before current layer! + sigmaMS = (planeInArr->GetSigmaThetaMS());///sqrt(2); // average in x and y + Double_t zLayer = planeInArr->GetPositionZ(); + + + if (planeReadout>0&&planeStatus<3&&iHitPlane==pl){// a plane for tracking + + preAlignment = aHit->GetPlane()->GetPrecAlignment(); + aPosition = preAlignment->TransformHitToTracker( *(aHit->GetPosition()) ); + resolutionU = aHit->GetResolutionUhit(); + resolutionV = aHit->GetResolutionVhit(); + zLayer = aPosition(2); + + tXMeasArr -> push_back(aPosition(0)); + tXSigmaArr -> push_back(resolutionU); + tXZArr -> push_back(zLayer); + tYMeasArr -> push_back(aPosition(1)); + tYSigmaArr -> push_back(resolutionV); + tYZArr -> push_back(zLayer); + if (aHit != aHitTList.Last()) + aHit = (DHit*)aHitTList.After(aHit);// Go to next hit + } + + tXSigmaMSArr -> push_back(sigmaMS); + tXZScatterArr -> push_back(zLayer); + tYSigmaMSArr -> push_back(sigmaMS); + tYZScatterArr -> push_back(zLayer); + }//end plane loop + + myLChi2X.Estimate(); + myLChi2Y.Estimate(); + + DPlane* dutPlane = (DPlane*)aPlaneArray.At(iDUT); + Double_t zDUT = dutPlane->GetPositionZ(); + Double_t resultPar[4]; + //Double_t resultCov[16]; + //resultPar[0] = myLChi2X.GetSigmaAtZ(zDUT); + resultPar[0] = myLChi2X.GetPar()[0]; + resultPar[1] = myLChi2X.GetPar()[1]; + resultPar[2] = myLChi2Y.GetPar()[0]; + resultPar[3] = myLChi2Y.GetPar()[1]; + + tLineFitOrigin(0) = /*fittedTrackOrigin(0);*/ resultPar[0]; + tLineFitOrigin(1) = /*fittedTrackOrigin(1);*/ resultPar[2]; + tLineFitOrigin(2) = 0; + tLineFitSlope(0) = /*fittedTrackDirections(0);*/ resultPar[1]; + tLineFitSlope(1) = /*fittedTrackDirections(1);*/ resultPar[3]; + tLineFitSlope(2) = 1.0; + + Float_t tDx, tDy, tDz; + DR3 tLineFitDirection; + tDx = tLineFitSlope(0); + tDy = tLineFitSlope(1); + tDz = 1/sqrt(tDx * tDx + tDy * tDy + 1); + tLineFitDirection = (tLineFitSlope * tDz); + + DLine tFittedLine; + tFittedLine.SetValue(tLineFitOrigin,tLineFitDirection,tLineFitSlope,0.); + aTrack->SetLinearFit2(&tFittedLine); + + Double_t sigmX = (myLChi2X.GetSigmaAtZ(zDUT)); + Double_t sigmY = (myLChi2Y.GetSigmaAtZ(zDUT)); + if(fDebugTracker){ + cout << "------------ Array print for singleton macro usage ---------\n"; + cout << "enum {kZPos, kTrackingLayer, kThickness, kXOverX0, kSigmaLayer,kNProperty};\n"; + cout << "Double_t Layers[][kNProperty] = {\n"; + //cout << "{ 0, 0, 50, 5.34188034188034242e-04, 3.5}, "; + size_t iTele = 0; + for(size_t i = 0; i < tXZScatterArr->size(); i++){ + if(i != 0) cout << ",\n"; + Int_t status = 0; // 1 -> used in tracking; + Double_t res = 999; + if((*tXZScatterArr)[i] == (*tXZArr)[iTele]){ + status = 1; + res = (*tXSigmaArr)[iTele]; + iTele++; + } + DPlane* planeInArr = (DPlane*)aPlaneArray.At(i); + Double_t thickness = planeInArr->GetPlaneThickness(); + TString material = planeInArr->GetPlaneMaterial(); + Double_t x0Layer = aTool.GetX0(material.Data()); + Double_t xOverX0 = thickness/x0Layer; + cout << " {\t"<<(*tXZScatterArr)[i]<<",\t"<GetDeltaOrigineX(), aTrack->GetDeltaOrigineY()); + } + aTrack->SetDeltaOrigineX(sigmX); + aTrack->SetDeltaOrigineY(sigmY); +} + + +//_____________________________________________________________________________ +// +DHit* DTracker::nearest_hit( DTrack *aTrack, Int_t aPlaneNumber, Bool_t &hitAssociated){ + + // For a given track, + // check if the track has an associated hit in the given plane, + // if so return this hit and set hitAssociated to true, + // otherwise return the the nearest hit in the given plane + // and set hitAssociated to false. + // + // Created by JB, 2009/07/17 + // Modified JB 2014/08/29, return hit associated to track if existing + + DPlane *aPlane = this->GetPlane( aPlaneNumber); + DHit *tHit = nullptr; // nullptr instead of 0 + + // Check if one the hit of the track belongs to this plane +// printf("DTracker::nearest_hit track %d, has %d hits to test.\n", aTrack->GetNumber(), aTrack->GetHitsNumber()); + for ( Int_t iHit=0; iHitGetHitsNumber(); iHit++) { + tHit = aTrack->GetHit( iHit); +// printf(" trying hit %d from plane %d tested plane %d.\n", iHit, tHit->GetPlane()->GetPlaneNumber(), aPlaneNumber); + if (tHit->GetPlane()->GetPlaneNumber() == aPlaneNumber) { +// cout << " --> plane associated: " << hitAssociated << endl; + hitAssociated = kTRUE; + return tHit; + } + } + + // Search for nearest hit in the plane + hitAssociated = kFALSE; + Double_t minDist(1.e9); + Double_t distance(0.); + DHit *tNearest = nullptr; // nullptr instead of 0 + for (Int_t ht = 1; ht <= aPlane->GetHitsN(); ht++) { // loop on hits + tHit = aPlane->GetHit(ht); + distance = tHit->Distance( aTrack) ; + if( distance < minDist) { + minDist = distance; + tNearest = tHit; + } + } //end loop on hits + return tNearest; +} + + +//_____________________________________________________________________________ +// +DTrack* DTracker::nearest_track( DHit *aHit){ + + // For a given hit of a given plane, return a pointer to the nearest track + // + // Created by JB, 2009/07/17 + // Modified JB 2009/08/26 to count track from 1 (not 0) + // Modified BB 2015/11/18 using do...while instead of for loop to avoid a breaking segmentation value while running DSFProduction + + Double_t minDist(1.e9); + Double_t distance(0.); + DTrack *tTrack = nullptr; + Int_t it = 1; + + DTrack *tNearest = nullptr; // nullptr instead of 0 + do{ + tTrack = this->GetTrack(it); + distance = aHit->Distance( tTrack); + if( distance < minDist) { + minDist = distance; + tNearest = tTrack; + } + it++; + }while(it <= fTracksN); // end loop on tracks + + return tNearest; +} +//_____________________________________________________________________________ +// +void DTracker::PrintStatistics(ostream &stream) { + // SS 2011/12/14 - Save statistics to the chosen output stream + // Modified JB 2014/08/29 + // Modified JB 2015/05/27 added plane status + + Int_t status; + Char_t use[4][20] = { "seed", "primary", "secondary", "DUT"}; + + stream<<"************************************"<= 1 ) { // if tracking was required + stream<<" Track reconstructed: "<At(ip-1)))->GetStatus(); + stream<<" pl "<fcn(n,gin,f,par,iflag); + //fgInstance->fcn(n,gin,f,par,iflag); + +} +//_____________________________________________________________________________ +// +void DTracker::fcn(Int_t &npar, Double_t *gin, Double_t &fValue, Double_t *x, Int_t iflag) +{ + + DTrack* aTrack; + fValue = 0; + Double_t chi2 = 0.0; + + //std::cout<<"fcn function 0"<mnexcm("SET STRATEGY ", arglist, 1, ierflg); // JB 2012/09/05 + + Double_t vstart[3] = {0.0, 0.0, 0.0}; + + static Double_t step[3] = {0.01, 0.01, 0.01}; + fit->mnparm(0, "x", vstart[0], step[0], 0,0,ierflg); + fit->mnparm(1, "y", vstart[1], step[1], 0,0,ierflg); + fit->mnparm(2, "z", vstart[2], step[2], 0,0,ierflg); + + // Now ready for minimization step + arglist[0] = 500; + arglist[1] = 1.; + gMinuit->mnexcm("MIGRAD", arglist, 2, ierflg); + + Double_t outPar[3]; + Double_t err[3]; + + for (Int_t i=0; i<3; ++i) { + fit->GetParameter(i,outPar[i],err[i]); + + } + + DTrack* aTrack; + + for (Int_t tr = 0; trSetVertex(outPar[0], outPar[1], outPar[2]); + } + + if( fDebugTracker) { + std::cout<<"//--- Vertex coordinate -------------------------//"<DoTrackTruthMatching(fTrack[itrk],MCPartID,NHitsMCPartID); + + fTrack[itrk]->SetMCPartID(MCPartID); + fTrack[itrk]->SetHitsFromMCPartID(NHitsMCPartID); + } + + return; + +} +//_____________________________________________________________________________ +// + +void DTracker::find_tracks_Beast(){ +std::cout << "******************INSIDE TRAKS BEAST************************" << '\n'; +DPlane *aPlane = NULL; +DPlane *aPlaneHit; +DHit *aHit = NULL; +DTrack aTrack( fPlanesN); +DLadder *aLadder; +aTrack.SetDebug( fDebugTracker); +// DTracker *tTracker = fSession->GetTracker(); +// tTracker->GetLadder +DR3 extrapolation; +Int_t oldfHits = 0; +DPlane *oldPlane = NULL; +Double_t minDistance = 1.e9; +Double_t aDistance, distanceWithoutSlope, distancewithSlope; +DHit *bestHit=0; +Float_t tPlaneResolution=fc->GetTrackerPar().Resolution; +DR3 *hitPositionPlane; // usefull for temporary computation check +DR3 hitPositionLadder; +int LadderNumber=0; +int PlaneIdx; +DBeaster *aBeaster; +aBeaster=GetBeaster(); +for(int ladderId=1;ladderId<3;ladderId++){ + cout <<"****** Ladder " <ListOfBeastHitsOnM1.clear(); + // aBeaster->ListOfBeastHitsOnM2.clear(); + // aBeaster->ListOfRecoParts_SP.clear(); + aBeaster->Clear_List(); + // std::cout << "Sp Reco Part size Avant = " << aBeaster->ListOfRecoParts_SP.size() <<'\n'; + + aBeaster->Fill_Modules_HitList(ladderId); + int BeastHitOnM1=aBeaster->ListOfBeastHitsOnM1.size(); + int BeastHitOnM2=aBeaster->ListOfBeastHitsOnM2.size(); + int HitSeuil=14; + std::cout << "HitsOnM1 = " << aBeaster->ListOfBeastHitsOnM1.size()<<'\n'; + std::cout << "HitsOnM2 = " << aBeaster->ListOfBeastHitsOnM2.size()<<'\n'; + if((BeastHitOnM1+BeastHitOnM2)!=0){ + aBeaster->Particle_Reconstruction(ladderId); + aBeaster->RecoCategorieClassification(ladderId,HitSeuil); + + // aBeaster->SimuCategorieClassification(ladderId,HitSeuil); + // VertexPosition(); + // Angular_DistributionSimuTS(); + // Angular_DistributionSimuTSL(); + // PurityTest(); + // PurityTest_Partner(); + //Categorie_Momentum(); + // MomentumCoherence(); + // std::cout << "Sp Reco Part size = " << aBeaster->ListOfRecoParts_SP.size() <<'\n'; + }else{ + if(ladderId==1) aBeaster->ListOfBeastRecoParts_L1.clear(); + if(ladderId==2) aBeaster->ListOfBeastRecoParts_L2.clear(); + }//END IF !=0 + +}//End loop on ladder +// delete aBeaster; +} +//_____________________________________________________________________________ +// diff --git a/src/DXRay2DPdf.cxx b/src/DXRay2DPdf.cxx new file mode 100755 index 0000000..52ed2f7 --- /dev/null +++ b/src/DXRay2DPdf.cxx @@ -0,0 +1,204 @@ +/***************************************************************************** + * Project: RooFit * + * * + * This code was autogenerated by RooClassFactory * + *****************************************************************************/ + +// Your description goes here... + +#include "Riostream.h" + +#include "DXRay2DPdf.h" +#include "RooAbsReal.h" +#include "RooAbsCategory.h" +#include +#include "TMath.h" + +ClassImp(DXRay2DPdf) + +//=============================================================================== +DXRay2DPdf::DXRay2DPdf() +{ +} +//=============================================================================== +DXRay2DPdf::DXRay2DPdf(const char *name, const char *title, + RooAbsReal& _x, + RooAbsReal& _y, + RooAbsReal& _X0, + RooAbsReal& _sigma, + RooAbsReal& _beta, + RooAbsReal& _alpha, + RooAbsReal& _phi, + RooAbsReal& _W1, + RooAbsReal& _W2, + RooAbsReal& _W3, + RooAbsReal& _W4, + RooAbsReal& _W5, + RooAbsReal& _S2, + RooAbsReal& _S3, + RooAbsReal& _S4, + RooAbsReal& _S5) : + RooAbsPdf(name,title), + x ("x", "x" , this,_x), + y ("y", "y" , this,_y), + X0 ("X0", "X_{0}", this,_X0), + sigma("sigma","#sigma",this,_sigma), + beta ("beta", "#beta", this,_beta), + alpha("alpha","#alpha",this,_alpha), + phi ("phi", "#phi", this,_phi), + W1 ("W1", "W_{1}", this,_W1), + W2 ("W2", "W_{2}", this,_W2), + W3 ("W3", "W_{3}", this,_W3), + W4 ("W4", "W_{4}", this,_W4), + W5 ("W5", "W_{5}", this,_W5), + S2 ("S2", "S_{2}", this,_S2), + S3 ("S3", "S_{3}", this,_S3), + S4 ("S4", "S_{4}", this,_S4), + S5 ("S5", "S_{5}", this,_S5) +{ +} +//=============================================================================== +DXRay2DPdf::DXRay2DPdf(const DXRay2DPdf& other, const char* name) : + RooAbsPdf(other,name), + x("x",this,other.x), + y("y",this,other.y), + X0("X0",this,other.X0), + sigma("sigma",this,other.sigma), + beta("beta",this,other.beta), + alpha("alpha",this,other.alpha), + phi("phi",this,other.phi), + W1("W1",this,other.W1), + W2("W2",this,other.W2), + W3("W3",this,other.W3), + W4("W4",this,other.W4), + W5("W5",this,other.W5), + S2("S2",this,other.S2), + S3("S3",this,other.S3), + S4("S4",this,other.S4), + S5("S5",this,other.S5) +{ +} +//=============================================================================== +TObject* DXRay2DPdf::clone(const char* newname) const +{ + + return new DXRay2DPdf(*this,newname); + +} +//=============================================================================== +DXRay2DPdf::~DXRay2DPdf() +{ +} +//=============================================================================== +double DXRay2DPdf::evaluate() const +{ + + const int Npeak(5); + + double W[Npeak]; + W[0] = W1; + W[1] = W2; + W[2] = W3; + W[3] = W4; + W[4] = W5; + + double S[Npeak]; + S[0] = 0.0; + S[1] = S2; + S[2] = S3; + S[3] = S4; + S[4] = S5; + + double ST = 0.0; + double WT = 0.0; + for(int i=0;i 1) { + for(int j=0;j= -180.0 && alpha < -90.0) { + radius = (SaddTot - Gamma)*(-cos(alpha*TMath::Pi()/180.0)) - 0.5*DeltaY*sin(alpha*TMath::Pi()/180.0); + } + else if(alpha >= -90.0 && alpha < 0.0) { + radius = (0.5*W[0] + Gamma)*cos(alpha*TMath::Pi()/180.0) - 0.5*DeltaY*sin(alpha*TMath::Pi()/180.0); + } + else if(alpha >= 0.0 && alpha < 90.0) { + radius = (0.5*W[0] + Gamma)*cos(alpha*TMath::Pi()/180.0) + 0.5*DeltaY*sin(alpha*TMath::Pi()/180.0); + } + else if(alpha >= 90.0 && alpha < 180.0) { + radius = (SaddTot - Gamma)*(-cos(alpha*TMath::Pi()/180.0)) + 0.5*DeltaY*sin(alpha*TMath::Pi()/180.0); + } + + double X0t = X0*cos(phi*TMath::Pi()/180.0) + AveY*sin(phi*TMath::Pi()/180.0); + double AveYt = -X0*sin(phi*TMath::Pi()/180.0) + AveY*cos(phi*TMath::Pi()/180.0); + + double Xvalt = x*cos(phi*TMath::Pi()/180.0) + y*sin(phi*TMath::Pi()/180.0); + double Yvalt = -x*sin(phi*TMath::Pi()/180.0) + y*cos(phi*TMath::Pi()/180.0); + + double Factor1 = cos(alpha*TMath::Pi()/180.0)*(Xvalt - X0t - Gamma) + sin(alpha*TMath::Pi()/180.0)*(Yvalt - AveYt); + Factor1 *= (beta/radius); + Factor1 += 1.0; + + double Factor2 = (beta/radius)*sigma*sqrt(2.0/TMath::Pi())*cos(alpha*TMath::Pi()/180.0); + + double val1 = 0.0; + double val2 = 0.0; + for(int i=0;i STOPPING\n", fBoardNumber); + return kFALSE; + } + + return kTRUE; +} + + +// ############################################################################# +Int_t DecoderM18::Get_Nevent() { + + if(!fFileInput){ printf("DecoderM18 [%d]: Error No Input File\n", fBoardNumber); return -1; } + + Long_t position; + position = ftell(fFileInput); //save current position + + fseek(fFileInput,0,SEEK_SET); // go to beginning of the file + + fNEvent=0; + while(!feof(fFileInput)) + { + if(!ReadNextInt()){ + cout << "No 32 bit words to read!" << endl; + return -1; + } + if(fDataChar == kTrailer){fNEvent++;} + } + + + fseek(fFileInput,position,SEEK_SET); //go back to initial position + + return fNEvent; + + + +} + + + +// ############################################################################# +Bool_t DecoderM18::ReadCDH() { + + // Take into account properly the header, + // this is necessary to extract the OMKDTransition information. + // BUT, the read OMKDTransition info is a priori not used for the same file, + // because it is expected that the DAQ sw has already used it in the computation + // of the column and row of the samples. + // JB, 2015/03/27 + + do{ + if(!ReadNextInt()) return kFALSE; + } + while(fDataChar != kTrailer); + + NewEvent(); + + Int_t NwordJump=0; + + fcountEv++; + + if(!ReadNextInt()) return kFALSE; + fEvCounterCDH = fDataChar; + if(fcountEv!=fEvCounterCDH) cout << "N ev mismatch!!! counter: " << fcountEv << " read from CDH " << fEvCounterCDH << endl; + if(!ReadNextInt()) return kFALSE; + kStopPointerTransitionRead = fDataChar%(kRowPerChip*kColPerChip); + //if(!ReadNextInt()) return kFALSE; //Dummy info (stop pointer) + if(!ReadNextInt()) return kFALSE; //Dummy info (wrap around bit) + if(!ReadNextInt()) return kFALSE; + + NwordJump=fDataChar; //(OMKDtransition) # of words to skip + Int_t info[4] = {0, 0, 0, 0}; + for(Int_t i=0; i (modulo %d) set to %d\n", fBoardNumber, info[0], info[1], info[2], info[3], kRowPerChip*kColPerChip, kOMKDTransitionRead); + + if (fDebugLevel) { + cout << "DecoderM18 [" << fBoardNumber << "] HEADER:" << endl; + cout << " event number = " << fEvCounterCDH << endl; + cout << " StopPointerTransitionRead = " << kStopPointerTransitionRead << endl; + cout << " NumOMKDTransitions = " << NwordJump << endl; + cout << " OMKDTransitionRead = " << kOMKDTransitionRead << endl; + + } + +return kTRUE; + +} +// ############################################################################# +void DecoderM18::NewEvent() { + + fEvCounterCDH=0; + fIndex.clear(); + fAmp.clear(); + + +} + + + +// ############################################################################# +Bool_t DecoderM18::ReadData( ) { + + if(!ReadCDH()) return kFALSE; + Int_t Amp=0; + Int_t Index=-1; + + if (fDebugLevel) printf("DecoderM18 [%d]::ReadData reading event %d with OMKDTransitionSet=%d\n with StopPointerTransitionSet=%d\n", fBoardNumber, fEvCounterCDH, kOMKDTransitionSet, kStopPointerTransitionSet); + + while(true){ + if(!ReadNextInt()) return kFALSE; + if(fDataChar != kTrailer){ + Index = CalculateIndex(); + fIndex.push_back( Index ); + Amp = (fDataChar & 0xffff0000) >> 16; + Amp = (Amp-kToBeSutractedFromAmp)*kAmpMultFactor; + fAmp.push_back( Amp ); + //cout << " Pixel[" << fIndex.size() << "]: initial hex= " << fDataChar << ", final amp= ", << Amp << ", at index " << Index << endl; + } + else { + fseek(fFileInput,-4,SEEK_CUR); + return kTRUE; + } + } + + if (fDebugLevel) printf(" DecoderM18 %d: event %d (real #=%d) completed with %lu pixels found\n", fBoardNumber, fEvCounterCDH, fcountEv, fIndex.size()); + +return kTRUE; + +} + + +// ############################################################################# +Int_t DecoderM18::CalculateIndex() { + + // Use the info aOMKDTransitionSet to shift the index computed + // from the col & row information read in the binary file. + // The shift is 0 by default and has no effect. + // The shift is set externally by the SetOMKDTransition( aTransition) method, + // since it is expected to be read from another file. + // + // JB 2015/03/27 + + Int_t row ,col, index; + + + // Get the row, col info from the file + row = fDataChar & 0x000000FF; + col = (fDataChar & 0x0000FF00) >> 8; + + + // Compute the index: + // if the OMKDTransition info is 0, do not modify basic formula + // otherwise shift index by OMKDTransition value + index =row *kRowPerChip +col; + if( kOMKDTransitionSet != 0 ) { + Int_t kFirst = kStopPointerTransitionSet-kOMKDTransitionSet; + if (index>=kFirst) index=(index+ kFirst)%(kRowPerChip*kColPerChip); + else index =(index+ kRowPerChip*kColPerChip+kFirst)%(kRowPerChip*kColPerChip); + +// index = (index+kOMK + } + + // if (fDebugLevel)cout << " !!!!!!!!!!!!!!!!check on kOMKD StopPointer row " << row << ", col " << col << ", initial index " << row *kRowPerChip +col << ",final index " << index <<" kOMD " <=kShift) index = index -kShift; + else index = kRowPerChip*kColPerChip + index - kShift; + + // cout << "row " << row << ", col " << col << ", initial index " << row *kRowPerChip +col << ", final index " << index << endl; + + if( index<0 || kRowPerChip*kColPerChip<=index ) + printf( "WARNING DecoderM18 [%d]: pb with crazy pixel index %d, initial( row=%d, col=%d, index=%d), OKMD=%d, Shift=%d\n, StopPointer=%d\n", fBoardNumber, index, row, col, row*kRowPerChip+col, kOMKDTransitionSet, kShift, kStopPointerTransitionSet); + + return index; + +} + +// ############################################################################# +void DecoderM18::PrintStatistics(ostream &stream) +{ + + // Print statistics on the events read by this board + // + // JB, 2014/05/14 + + stream << "***********************************************" << endl; + stream << " Board DecoderM18 " << fBoardNumber << " found:" << endl; + stream << fEvCounterCDH << " events in total," << endl; + stream << "***********************************************" << endl; + + +} diff --git a/src/DecoderM18_fb.cxx b/src/DecoderM18_fb.cxx new file mode 100755 index 0000000..eaab65c --- /dev/null +++ b/src/DecoderM18_fb.cxx @@ -0,0 +1,379 @@ + +/* $Id: DecoderM18_fb.h 0 2012-11-14 15:26:05Z valtini $ */ + +/////////////////////////////////////////////////////////////////////////////// +/// +/// This class provides access to MIMOSA digits in raw data. +/// Developer: fb +////////////////////////////////////////////////////////////////////////////// + +#include "DecoderM18_fb.h" + +ClassImp(DecoderM18_fb) + +// ############################################################################# + +DecoderM18_fb::DecoderM18_fb( Int_t aBoardNumber, Int_t aRunNumber, Int_t aSensorNumber) : +fFileInput(0x0), +fDataChar1(0), +fDataChar2(0), +fDataChar3(0), +fDataChar4(0), +fEventCounterCDH(0), +fWordCounterCDH(0), +fTriggerExternalCounter(0), +fLastEvt(0), +fTrigger(0), +fModeRead(-1), +fMimosaMode(0), +fChipNbr(0), +fNbrChip(0), +fEventCounterLH(0), +fWordCounterLH(0), +fEvent(0), +fEvent2(0), +fCount(0), +fEvt(0), +fjump(0), +fcol(0), +frow(0), +famp(0), +Index_Max(0) +{ + fBoardNumber = aBoardNumber; + fRunNumber = aRunNumber; + fSensorNumber = aSensorNumber; + + for(Int_t gg=0; gg<=1000; gg++) PIXEL[gg]=0x2bc; + + for(Int_t i=0;i %x\n",word1); + } + //START THE COUNTER OF WORDS + NonNcount++; + //IF THE COUNTER == 2 YOU GET THE "REAL EVENT" + if(NonNcount==2){fEvent=word1;printf("--fevent----> %d \n",fEvent);} + if(NonNcount==3){ printf("--3 word----> %d \n",word1); } + if(NonNcount==4){ printf("--4 word----> %d \n",word1); } + if(NonNcount==5){fjump =word1;printf("-- fjump ---> %d \n",fjump); } + //JUST PRINT THE WORD TO JUMP; + if(NonNcount>5 && NonNcount< 6 + fjump){printf("----> %d \n",word1);} + // printf("NonNcount = %d \n", NonNcount); + // START THE ANALYSIS OF THE PIXEL; + if(NonNcount>= 6 + fjump){ + // GET INFO ON THE PIXEL FIRED, I.E., N EVT, COL, ROW, AMPL; + GetPixeltrs(word1, fcol, frow, famp, fEvent); + // CODE TO PRINT THE N OF FIRED PIXEL FOR EVENT; + for(Int_t jk=10; jk<=NonNcount; jk++){ + Int_t npixelfired=jk-9; + if(NonNcount==jk) NumeroDiPixelAccesi=npixelfired; + } + printf("N pixel fired = %d \n", NumeroDiPixelAccesi); + } + fread(pointer1, 1, 4, fFileInput); + } + return fEvent; // fjump; +} +// ############################################################################# + +Int_t DecoderM18_fb::GetPixel_i_index(Int_t i){ + + // Return the index of the pixel + + Int_t row = PIXEL[i] & 0x000000FF; + Int_t col = (PIXEL[i] & 0x0000FF00) >> 8; + Int_t index = row*256 + col; + + if (fDebugLevel>1) { + printf("DecoderM18:: Getting index for pixel %d, row=%d, col=%d => index=%d\n", i, row, col, index); + } + + return index ; + +} + // ############################################################################# + + Bool_t DecoderM18_fb::GetPixeltrs(unsigned int WORD, Int_t FCOL, Int_t FROW, Int_t FAMP, Int_t FEVENT){ + + + FROW = WORD & 0x000000FF; + FCOL = (WORD & 0x0000FF00) >> 8; + FAMP = (WORD & 0xFFFF0000) >> 16; + + printf("PIXEL INFO--- EVT: -- > (row, col, amp) (WORD: ..), %d, %d, %d, %d, %x \n", FEVENT, FROW, FCOL, FAMP, WORD); + + return kTRUE; //fcol, frow, famp, fEvent; +} + +// ############################################################################# +Int_t DecoderM18_fb::Read_Evento(Int_t evt){ + + UInt_t word = 0; + + fEvt=0; + + Int_t evento; + Int_t indice=-1000; + + //for(Int_t jk=0; jk<=1000; jk++){ + while(!feof(fFileInput)){ + //do{ + if(!ReadNextInt())return kFALSE; + + word = fDataChar1; + + if(word == 0xfafafafa) indice=0; + if(indice==1) evento = word; + if(evento==evt){printf("----------EVENTO ----> %x",word);printf("\n");} + printf("----------WORD ----> %x",word); printf("\n"); + + + //}while(fDataChar1 != 0xfafafafa); + + //Read_Evento(0); + } + + if(!ReadNextInt())return kFALSE; + + return 0; +} + +// ############################################################################# +/* +UInt_t DecoderM18_fb::ReadData() // READ THE SINGLE EVENT; +{ + + //UInt_t fElem[100000]={0x0}; + + Int_t NonNcount2=0; + //UInt_t PIXEL[]; + + do{ + //if(!ReadNextInt())return kFALSE; + fDataChar2 = ReadNextInt(); + NonNcount2++; + //printf("-------fdatachar2----> %x \n",fDataChar2); + //printf("-------NonNcount2----> %d \n",NonNcount2); + if(NonNcount2==1){ fEvent2 = fDataChar2;} + if(NonNcount2==4){ fjump = fDataChar2;} // printf("-------fjump ----> %d\n",fjump);} + if(NonNcount2>= 5 + fjump){ + + Int_t npixel = NonNcount2-5-fjump; + if(fDataChar2!=0xfafafafa){ + printf("---che cazzo di evento è ----> %d \n",npixel); + //GetPixel(fDataChar2, fcol, frow, famp, fEvent2); + frow = fDataChar2 & 0x000000FF; + fcol = (fDataChar2 & 0x0000FF00) >> 8; + famp = (fDataChar2 & 0xFFFF0000) >> 16; + printf("PIXEL INFO - - - -EVT - - - -> (row, col, amp) (WORD: ..), %d, %d, %d, %d, %x \n", fEvent2, frow, fcol, famp, fDataChar2); + } + } + + }while(fDataChar2!=0xfafafafa); + + + return fEvent2, fcol, frow, famp; +}*/ +// ############################################################################# +// ############################################################################# +Bool_t DecoderM18_fb::ReadData() // READ THE SINGLE EVENT; +{ + + for(Int_t i = 0; i<=1000; i++){ + + fDataChar1 = ReadNextInt(); + + //printf("i: %d---------------------------------- generic words ->->->-> %x \n",i, fDataChar1); + + if(i==0){ + fEvent2 = fDataChar1; + if (fDebugLevel) printf(" Real event number is %d for event %d\n", fEvent2, fCount); + } + + if(i==3){ + fjump = fDataChar1; + if (fDebugLevel>1) printf(" words to jump %d for event %d\n", fjump, fCount); + } + + if(i >= 4 + fjump){ + + if(fDataChar1==0xfafafafa) { + if (fDebugLevel) printf(" Trailer %x found => end of event %d\n", fDataChar1, fCount); + break; + } + + if(fDataChar1==0x2bc) { + if (fDebugLevel) printf(" word %x found => break reading for event %d\n", fDataChar1, fCount); + break; + } + + Int_t index = i-4-fjump; + + PIXEL[index]=fDataChar1-32756; + //printf("PIXEL -> %x\n", PIXEL[index]); + + Index_Max=index+1; + //printf("Valore max dell'indice => %d \n", Index_Max); + + + } + + } + + // printf("---- the end of event ------ \n"); + + +return true; +} + +//__________________________________________________________________________ +Bool_t DecoderM18_fb::HasData() +{ + + if (fDebugLevel) printf("DecoderM18::HasData reading event %d\n", fCount); + + Index_Max = 0; // reset nb of pixels fired + + if( !ReadData() ) return false; + + if (fDebugLevel) printf(" event %d (real #=%d) completed with %d pixels found\n", fCount, fEvent2, Index_Max); + + fCount++; + return true; + +} + + +//__________________________________________________________________________ +void DecoderM18_fb::PrintStatistics(ostream &stream) +{ + + // Print statistics on the events read by this board + // + // JB, 2014/05/14 + + stream << "***********************************************" << endl; + stream << " Board DecoderM18 " << fBoardNumber << " found:" << endl; + stream << fCount << " events in total," << endl; + stream << "***********************************************" << endl; + + +} +// ############################################################################# +// ############################################################################# + diff --git a/src/GIGBoardReader.cxx b/src/GIGBoardReader.cxx new file mode 100755 index 0000000..a620892 --- /dev/null +++ b/src/GIGBoardReader.cxx @@ -0,0 +1,359 @@ +///////////////////////////////////////////////////////////// +// Class Description of GIGBoardReader // +// // +// Read simulated data from GEANT digitized by the DIGMAPS code +// +// +// Notice the current version assumes the data are contained +// only in one file +// // +///////////////////////////////////////////////////////////// +// +// created JB, 2012/04/24 +// Modified LC, 2012/05/09 +// Modified LC, 2014/12/16 + +#include "TCanvas.h" +#include "GIGBoardReader.h" + +ClassImp(GIGBoardReader) +ClassImp(GIGEvent) + +// -------------------------------------------------------------------------------------- + +GIGBoardReader::GIGBoardReader( int boardNumber, int nSensors) { + + // JB, 2012/04/22 + + BoardNumber = boardNumber; + NSensors = nSensors; + bufferPlane = 0; + + cout << "DIGBoardRead " << BoardNumber << " created with " << NSensors << " sensors." << endl; + + ReadingOK = true; + EventReady = false; + EventStarted = true; + CurrentEventID = -1; // required to start with the first ID of the file + NewEventID = 0; + + // init counters and histos for statistics + EventsCount = 0; + NumberOfFiles = 0; + CurrentFileNumber = 0; + AveragePixelCountTotal = 0; + AveragePixelCountTotalTemp = 0; + AveragePixelCount = new int[NSensors]; + AveragePixelCountTemp = new int[NSensors]; + for( int is=0; is::iterator iterGIGPixel = ListOfPixels.begin(); + for( ; iterGIGPixel!=ListOfPixels.end() ; ++iterGIGPixel ) delete *iterGIGPixel; + ListOfPixels.clear(); + + std::vector::iterator iterGIGMonteCarlo = ListOfMonteCarlo.begin(); + for( ; iterGIGMonteCarlo!=ListOfMonteCarlo.end() ; ++iterGIGMonteCarlo ) delete *iterGIGMonteCarlo; + ListOfMonteCarlo.clear(); + + delete AveragePixelCount; + delete AveragePixelCountTemp; + + delete InputFileName; + delete PrefixFileName; + delete SuffixFileName; + +} + +// -------------------------------------------------------------------------------------- + +bool GIGBoardReader::AddFile(char *fileName) { + + // JB, 2012/04/09 + // LC, 2014/12/16 + + NumberOfFiles = 1; + CurrentFileNumber = 1; + InputFileName = fileName; + sprintf(InputFileName,"%s", fTool.LocalizeDirName( InputFileName)); + + RawFileStream.open( InputFileName); + + if( RawFileStream.fail() ) { + cout << endl << "ERROR GIGBoardReader " << BoardNumber << " file " << InputFileName << " does not exist!" << endl; + return false; + } + // To read the first line + //Char_t aLine[200]; + //RawFileStream.getline( &aLine, 200); + cout << endl << " --> GIGBoardReader " << BoardNumber << " New file " << InputFileName << endl; + + return true; +} + +// -------------------------------------------------------------------------------------- + +void GIGBoardReader::Close() { + + // Closes every files needed to be + // 2012/04/09 + + RawFileStream.close(); +} + +// -------------------------------------------------------------------------------------- + +void GIGBoardReader::SkipNextEvent() { + + // This method is used to ignore the next event, + // that means no event is generated + // + // JB, 2012/04/24 + + if(DebugLevel) printf(" GIGBoardReader board %d, Skipping event %d\n", BoardNumber, CurrentEventID); + + while( !EventReady && ReadingOK ) { + ReadLine(); + } + +} + +// -------------------------------------------------------------------------------------- + +void GIGBoardReader::ReadLine() { + + // Read a line from the text input file. + // The eventID is used to decide whether + // this line starts a new event or not. + // + // The format of input file follows specification by Loic Cousin + // eventID sensorID row column pixelNumber pixelCoordX pixelCoordY pixelCoordZ + // as of 2012/04/12. + // + // JB 2012/04/22 + + + if(DebugLevel>2) printf(" GIGBoardReader board %d: Reading line - current event id %d\n", BoardNumber, CurrentEventID ); + + // If there is no more line to read, stop + if( RawFileStream.eof() || CurrentFileNumber> eventID; + + if( CurrentEventID<0 ) CurrentEventID = eventID; + + if(DebugLevel>2) printf(" event %d\n", eventID ); + } + else { + eventID = CurrentEventID; + } + + // If the eventID is different from the current event number, + // indicate the event is ready. + // The pixel fields of this line is not read yet. + if( eventID != CurrentEventID ) { + if(DebugLevel) printf("GIGBoardReader::ReadLine New event %d detected, current event is %d\n", eventID, CurrentEventID); + + EventReady = true; // will generate a new event + EventStarted = false; // will prevent next reading of eventID + NewEventID = eventID; + } + + // Read the sensor and pixel fields when this is still the same event + else { + + RawFileStream >> sensorID >> line >> column >> pixelNumber >> realEnergy >> digitizedEnergy >> coordX >> coordY >> coordZ; // LC, 2012/05/09 + + AddPixel( sensorID, 1, line, column, coordX, coordY, coordZ); + EventStarted = true; // will force next reading of eventID + + if(DebugLevel>2) printf(" event %d sensor %d, line %d, col %d, pixel %d\n", eventID, sensorID, line, column, pixelNumber ); + } + +} + +// -------------------------------------------------------------------------------------- + +bool GIGBoardReader::HasData( ) { + + // Fill a new event containing all the fired pixels of each sensors acquired, + // return "true" if the event is OK, "false" otherwise + // + // + // JB, 2012/04/09 + + // -+-+- Initialization + + if(DebugLevel>1) cout << " GIGBoardReader board " << BoardNumber << "::HasData - reading OK " + << ReadingOK << " event readiness " << EventReady << " event started " << EventStarted << endl + << " events generated " << EventsCount << " current event " << CurrentEventID << endl; + if(ListOfPixels.size()>0) { + std::vector::iterator iterGIGPixel = ListOfPixels.begin(); + for( ; iterGIGPixel!=ListOfPixels.end() ; ++iterGIGPixel ) delete *iterGIGPixel; + ListOfPixels.clear(); + } + + if(ListOfMonteCarlo.size()>0) { + std::vector::iterator iterGIGMonteCarlo = ListOfMonteCarlo.begin(); + for( ; iterGIGMonteCarlo!=ListOfMonteCarlo.end() ; ++iterGIGMonteCarlo ) delete *iterGIGMonteCarlo; + ListOfMonteCarlo.clear(); + } + + // -+-+- Check files have been associated + + if( NumberOfFiles==0 ) { + cout << "ERROR: GIGBoardReader NO RAW DATA FILE WAS ASSOCIATED WITH BOARD " << BoardNumber << ", STOPPING!" << endl << endl; + return false; + } + + // -+-+- Loop over Daq Events (or frames for all sensors) + + while( !EventReady && ReadingOK ) { + ReadLine(); + } + + + // -+-+- Create the event when ready + + if( EventReady ) { + GenerateNewEvent(); + } + + + // -+-+- End + return ReadingOK; + +} + +// -------------------------------------------------------------------------------------- + +void GIGBoardReader::GenerateNewEvent() { + + // Generate a new event + // + // JB 2012/04/22 + + CurrentEvent = new GIGEvent( EventsCount, BoardNumber, ListOfPixels, ListOfMonteCarlo ); + if(DebugLevel>1) printf(" New event %d (id %d) from board %d with %d pixels\n", EventsCount, CurrentEventID, BoardNumber, (int)ListOfPixels.size()); + + EventsCount++; + + // compute average of pixel counts per event + AveragePixelCountTotal = ( AveragePixelCountTotal*(EventsCount-1) + AveragePixelCountTotalTemp ) / EventsCount; + AveragePixelCountTotalTemp = 0; + for( int is=0; is& listOfPixels, vector& listOfMonteCarlo ) { + + // JB, 2012/04/09 + // LC, 2014/12/15 : Now vectors passing by ref + + EventNumber = eventNumber; + BoardNumber = boardNumber; + ListOfPixels = listOfPixels; + ListOfMonteCarlo = listOfMonteCarlo; // LC 2012/10/17 + +} + +// -------------------------------------------------------------------------------------- + +GIGEvent::~GIGEvent() { + + // crashing for the time bein...? + // JB, 2009/09/14 + // LC, 2014/12/16 + + //if(DebugLevel) std::cout<<"In Destructor GIGEvent"< So don't delete these objects. +/* + std::vector::iterator iterGIGPixel = ListOfPixels.begin(); + for( ; iterGIGPixel!=ListOfPixels.end() ; ++iterGIGPixel ) delete *iterGIGPixel; + ListOfPixels.clear(); + + std::vector::iterator iterGIGMonteCarlo = ListOfMonteCarlo.begin(); + for( ; iterGIGMonteCarlo!=ListOfMonteCarlo.end() ; ++iterGIGMonteCarlo ) delete *iterGIGMonteCarlo; + ListOfMonteCarlo.clear(); +*/ + +} diff --git a/src/IMGBoardReader.cxx b/src/IMGBoardReader.cxx new file mode 100644 index 0000000..01bc665 --- /dev/null +++ b/src/IMGBoardReader.cxx @@ -0,0 +1,1454 @@ +///////////////////////////////////////////////////////////// +// Class Description of IMGBoardReader // +// // +// Read raw data file from Imager Board, +// which corresponds to: +// - non sparsified data, +// - "analogue" data, that is encoded on a number of bits, +// - "data" of a pixel includes usually 2 frames for CDS +// but a specific mode allows for more than 2 frames/data. +// +// See constructor IMGBoardReader for the list of options. +// !!! some parameters are hardcoded in this constructor !!! +// +// The file format is described in the documents by Gilles Clauss: +// mi32A_pxia_pxid_beam_test_file_format__template_files_v1.0.txt +// das_data_format_d7.txt +// +// Each event has a fixed size with a header and a data part. +// The data part is subdivided in inputs (=sensors, a priori bu not necessarily), +// all with an equivalent lenght. Each input contains a number +// of rawdata values of a given bit size (NumberOfBitsValue). +// Then, there are two possibilities to extract a channel (=pixels) signal, +// which is a SignificantBits bits word: +// 1) more than one rawdata value is needed, +// 2) a single rawdata value contains several channel signal +// corresponds to a N-bits value. +// +// Variables defining the class behavior (set by the constructor) +// - NbOfInputs +// - SizeOfEvent +// - ifStripTelescope = +// If true very specific format for 8 planes of silicon strips. +// This format is HARD-CODED. +// - ifMultiFrame = +// - First / LastTriggerChannel = limits where to look for trigger info in data +// - First / LastExcludedChannel = limits of channel indexes not taken into account +// - triggerLowThreshold/triggerHighThreshold = define interaval to identify a trigger +// +// +// Methods to interact externally with the class +// - HasData() = +// To be called for each event, get and decode the data +// corresponding to next event. Update the IMGEvent object. +// - SkipNextEvent = jump an event, ignoring its data. +// - AddFile/AddFileList = +// Add file names to the list of binary files to be considered for the readout +// +// Methods internal to the class +// - IMGBoardReader = constructor, sets almost all control variables +// - LookUpRawFile, OpenRawFile, CloseRawFile = raw data file management +// - GetNextBuffer = load a full event in the memory (= Data buffer) +// - SetBufferPointers = set the pointers to the different part of +// the Data buffer (Header, inpu0, input1, ..., Trailer) for an event +// - BuildValue( anAddress, wordSize) = return the content of the Data buffer +// at anAddress and with length wordSize. +// - GetInputData = extract the rawdata value(s) for each channel (=pixel or strip) +// of each inputs and call the AddPixel method for it. +// - AddPixel = build the channel signal associated with the given rawdata value. +// +// // +///////////////////////////////////////////////////////////// +// +// JB, 2012/06/ +// Last modified: SS 2012/08/01 number of bug fixes +// Last modified: JB 2012/08/18 upgraded management of multi-files and eof +// Last modified: JB 2012/08/18 trigger info added to event +// Last modified: SS 2012/08/21 new CDS in AddPixel +// Last modified: JB 2012/08/22,23 strip-telescope specific treatments +// Last modified: JB 2013/06/16-20 multi-frame specific treatments +// Last modified: JB 2013/07/19 AddPixel +// Last modified: JB 2014/01/28 IMGBoardReader +// Last modified: JB 2016/08/17 GetInputData +// Last modified: JB 2016/09/20 IMGBoardReader, GetInputData +// Last modified: JB 2017/03/03 IMGBoardReader, GetInputData +// Last modified: JB 2017/11/20 IMGBoardReader, SetZeroSuppression, AddPixel +// Last modified: JB 2018/03/18 SetBufferPointers +// Last modified: JB 2020/11/25 IMGBoardReader, GetInputData for daqmode=5 (blocReading) + +#include "IMGBoardReader.h" + +ClassImp(IMGBoardReader) +ClassImp(IMGEvent) + +// -------------------------------------------------------------------------------------- + +IMGBoardReader::IMGBoardReader( int boardNumber, int nInputs, int *nChannels, int sizeOfEvent, int eventsInFile, int headerSize, int trailerSize, int *numberOfBits, int *sigBits, int endian, int triggermode, int daqmode, int Ncolumns, int Nframes) { + + // numberOfBits = size of the words (= rawdata values) to read from inputs + // it may corresponds to one or more channels + // If numberOfBits<0, build signed signals for channels, unsigned otherwise. + // + // sigBits = size of the word containing one channel signal + // usually it encompasses the signals on two succesive frames + // If sigBits<0, do CDS (frame2-frame1) to build the final channel signal. + // + // daqmode = 0 standard mode (1 rawdata value = 2 frames), + // = 1 strip-telescope mode (8 1st planes=strips) + // = 2 multiframe mode, each rawdata value corresponds to more than 2 frames + // -> ifMultiFrame contains the number of rawdata values + // associated with one channel + // -> Note that if CDS is required, 5 frames means 5 times frame0+frame1 + // and nb of columns in sensor needs to be known + // = 3 all frame1 pixel values comes first, then all frame 2 values + // = 4 for 16 parallel outputs + // = 5 blocReading mode, data are organized by blocs and rows + // -> 1 input = Nrows successive rows of Nblocs pixels + // -> need to combine Ninputs to build the full row + // + // strip-telescope mode : + // map a single input to 4 interleaved inputs + // according to description in + // das_data_format_d7.txt by G.Clauss + // + // + // JB, 2012/07/16 + // Modified: JB 2012/08/18 take into account nb of events in file + // Modified: JB 2012/08/19 to allow different setup for each input + // Modified: JB 2012/08/22 specific treatment when strip-telescope data + // Modified: JB 2012/08/23 new argument daqmode to select strip-tel or not + // Modified: JB 2013/06/16 daqmode 2 with new ifMultiFrame variable + // Modified: JB 2014/01/28 manage case with or without trigger for multiFrame mode + // Modified: JB 2014/11/20 new daqmode=3 for Maciej's DAQ (ifSplitFrames) + // Modified: JB 2016/09/19 NValuesToJumpPerChannel updated to handle both CDS/non-CDS cases + // Modified: JB 2017/03/03 new daqmode=4 to handle 16 parallel inputs DAQ + // Modified: JB 2018/03/19 trailerSize introduced + // Modified: JB 2020/11/25 daqmode=5 for blocReading introduced + + cout << "Creating IMGBoardReader for board " << boardNumber << " with " << nInputs << " inputs of " << nChannels[0] << " channels (for " << Ncolumns << " columns), event is " << sizeOfEvent << " bytes, " << eventsInFile << " events per file, header is " << headerSize << " bytes, trailer is " << trailerSize << " bytes, each value has " << numberOfBits[0] << " bits among which " << sigBits[0] << " are significant and endianess is " << endian << ", trigger mode is " << triggermode << ", daq mode is " << daqmode << "." << endl; + + BoardNumber = boardNumber; + ifStripTelescope = false; + SizeOfTrailer = trailerSize; + ifMultiFrame = 0; + ifSplitFrames = 0; + if16outputs = 0; + ifBlocReading = 0; + if( daqmode==1 ) { // daq mode for strip telescope + ifStripTelescope = true; + SizeOfTrailer = 4; + } + else if( daqmode==2 ) { // daq mode with multiFrame, JB 2013/06/16 + cout << "IMGBoardReader board: multiFrame mode detected!" << endl; + ifMultiFrame = Nframes; + } + else if( daqmode==3 ) { // daq mode for all frame1 values before all frame2 values + cout << "IMGBoardReader board: split-frame mode (all reference values after all signal values) detected!" << endl; + ifSplitFrames = 1; + } + else if( daqmode==4 ) { + if16outputs = 1; + cout << "IMGBoardReader board: 16 parallel outputs DAQ mode detected!" << endl; + } + else if( daqmode==5 ) { + ifBlocReading = 128; + cout << "IMGBoardReader board: bloc-reading mode (rows are split in blocs of " << ifBlocReading << " pixels) detected!" << endl; + } + + if( ifStripTelescope ) { + // when strip telescope is read, the 4 first input from the config + // are to be turned into 1 physical input (hence -3) + NbOfInputs = nInputs; // was nInputs-3 + cout << "IMGBoardReader board " << boardNumber << ": strip-telescope configuration -> consider 4 imbricated channels per value (..., i i i i, i+1, i+1, i+1, i+1, ...) for 2 first inputs!" << endl; + } + else { + NbOfInputs = nInputs; + } + + if( ifMultiFrame ) { // JB 2013/06/19 + triggerLowThreshold = 5000; + triggerHighThreshold = 100000; + } + else { + triggerLowThreshold = 0; + triggerHighThreshold = 0; + } + + SizeOfEvent = sizeOfEvent; + EventsInFile = eventsInFile; // JB 2012/08/18 + SizeOfHeader = headerSize; + Data = new char[SizeOfEvent]; + Endianness = endian; + IfZeroSupress = 0; + + SetNumberOfColumns(Ncolumns); + + // Setup input parameters + // JB 2012/08/19 + NbOfChannels = new int[NbOfInputs]; + NumberOfBitsValue = new int[NbOfInputs]; + SignificantBits = new int[NbOfInputs]; + SignedValues = new bool[NbOfInputs]; + InputDataAdress = new int[NbOfInputs]; + MaxSignedValue = new unsigned int[NbOfInputs]; + SizeOfInputData = new size_t[NbOfInputs]; + SizeOfValue = new size_t[NbOfInputs]; + NChannelsPerValue = new int[NbOfInputs]; + NValuesToRead = new int[NbOfInputs]; + WithCDS = new bool[NbOfInputs]; + NValuesPerChannel = new int[NbOfInputs]; // JB 2013/06/16 + NValuesToJumpPerChannel = new int[NbOfInputs]; + FirstTriggerChannel = new int[NbOfInputs]; + LastTriggerChannel = new int[NbOfInputs]; + FirstExcludedChannel = new int[NbOfInputs]; + LastExcludedChannel = new int[NbOfInputs]; + + for( int iInput=0; iInput CDS is " << (WithCDS[iInput]?"":"NOT") << " required, # values to jump per channel = " << NValuesToJumpPerChannel[iInput] << endl; + cout << " -> search for trigger info between channels " << FirstTriggerChannel[iInput] << " and " << LastTriggerChannel[iInput] << " in a value range from " << triggerLowThreshold << " to " << triggerHighThreshold << "!" << endl; + } + + } // end loop on inputs + + + BuffersRead = 0; // JB 2012/08/18 + NumberOfFiles = 0; + CurrentFileNumber = 0; + NoMoreFile = false; + + ReadingEvent = false; + CurrentEvent = 0; // Allow to know wether data are correct, JB 2009/05/26 + CurrentEventNumber = 0; + CurrentTriggerNumber = 0; + CurrentFrameNumber = 0; + CurrentTimestamp = 0; + TriggerMode = triggermode; // define limits of events: 0=with trigger, 1=with frames + + + // Initialise statistics + EventsCount = 0; + FramesRead = 0; + +} + +// -------------------------------------------------------------------------------------- + +IMGBoardReader::~IMGBoardReader() { + + // JB, 2008/09/27 + delete CurrentEvent; + delete InputFileName; + delete Data; + ListOfTriggers.clear(); + ListOfTimestamps.clear(); + ListOfFrames.clear(); + ListOfPixels.clear(); + + delete[] NbOfChannels; + delete[] NumberOfBitsValue; + delete[] SignificantBits; + delete[] SignedValues; + delete[] InputDataAdress; + delete[] MaxSignedValue; + delete[] SizeOfInputData; + delete[] SizeOfValue; + delete[] NChannelsPerValue; + delete[] NValuesToRead; + delete[] WithCDS; + delete[] NValuesPerChannel; + delete[] NValuesToJumpPerChannel; + delete[] FirstTriggerChannel; + delete[] LastTriggerChannel; + delete[] FirstExcludedChannel; + delete[] LastExcludedChannel; + +} + +// -------------------------------------------------------------------------------------- + +void IMGBoardReader::SetZeroSuppression(int aThreshold) { + + // Used to set zero suppression and define the threshold + // + // JB 2017/11/20 + + IfZeroSupress = 1; + ZeroThreshold = aThreshold; + + cout << endl << " ==> ZERO SUPPRESSION used with threshold " << ZeroThreshold << endl; + +} + +// -------------------------------------------------------------------------------------- + +bool IMGBoardReader::AddFile(char *fileName) { + + // JB, 2008/09/27 + + NumberOfFiles++; + CurrentFileNumber = 0; + InputFileName = fileName; +#ifndef STANDALONE + sprintf(InputFileName,"%s", fTool.LocalizeDirName( InputFileName)); // JB 2011/07/07 +#endif + RawFileStream.open( InputFileName); + if( RawFileStream.fail() ) { + cout << endl << "ERROR IMGBoardReader " << BoardNumber << " file " << InputFileName << " does not exist!" << endl; + return false; + } + cout << endl << " --> IMGBoardReader " << BoardNumber << " New file " << InputFileName << endl; + + return true; +} + +// -------------------------------------------------------------------------------------- +bool IMGBoardReader::AddFileList(const char *prefixFileName, int startIndex, int endIndex, const char *suffixFileName) { + + // Store the inputs to be able to read several files one after the other + // JB, 2008/10/8 + // Modified: JB 2010/10/05 to allow a first index file not 1 and read file#>10 + // Modified: SS 2012/08/01 really add several files + // Modified: JB 2012/08/18 consider endIndex as inclusive + // Modified: JB 2013/10/04 Fix behavior of NumberOfFiles and CurrentFileNumber + // Modified: JB 2017/11/20 allows to find files without index at second try + + bool rc = true; + int nbFilesOK = 0; + + if(DebugLevel>0) cout << "Indices: start = " << startIndex << ", end = " << endIndex << endl; + NumberOfFiles = endIndex-startIndex+1; // Better way to handle non-0 start index, JB 2013/10/04 + CurrentFileNumber = 0; + SuffixFileName = new char[10]; + PrefixFileName = new char[300]; + ListOfInputFileNames = new char*[endIndex-startIndex+1]; + sprintf( PrefixFileName, "%s", prefixFileName); + sprintf( SuffixFileName, "%s", suffixFileName); + /*if(DebugLevel>0)*/ cout << "IMGBoardReader " << BoardNumber << " adding " << NumberOfFiles << " files like " << prefixFileName << "*" << SuffixFileName << endl; + + // Try filenames using an index + for(int FileNumberToAdd=0; FileNumberToAdd<=endIndex-startIndex;FileNumberToAdd++){ + InputFileName = new char[300]; + sprintf( InputFileName, "%s%d%s", PrefixFileName, FileNumberToAdd+startIndex, SuffixFileName); +#ifndef STANDALONE + sprintf(InputFileName,"%s", fTool.LocalizeDirName( InputFileName)); +#endif + if(DebugLevel>0) cout << " trying file " << InputFileName << endl; + RawFileStream.open( InputFileName); + if( RawFileStream.fail() ) { + cout << endl << "ERROR IMGBoardReader " << BoardNumber << " file " << InputFileName << " does not exist!!" << endl; + RawFileStream.close(); + rc = false; + } + else{ + nbFilesOK++; + ListOfInputFileNames[FileNumberToAdd]=InputFileName; + cout << " --> IMGBoardReader " << BoardNumber << " New file " << ListOfInputFileNames[FileNumberToAdd] << ", total of " << FileNumberToAdd+1 << " files." << endl; + RawFileStream.close(); + } + } + cout << "#files OK = " << nbFilesOK << " out of " << NumberOfFiles << endl; + + // If there is only one file, try a filename without an index (JB 2017/04/05) + if ( !rc && NumberOfFiles == 1 ) { + sprintf( InputFileName, "%s%s", PrefixFileName, SuffixFileName); +#ifndef STANDALONE + sprintf(InputFileName,"%s", fTool.LocalizeDirName( InputFileName)); +#endif + /*if(DebugLevel>0)*/ cout << " trying file " << InputFileName << endl; + RawFileStream.open( InputFileName); + if( RawFileStream.fail() ) { + cout << endl << "ERROR IMGBoardReader " << BoardNumber << " file " << InputFileName << " does not exist!!" << endl; + RawFileStream.close(); + rc = false; + } + else{ + ListOfInputFileNames[0]=InputFileName; + cout << " --> IMGBoardReader " << BoardNumber << " New file " << ListOfInputFileNames[0] << ", total of " << 1 << " files." << endl; + RawFileStream.close(); + rc = true; + } + } + + // if at least some files are OK, JB 2017/11/20 + else if ( !rc && nbFilesOK > 0 ) { + rc = true; + } + + if( rc) OpenRawFile(ListOfInputFileNames[0]); //reopens the very first file +// RawFileStream.clear(); + return rc; +} + +// -------------------------------------------------------------------------------------- +bool IMGBoardReader::LookUpRawFile() { + + // Try to open the next rawdata file. + // The file name is decided upon + + if( CurrentFileNumber < NumberOfFiles-1) { + + + +// if( CurrentFileNumber ) { // only close if not first file + CloseRawFile(); + CurrentFileNumber++; +// } + if(DebugLevel) cout << " --> IMGBoardReader " << BoardNumber << " New file to read " << CurrentFileNumber+1 << " < " << NumberOfFiles << " closing and opening." << endl; + InputFileName = ListOfInputFileNames[CurrentFileNumber]; + return OpenRawFile( InputFileName); + +/* + if( CurrentFileNumber<10 ) { + sprintf( InputFileName, "%s000%d%s", PrefixFileName, CurrentFileNumber, SuffixFileName); + } + else if( CurrentFileNumber<100 ) { + sprintf( InputFileName, "%s00%d%s", PrefixFileName, CurrentFileNumber, SuffixFileName); + } + else if( CurrentFileNumber<1000 ) { + sprintf( InputFileName, "%s0%d%s", PrefixFileName, CurrentFileNumber, SuffixFileName); + } + else { + sprintf( InputFileName, "%s%d%s", PrefixFileName, CurrentFileNumber, SuffixFileName); + } + sprintf(InputFileName,"%s", fTool.LocalizeDirName( InputFileName)); // JB 2011/07/07 + */ +// RawFileStream.open( InputFileName); //SS 2012.08.09 - commented out as it repeats OpenRawFile() +// return true; + + } // end if( CurrentFileNumber < NumberOfFiles) + + else if ( NumberOfFiles==0 ) { + cout << "ERROR: IMGBoardReader NO RAW DATA FILE WAS ASSOCIATED WITH BOARD " << BoardNumber << ", STOPPING!" << endl << endl; + return false; + } + else { // Otherwise no more file, end the reading + cout << " --> IMGBoardReader " << BoardNumber << ": No more files to read " << CurrentFileNumber+1 << " >= " << NumberOfFiles << " closing!" << endl; + CloseRawFile(); + NoMoreFile = true; + return false; + } + +} + +// -------------------------------------------------------------------------------------- +bool IMGBoardReader::OpenRawFile( const char *fileName) { + + // Open a File of a Run + + RawFileStream.open( fileName); + bool b = RawFileStream.fail(); + if (b == 0) { + BuffersRead = 0; + cout << " -+-+- INFO IMGBoardReader " << BoardNumber << ": File " << fileName << " opened." << endl; + } + else { + cout << " -/-/- INFO IMGBoardReader " << BoardNumber << ": File " << fileName << " not opened, rc = " << b << "." << endl; + } + return !b; + +} + +// -------------------------------------------------------------------------------------- +bool IMGBoardReader::CloseRawFile() { + // Closes a File of a Run + + RawFileStream.close(); + bool b = RawFileStream.fail(); + if (b == 0) + cout << " -+-+- INFO IMGBoardReader " << BoardNumber << ": File " << CurrentFileNumber << " closed " << endl; + else + cout << " -/-/- INFO IMGBoardReader " << BoardNumber << ": File " << CurrentFileNumber << " not closed, rc = " << b << "(eof="<< RawFileStream.eof() << ", bad="<< RawFileStream.bad() <<"." << endl; + return b; + +} + +// -------------------------------------------------------------------------------------- + +bool IMGBoardReader::GetNextBuffer( ) { + + // Try to get the next word index from the Data buffer + // either by reading in the current Data buffer + // either by getting a new Data buffer from file and reading first word + // + // Change the bit order according to the endianess. + // + // SizeOfEvent corresponds typically to one event + // + // + // return "false" if nothing to read, "true" otherwise + // + // JB, 2012/06/ + // Modified: JB, 2012/08/18 test the nb of events read + + bool readSuccess = false; + + // If we have read the full current Data buffer alreay, + // try to get a new Data buffer + // either from the current file or a new one + if ( !( BuffersRead>=EventsInFile || RawFileStream.eof() ) || LookUpRawFile() ) { + + // Now we can get the next data buffer + RawFileStream.read(reinterpret_cast ( &Data[0] ), sizeof(char) * SizeOfEvent); + if(DebugLevel>2) cout << " IMGBoardReader " << BoardNumber << ": Got new data buffer " << BuffersRead << " with gcount=" << RawFileStream.gcount() << " bytes, SizeOfEvent=" << SizeOfEvent << endl; + readSuccess = ( (size_t)RawFileStream.gcount() == SizeOfEvent ); + BuffersRead++; + } + return readSuccess; + +} + +// -------------------------------------------------------------------------------------- + +bool IMGBoardReader::SetBufferPointers( ) { + + // Set the pointers to the differrent buffers, + // event header and each input. + // + // JB, 2012/07/20 + // Modified: JB 2012/08/19 to allow different setup for each input + // Modified: JB 2012/08/21 corrected address compuation + // Modified: JB 2014/11/20 SizeOfTrailer introduced + // Modified: JB 2018/03/18 Consider no even trailer case + + if( Data==NULL) { + cout << "WARNING in IMGBoardReader board " << BoardNumber << ", event pointer is null!" << endl; + return false; + } + + EventHeader = (TEventHeader*)Data; + TriggerLine = EventHeader->VFasCnt[0]; + for( int iInput=0; iInput1 ) cout << " shift for input " << iInput << " is " << InputDataAdress[iInput] << " bytes." << endl; + } + + if( SizeOfTrailer==0 ) { + EventTrailer = (int)0x89abcdef; + if( DebugLevel>1 ) cout << " trailer forced to " << hex << EventTrailer << endl; + } + else if( SizeOfTrailer>4 ) { + EventTrailer = BuildValue( SizeOfEvent - SizeOfTrailer + 4, 4); + } + else { + EventTrailer = BuildValue( SizeOfEvent - SizeOfTrailer, 4); + } + + FramesRead++; + + if( DebugLevel>1 ) cout << " SetBufferPointers for IMGBoard " << BoardNumber << " done, trailer is " << hex << EventTrailer << dec << endl; + +// EventTrailer = (int)0x89abcdef; // use this to trick the final test....only if you know what you are doing! + + return (EventTrailer == (int)0x89abcdef); + +} + +// -------------------------------------------------------------------------------------- + +void IMGBoardReader::PrintEventHeader( ) { + + // Print the buffer information. + // + // From Gilles Claus documentation 17/07/2012 + //VFasCnt[0] = Trigger line + //VFasCnt[1] = Trigger frame = id of the frame on which trigger occurs + //VFasCnt[2] = Number of trigger received since beginning of run + //VFasCnt[3] = Number of trigger accepted by DAQ since beginning of run + // + //VFasReg[0] = Counter of Mi26 Sync pulse read on current trigger / event + //VFasReg[1] = Current value of counter of Mi26 Sync pulse since beginning of run + //VFasReg[2] = Reserved + //VFasReg[3] = Acquisition state ( number of "Acq lines" acquired => should be 128 ) + // + // + // JB, 2012/07/20 (copy of what was in MAF) + + if( EventHeader==NULL) { + cout << "WARNING in IMGBoardReader board " << BoardNumber << ", header pointer is null!" << endl; + return; + } + + printf("EvTrig %10d \n",EventHeader->EvTrig); + printf("EvNo %10d \n", EventHeader->EvNo); + printf("EvPos %10d \n", EventHeader->EvPos); + printf("EvTag %10d \n",EventHeader->EvTag); + printf("EvDate %10d \n",EventHeader->EvDate); + printf("EvTime %10d \n",EventHeader->EvTime); + printf("TrigCnt %10d \n",EventHeader->TrigCnt); + printf("EvVmeTime %10d ms \n",EventHeader->EvVmeTime); + for( int ifas=0; ifasVFasCnt[ifas], EventHeader->VFasReg[ifas]); + } + printf("EvNetTime %10d ms \n",EventHeader->EvNetTime); + printf("MeasNo %5d \n",EventHeader->MeasNo); + printf("EvInMeasNo %5d \n",EventHeader->EvInMeasNo); + + printf("\nEvent trailer 0x%x \n", EventTrailer); + +} + +// -------------------------------------------------------------------------------------- + +void IMGBoardReader::GetInputData( int mode) { + + // Naviguate through the rawdatas in order to: + // If mode = 0 (default) + // Build the rawdata(s) for each channel (=pixel or strip) of each inputs. + // Create the pixel from these rawdata(s). + // + // If mode = 1 + // Search for triggers in a specific channel range. + // + // Associating rawdatas to channels takes into account that: + // - several rawdatas (=values) may be needed to built a channel signal, + // - one rawdata may contain more than one channel signal. + // + // + // + // Add to the event list of frames each frame tested. + // + // JB, 2012/07/20 + // Modified: JB 2012/08/19 allow to read several channels from one value + // Modified: JB 2013/06/16 allow to read several values from one channel + // Modified: JB 2013/06/17 allow to read trigger info from special input + // Modified: JB 2013/06/20 use a mode, to decide what to do + // Modified: JB 2013/06/20 also update frame counter + // Modified: JB 2016/08/17 correction for multiframe mode (compatible with run 34939) + // Modified: JB 2016/09/20 upgrade of multiframe mode to handle both CDS and non-CDS case + // Modified: JB 2020/11/25 blocReading handling + + if( Data==NULL) { + cout << "WARNING in IMGBoardReader board " << BoardNumber << ", event pointer is null!" << endl; + return; + } + + if( mode == 0 ) { + for ( int iFrame=0; iFrame2 ) { + printf( " GetInputData for %s input %d, with %d values and %d channels per value and %d values per channel; mask is 0x%x\n", goal, iInput, totalValuesToRead, NChannelsPerValue[iInput], NValuesPerChannel[iInput], mask); + } + + for( int iValue=0; iValue=NValuesPerChannel[iInput] ) { + channel += NChannelsPerValue[iInput]; //was ++, JB 2013/08/14 + valuesReadForCurrentChannel=0; + } + + // Compute the address of the next value to read depending on + // the number of values already read for this channel (a) + // and the number of channels already read (b) + // When ifMultiFrame add (c) + if( ifMultiFrame ) { + if( WithCDS[iInput] ) { // if CDS ( MIMOSA-32, MIMOSA-34, PIPPER) + shifta = valuesReadForCurrentChannel*NValuesToJumpPerChannel[iInput]*SizeOfValue[iInput]; // previous computation, before 2014 + // channel/NChannelsPerValue[iInput]*NValuesPerChannel[iInput]*SizeOfValue[iInput] // new computation, after 2014/01, BUT does not work with run 34939 ! + // for some reason, the computation does not work if not using (channel/j)*j ... even if it looks stupid + shiftb = (channel/NValuesToJumpPerChannel[iInput])*NValuesToJumpPerChannel[iInput]*NValuesPerChannel[iInput]*SizeOfValue[iInput]; + shiftc = (channel%NValuesToJumpPerChannel[iInput])*SizeOfValue[iInput]; + } + else { // if no CDS (MIMOSA-22-SX) + shifta = valuesReadForCurrentChannel*NValuesToJumpPerChannel[iInput]*SizeOfValue[iInput]; // previous computation, before 2014 + // + channel/NChannelsPerValue[iInput]*NValuesPerChannel[iInput]*SizeOfValue[iInput] // new computation, after 2014/01, BUT does not work with run 34939 ! + shiftb = channel/NChannelsPerValue[iInput]*1*SizeOfValue[iInput]; + shiftc = 0; + } + // if( shiftc != 0 ) cout << "shiftc not zero!" << endl; + } // end if multiframe + + else if( ifBlocReading ) { + shifta = (channel/ifBlocReading)*NValuesToJumpPerChannel[iInput]*SizeOfValue[iInput]; + shiftb = channel/NChannelsPerValue[iInput]*1*SizeOfValue[iInput]; + shiftc = 0; + } + + else { + // Note that in this case NValuesPerChannel=1 AND NValuesToJumpPerChannel=1 + shifta = valuesReadForCurrentChannel*NValuesToJumpPerChannel[iInput]*SizeOfValue[iInput]; + shiftb = channel/NChannelsPerValue[iInput]*NValuesPerChannel[iInput]*SizeOfValue[iInput]; + shiftc = 0; + } + address = InputDataAdress[iInput] + shifta + shiftb + shiftc; + + if( DebugLevel>2 ) printf( " Getting next value with a shift of %d (=%d+%d+%d) bytes computed for channel %d, currentValue %d, ChannelsPerValue %d, ValuesPerChannel %d, ValuesToJumpPerChannel %d, sizeOfValue %d bytes\n", address-InputDataAdress[iInput], shifta, shiftb, shiftc, channel, valuesReadForCurrentChannel, NChannelsPerValue[iInput], NValuesPerChannel[iInput], NValuesToJumpPerChannel[iInput], (Int_t)SizeOfValue[iInput]); + + + // value is a word of SizeOfValue Bytes + // it contains nChannelsPerValue channels + value = BuildValue( address, (int)SizeOfValue[iInput] ); + + // If splitFrames || blocReading option is ON, it means a second value (Frame2) is to be read + if ( ifSplitFrames ) { + // second address = adressOfFrame1 + all frame size + if( DebugLevel>2 ) printf( " getting second value with a shift of %lu bytes computed for channel %d, sizeOfValue %d bytes\n", totalValuesToRead*SizeOfValue[iInput], channel, (Int_t)SizeOfValue[iInput]); + second_value = BuildValue( address+totalValuesToRead*SizeOfValue[iInput], (int)SizeOfValue[iInput] ); + } + else if( ifBlocReading ) { + // second address = adressOfFrame1 + all frame size + if( DebugLevel>2 ) printf( " getting second value with a shift of %lu bytes computed for channel %d, sizeOfValue %d bytes\n", NValuesToJumpPerChannel[iInput]*SizeOfValue[iInput], channel, (Int_t)SizeOfValue[iInput]); + second_value = BuildValue( address+NValuesToJumpPerChannel[iInput]*SizeOfValue[iInput], (int)SizeOfValue[iInput] ); + } + + + if( DebugLevel>3 ) { + printf( " got value[%d] = 0x%x, nb %d for channels %d to %d\n", iValue, value, valuesReadForCurrentChannel, channel, channel+NChannelsPerValue[iInput]-1); + } + + for( int iChannel=channel; iChannel> SignificantBits[iInput]; + if( DebugLevel>3 ) { + printf( " channel[%d] = 0x%x (value is now 0x%x) (0-supp on = %d, threshold = %d)\n", iChannel, rawdata, value, IfZeroSupress, ZeroThreshold); + } + if( valuesReadForCurrentChannel == NValuesPerChannel[iInput]-1 ) { + + if ( mode==1 && FirstTriggerChannel[iInput]<=iChannel && iChannel<=LastTriggerChannel[iInput] ) { + DecodeTriggerFromData( iInput, iChannel-FirstTriggerChannel[iInput], rawdatas, NValuesPerChannel[iInput]); + } + + else if ( mode==0 + && !(FirstTriggerChannel[iInput]<=iChannel + && iChannel<=LastTriggerChannel[iInput]) + && !(FirstExcludedChannel[iInput]<=iChannel + && iChannel<=LastExcludedChannel[iInput]) + ) { // standard pixel + + if ( ifSplitFrames || ifBlocReading ) { // perform CDS here, JB 2014/11/20 + second_rawdata = second_value & mask; + rawdatas[valuesReadForCurrentChannel] = rawdata - second_rawdata; + if( DebugLevel>3 ) { + printf( " got second value[%d] = 0x%x, nb %d for channels %d to %d\n", iValue, second_value, valuesReadForCurrentChannel, channel, channel+NChannelsPerValue[iInput]-1); + printf( " second channel[%d] = 0x%x\n", iChannel, second_rawdata); + printf( " CDS for channel[%d] = 0x%x\n", iChannel, rawdatas[valuesReadForCurrentChannel]); + } + } + + AddPixel( iInput, rawdatas, NValuesPerChannel[iInput], iChannel); + + } + + } + } // end loop on channels contained in a value + + valuesReadForCurrentChannel++; + + } // end loop on values + + delete[] rawdatas; // reduce memory leak, BH 2013/08/21 + } // end loop on inputs + +} + +// -------------------------------------------------------------------------------------- + +void IMGBoardReader::GetTriggerData( ) { + + // Get the information on the trigger position + // + // + // JB, 2012/08/18 + // Modified: JB 2013/06/20 allow to search for trigger in data + + ListOfTriggers.push_back( EventHeader->VFasCnt[0] ); // get trigger in header + + if( ifMultiFrame ) { // search for trigger in data, JB 2013/06/20 + ListOfTriggersFromData.clear(); + GetInputData( 1); + ListOfTriggers.insert( ListOfTriggers.end(), ListOfTriggersFromData.begin(), ListOfTriggersFromData.end()); + } + + if( DebugLevel ) { + printf(" Total triggers found in event = %d: at lines =", (int)ListOfTriggers.size()); + for ( int iTrig=0; iTrig<(int)ListOfTriggers.size(); iTrig++ ) { + printf(" %d", ListOfTriggers.at(iTrig) ); + } + printf("\n"); + } + +} + +// -------------------------------------------------------------------------------------- + +int IMGBoardReader::DecodeTriggerFromData( int input, int rowNumber, unsigned int *rawdatas, int nFrames) { + + // From the rawdata of each frame (more than one if ifMultiframe) + // test if the value is in the expected range for a trigger. + // If so, add the corresponding line number in the trigger list. + // + // JB 2013/06/17 + // Modified: JB 2013/06/23 detect trigger up front, not just value + + int nFoundTriggers = 0; + bool triggerUp = false; + int triggerRow; + signed int value; + //signed int previousValue; + signed short int *frames = new signed short int[nFrames*2]; + + // Re-order the frames in a "physical" order, + // knowing that + for ( int iFrame=0; iFrame3 ) printf( " raw[%d] = 0x%8x -> frame[%d] = 0x%4x, frame[%d] = 0x%4x\n", iFrame, rawdatas[iFrame], iFrame, frames[iFrame], iFrame+nFrames, frames[iFrame+nFrames]); + } // end loop on daq frames + + // Search for a trigger in the physical frames. + // Do not consider two triggers on consecutive lines with same value, + // this is a "feature" of the DAQ system and only ONE trigger shall be kept. + for ( int iFrame=0; iFrame<2*nFrames; iFrame++) { // loop on physical frames + value = (int)frames[iFrame]; + triggerRow = rowNumber + iFrame*NValuesToJumpPerChannel[input]; + + if( triggerLowThreshold <= value && value <= triggerHighThreshold ) { + // Create a new trigger only if + // there was none seen in the previous rows (triggerUp would be true), + // it is not the same as the one registered in the EventHeader. + if( !triggerUp && abs(triggerRow-EventHeader->VFasCnt[0])>1 ) { + triggerUp = true; + //previousValue = value; + if( DebugLevel>1 ) printf( " found trigger nb %d at row %d and frame %d with value 0x%4x or %d\n", nFoundTriggers, triggerRow, iFrame, value, value); + ListOfTriggersFromData.push_back( triggerRow); + nFoundTriggers++; + } + else if( DebugLevel>1 ) { + printf(" trigger %d still up at row %d\n", nFoundTriggers, triggerRow); + } + } + else { + triggerUp = false; + } + + } // end loop on physical frames + + delete[] frames; // remove memory leaks, BH 2013/08/21 + return nFoundTriggers; + +} + +// -------------------------------------------------------------------------------------- + +void IMGBoardReader::AddPixel( int input, unsigned int rawdata, int index) { + + // Compute the signal value of the channel (or pixel) from the rawdata value + // and add the pixel to the vector of pixels + // + // THIS VERSION STILL DOES NOT HAVE THE CORRECT POLARIZATION COMPUTATION + // + // Requires the following info + // - input = input number of the board + // - rawdata = rawdata value containing the two frames embedded (if CDS) + // - index = index of this pixel on this input + // + // JB, 2008/09/27 + // Modified: SS, 2012/08/01 signed frame value + // Modified: JB, 2012/08/18 CDS or no-CDS possibility + // Modified: SS, 2012/08/21 correct CDS according to trigger position + // Modified: JB, 2012/08/22 specific input-index setup when strip-telescope + // Modified: JB, 2013/08/18 trim 0 when significantBit==1 (binary output) + // Modified: JB, 2017/11/20 new mode for zero suppression + + int trueInput = input; + int trueIndex = index; + + if( ifStripTelescope ) { // specific settings when strip-telescope read + // re-shuffle the channel of the first input to inputs 0-4 + // other inputs correspond to input+3 + if( input<2 ) { + trueIndex = index/4+(index%4)*NbOfChannels[input]; // was index/4 + trueInput = input; // was index%4 + } + else { + trueIndex = index; + trueInput = input; // was input+3 + } + } + + //unsigned int value; + signed int value; + + if( !WithCDS[input] || ifSplitFrames || ifBlocReading ) { // if no CDS needed or already performed + value = rawdata; + if( DebugLevel>2 ) { + printf( " input %d, channel %d: raw = 0x%8x, value = 0x%8x or %d\n", input, index, rawdata, value, value); + } + } + + else { // With CDS + //SS 2012.08.10 frame1 and frame2 should be signed short int to keep values between -32768 and +32678 +// signed short int *frames = new signed short int[NValuesPerChannel[input]]; +// signed int *values = new signed int[NValuesPerChannel[input]]; +// for( int iFrame=0; iFrame> SignificantBits[input]; +// values[iFrame] = frames[iFrame]-frames[(iFrame>0?iFrame-1:0)]; +// if( DebugLevel>3 ) printf( " frame[%d] = 0x%x or %d, value = 0x%x or %d, raw = 0x%x\n\n", iFrame, frames[iFrame], frames[iFrame], values[iFrame], values[iFrame], rawdata); +// } + + signed short int frame1 = rawdata / MaxSignedValue[input]; + signed short int frame2 = rawdata % MaxSignedValue[input]; + + // Decision of polarity + // from TriggerLine + // SS 2012/08/21 +/* int TriggerLine2=TriggerLine/5; + int TriggerLine3=TriggerLine%64; + int PixelLine=index%64; //here the transformation from index to PixelLine is hardcoded for Mimosa 32 which has 64 lines. + if (TriggerLine2>63) { + if (PixelLine>TriggerLine3) { + value=frame1-frame2; + } + else{ + value=frame2-frame1; + } + } + else{ + if (PixelLine>TriggerLine3) { + value=frame2-frame1; + } + else{ + value=frame1-frame2; + } + } */ + // CDS using absolute value. + // the absolute value is set in DPlane depending on the #events / init + value = (int)(frame1 - frame2); + if( DebugLevel>2 ) printf( " input %d, channel %d: raw = 0x%8x, frame1 = 0x%4x, frame2 = 0x%4x, value = 0x%4x or %d (0-supp on = %d, threshold = %d)\n", input, index, rawdata, frame1, frame2, value, value, IfZeroSupress, ZeroThreshold); + +// if (ifMultiFrame) { +// value = values[5]-values[4]; +// } +// else { +// value = values[1]-values[0]; +// } +// +// if( DebugLevel>3 ) printf( " input %d, channel %d: raw = 0x%x, value = 0x%4x or %d\n", input, index, rawdata, value, value); + + } // end with CDS + + // If binary output, create a pixel only if non-zero value, JB 2013/08/18 + // test if zero suppression is required + if ( abs(SignificantBits[input])!=1 || value!=0 ) { + if( IfZeroSupress == 0 || value > ZeroThreshold ) { + ListOfPixels.push_back( IMGPixel( trueInput, value, trueIndex)); + } + } + +} + +// -------------------------------------------------------------------------------------- + +void IMGBoardReader::AddPixel( int input, unsigned int *rawdatas, int nFrames, int index) { + + // Compute the signal value of the channel (or pixel) from the rawdata value + // and add the pixel to the vector of pixels + // + // THIS VERSION STILL DOES NOT HAVE THE CORRECT POLARIZATION COMPUTATION + // + // Requires the following info + // - input = input number of the board + // - rawdatas = array of nFrames rawdata values, + // each containing two frames embedded (if CDS) + // - index = index of this pixel on this input + // + // How pixel values are computed if nFrames>1 + // - if no CDS required, simply associate each rawdata to one frame value, + // - if CDS required, re-organize the frames in the following way: + // In the case of nFrames = 5 => 2x5=10 frames are contained in rawdatas + // and 9 CDS values will be build + // frame[0] = frame1_rawdatas[0] + // frame[1] = frame1_rawdatas[1] + // ... + // frame[3] = frame1_rawdatas[3] + // frame[4] = frame1_rawdatas[4] + // frame[5] = frame2_rawdatas[0] + // frame[6] = frame2_rawdatas[1] + // ... + // frame[8] = frame2_rawdatas[3] + // frame[9] = frame2_rawdatas[4] + // and + // event 0 = frame[0]-frame[1] + // event 1 = frame[1]-frame[2] + // ... + // event 7 = frame[7]-frame[8] + // event 8 = frame[8]-frame[9] + // + // Behaviour is also adapted for flags ifStripTelescope & if16outputs + // + // JB, 2008/09/27 + // Modified: SS, 2012/08/01 signed frame value + // Modified: JB, 2012/08/18 CDS or no-CDS possibility + // Modified: SS, 2012/08/21 correct CDS according to trigger position + // Modified: JB, 2012/08/22 specific input-index setup when strip-telescope + // Modified: JB, 2013/06/19 manage multi-frame rawdatas + // Modified: JB, 2013/07/19 memory leak fixed with delete frames + // Modified: JB, 2017/03/03 new mode for if16outputs + // Modified: JB, 2017/11/20 new mode for zero suppression + + int trueInput = input; + int trueIndex = index; + + if( ifStripTelescope ) { // specific settings when strip-telescope read + // re-shuffle the channels of the first input to input 0-3 + // other inputs correspond to input+3 + if( input<2 ) { + trueIndex = index/4+(index%4)*NbOfChannels[input]/4; // was index/4 + trueInput = input; // was index%4 + } + else { + trueIndex = index; + trueInput = input; // was input + } + } + + if( if16outputs ) { // Maciej's DAQ for MIMOSA-22-SX, 2017/03/03 + // 1U16 => [127,119,111,103,95,...,23,15,7] u=0 + // 2U16 => [126,118,110,102,94,...,22,14,6] u=1 + // . + // 8U16 => [120,112,104,196,88,...,16, 8,0] u=7 + Int_t u = index/16; + Int_t b = index%16; + trueIndex = 7 - (u-1)%8 + 128*((u-1)/8) + b*8; + //printf( " trueIndex = %5d (or %5d) from index=%5d with u=%4d and b=%2d\n", trueIndex, 8 - u%8 + b*8 + 128*(u/8), index, u, b); + } + + //unsigned int value; + signed int value; + + if( !WithCDS[input] || ifSplitFrames || ifBlocReading ) { // if no CDS needed or already performed + for ( int iFrame=0; iFrame new pixel = %d\n", value!=0, SignificantBits[input], abs(SignificantBits[input])!=1, abs(SignificantBits[input])!=1 || value!=0); + if ( abs(SignificantBits[input])!=1 || value!=0 ) { + if( IfZeroSupress == 0 || value > ZeroThreshold ) { + ListOfPixels.push_back( IMGPixel( trueInput, value, trueIndex)); + } + if( DebugLevel>2 ) { + printf( " input %d(true %d), channel %d(true %d): raw = 0x%8x, value = 0x%8x or %d for frame %d\n", input, trueInput, index, trueIndex, rawdatas[iFrame], value, value, iFrame); + } + } + } // end loop on frames + } + + else { // With CDS + //SS 2012.08.10 frame1 and frame2 should be signed short int to keep values between -32768 and +32678 + // signed short int *frames = new signed short int[NValuesPerChannel[input]]; + // signed int *values = new signed int[NValuesPerChannel[input]]; + // for( int iFrame=0; iFrame> SignificantBits[input]; + // values[iFrame] = frames[iFrame]-frames[(iFrame>0?iFrame-1:0)]; + // if( DebugLevel>3 ) printf( " frame[%d] = 0x%x or %d, value = 0x%x or %d, raw = 0x%x\n\n", iFrame, frames[iFrame], frames[iFrame], values[iFrame], values[iFrame], rawdata); + // } + + signed short int *frames = new signed short int[nFrames*2]; + + // Re-order the frames in a "physical" order, + // knowing that + for ( int iFrame=0; iFrame3 ) printf( " raw[%d] = 0x%8x -> frame[%d] = 0x%4x, frame[%d] = 0x%4x\n", iFrame, rawdatas[iFrame], iFrame*2, frames[iFrame*2], iFrame*2+1, frames[iFrame*2+1]); + frames[iFrame] = rawdatas[iFrame] / MaxSignedValue[input]; + frames[iFrame+nFrames] = rawdatas[iFrame] % MaxSignedValue[input]; + if( DebugLevel>2 ) printf( " raw[%d] = 0x%8x -> frame[%d] = 0x%4x, frame[%d] = 0x%4x\n", iFrame, rawdatas[iFrame], iFrame, frames[iFrame], iFrame+nFrames, frames[iFrame+nFrames]); + } // end loop on daq frames + + // Build pixel signal for each physical events following + // signal(frame i+1) = frame[i]-frame[i+1] with i<2*nFrames-1 + // CURRENTLY: CDS using absolute value. + // the absolute value is set in DPlane depending on the #events / init + // + +// for ( int iFrame=0; iFrame3 ) printf( " input %d(true %d), channel %d(true %d), timestamp %d: frame1 = 0x%4x, frame2 = 0x%4x, value = 0x%4x or %d\n", input, trueInput, index, trueIndex, iFrame, frames[2*iFrame], frames[2*iFrame+1], value, value); + + for ( int iFrame=0; iFrame<2*nFrames-1; iFrame++) { // loop on physical frames + value = (int)(frames[iFrame] - frames[iFrame+1]); + + if( DebugLevel>2 ) printf( " input %d(true %d), channel %d(true %d), timestamp %d: frame1 = 0x%4x, frame2 = 0x%4x, value = 0x%4x or %d (0-supp on = %d, threshold = %d)\n", input, trueInput, index, trueIndex, iFrame, frames[iFrame], frames[iFrame+1], value, value, IfZeroSupress, ZeroThreshold ); + + /*if( iFrame==4)*/ + /*if( 2